diff --git a/Documentation/RCU/RTFP.txt b/Documentation/RCU/RTFP.txt
index fcbcbc3..6221464 100644
--- a/Documentation/RCU/RTFP.txt
+++ b/Documentation/RCU/RTFP.txt
@@ -90,16 +90,20 @@ at OLS.  The resulting abundance of RCU 
 following year [McKenney02a], and use of RCU in dcache was first
 described that same year [Linder02a].
 
-Also in 2002, Michael [Michael02b,Michael02a] presented techniques
-that defer the destruction of data structures to simplify non-blocking
-synchronization (wait-free synchronization, lock-free synchronization,
-and obstruction-free synchronization are all examples of non-blocking
-synchronization).  In particular, this technique eliminates locking,
-reduces contention, reduces memory latency for readers, and parallelizes
-pipeline stalls and memory latency for writers.  However, these
-techniques still impose significant read-side overhead in the form of
-memory barriers.  Researchers at Sun worked along similar lines in the
-same timeframe [HerlihyLM02,HerlihyLMS03].
+Also in 2002, Michael [Michael02b,Michael02a] presented "hazard-pointer"
+techniques that defer the destruction of data structures to simplify
+non-blocking synchronization (wait-free synchronization, lock-free
+synchronization, and obstruction-free synchronization are all examples of
+non-blocking synchronization).  In particular, this technique eliminates
+locking, reduces contention, reduces memory latency for readers, and
+parallelizes pipeline stalls and memory latency for writers.  However,
+these techniques still impose significant read-side overhead in the
+form of memory barriers.  Researchers at Sun worked along similar lines
+in the same timeframe [HerlihyLM02,HerlihyLMS03].  These techniques
+can be thought of as inside-out reference counts, where the count is
+represented by the number of hazard pointers referencing a given data
+structure (rather than the more conventional counter field within the
+data structure itself).
 
 In 2003, the K42 group described how RCU could be used to create
 hot-pluggable implementations of operating-system functions.  Later that
@@ -113,7 +117,6 @@ number of operating-system kernels [Paul
 describing how to make RCU safe for soft-realtime applications [Sarma04c],
 and a paper describing SELinux performance with RCU [JamesMorris04b].
 
-
 2005 has seen further adaptation of RCU to realtime use, permitting
 preemption of RCU realtime critical sections [PaulMcKenney05a,
 PaulMcKenney05b].
diff --git a/Documentation/RCU/checklist.txt b/Documentation/RCU/checklist.txt
index e118a7c..49e27cc 100644
--- a/Documentation/RCU/checklist.txt
+++ b/Documentation/RCU/checklist.txt
@@ -177,3 +177,9 @@ over a rather long period of time, but i
 
 	If you want to wait for some of these other things, you might
 	instead need to use synchronize_irq() or synchronize_sched().
+
+12.	Any lock acquired by an RCU callback must be acquired elsewhere
+	with irq disabled, e.g., via spin_lock_irqsave().  Failing to
+	disable irq on a given acquisition of that lock will result in
+	deadlock as soon as the RCU callback happens to interrupt that
+	acquisition's critical section.
diff --git a/Documentation/RCU/listRCU.txt b/Documentation/RCU/listRCU.txt
index f8a54fa..1fd1753 100644
--- a/Documentation/RCU/listRCU.txt
+++ b/Documentation/RCU/listRCU.txt
@@ -232,7 +232,7 @@ entry does not exist.  For this to be he
 return holding the per-entry spinlock, as ipc_lock() does in fact do.
 
 Quick Quiz:  Why does the search function need to return holding the
-per-entry lock for this deleted-flag technique to be helpful?
+	per-entry lock for this deleted-flag technique to be helpful?
 
 If the system-call audit module were to ever need to reject stale data,
 one way to accomplish this would be to add a "deleted" flag and a "lock"
@@ -275,8 +275,8 @@ flag under the spinlock as follows:
 	{
 		struct audit_entry  *e;
 
-		/* Do not use the _rcu iterator here, since this is the only
-		 * deletion routine. */
+		/* Do not need to use the _rcu iterator here, since this
+		 * is the only deletion routine. */
 		list_for_each_entry(e, list, list) {
 			if (!audit_compare_rule(rule, &e->rule)) {
 				spin_lock(&e->lock);
@@ -304,9 +304,12 @@ function to reject newly deleted data.
 
 
 Answer to Quick Quiz
+	Why does the search function need to return holding the per-entry
+	lock for this deleted-flag technique to be helpful?
 
-If the search function drops the per-entry lock before returning, then
-the caller will be processing stale data in any case.  If it is really
-OK to be processing stale data, then you don't need a "deleted" flag.
-If processing stale data really is a problem, then you need to hold the
-per-entry lock across all of the code that uses the value looked up.
+	If the search function drops the per-entry lock before returning,
+	then the caller will be processing stale data in any case.  If it
+	is really OK to be processing stale data, then you don't need a
+	"deleted" flag.  If processing stale data really is a problem,
+	then you need to hold the per-entry lock across all of the code
+	that uses the value that was returned.
diff --git a/Documentation/RCU/rcu.txt b/Documentation/RCU/rcu.txt
index 6fa0922..02e27bf 100644
--- a/Documentation/RCU/rcu.txt
+++ b/Documentation/RCU/rcu.txt
@@ -111,6 +111,11 @@ o	What are all these files in this direc
 
 		You are reading it!
 
+	rcuref.txt
+
+		Describes how to combine use of reference counts
+		with RCU.
+
 	whatisRCU.txt
 
 		Overview of how the RCU implementation works.  Along
diff --git a/Documentation/RCU/rcuref.txt b/Documentation/RCU/rcuref.txt
index 3f60db4..451de2a 100644
--- a/Documentation/RCU/rcuref.txt
+++ b/Documentation/RCU/rcuref.txt
@@ -1,7 +1,7 @@
-Refcounter design for elements of lists/arrays protected by RCU.
+Reference-count design for elements of lists/arrays protected by RCU.
 
-Refcounting on elements of  lists which are protected by traditional
-reader/writer spinlocks or semaphores are straight forward as in:
+Reference counting on elements of lists which are protected by traditional
+reader/writer spinlocks or semaphores are straightforward:
 
 1.				2.
 add()				search_and_reference()
@@ -28,12 +28,12 @@ release_referenced()			delete()
 					    ...
 					}
 
-If this list/array is made lock free using rcu as in changing the
-write_lock in add() and delete() to spin_lock and changing read_lock
+If this list/array is made lock free using RCU as in changing the
+write_lock() in add() and delete() to spin_lock and changing read_lock
 in search_and_reference to rcu_read_lock(), the atomic_get in
 search_and_reference could potentially hold reference to an element which
-has already been deleted from the list/array.  atomic_inc_not_zero takes
-care of this scenario. search_and_reference should look as;
+has already been deleted from the list/array.  Use atomic_inc_not_zero()
+in this scenario as follows:
 
 1.					2.
 add()					search_and_reference()
@@ -51,17 +51,16 @@ add()					search_and_reference()
 release_referenced()			delete()
 {					{
     ...					    write_lock(&list_lock);
-    atomic_dec(&el->rc, relfunc)	    ...
-    ...					    delete_element
-}					    write_unlock(&list_lock);
- 					    ...
+    if (atomic_dec_and_test(&el->rc))       ...
+        call_rcu(&el->head, el_free);       delete_element
+    ...                                     write_unlock(&list_lock);
+} 					    ...
 					    if (atomic_dec_and_test(&el->rc))
 					        call_rcu(&el->head, el_free);
 					    ...
 					}
 
-Sometimes, reference to the element need to be obtained in the
-update (write) stream.  In such cases, atomic_inc_not_zero might be an
-overkill since the spinlock serialising list updates are held. atomic_inc
-is to be used in such cases.
-
+Sometimes, a reference to the element needs to be obtained in the
+update (write) stream.  In such cases, atomic_inc_not_zero() might be
+overkill, since we hold the update-side spinlock.  One might instead
+use atomic_inc() in such cases.
diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt
index 15da168..5ed85af 100644
--- a/Documentation/RCU/whatisRCU.txt
+++ b/Documentation/RCU/whatisRCU.txt
@@ -200,10 +200,11 @@ rcu_assign_pointer()
 	the new value, and also executes any memory-barrier instructions
 	required for a given CPU architecture.
 
-	Perhaps more important, it serves to document which pointers
-	are protected by RCU.  That said, rcu_assign_pointer() is most
-	frequently used indirectly, via the _rcu list-manipulation
-	primitives such as list_add_rcu().
+	Perhaps just as important, it serves to document (1) which
+	pointers are protected by RCU and (2) the point at which a
+	given structure becomes accessible to other CPUs.  That said,
+	rcu_assign_pointer() is most frequently used indirectly, via
+	the _rcu list-manipulation primitives such as list_add_rcu().
 
 rcu_dereference()
 
@@ -258,9 +259,11 @@ rcu_dereference()
 	locking.
 
 	As with rcu_assign_pointer(), an important function of
-	rcu_dereference() is to document which pointers are protected
-	by RCU.  And, again like rcu_assign_pointer(), rcu_dereference()
-	is typically used indirectly, via the _rcu list-manipulation
+	rcu_dereference() is to document which pointers are protected by
+	RCU, in particular, flagging a pointer that is subject to changing
+	at any time, including immediately after the rcu_dereference().
+	And, again like rcu_assign_pointer(), rcu_dereference() is
+	typically used indirectly, via the _rcu list-manipulation
 	primitives, such as list_for_each_entry_rcu().
 
 The following diagram shows how each API communicates among the
@@ -327,7 +330,7 @@ for specialized uses, but are relatively
 3.  WHAT ARE SOME EXAMPLE USES OF CORE RCU API?
 
 This section shows a simple use of the core RCU API to protect a
-global pointer to a dynamically allocated structure.  More typical
+global pointer to a dynamically allocated structure.  More-typical
 uses of RCU may be found in listRCU.txt, arrayRCU.txt, and NMI-RCU.txt.
 
 	struct foo {
@@ -410,6 +413,8 @@ o	Use synchronize_rcu() -after- removing
 	data item.
 
 See checklist.txt for additional rules to follow when using RCU.
+And again, more-typical uses of RCU may be found in listRCU.txt,
+arrayRCU.txt, and NMI-RCU.txt.
 
 
 4.  WHAT IF MY UPDATING THREAD CANNOT BLOCK?
@@ -513,7 +518,7 @@ production-quality implementation, and s
 
 for papers describing the Linux kernel RCU implementation.  The OLS'01
 and OLS'02 papers are a good introduction, and the dissertation provides
-more details on the current implementation.
+more details on the current implementation as of early 2004.
 
 
 5A.  "TOY" IMPLEMENTATION #1: LOCKING
@@ -768,7 +773,6 @@ RCU pointer/list traversal:
 	rcu_dereference
 	list_for_each_rcu		(to be deprecated in favor of
 					 list_for_each_entry_rcu)
-	list_for_each_safe_rcu		(deprecated, not used)
 	list_for_each_entry_rcu
 	list_for_each_continue_rcu	(to be deprecated in favor of new
 					 list_for_each_entry_continue_rcu)
@@ -807,7 +811,8 @@ Quick Quiz #1:	Why is this argument naiv
 Answer:		Consider the following sequence of events:
 
 		1.	CPU 0 acquires some unrelated lock, call it
-			"problematic_lock".
+			"problematic_lock", disabling irq via
+			spin_lock_irqsave().
 
 		2.	CPU 1 enters synchronize_rcu(), write-acquiring
 			rcu_gp_mutex.
@@ -894,7 +899,7 @@ Answer:		Just as PREEMPT_RT permits pree
 ACKNOWLEDGEMENTS
 
 My thanks to the people who helped make this human-readable, including
-Jon Walpole, Josh Triplett, Serge Hallyn, and Suzanne Wood.
+Jon Walpole, Josh Triplett, Serge Hallyn, Suzanne Wood, and Alan Stern.
 
 
 For more information, see http://www.rdrop.com/users/paulmck/RCU.
diff --git a/Documentation/drivers/edac/edac.txt b/Documentation/drivers/edac/edac.txt
new file mode 100644
index 0000000..d37191f
--- /dev/null
+++ b/Documentation/drivers/edac/edac.txt
@@ -0,0 +1,673 @@
+
+
+EDAC - Error Detection And Correction
+
+Written by Doug Thompson <norsk5@xmission.com>
+7 Dec 2005
+
+
+EDAC was written by:
+	Thayne Harbaugh,
+	modified by Dave Peterson, Doug Thompson, et al,
+	from the bluesmoke.sourceforge.net project.
+
+
+============================================================================
+EDAC PURPOSE
+
+The 'edac' kernel module goal is to detect and report errors that occur
+within the computer system. In the initial release, memory Correctable Errors
+(CE) and Uncorrectable Errors (UE) are the primary errors being harvested.
+
+Detecting CE events, then harvesting those events and reporting them,
+CAN be a predictor of future UE events.  With CE events, the system can
+continue to operate, but with less safety. Preventive maintainence and
+proactive part replacement of memory DIMMs exhibiting CEs can reduce
+the likelihood of the dreaded UE events and system 'panics'.
+
+
+In addition, PCI Bus Parity and SERR Errors are scanned for on PCI devices
+in order to determine if errors are occurring on data transfers.
+The presence of PCI Parity errors must be examined with a grain of salt.
+There are several addin adapters that do NOT follow the PCI specification
+with regards to Parity generation and reporting. The specification says
+the vendor should tie the parity status bits to 0 if they do not intend
+to generate parity.  Some vendors do not do this, and thus the parity bit
+can "float" giving false positives.
+
+The PCI Parity EDAC device has the ability to "skip" known flakey
+cards during the parity scan. These are set by the parity "blacklist"
+interface in the sysfs for PCI Parity. (See the PCI section in the sysfs
+section below.) There is also a parity "whitelist" which is used as
+an explicit list of devices to scan, while the blacklist is a list
+of devices to skip.
+
+EDAC will have future error detectors that will be added or integrated
+into EDAC in the following list:
+
+	MCE	Machine Check Exception
+	MCA	Machine Check Architecture
+	NMI	NMI notification of ECC errors
+	MSRs 	Machine Specific Register error cases
+	and other mechanisms.
+
+These errors are usually bus errors, ECC errors, thermal throttling
+and the like.
+
+
+============================================================================
+EDAC VERSIONING
+
+EDAC is composed of a "core" module (edac_mc.ko) and several Memory
+Controller (MC) driver modules. On a given system, the CORE
+is loaded and one MC driver will be loaded. Both the CORE and
+the MC driver have individual versions that reflect current release
+level of their respective modules.  Thus, to "report" on what version
+a system is running, one must report both the CORE's and the
+MC driver's versions.
+
+
+LOADING
+
+If 'edac' was statically linked with the kernel then no loading is
+necessary.  If 'edac' was built as modules then simply modprobe the
+'edac' pieces that you need.  You should be able to modprobe
+hardware-specific modules and have the dependencies load the necessary core
+modules.
+
+Example:
+
+$> modprobe amd76x_edac
+
+loads both the amd76x_edac.ko memory controller module and the edac_mc.ko
+core module.
+
+
+============================================================================
+EDAC sysfs INTERFACE
+
+EDAC presents a 'sysfs' interface for control, reporting and attribute
+reporting purposes.
+
+EDAC lives in the /sys/devices/system/edac directory. Within this directory
+there currently reside 2 'edac' components:
+
+	mc	memory controller(s) system
+	pci	PCI status system
+
+
+============================================================================
+Memory Controller (mc) Model
+
+First a background on the memory controller's model abstracted in EDAC.
+Each mc device controls a set of DIMM memory modules. These modules are
+layed out in a Chip-Select Row (csrowX) and Channel table (chX). There can
+be multiple csrows and two channels.
+
+Memory controllers allow for several csrows, with 8 csrows being a typical value.
+Yet, the actual number of csrows depends on the electrical "loading"
+of a given motherboard, memory controller and DIMM characteristics.
+
+Dual channels allows for 128 bit data transfers to the CPU from memory.
+
+
+		Channel 0	Channel 1
+	===================================
+	csrow0	| DIMM_A0	| DIMM_B0 |
+	csrow1	| DIMM_A0	| DIMM_B0 |
+	===================================
+
+	===================================
+	csrow2	| DIMM_A1	| DIMM_B1 |
+	csrow3	| DIMM_A1	| DIMM_B1 |
+	===================================
+
+In the above example table there are 4 physical slots on the motherboard
+for memory DIMMs:
+
+	DIMM_A0
+	DIMM_B0
+	DIMM_A1
+	DIMM_B1
+
+Labels for these slots are usually silk screened on the motherboard. Slots
+labeled 'A' are channel 0 in this example. Slots labled 'B'
+are channel 1. Notice that there are two csrows possible on a
+physical DIMM. These csrows are allocated their csrow assignment
+based on the slot into which the memory DIMM is placed. Thus, when 1 DIMM
+is placed in each Channel, the csrows cross both DIMMs.
+
+Memory DIMMs come single or dual "ranked". A rank is a populated csrow.
+Thus, 2 single ranked DIMMs, placed in slots DIMM_A0 and DIMM_B0 above
+will have 1 csrow, csrow0. csrow1 will be empty. On the other hand,
+when 2 dual ranked DIMMs are similiaryly placed, then both csrow0 and
+csrow1 will be populated. The pattern repeats itself for csrow2 and
+csrow3.
+
+The representation of the above is reflected in the directory tree
+in EDAC's sysfs interface. Starting in directory
+/sys/devices/system/edac/mc each memory controller will be represented
+by its own 'mcX' directory, where 'X" is the index of the MC.
+
+
+	..../edac/mc/
+		   |
+		   |->mc0
+		   |->mc1
+		   |->mc2
+		   ....
+
+Under each 'mcX' directory each 'csrowX' is again represented by a
+'csrowX', where 'X" is the csrow index:
+
+
+	.../mc/mc0/
+		|
+		|->csrow0
+		|->csrow2
+		|->csrow3
+		....
+
+Notice that there is no csrow1, which indicates that csrow0 is
+composed of a single ranked DIMMs. This should also apply in both
+Channels, in order to have dual-channel mode be operational. Since
+both csrow2 and csrow3 are populated, this indicates a dual ranked
+set of DIMMs for channels 0 and 1.
+
+
+Within each of the 'mc','mcX' and 'csrowX' directories are several
+EDAC control and attribute files.
+
+
+============================================================================
+DIRECTORY 'mc'
+
+In directory 'mc' are EDAC system overall control and attribute files:
+
+
+Panic on UE control file:
+
+	'panic_on_ue'
+
+	An uncorrectable error will cause a machine panic.  This is usually
+	desirable.  It is a bad idea to continue when an uncorrectable error
+	occurs - it is indeterminate what was uncorrected and the operating
+	system context might be so mangled that continuing will lead to further
+	corruption. If the kernel has MCE configured, then EDAC will never
+	notice the UE.
+
+	LOAD TIME: module/kernel parameter: panic_on_ue=[0|1]
+
+	RUN TIME:  echo "1" >/sys/devices/system/edac/mc/panic_on_ue
+
+
+Log UE control file:
+
+	'log_ue'
+
+	Generate kernel messages describing uncorrectable errors.  These errors
+	are reported through the system message log system.  UE statistics
+	will be accumulated even when UE logging is disabled.
+
+	LOAD TIME: module/kernel parameter: log_ue=[0|1]
+
+	RUN TIME: echo "1" >/sys/devices/system/edac/mc/log_ue
+
+
+Log CE control file:
+
+	'log_ce'
+
+	Generate kernel messages describing correctable errors.  These
+	errors are reported through the system message log system.
+	CE statistics will be accumulated even when CE logging is disabled.
+
+	LOAD TIME: module/kernel parameter: log_ce=[0|1]
+
+	RUN TIME: echo "1" >/sys/devices/system/edac/mc/log_ce
+
+
+Polling period control file:
+
+	'poll_msec'
+
+	The time period, in milliseconds, for polling for error information.
+	Too small a value wastes resources.  Too large a value might delay
+	necessary handling of errors and might loose valuable information for
+	locating the error.  1000 milliseconds (once each second) is about
+	right for most uses.
+
+	LOAD TIME: module/kernel parameter: poll_msec=[0|1]
+
+	RUN TIME: echo "1000" >/sys/devices/system/edac/mc/poll_msec
+
+
+Module Version read-only attribute file:
+
+	'mc_version'
+
+	The EDAC CORE modules's version and compile date are shown here to
+	indicate what EDAC is running.
+
+
+
+============================================================================
+'mcX' DIRECTORIES
+
+
+In 'mcX' directories are EDAC control and attribute files for
+this 'X" instance of the memory controllers:
+
+
+Counter reset control file:
+
+	'reset_counters'
+
+	This write-only control file will zero all the statistical counters
+	for UE and CE errors.  Zeroing the counters will also reset the timer
+	indicating how long since the last counter zero.  This is useful
+	for computing errors/time.  Since the counters are always reset at
+	driver initialization time, no module/kernel parameter is available.
+
+	RUN TIME: echo "anything" >/sys/devices/system/edac/mc/mc0/counter_reset
+
+		This resets the counters on memory controller 0
+
+
+Seconds since last counter reset control file:
+
+	'seconds_since_reset'
+
+	This attribute file displays how many seconds have elapsed since the
+	last counter reset. This can be used with the error counters to
+	measure error rates.
+
+
+
+DIMM capability attribute file:
+
+	'edac_capability'
+
+	The EDAC (Error Detection and Correction) capabilities/modes of
+	the memory controller hardware.
+
+
+DIMM Current Capability attribute file:
+
+	'edac_current_capability'
+
+	The EDAC capabilities available with the hardware
+	configuration.  This may not be the same as "EDAC capability"
+	if the correct memory is not used.  If a memory controller is
+	capable of EDAC, but DIMMs without check bits are in use, then
+	Parity, SECDED, S4ECD4ED capabilities will not be available
+	even though the memory controller might be capable of those
+	modes with the proper memory loaded.
+
+
+Memory Type supported on this controller attribute file:
+
+	'supported_mem_type'
+
+	This attribute file displays the memory type, usually
+	buffered and unbuffered DIMMs.
+
+
+Memory Controller name attribute file:
+
+	'mc_name'
+
+	This attribute file displays the type of memory controller
+	that is being utilized.
+
+
+Memory Controller Module name attribute file:
+
+	'module_name'
+
+	This attribute file displays the memory controller module name,
+	version and date built.  The name of the memory controller
+	hardware - some drivers work with multiple controllers and
+	this field shows which hardware is present.
+
+
+Total memory managed by this memory controller attribute file:
+
+	'size_mb'
+
+	This attribute file displays, in count of megabytes, of memory
+	that this instance of memory controller manages.
+
+
+Total Uncorrectable Errors count attribute file:
+
+	'ue_count'
+
+	This attribute file displays the total count of uncorrectable
+	errors that have occurred on this memory controller. If panic_on_ue
+	is set this counter will not have a chance to increment,
+	since EDAC will panic the system.
+
+
+Total UE count that had no information attribute fileY:
+
+	'ue_noinfo_count'
+
+	This attribute file displays the number of UEs that
+	have occurred have occurred with  no informations as to which DIMM
+	slot is having errors.
+
+
+Total Correctable Errors count attribute file:
+
+	'ce_count'
+
+	This attribute file displays the total count of correctable
+	errors that have occurred on this memory controller. This
+	count is very important to examine. CEs provide early
+	indications that a DIMM is beginning to fail. This count
+	field should be monitored for non-zero values and report
+	such information to the system administrator.
+
+
+Total Correctable Errors count attribute file:
+
+	'ce_noinfo_count'
+
+	This attribute file displays the number of CEs that
+	have occurred wherewith no informations as to which DIMM slot
+	is having errors. Memory is handicapped, but operational,
+	yet no information is available to indicate which slot
+	the failing memory is in. This count field should be also
+	be monitored for non-zero values.
+
+Device Symlink:
+
+	'device'
+
+	Symlink to the memory controller device
+
+
+
+============================================================================
+'csrowX' DIRECTORIES
+
+In the 'csrowX' directories are EDAC control and attribute files for
+this 'X" instance of csrow:
+
+
+Total Uncorrectable Errors count attribute file:
+
+	'ue_count'
+
+	This attribute file displays the total count of uncorrectable
+	errors that have occurred on this csrow. If panic_on_ue is set
+	this counter will not have a chance to increment, since EDAC
+	will panic the system.
+
+
+Total Correctable Errors count attribute file:
+
+	'ce_count'
+
+	This attribute file displays the total count of correctable
+	errors that have occurred on this csrow. This
+	count is very important to examine. CEs provide early
+	indications that a DIMM is beginning to fail. This count
+	field should be monitored for non-zero values and report
+	such information to the system administrator.
+
+
+Total memory managed by this csrow attribute file:
+
+	'size_mb'
+
+	This attribute file displays, in count of megabytes, of memory
+	that this csrow contatins.
+
+
+Memory Type attribute file:
+
+	'mem_type'
+
+	This attribute file will display what type of memory is currently
+	on this csrow. Normally, either buffered or unbuffered memory.
+
+
+EDAC Mode of operation attribute file:
+
+	'edac_mode'
+
+	This attribute file will display what type of Error detection
+	and correction is being utilized.
+
+
+Device type attribute file:
+
+	'dev_type'
+
+	This attribute file will display what type of DIMM device is
+	being utilized. Example:  x4
+
+
+Channel 0 CE Count attribute file:
+
+	'ch0_ce_count'
+
+	This attribute file will display the count of CEs on this
+	DIMM located in channel 0.
+
+
+Channel 0 UE Count attribute file:
+
+	'ch0_ue_count'
+
+	This attribute file will display the count of UEs on this
+	DIMM located in channel 0.
+
+
+Channel 0 DIMM Label control file:
+
+	'ch0_dimm_label'
+
+	This control file allows this DIMM to have a label assigned
+	to it. With this label in the module, when errors occur
+	the output can provide the DIMM label in the system log.
+	This becomes vital for panic events to isolate the
+	cause of the UE event.
+
+	DIMM Labels must be assigned after booting, with information
+	that correctly identifies the physical slot with its
+	silk screen label. This information is currently very
+	motherboard specific and determination of this information
+	must occur in userland at this time.
+
+
+Channel 1 CE Count attribute file:
+
+	'ch1_ce_count'
+
+	This attribute file will display the count of CEs on this
+	DIMM located in channel 1.
+
+
+Channel 1 UE Count attribute file:
+
+	'ch1_ue_count'
+
+	This attribute file will display the count of UEs on this
+	DIMM located in channel 0.
+
+
+Channel 1 DIMM Label control file:
+
+	'ch1_dimm_label'
+
+	This control file allows this DIMM to have a label assigned
+	to it. With this label in the module, when errors occur
+	the output can provide the DIMM label in the system log.
+	This becomes vital for panic events to isolate the
+	cause of the UE event.
+
+	DIMM Labels must be assigned after booting, with information
+	that correctly identifies the physical slot with its
+	silk screen label. This information is currently very
+	motherboard specific and determination of this information
+	must occur in userland at this time.
+
+
+============================================================================
+SYSTEM LOGGING
+
+If logging for UEs and CEs are enabled then system logs will have
+error notices indicating errors that have been detected:
+
+MC0: CE page 0x283, offset 0xce0, grain 8, syndrome 0x6ec3, row 0,
+channel 1 "DIMM_B1": amd76x_edac
+
+MC0: CE page 0x1e5, offset 0xfb0, grain 8, syndrome 0xb741, row 0,
+channel 1 "DIMM_B1": amd76x_edac
+
+
+The structure of the message is:
+	the memory controller			(MC0)
+	Error type				(CE)
+	memory page				(0x283)
+	offset in the page			(0xce0)
+	the byte granularity 			(grain 8)
+		or resolution of the error
+	the error syndrome			(0xb741)
+	memory row				(row 0)
+	memory channel				(channel 1)
+	DIMM label, if set prior		(DIMM B1
+	and then an optional, driver-specific message that may
+		have additional information.
+
+Both UEs and CEs with no info will lack all but memory controller,
+error type, a notice of "no info" and then an optional,
+driver-specific error message.
+
+
+
+============================================================================
+PCI Bus Parity Detection
+
+
+On Header Type 00 devices the primary status is looked at
+for any parity error regardless of whether Parity is enabled on the
+device.  (The spec indicates parity is generated in some cases).
+On Header Type 01 bridges, the secondary status register is also
+looked at to see if parity ocurred on the bus on the other side of
+the bridge.
+
+
+SYSFS CONFIGURATION
+
+Under /sys/devices/system/edac/pci are control and attribute files as follows:
+
+
+Enable/Disable PCI Parity checking control file:
+
+	'check_pci_parity'
+
+
+	This control file enables or disables the PCI Bus Parity scanning
+	operation. Writing a 1 to this file enables the scanning. Writing
+	a 0 to this file disables the scanning.
+
+	Enable:
+	echo "1" >/sys/devices/system/edac/pci/check_pci_parity
+
+	Disable:
+	echo "0" >/sys/devices/system/edac/pci/check_pci_parity
+
+
+
+Panic on PCI PARITY Error:
+
+	'panic_on_pci_parity'
+
+
+	This control files enables or disables panic'ing when a parity
+	error has been detected.
+
+
+	module/kernel parameter: panic_on_pci_parity=[0|1]
+
+	Enable:
+	echo "1" >/sys/devices/system/edac/pci/panic_on_pci_parity
+
+	Disable:
+	echo "0" >/sys/devices/system/edac/pci/panic_on_pci_parity
+
+
+Parity Count:
+
+	'pci_parity_count'
+
+	This attribute file will display the number of parity errors that
+	have been detected.
+
+
+
+PCI Device Whitelist:
+
+	'pci_parity_whitelist'
+
+	This control file allows for an explicit list of PCI devices to be
+	scanned for parity errors. Only devices found on this list will
+	be examined.  The list is a line of hexadecimel VENDOR and DEVICE
+	ID tuples:
+
+	1022:7450,1434:16a6
+
+	One or more can be inserted, seperated by a comma.
+
+	To write the above list doing the following as one command line:
+
+	echo "1022:7450,1434:16a6"
+		> /sys/devices/system/edac/pci/pci_parity_whitelist
+
+
+
+	To display what the whitelist is, simply 'cat' the same file.
+
+
+PCI Device Blacklist:
+
+	'pci_parity_blacklist'
+
+	This control file allows for a list of PCI devices to be
+	skipped for scanning.
+	The list is a line of hexadecimel VENDOR and DEVICE ID tuples:
+
+	1022:7450,1434:16a6
+
+	One or more can be inserted, seperated by a comma.
+
+	To write the above list doing the following as one command line:
+
+	echo "1022:7450,1434:16a6"
+		> /sys/devices/system/edac/pci/pci_parity_blacklist
+
+
+	To display what the whitelist current contatins,
+	simply 'cat' the same file.
+
+=======================================================================
+
+PCI Vendor and Devices IDs can be obtained with the lspci command. Using
+the -n option lspci will display the vendor and device IDs. The system
+adminstrator will have to determine which devices should be scanned or
+skipped.
+
+
+
+The two lists (white and black) are prioritized. blacklist is the lower
+priority and will NOT be utilized when a whitelist has been set.
+Turn OFF a whitelist by an empty echo command:
+
+	echo > /sys/devices/system/edac/pci/pci_parity_whitelist
+
+and any previous blacklist will be utililzed.
+
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index b4a1ea7..4d4897c 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -148,3 +148,17 @@ Why:	The 8250 serial driver now has the 
 	brother on Alchemy SOCs.  The loss of features is not considered an
 	issue.
 Who:	Ralf Baechle <ralf@linux-mips.org>
+
+---------------------------
+
+What:	Legacy /proc/pci interface (PCI_LEGACY_PROC)
+When:	March 2006
+Why:	deprecated since 2.5.53 in favor of lspci(8)
+Who:	Adrian Bunk <bunk@stusta.de>
+
+---------------------------
+
+What:	pci_module_init(driver)
+When:	January 2007
+Why:	Is replaced by pci_register_driver(pci_driver).
+Who:	Richard Knutsson <ricknu-0@student.ltu.se> and Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/Documentation/kernel-doc-nano-HOWTO.txt b/Documentation/kernel-doc-nano-HOWTO.txt
index c406ce6..c65233d 100644
--- a/Documentation/kernel-doc-nano-HOWTO.txt
+++ b/Documentation/kernel-doc-nano-HOWTO.txt
@@ -45,10 +45,10 @@ How to extract the documentation
 
 If you just want to read the ready-made books on the various
 subsystems (see Documentation/DocBook/*.tmpl), just type 'make
-psdocs', or 'make pdfdocs', or 'make htmldocs', depending on your 
-preference.  If you would rather read a different format, you can type 
-'make sgmldocs' and then use DocBook tools to convert 
-Documentation/DocBook/*.sgml to a format of your choice (for example, 
+psdocs', or 'make pdfdocs', or 'make htmldocs', depending on your
+preference.  If you would rather read a different format, you can type
+'make sgmldocs' and then use DocBook tools to convert
+Documentation/DocBook/*.sgml to a format of your choice (for example,
 'db2html ...' if 'make htmldocs' was not defined).
 
 If you want to see man pages instead, you can do this:
@@ -124,6 +124,36 @@ patterns, which are highlighted appropri
 Take a look around the source tree for examples.
 
 
+kernel-doc for structs, unions, enums, and typedefs
+---------------------------------------------------
+
+Beside functions you can also write documentation for structs, unions,
+enums and typedefs. Instead of the function name you must write the name
+of the declaration;  the struct/union/enum/typedef must always precede
+the name. Nesting of declarations is not supported.
+Use the argument mechanism to document members or constants.
+
+Inside a struct description, you can use the "private:" and "public:"
+comment tags.  Structure fields that are inside a "private:" area
+are not listed in the generated output documentation.
+
+Example:
+
+/**
+ * struct my_struct - short description
+ * @a: first member
+ * @b: second member
+ *
+ * Longer description
+ */
+struct my_struct {
+    int a;
+    int b;
+/* private: */
+    int c;
+};
+
+
 How to make new SGML template files
 -----------------------------------
 
@@ -147,4 +177,3 @@ documentation, in <filename>, for the fu
 
 Tim.
 */ <twaugh@redhat.com>
-
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 1cbcf65..8437036 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -452,6 +452,11 @@ running once the system is up.
 
 	eata=		[HW,SCSI]
 
+	ec_intr=	[HW,ACPI] ACPI Embedded Controller interrupt mode
+			Format: <int>
+			0: polling mode
+			non-0: interrupt mode (default)
+
 	eda=		[HW,PS2]
 
 	edb=		[HW,PS2]
diff --git a/Documentation/power/interface.txt b/Documentation/power/interface.txt
index bd4ffb5..4117802 100644
--- a/Documentation/power/interface.txt
+++ b/Documentation/power/interface.txt
@@ -44,7 +44,7 @@ it. 
 /sys/power/image_size controls the size of the image created by
 the suspend-to-disk mechanism.  It can be written a string
 representing a non-negative integer that will be used as an upper
-limit of the image size, in megabytes.  The suspend-to-disk mechanism will
+limit of the image size, in bytes.  The suspend-to-disk mechanism will
 do its best to ensure the image size will not exceed that number.  However,
 if this turns out to be impossible, it will try to suspend anyway using the
 smallest image possible.  In particular, if "0" is written to this file, the
diff --git a/Documentation/power/swsusp.txt b/Documentation/power/swsusp.txt
index 08c79d4..b28b7f0 100644
--- a/Documentation/power/swsusp.txt
+++ b/Documentation/power/swsusp.txt
@@ -27,7 +27,7 @@ echo shutdown > /sys/power/disk; echo di
 
 echo platform > /sys/power/disk; echo disk > /sys/power/state
 
-If you want to limit the suspend image size to N megabytes, do
+If you want to limit the suspend image size to N bytes, do
 
 echo N > /sys/power/image_size
 
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
new file mode 100644
index 0000000..1284498
--- /dev/null
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -0,0 +1,1420 @@
+           Booting the Linux/ppc kernel without Open Firmware
+           --------------------------------------------------
+
+
+(c) 2005 Benjamin Herrenschmidt <benh at kernel.crashing.org>,
+    IBM Corp.
+(c) 2005 Becky Bruce <becky.bruce at freescale.com>,
+    Freescale Semiconductor, FSL SOC and 32-bit additions
+
+   May 18, 2005: Rev 0.1 - Initial draft, no chapter III yet.
+
+   May 19, 2005: Rev 0.2 - Add chapter III and bits & pieces here or
+                           clarifies the fact that a lot of things are
+                           optional, the kernel only requires a very
+                           small device tree, though it is encouraged
+                           to provide an as complete one as possible.
+
+   May 24, 2005: Rev 0.3 - Precise that DT block has to be in RAM
+			 - Misc fixes
+			 - Define version 3 and new format version 16
+			   for the DT block (version 16 needs kernel
+			   patches, will be fwd separately).
+			   String block now has a size, and full path
+			   is replaced by unit name for more
+			   compactness.
+			   linux,phandle is made optional, only nodes
+			   that are referenced by other nodes need it.
+			   "name" property is now automatically
+			   deduced from the unit name
+
+   June 1, 2005: Rev 0.4 - Correct confusion between OF_DT_END and
+                           OF_DT_END_NODE in structure definition.
+                         - Change version 16 format to always align
+                           property data to 4 bytes. Since tokens are
+                           already aligned, that means no specific
+                           required alignement between property size
+                           and property data. The old style variable
+                           alignment would make it impossible to do
+                           "simple" insertion of properties using
+                           memove (thanks Milton for
+                           noticing). Updated kernel patch as well
+			 - Correct a few more alignement constraints
+			 - Add a chapter about the device-tree
+                           compiler and the textural representation of
+                           the tree that can be "compiled" by dtc.
+
+
+   November 21, 2005: Rev 0.5
+			 - Additions/generalizations for 32-bit
+			 - Changed to reflect the new arch/powerpc
+			   structure
+			 - Added chapter VI
+
+
+ ToDo:
+	- Add some definitions of interrupt tree (simple/complex)
+	- Add some definitions for pci host bridges
+	- Add some common address format examples
+	- Add definitions for standard properties and "compatible"
+	  names for cells that are not already defined by the existing
+	  OF spec.
+	- Compare FSL SOC use of PCI to standard and make sure no new
+	  node definition required.
+	- Add more information about node definitions for SOC devices
+  	  that currently have no standard, like the FSL CPM.
+
+
+I - Introduction
+================
+
+During the recent development of the Linux/ppc64 kernel, and more
+specifically, the addition of new platform types outside of the old
+IBM pSeries/iSeries pair, it was decided to enforce some strict rules
+regarding the kernel entry and bootloader <-> kernel interfaces, in
+order to avoid the degeneration that had become the ppc32 kernel entry
+point and the way a new platform should be added to the kernel. The
+legacy iSeries platform breaks those rules as it predates this scheme,
+but no new board support will be accepted in the main tree that
+doesn't follows them properly.  In addition, since the advent of the
+arch/powerpc merged architecture for ppc32 and ppc64, new 32-bit
+platforms and 32-bit platforms which move into arch/powerpc will be
+required to use these rules as well.
+
+The main requirement that will be defined in more detail below is
+the presence of a device-tree whose format is defined after Open
+Firmware specification. However, in order to make life easier
+to embedded board vendors, the kernel doesn't require the device-tree
+to represent every device in the system and only requires some nodes
+and properties to be present. This will be described in detail in
+section III, but, for example, the kernel does not require you to
+create a node for every PCI device in the system. It is a requirement
+to have a node for PCI host bridges in order to provide interrupt
+routing informations and memory/IO ranges, among others. It is also
+recommended to define nodes for on chip devices and other busses that
+don't specifically fit in an existing OF specification. This creates a
+great flexibility in the way the kernel can then probe those and match
+drivers to device, without having to hard code all sorts of tables. It
+also makes it more flexible for board vendors to do minor hardware
+upgrades without significantly impacting the kernel code or cluttering
+it with special cases.
+
+
+1) Entry point for arch/powerpc
+-------------------------------
+
+   There is one and one single entry point to the kernel, at the start
+   of the kernel image. That entry point supports two calling
+   conventions:
+
+        a) Boot from Open Firmware. If your firmware is compatible
+        with Open Firmware (IEEE 1275) or provides an OF compatible
+        client interface API (support for "interpret" callback of
+        forth words isn't required), you can enter the kernel with:
+
+              r5 : OF callback pointer as defined by IEEE 1275
+              bindings to powerpc. Only the 32 bit client interface
+              is currently supported
+
+              r3, r4 : address & length of an initrd if any or 0
+
+              The MMU is either on or off; the kernel will run the
+              trampoline located in arch/powerpc/kernel/prom_init.c to
+              extract the device-tree and other information from open
+              firmware and build a flattened device-tree as described
+              in b). prom_init() will then re-enter the kernel using
+              the second method. This trampoline code runs in the
+              context of the firmware, which is supposed to handle all
+              exceptions during that time.
+
+        b) Direct entry with a flattened device-tree block. This entry
+        point is called by a) after the OF trampoline and can also be
+        called directly by a bootloader that does not support the Open
+        Firmware client interface. It is also used by "kexec" to
+        implement "hot" booting of a new kernel from a previous
+        running one. This method is what I will describe in more
+        details in this document, as method a) is simply standard Open
+        Firmware, and thus should be implemented according to the
+        various standard documents defining it and its binding to the
+        PowerPC platform. The entry point definition then becomes:
+
+                r3 : physical pointer to the device-tree block
+                (defined in chapter II) in RAM
+
+                r4 : physical pointer to the kernel itself. This is
+                used by the assembly code to properly disable the MMU
+                in case you are entering the kernel with MMU enabled
+                and a non-1:1 mapping.
+
+                r5 : NULL (as to differenciate with method a)
+
+        Note about SMP entry: Either your firmware puts your other
+        CPUs in some sleep loop or spin loop in ROM where you can get
+        them out via a soft reset or some other means, in which case
+        you don't need to care, or you'll have to enter the kernel
+        with all CPUs. The way to do that with method b) will be
+        described in a later revision of this document.
+
+
+2) Board support
+----------------
+
+64-bit kernels:
+
+   Board supports (platforms) are not exclusive config options. An
+   arbitrary set of board supports can be built in a single kernel
+   image. The kernel will "know" what set of functions to use for a
+   given platform based on the content of the device-tree. Thus, you
+   should:
+
+        a) add your platform support as a _boolean_ option in
+        arch/powerpc/Kconfig, following the example of PPC_PSERIES,
+        PPC_PMAC and PPC_MAPLE. The later is probably a good
+        example of a board support to start from.
+
+        b) create your main platform file as
+        "arch/powerpc/platforms/myplatform/myboard_setup.c" and add it
+        to the Makefile under the condition of your CONFIG_
+        option. This file will define a structure of type "ppc_md"
+        containing the various callbacks that the generic code will
+        use to get to your platform specific code
+
+        c) Add a reference to your "ppc_md" structure in the
+        "machines" table in arch/powerpc/kernel/setup_64.c if you are
+        a 64-bit platform.
+
+        d) request and get assigned a platform number (see PLATFORM_*
+        constants in include/asm-powerpc/processor.h
+
+32-bit embedded kernels:
+
+  Currently, board support is essentially an exclusive config option.
+  The kernel is configured for a single platform.  Part of the reason
+  for this is to keep kernels on embedded systems small and efficient;
+  part of this is due to the fact the code is already that way. In the
+  future, a kernel may support multiple platforms, but only if the
+  platforms feature the same core architectire.  A single kernel build
+  cannot support both configurations with Book E and configurations
+  with classic Powerpc architectures.
+
+  32-bit embedded platforms that are moved into arch/powerpc using a
+  flattened device tree should adopt the merged tree practice of
+  setting ppc_md up dynamically, even though the kernel is currently
+  built with support for only a single platform at a time.  This allows
+  unification of the setup code, and will make it easier to go to a
+  multiple-platform-support model in the future.
+
+NOTE: I believe the above will be true once Ben's done with the merge
+of the boot sequences.... someone speak up if this is wrong!
+
+  To add a 32-bit embedded platform support, follow the instructions
+  for 64-bit platforms above, with the exception that the Kconfig
+  option should be set up such that the kernel builds exclusively for
+  the platform selected.  The processor type for the platform should
+  enable another config option to select the specific board
+  supported.
+
+NOTE: If ben doesn't merge the setup files, may need to change this to
+point to setup_32.c
+
+
+   I will describe later the boot process and various callbacks that
+   your platform should implement.
+
+
+II - The DT block format
+========================
+
+
+This chapter defines the actual format of the flattened device-tree
+passed to the kernel. The actual content of it and kernel requirements
+are described later. You can find example of code manipulating that
+format in various places, including arch/powerpc/kernel/prom_init.c
+which will generate a flattened device-tree from the Open Firmware
+representation, or the fs2dt utility which is part of the kexec tools
+which will generate one from a filesystem representation. It is
+expected that a bootloader like uboot provides a bit more support,
+that will be discussed later as well.
+
+Note: The block has to be in main memory. It has to be accessible in
+both real mode and virtual mode with no mapping other than main
+memory. If you are writing a simple flash bootloader, it should copy
+the block to RAM before passing it to the kernel.
+
+
+1) Header
+---------
+
+   The kernel is entered with r3 pointing to an area of memory that is
+   roughtly described in include/asm-powerpc/prom.h by the structure
+   boot_param_header:
+
+struct boot_param_header {
+        u32     magic;                  /* magic word OF_DT_HEADER */
+        u32     totalsize;              /* total size of DT block */
+        u32     off_dt_struct;          /* offset to structure */
+        u32     off_dt_strings;         /* offset to strings */
+        u32     off_mem_rsvmap;         /* offset to memory reserve map
+*/
+        u32     version;                /* format version */
+        u32     last_comp_version;      /* last compatible version */
+
+        /* version 2 fields below */
+        u32     boot_cpuid_phys;        /* Which physical CPU id we're
+                                           booting on */
+        /* version 3 fields below */
+        u32     size_dt_strings;        /* size of the strings block */
+};
+
+   Along with the constants:
+
+/* Definitions used by the flattened device tree */
+#define OF_DT_HEADER            0xd00dfeed      /* 4: version,
+						   4: total size */
+#define OF_DT_BEGIN_NODE        0x1             /* Start node: full name
+*/
+#define OF_DT_END_NODE          0x2             /* End node */
+#define OF_DT_PROP              0x3             /* Property: name off,
+                                                   size, content */
+#define OF_DT_END               0x9
+
+   All values in this header are in big endian format, the various
+   fields in this header are defined more precisely below. All
+   "offset" values are in bytes from the start of the header; that is
+   from the value of r3.
+
+   - magic
+
+     This is a magic value that "marks" the beginning of the
+     device-tree block header. It contains the value 0xd00dfeed and is
+     defined by the constant OF_DT_HEADER
+
+   - totalsize
+
+     This is the total size of the DT block including the header. The
+     "DT" block should enclose all data structures defined in this
+     chapter (who are pointed to by offsets in this header). That is,
+     the device-tree structure, strings, and the memory reserve map.
+
+   - off_dt_struct
+
+     This is an offset from the beginning of the header to the start
+     of the "structure" part the device tree. (see 2) device tree)
+
+   - off_dt_strings
+
+     This is an offset from the beginning of the header to the start
+     of the "strings" part of the device-tree
+
+   - off_mem_rsvmap
+
+     This is an offset from the beginning of the header to the start
+     of the reserved memory map. This map is a list of pairs of 64
+     bit integers. Each pair is a physical address and a size. The
+
+     list is terminated by an entry of size 0. This map provides the
+     kernel with a list of physical memory areas that are "reserved"
+     and thus not to be used for memory allocations, especially during
+     early initialization. The kernel needs to allocate memory during
+     boot for things like un-flattening the device-tree, allocating an
+     MMU hash table, etc... Those allocations must be done in such a
+     way to avoid overriding critical things like, on Open Firmware
+     capable machines, the RTAS instance, or on some pSeries, the TCE
+     tables used for the iommu. Typically, the reserve map should
+     contain _at least_ this DT block itself (header,total_size). If
+     you are passing an initrd to the kernel, you should reserve it as
+     well. You do not need to reserve the kernel image itself. The map
+     should be 64 bit aligned.
+
+   - version
+
+     This is the version of this structure. Version 1 stops
+     here. Version 2 adds an additional field boot_cpuid_phys.
+     Version 3 adds the size of the strings block, allowing the kernel
+     to reallocate it easily at boot and free up the unused flattened
+     structure after expansion. Version 16 introduces a new more
+     "compact" format for the tree itself that is however not backward
+     compatible. You should always generate a structure of the highest
+     version defined at the time of your implementation. Currently
+     that is version 16, unless you explicitely aim at being backward
+     compatible.
+
+   - last_comp_version
+
+     Last compatible version. This indicates down to what version of
+     the DT block you are backward compatible. For example, version 2
+     is backward compatible with version 1 (that is, a kernel build
+     for version 1 will be able to boot with a version 2 format). You
+     should put a 1 in this field if you generate a device tree of
+     version 1 to 3, or 0x10 if you generate a tree of version 0x10
+     using the new unit name format.
+
+   - boot_cpuid_phys
+
+     This field only exist on version 2 headers. It indicate which
+     physical CPU ID is calling the kernel entry point. This is used,
+     among others, by kexec. If you are on an SMP system, this value
+     should match the content of the "reg" property of the CPU node in
+     the device-tree corresponding to the CPU calling the kernel entry
+     point (see further chapters for more informations on the required
+     device-tree contents)
+
+
+   So the typical layout of a DT block (though the various parts don't
+   need to be in that order) looks like this (addresses go from top to
+   bottom):
+
+
+             ------------------------------
+       r3 -> |  struct boot_param_header  |
+             ------------------------------
+             |      (alignment gap) (*)   |
+             ------------------------------
+             |      memory reserve map    |
+             ------------------------------
+             |      (alignment gap)       |
+             ------------------------------
+             |                            |
+             |    device-tree structure   |
+             |                            |
+             ------------------------------
+             |      (alignment gap)       |
+             ------------------------------
+             |                            |
+             |     device-tree strings    |
+             |                            |
+      -----> ------------------------------
+      |
+      |
+      --- (r3 + totalsize)
+
+  (*) The alignment gaps are not necessarily present; their presence
+      and size are dependent on the various alignment requirements of
+      the individual data blocks.
+
+
+2) Device tree generalities
+---------------------------
+
+This device-tree itself is separated in two different blocks, a
+structure block and a strings block. Both need to be aligned to a 4
+byte boundary.
+
+First, let's quickly describe the device-tree concept before detailing
+the storage format. This chapter does _not_ describe the detail of the
+required types of nodes & properties for the kernel, this is done
+later in chapter III.
+
+The device-tree layout is strongly inherited from the definition of
+the Open Firmware IEEE 1275 device-tree. It's basically a tree of
+nodes, each node having two or more named properties. A property can
+have a value or not.
+
+It is a tree, so each node has one and only one parent except for the
+root node who has no parent.
+
+A node has 2 names. The actual node name is generally contained in a
+property of type "name" in the node property list whose value is a
+zero terminated string and is mandatory for version 1 to 3 of the
+format definition (as it is in Open Firmware). Version 0x10 makes it
+optional as it can generate it from the unit name defined below.
+
+There is also a "unit name" that is used to differenciate nodes with
+the same name at the same level, it is usually made of the node
+name's, the "@" sign, and a "unit address", which definition is
+specific to the bus type the node sits on.
+
+The unit name doesn't exist as a property per-se but is included in
+the device-tree structure. It is typically used to represent "path" in
+the device-tree. More details about the actual format of these will be
+below.
+
+The kernel powerpc generic code does not make any formal use of the
+unit address (though some board support code may do) so the only real
+requirement here for the unit address is to ensure uniqueness of
+the node unit name at a given level of the tree. Nodes with no notion
+of address and no possible sibling of the same name (like /memory or
+/cpus) may omit the unit address in the context of this specification,
+or use the "@0" default unit address. The unit name is used to define
+a node "full path", which is the concatenation of all parent node
+unit names separated with "/".
+
+The root node doesn't have a defined name, and isn't required to have
+a name property either if you are using version 3 or earlier of the
+format. It also has no unit address (no @ symbol followed by a unit
+address). The root node unit name is thus an empty string. The full
+path to the root node is "/".
+
+Every node which actually represents an actual device (that is, a node
+which isn't only a virtual "container" for more nodes, like "/cpus"
+is) is also required to have a "device_type" property indicating the
+type of node .
+
+Finally, every node that can be referenced from a property in another
+node is required to have a "linux,phandle" property. Real open
+firmware implementations provide a unique "phandle" value for every
+node that the "prom_init()" trampoline code turns into
+"linux,phandle" properties. However, this is made optional if the
+flattened device tree is used directly. An example of a node
+referencing another node via "phandle" is when laying out the
+interrupt tree which will be described in a further version of this
+document.
+
+This "linux, phandle" property is a 32 bit value that uniquely
+identifies a node. You are free to use whatever values or system of
+values, internal pointers, or whatever to generate these, the only
+requirement is that every node for which you provide that property has
+a unique value for it.
+
+Here is an example of a simple device-tree. In this example, an "o"
+designates a node followed by the node unit name. Properties are
+presented with their name followed by their content. "content"
+represents an ASCII string (zero terminated) value, while <content>
+represents a 32 bit hexadecimal value. The various nodes in this
+example will be discussed in a later chapter. At this point, it is
+only meant to give you a idea of what a device-tree looks like. I have
+purposefully kept the "name" and "linux,phandle" properties which
+aren't necessary in order to give you a better idea of what the tree
+looks like in practice.
+
+  / o device-tree
+      |- name = "device-tree"
+      |- model = "MyBoardName"
+      |- compatible = "MyBoardFamilyName"
+      |- #address-cells = <2>
+      |- #size-cells = <2>
+      |- linux,phandle = <0>
+      |
+      o cpus
+      | | - name = "cpus"
+      | | - linux,phandle = <1>
+      | | - #address-cells = <1>
+      | | - #size-cells = <0>
+      | |
+      | o PowerPC,970@0
+      |   |- name = "PowerPC,970"
+      |   |- device_type = "cpu"
+      |   |- reg = <0>
+      |   |- clock-frequency = <5f5e1000>
+      |   |- linux,boot-cpu
+      |   |- linux,phandle = <2>
+      |
+      o memory@0
+      | |- name = "memory"
+      | |- device_type = "memory"
+      | |- reg = <00000000 00000000 00000000 20000000>
+      | |- linux,phandle = <3>
+      |
+      o chosen
+        |- name = "chosen"
+        |- bootargs = "root=/dev/sda2"
+        |- linux,platform = <00000600>
+        |- linux,phandle = <4>
+
+This tree is almost a minimal tree. It pretty much contains the
+minimal set of required nodes and properties to boot a linux kernel;
+that is, some basic model informations at the root, the CPUs, and the
+physical memory layout.  It also includes misc information passed
+through /chosen, like in this example, the platform type (mandatory)
+and the kernel command line arguments (optional).
+
+The /cpus/PowerPC,970@0/linux,boot-cpu property is an example of a
+property without a value. All other properties have a value. The
+significance of the #address-cells and #size-cells properties will be
+explained in chapter IV which defines precisely the required nodes and
+properties and their content.
+
+
+3) Device tree "structure" block
+
+The structure of the device tree is a linearized tree structure. The
+"OF_DT_BEGIN_NODE" token starts a new node, and the "OF_DT_END_NODE"
+ends that node definition. Child nodes are simply defined before
+"OF_DT_END_NODE" (that is nodes within the node). A 'token' is a 32
+bit value. The tree has to be "finished" with a OF_DT_END token
+
+Here's the basic structure of a single node:
+
+     * token OF_DT_BEGIN_NODE (that is 0x00000001)
+     * for version 1 to 3, this is the node full path as a zero
+       terminated string, starting with "/". For version 16 and later,
+       this is the node unit name only (or an empty string for the
+       root node)
+     * [align gap to next 4 bytes boundary]
+     * for each property:
+        * token OF_DT_PROP (that is 0x00000003)
+        * 32 bit value of property value size in bytes (or 0 of no
+     * value)
+        * 32 bit value of offset in string block of property name
+        * property value data if any
+        * [align gap to next 4 bytes boundary]
+     * [child nodes if any]
+     * token OF_DT_END_NODE (that is 0x00000002)
+
+So the node content can be summmarised as a start token, a full path,
+a list of properties, a list of child node and an end token. Every
+child node is a full node structure itself as defined above.
+
+4) Device tree 'strings" block
+
+In order to save space, property names, which are generally redundant,
+are stored separately in the "strings" block. This block is simply the
+whole bunch of zero terminated strings for all property names
+concatenated together. The device-tree property definitions in the
+structure block will contain offset values from the beginning of the
+strings block.
+
+
+III - Required content of the device tree
+=========================================
+
+WARNING: All "linux,*" properties defined in this document apply only
+to a flattened device-tree. If your platform uses a real
+implementation of Open Firmware or an implementation compatible with
+the Open Firmware client interface, those properties will be created
+by the trampoline code in the kernel's prom_init() file. For example,
+that's where you'll have to add code to detect your board model and
+set the platform number. However, when using the flatenned device-tree
+entry point, there is no prom_init() pass, and thus you have to
+provide those properties yourself.
+
+
+1) Note about cells and address representation
+----------------------------------------------
+
+The general rule is documented in the various Open Firmware
+documentations. If you chose to describe a bus with the device-tree
+and there exist an OF bus binding, then you should follow the
+specification. However, the kernel does not require every single
+device or bus to be described by the device tree.
+
+In general, the format of an address for a device is defined by the
+parent bus type, based on the #address-cells and #size-cells
+property. In the absence of such a property, the parent's parent
+values are used, etc... The kernel requires the root node to have
+those properties defining addresses format for devices directly mapped
+on the processor bus.
+
+Those 2 properties define 'cells' for representing an address and a
+size. A "cell" is a 32 bit number. For example, if both contain 2
+like the example tree given above, then an address and a size are both
+composed of 2 cells, and each is a 64 bit number (cells are
+concatenated and expected to be in big endian format). Another example
+is the way Apple firmware defines them, with 2 cells for an address
+and one cell for a size.  Most 32-bit implementations should define
+#address-cells and #size-cells to 1, which represents a 32-bit value.
+Some 32-bit processors allow for physical addresses greater than 32
+bits; these processors should define #address-cells as 2.
+
+"reg" properties are always a tuple of the type "address size" where
+the number of cells of address and size is specified by the bus
+#address-cells and #size-cells. When a bus supports various address
+spaces and other flags relative to a given address allocation (like
+prefetchable, etc...) those flags are usually added to the top level
+bits of the physical address. For example, a PCI physical address is
+made of 3 cells, the bottom two containing the actual address itself
+while the top cell contains address space indication, flags, and pci
+bus & device numbers.
+
+For busses that support dynamic allocation, it's the accepted practice
+to then not provide the address in "reg" (keep it 0) though while
+providing a flag indicating the address is dynamically allocated, and
+then, to provide a separate "assigned-addresses" property that
+contains the fully allocated addresses. See the PCI OF bindings for
+details.
+
+In general, a simple bus with no address space bits and no dynamic
+allocation is preferred if it reflects your hardware, as the existing
+kernel address parsing functions will work out of the box. If you
+define a bus type with a more complex address format, including things
+like address space bits, you'll have to add a bus translator to the
+prom_parse.c file of the recent kernels for your bus type.
+
+The "reg" property only defines addresses and sizes (if #size-cells
+is
+non-0) within a given bus. In order to translate addresses upward
+(that is into parent bus addresses, and possibly into cpu physical
+addresses), all busses must contain a "ranges" property. If the
+"ranges" property is missing at a given level, it's assumed that
+translation isn't possible. The format of the "ranges" proprety for a
+bus is a list of:
+
+	bus address, parent bus address, size
+
+"bus address" is in the format of the bus this bus node is defining,
+that is, for a PCI bridge, it would be a PCI address. Thus, (bus
+address, size) defines a range of addresses for child devices. "parent
+bus address" is in the format of the parent bus of this bus. For
+example, for a PCI host controller, that would be a CPU address. For a
+PCI<->ISA bridge, that would be a PCI address. It defines the base
+address in the parent bus where the beginning of that range is mapped.
+
+For a new 64 bit powerpc board, I recommend either the 2/2 format or
+Apple's 2/1 format which is slightly more compact since sizes usually
+fit in a single 32 bit word.   New 32 bit powerpc boards should use a
+1/1 format, unless the processor supports physical addresses greater
+than 32-bits, in which case a 2/1 format is recommended.
+
+
+2) Note about "compatible" properties
+-------------------------------------
+
+These properties are optional, but recommended in devices and the root
+node. The format of a "compatible" property is a list of concatenated
+zero terminated strings. They allow a device to express its
+compatibility with a family of similar devices, in some cases,
+allowing a single driver to match against several devices regardless
+of their actual names.
+
+3) Note about "name" properties
+-------------------------------
+
+While earlier users of Open Firmware like OldWorld macintoshes tended
+to use the actual device name for the "name" property, it's nowadays
+considered a good practice to use a name that is closer to the device
+class (often equal to device_type). For example, nowadays, ethernet
+controllers are named "ethernet", an additional "model" property
+defining precisely the chip type/model, and "compatible" property
+defining the family in case a single driver can driver more than one
+of these chips. However, the kernel doesn't generally put any
+restriction on the "name" property; it is simply considered good
+practice to follow the standard and its evolutions as closely as
+possible.
+
+Note also that the new format version 16 makes the "name" property
+optional. If it's absent for a node, then the node's unit name is then
+used to reconstruct the name. That is, the part of the unit name
+before the "@" sign is used (or the entire unit name if no "@" sign
+is present).
+
+4) Note about node and property names and character set
+-------------------------------------------------------
+
+While open firmware provides more flexibe usage of 8859-1, this
+specification enforces more strict rules. Nodes and properties should
+be comprised only of ASCII characters 'a' to 'z', '0' to
+'9', ',', '.', '_', '+', '#', '?', and '-'. Node names additionally
+allow uppercase characters 'A' to 'Z' (property names should be
+lowercase. The fact that vendors like Apple don't respect this rule is
+irrelevant here). Additionally, node and property names should always
+begin with a character in the range 'a' to 'z' (or 'A' to 'Z' for node
+names).
+
+The maximum number of characters for both nodes and property names
+is 31. In the case of node names, this is only the leftmost part of
+a unit name (the pure "name" property), it doesn't include the unit
+address which can extend beyond that limit.
+
+
+5) Required nodes and properties
+--------------------------------
+  These are all that are currently required. However, it is strongly
+  recommended that you expose PCI host bridges as documented in the
+  PCI binding to open firmware, and your interrupt tree as documented
+  in OF interrupt tree specification.
+
+  a) The root node
+
+  The root node requires some properties to be present:
+
+    - model : this is your board name/model
+    - #address-cells : address representation for "root" devices
+    - #size-cells: the size representation for "root" devices
+
+  Additionally, some recommended properties are:
+
+    - compatible : the board "family" generally finds its way here,
+      for example, if you have 2 board models with a similar layout,
+      that typically get driven by the same platform code in the
+      kernel, you would use a different "model" property but put a
+      value in "compatible". The kernel doesn't directly use that
+      value (see /chosen/linux,platform for how the kernel choses a
+      platform type) but it is generally useful.
+
+  The root node is also generally where you add additional properties
+  specific to your board like the serial number if any, that sort of
+  thing. it is recommended that if you add any "custom" property whose
+  name may clash with standard defined ones, you prefix them with your
+  vendor name and a comma.
+
+  b) The /cpus node
+
+  This node is the parent of all individual CPU nodes. It doesn't
+  have any specific requirements, though it's generally good practice
+  to have at least:
+
+               #address-cells = <00000001>
+               #size-cells    = <00000000>
+
+  This defines that the "address" for a CPU is a single cell, and has
+  no meaningful size. This is not necessary but the kernel will assume
+  that format when reading the "reg" properties of a CPU node, see
+  below
+
+  c) The /cpus/* nodes
+
+  So under /cpus, you are supposed to create a node for every CPU on
+  the machine. There is no specific restriction on the name of the
+  CPU, though It's common practice to call it PowerPC,<name>. For
+  example, Apple uses PowerPC,G5 while IBM uses PowerPC,970FX.
+
+  Required properties:
+
+    - device_type : has to be "cpu"
+    - reg : This is the physical cpu number, it's a single 32 bit cell
+      and is also used as-is as the unit number for constructing the
+      unit name in the full path. For example, with 2 CPUs, you would
+      have the full path:
+        /cpus/PowerPC,970FX@0
+        /cpus/PowerPC,970FX@1
+      (unit addresses do not require leading zeroes)
+    - d-cache-line-size : one cell, L1 data cache line size in bytes
+    - i-cache-line-size : one cell, L1 instruction cache line size in
+      bytes
+    - d-cache-size : one cell, size of L1 data cache in bytes
+    - i-cache-size : one cell, size of L1 instruction cache in bytes
+    - linux, boot-cpu : Should be defined if this cpu is the boot cpu.
+
+  Recommended properties:
+
+    - timebase-frequency : a cell indicating the frequency of the
+      timebase in Hz. This is not directly used by the generic code,
+      but you are welcome to copy/paste the pSeries code for setting
+      the kernel timebase/decrementer calibration based on this
+      value.
+    - clock-frequency : a cell indicating the CPU core clock frequency
+      in Hz. A new property will be defined for 64 bit values, but if
+      your frequency is < 4Ghz, one cell is enough. Here as well as
+      for the above, the common code doesn't use that property, but
+      you are welcome to re-use the pSeries or Maple one. A future
+      kernel version might provide a common function for this.
+
+  You are welcome to add any property you find relevant to your board,
+  like some information about the mechanism used to soft-reset the
+  CPUs. For example, Apple puts the GPIO number for CPU soft reset
+  lines in there as a "soft-reset" property since they start secondary
+  CPUs by soft-resetting them.
+
+
+  d) the /memory node(s)
+
+  To define the physical memory layout of your board, you should
+  create one or more memory node(s). You can either create a single
+  node with all memory ranges in its reg property, or you can create
+  several nodes, as you wish. The unit address (@ part) used for the
+  full path is the address of the first range of memory defined by a
+  given node. If you use a single memory node, this will typically be
+  @0.
+
+  Required properties:
+
+    - device_type : has to be "memory"
+    - reg : This property contains all the physical memory ranges of
+      your board. It's a list of addresses/sizes concatenated
+      together, with the number of cells of each defined by the
+      #address-cells and #size-cells of the root node. For example,
+      with both of these properties beeing 2 like in the example given
+      earlier, a 970 based machine with 6Gb of RAM could typically
+      have a "reg" property here that looks like:
+
+      00000000 00000000 00000000 80000000
+      00000001 00000000 00000001 00000000
+
+      That is a range starting at 0 of 0x80000000 bytes and a range
+      starting at 0x100000000 and of 0x100000000 bytes. You can see
+      that there is no memory covering the IO hole between 2Gb and
+      4Gb. Some vendors prefer splitting those ranges into smaller
+      segments, but the kernel doesn't care.
+
+  e) The /chosen node
+
+  This node is a bit "special". Normally, that's where open firmware
+  puts some variable environment information, like the arguments, or
+  phandle pointers to nodes like the main interrupt controller, or the
+  default input/output devices.
+
+  This specification makes a few of these mandatory, but also defines
+  some linux-specific properties that would be normally constructed by
+  the prom_init() trampoline when booting with an OF client interface,
+  but that you have to provide yourself when using the flattened format.
+
+  Required properties:
+
+    - linux,platform : This is your platform number as assigned by the
+      architecture maintainers
+
+  Recommended properties:
+
+    - bootargs : This zero-terminated string is passed as the kernel
+      command line
+    - linux,stdout-path : This is the full path to your standard
+      console device if any. Typically, if you have serial devices on
+      your board, you may want to put the full path to the one set as
+      the default console in the firmware here, for the kernel to pick
+      it up as it's own default console. If you look at the funciton
+      set_preferred_console() in arch/ppc64/kernel/setup.c, you'll see
+      that the kernel tries to find out the default console and has
+      knowledge of various types like 8250 serial ports. You may want
+      to extend this function to add your own.
+    - interrupt-controller : This is one cell containing a phandle
+      value that matches the "linux,phandle" property of your main
+      interrupt controller node. May be used for interrupt routing.
+
+
+  Note that u-boot creates and fills in the chosen node for platforms
+  that use it.
+
+  f) the /soc<SOCname> node
+
+  This node is used to represent a system-on-a-chip (SOC) and must be
+  present if the processor is a SOC. The top-level soc node contains
+  information that is global to all devices on the SOC. The node name
+  should contain a unit address for the SOC, which is the base address
+  of the memory-mapped register set for the SOC. The name of an soc
+  node should start with "soc", and the remainder of the name should
+  represent the part number for the soc.  For example, the MPC8540's
+  soc node would be called "soc8540".
+
+  Required properties:
+
+    - device_type : Should be "soc"
+    - ranges : Should be defined as specified in 1) to describe the
+      translation of SOC addresses for memory mapped SOC registers.
+
+  Recommended properties:
+
+    - reg : This property defines the address and size of the
+      memory-mapped registers that are used for the SOC node itself.
+      It does not include the child device registers - these will be
+      defined inside each child node.  The address specified in the
+      "reg" property should match the unit address of the SOC node.
+    - #address-cells : Address representation for "soc" devices.  The
+      format of this field may vary depending on whether or not the
+      device registers are memory mapped.  For memory mapped
+      registers, this field represents the number of cells needed to
+      represent the address of the registers.  For SOCs that do not
+      use MMIO, a special address format should be defined that
+      contains enough cells to represent the required information.
+      See 1) above for more details on defining #address-cells.
+    - #size-cells : Size representation for "soc" devices
+    - #interrupt-cells : Defines the width of cells used to represent
+       interrupts.  Typically this value is <2>, which includes a
+       32-bit number that represents the interrupt number, and a
+       32-bit number that represents the interrupt sense and level.
+       This field is only needed if the SOC contains an interrupt
+       controller.
+
+  The SOC node may contain child nodes for each SOC device that the
+  platform uses.  Nodes should not be created for devices which exist
+  on the SOC but are not used by a particular platform. See chapter VI
+  for more information on how to specify devices that are part of an
+SOC.
+
+  Example SOC node for the MPC8540:
+
+	soc8540@e0000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		#interrupt-cells = <2>;
+		device_type = "soc";
+		ranges = <00000000 e0000000 00100000>
+		reg = <e0000000 00003000>;
+	}
+
+
+
+IV - "dtc", the device tree compiler
+====================================
+
+
+dtc source code can be found at
+<http://ozlabs.org/~dgibson/dtc/dtc.tar.gz>
+
+WARNING: This version is still in early development stage; the
+resulting device-tree "blobs" have not yet been validated with the
+kernel. The current generated bloc lacks a useful reserve map (it will
+be fixed to generate an empty one, it's up to the bootloader to fill
+it up) among others. The error handling needs work, bugs are lurking,
+etc...
+
+dtc basically takes a device-tree in a given format and outputs a
+device-tree in another format. The currently supported formats are:
+
+  Input formats:
+  -------------
+
+     - "dtb": "blob" format, that is a flattened device-tree block
+       with
+        header all in a binary blob.
+     - "dts": "source" format. This is a text file containing a
+       "source" for a device-tree. The format is defined later in this
+        chapter.
+     - "fs" format. This is a representation equivalent to the
+        output of /proc/device-tree, that is nodes are directories and
+	properties are files
+
+ Output formats:
+ ---------------
+
+     - "dtb": "blob" format
+     - "dts": "source" format
+     - "asm": assembly language file. This is a file that can be
+       sourced by gas to generate a device-tree "blob". That file can
+       then simply be added to your Makefile. Additionally, the
+       assembly file exports some symbols that can be use
+
+
+The syntax of the dtc tool is
+
+    dtc [-I <input-format>] [-O <output-format>]
+        [-o output-filename] [-V output_version] input_filename
+
+
+The "output_version" defines what versio of the "blob" format will be
+generated. Supported versions are 1,2,3 and 16. The default is
+currently version 3 but that may change in the future to version 16.
+
+Additionally, dtc performs various sanity checks on the tree, like the
+uniqueness of linux,phandle properties, validity of strings, etc...
+
+The format of the .dts "source" file is "C" like, supports C and C++
+style commments.
+
+/ {
+}
+
+The above is the "device-tree" definition. It's the only statement
+supported currently at the toplevel.
+
+/ {
+  property1 = "string_value";	/* define a property containing a 0
+                                 * terminated string
+				 */
+
+  property2 = <1234abcd>;	/* define a property containing a
+                                 * numerical 32 bits value (hexadecimal)
+				 */
+
+  property3 = <12345678 12345678 deadbeef>;
+                                /* define a property containing 3
+                                 * numerical 32 bits values (cells) in
+                                 * hexadecimal
+				 */
+  property4 = [0a 0b 0c 0d de ea ad be ef];
+                                /* define a property whose content is
+                                 * an arbitrary array of bytes
+                                 */
+
+  childnode@addresss {	/* define a child node named "childnode"
+                                 * whose unit name is "childnode at
+				 * address"
+                                 */
+
+    childprop = "hello\n";      /* define a property "childprop" of
+                                 * childnode (in this case, a string)
+                                 */
+  };
+};
+
+Nodes can contain other nodes etc... thus defining the hierarchical
+structure of the tree.
+
+Strings support common escape sequences from C: "\n", "\t", "\r",
+"\(octal value)", "\x(hex value)".
+
+It is also suggested that you pipe your source file through cpp (gcc
+preprocessor) so you can use #include's, #define for constants, etc...
+
+Finally, various options are planned but not yet implemented, like
+automatic generation of phandles, labels (exported to the asm file so
+you can point to a property content and change it easily from whatever
+you link the device-tree with), label or path instead of numeric value
+in some cells to "point" to a node (replaced by a phandle at compile
+time), export of reserve map address to the asm file, ability to
+specify reserve map content at compile time, etc...
+
+We may provide a .h include file with common definitions of that
+proves useful for some properties (like building PCI properties or
+interrupt maps) though it may be better to add a notion of struct
+definitions to the compiler...
+
+
+V - Recommendations for a bootloader
+====================================
+
+
+Here are some various ideas/recommendations that have been proposed
+while all this has been defined and implemented.
+
+  - The bootloader may want to be able to use the device-tree itself
+    and may want to manipulate it (to add/edit some properties,
+    like physical memory size or kernel arguments). At this point, 2
+    choices can be made. Either the bootloader works directly on the
+    flattened format, or the bootloader has its own internal tree
+    representation with pointers (similar to the kernel one) and
+    re-flattens the tree when booting the kernel. The former is a bit
+    more difficult to edit/modify, the later requires probably a bit
+    more code to handle the tree structure. Note that the structure
+    format has been designed so it's relatively easy to "insert"
+    properties or nodes or delete them by just memmoving things
+    around. It contains no internal offsets or pointers for this
+    purpose.
+
+  - An example of code for iterating nodes & retreiving properties
+    directly from the flattened tree format can be found in the kernel
+    file arch/ppc64/kernel/prom.c, look at scan_flat_dt() function,
+    it's usage in early_init_devtree(), and the corresponding various
+    early_init_dt_scan_*() callbacks. That code can be re-used in a
+    GPL bootloader, and as the author of that code, I would be happy
+    do discuss possible free licencing to any vendor who wishes to
+    integrate all or part of this code into a non-GPL bootloader.
+
+
+
+VI - System-on-a-chip devices and nodes
+=======================================
+
+Many companies are now starting to develop system-on-a-chip
+processors, where the processor core (cpu) and many peripheral devices
+exist on a single piece of silicon.  For these SOCs, an SOC node
+should be used that defines child nodes for the devices that make
+up the SOC. While platforms are not required to use this model in
+order to boot the kernel, it is highly encouraged that all SOC
+implementations define as complete a flat-device-tree as possible to
+describe the devices on the SOC.  This will allow for the
+genericization of much of the kernel code.
+
+
+1) Defining child nodes of an SOC
+---------------------------------
+
+Each device that is part of an SOC may have its own node entry inside
+the SOC node.  For each device that is included in the SOC, the unit
+address property represents the address offset for this device's
+memory-mapped registers in the parent's address space.  The parent's
+address space is defined by the "ranges" property in the top-level soc
+node. The "reg" property for each node that exists directly under the
+SOC node should contain the address mapping from the child address space
+to the parent SOC address space and the size of the device's
+memory-mapped register file.
+
+For many devices that may exist inside an SOC, there are predefined
+specifications for the format of the device tree node.  All SOC child
+nodes should follow these specifications, except where noted in this
+document.
+
+See appendix A for an example partial SOC node definition for the
+MPC8540.
+
+
+2) Specifying interrupt information for SOC devices
+---------------------------------------------------
+
+Each device that is part of an SOC and which generates interrupts
+should have the following properties:
+
+	- interrupt-parent : contains the phandle of the interrupt
+          controller which handles interrupts for this device
+	- interrupts : a list of tuples representing the interrupt
+          number and the interrupt sense and level for each interupt
+          for this device.
+
+This information is used by the kernel to build the interrupt table
+for the interrupt controllers in the system.
+
+Sense and level information should be encoded as follows:
+
+   Devices connected to openPIC-compatible controllers should encode
+   sense and polarity as follows:
+
+	0 = high to low edge sensitive type enabled
+	1 = active low level sensitive type enabled
+	2 = low to high edge sensitive type enabled
+	3 = active high level sensitive type enabled
+
+   ISA PIC interrupt controllers should adhere to the ISA PIC
+   encodings listed below:
+
+	0 =  active low level sensitive type enabled
+	1 =  active high level sensitive type enabled
+	2 =  high to low edge sensitive type enabled
+	3 =  low to high edge sensitive type enabled
+
+
+
+3) Representing devices without a current OF specification
+----------------------------------------------------------
+
+Currently, there are many devices on SOCs that do not have a standard
+representation pre-defined as part of the open firmware
+specifications, mainly because the boards that contain these SOCs are
+not currently booted using open firmware.   This section contains
+descriptions for the SOC devices for which new nodes have been
+defined; this list will expand as more and more SOC-containing
+platforms are moved over to use the flattened-device-tree model.
+
+  a) MDIO IO device
+
+  The MDIO is a bus to which the PHY devices are connected.  For each
+  device that exists on this bus, a child node should be created.  See
+  the definition of the PHY node below for an example of how to define
+  a PHY.
+
+  Required properties:
+    - reg : Offset and length of the register set for the device
+    - device_type : Should be "mdio"
+    - compatible : Should define the compatible device type for the
+      mdio.  Currently, this is most likely to be "gianfar"
+
+  Example:
+
+	mdio@24520 {
+		reg = <24520 20>;
+
+		ethernet-phy@0 {
+			......
+		};
+	};
+
+
+  b) Gianfar-compatible ethernet nodes
+
+  Required properties:
+
+    - device_type : Should be "network"
+    - model : Model of the device.  Can be "TSEC", "eTSEC", or "FEC"
+    - compatible : Should be "gianfar"
+    - reg : Offset and length of the register set for the device
+    - address : List of bytes representing the ethernet address of
+      this controller
+    - interrupts : <a b> where a is the interrupt number and b is a
+      field that represents an encoding of the sense and level
+      information for the interrupt.  This should be encoded based on
+      the information in section 2) depending on the type of interrupt
+      controller you have.
+    - interrupt-parent : the phandle for the interrupt controller that
+      services interrupts for this device.
+    - phy-handle : The phandle for the PHY connected to this ethernet
+      controller.
+
+  Example:
+
+	ethernet@24000 {
+		#size-cells = <0>;
+		device_type = "network";
+		model = "TSEC";
+		compatible = "gianfar";
+		reg = <24000 1000>;
+		address = [ 00 E0 0C 00 73 00 ];
+		interrupts = <d 3 e 3 12 3>;
+		interrupt-parent = <40000>;
+		phy-handle = <2452000>
+	};
+
+
+
+   c) PHY nodes
+
+   Required properties:
+
+    - device_type : Should be "ethernet-phy"
+    - interrupts : <a b> where a is the interrupt number and b is a
+      field that represents an encoding of the sense and level
+      information for the interrupt.  This should be encoded based on
+      the information in section 2) depending on the type of interrupt
+      controller you have.
+    - interrupt-parent : the phandle for the interrupt controller that
+      services interrupts for this device.
+    - reg : The ID number for the phy, usually a small integer
+    - linux,phandle :  phandle for this node; likely referenced by an
+      ethernet controller node.
+
+
+   Example:
+
+	ethernet-phy@0 {
+		linux,phandle = <2452000>
+		interrupt-parent = <40000>;
+		interrupts = <35 1>;
+		reg = <0>;
+		device_type = "ethernet-phy";
+	};
+
+
+   d) Interrupt controllers
+
+   Some SOC devices contain interrupt controllers that are different
+   from the standard Open PIC specification.  The SOC device nodes for
+   these types of controllers should be specified just like a standard
+   OpenPIC controller.  Sense and level information should be encoded
+   as specified in section 2) of this chapter for each device that
+   specifies an interrupt.
+
+   Example :
+
+	pic@40000 {
+		linux,phandle = <40000>;
+		clock-frequency = <0>;
+		interrupt-controller;
+		#address-cells = <0>;
+		reg = <40000 40000>;
+		built-in;
+		compatible = "chrp,open-pic";
+		device_type = "open-pic";
+		big-endian;
+	};
+
+
+   e) I2C
+
+   Required properties :
+
+    - device_type : Should be "i2c"
+    - reg : Offset and length of the register set for the device
+
+   Recommended properties :
+
+    - compatible : Should be "fsl-i2c" for parts compatible with
+      Freescale I2C specifications.
+    - interrupts : <a b> where a is the interrupt number and b is a
+      field that represents an encoding of the sense and level
+      information for the interrupt.  This should be encoded based on
+      the information in section 2) depending on the type of interrupt
+      controller you have.
+    - interrupt-parent : the phandle for the interrupt controller that
+      services interrupts for this device.
+    - dfsrr : boolean; if defined, indicates that this I2C device has
+      a digital filter sampling rate register
+    - fsl5200-clocking : boolean; if defined, indicated that this device
+      uses the FSL 5200 clocking mechanism.
+
+   Example :
+
+	i2c@3000 {
+		interrupt-parent = <40000>;
+		interrupts = <1b 3>;
+		reg = <3000 18>;
+		device_type = "i2c";
+		compatible  = "fsl-i2c";
+		dfsrr;
+	};
+
+
+   More devices will be defined as this spec matures.
+
+
+Appendix A - Sample SOC node for MPC8540
+========================================
+
+Note that the #address-cells and #size-cells for the SoC node
+in this example have been explicitly listed; these are likely
+not necessary as they are usually the same as the root node.
+
+	soc8540@e0000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		#interrupt-cells = <2>;
+		device_type = "soc";
+		ranges = <00000000 e0000000 00100000>
+		reg = <e0000000 00003000>;
+
+		mdio@24520 {
+			reg = <24520 20>;
+			device_type = "mdio";
+			compatible = "gianfar";
+
+			ethernet-phy@0 {
+				linux,phandle = <2452000>
+				interrupt-parent = <40000>;
+				interrupts = <35 1>;
+				reg = <0>;
+				device_type = "ethernet-phy";
+			};
+
+			ethernet-phy@1 {
+				linux,phandle = <2452001>
+				interrupt-parent = <40000>;
+				interrupts = <35 1>;
+				reg = <1>;
+				device_type = "ethernet-phy";
+			};
+
+			ethernet-phy@3 {
+				linux,phandle = <2452002>
+				interrupt-parent = <40000>;
+				interrupts = <35 1>;
+				reg = <3>;
+				device_type = "ethernet-phy";
+			};
+
+		};
+
+		ethernet@24000 {
+			#size-cells = <0>;
+			device_type = "network";
+			model = "TSEC";
+			compatible = "gianfar";
+			reg = <24000 1000>;
+			address = [ 00 E0 0C 00 73 00 ];
+			interrupts = <d 3 e 3 12 3>;
+			interrupt-parent = <40000>;
+			phy-handle = <2452000>;
+		};
+
+		ethernet@25000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "TSEC";
+			compatible = "gianfar";
+			reg = <25000 1000>;
+			address = [ 00 E0 0C 00 73 01 ];
+			interrupts = <13 3 14 3 18 3>;
+			interrupt-parent = <40000>;
+			phy-handle = <2452001>;
+		};
+
+		ethernet@26000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "FEC";
+			compatible = "gianfar";
+			reg = <26000 1000>;
+			address = [ 00 E0 0C 00 73 02 ];
+			interrupts = <19 3>;
+			interrupt-parent = <40000>;
+			phy-handle = <2452002>;
+		};
+
+		serial@4500 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <4500 100>;
+			clock-frequency = <0>;
+			interrupts = <1a 3>;
+			interrupt-parent = <40000>;
+		};
+
+		pic@40000 {
+			linux,phandle = <40000>;
+			clock-frequency = <0>;
+			interrupt-controller;
+			#address-cells = <0>;
+			reg = <40000 40000>;
+			built-in;
+			compatible = "chrp,open-pic";
+			device_type = "open-pic";
+                        big-endian;
+		};
+
+		i2c@3000 {
+			interrupt-parent = <40000>;
+			interrupts = <1b 3>;
+			reg = <3000 18>;
+			device_type = "i2c";
+			compatible  = "fsl-i2c";
+			dfsrr;
+		};
+
+	};
diff --git a/Documentation/scsi/ChangeLog.megaraid_sas b/Documentation/scsi/ChangeLog.megaraid_sas
new file mode 100644
index 0000000..f8c16cb
--- /dev/null
+++ b/Documentation/scsi/ChangeLog.megaraid_sas
@@ -0,0 +1,24 @@
+1 Release Date    : Mon Jan 23 14:09:01 PST 2006 - Sumant Patro <Sumant.Patro@lsil.com>
+2 Current Version : 00.00.02.02
+3 Older Version   : 00.00.02.01 
+
+i.	New template defined to represent each family of controllers (identified by processor used). 
+	The template will have defintions that will be initialised to appropritae values for a specific family of controllers. The template definition has four function pointers. During driver initialisation the function pointers will be set based on the controller family type. This change is done to support new controllers that has different processors and thus different register set.
+
+		-Sumant Patro <Sumant.Patro@lsil.com>
+
+1 Release Date    : Mon Dec 19 14:36:26 PST 2005 - Sumant Patro <Sumant.Patro@lsil.com>
+2 Current Version : 00.00.02.00-rc4 
+3 Older Version   : 00.00.02.01 
+
+i.	Code reorganized to remove code duplication in megasas_build_cmd. 
+
+	"There's a lot of duplicate code megasas_build_cmd.  Move that out of the different codepathes and merge the reminder of megasas_build_cmd into megasas_queue_command"
+
+		- Christoph Hellwig <hch@lst.de>
+
+ii.	Defined MEGASAS_IOC_FIRMWARE32 for code paths that handles 32 bit applications in 64 bit systems.
+
+	"MEGASAS_IOC_FIRMWARE can't be redefined if CONFIG_COMPAT is set, we need to define a MEGASAS_IOC_FIRMWARE32 define so native binaries continue to work"
+
+		- Christoph Hellwig <hch@lst.de>
diff --git a/Documentation/scsi/aic79xx.txt b/Documentation/scsi/aic79xx.txt
index 0aeef74..382b439 100644
--- a/Documentation/scsi/aic79xx.txt
+++ b/Documentation/scsi/aic79xx.txt
@@ -1,5 +1,5 @@
 ====================================================================
-=             Adaptec Ultra320 Family Manager Set v1.3.11          =
+=             Adaptec Ultra320 Family Manager Set                  =
 =                                                                  =
 =                            README for                            =
 =                    The Linux Operating System                    =
@@ -63,6 +63,11 @@ The following information is available i
                               68-pin)
 2. Version History
 
+   3.0	  (December 1st, 2005)
+	- Updated driver to use SCSI transport class infrastructure
+	- Upported sequencer and core fixes from adaptec released
+	  version 2.0.15 of the driver.
+
    1.3.11 (July 11, 2003)
         - Fix several deadlock issues.
         - Add 29320ALP and 39320B Id's.
@@ -194,7 +199,7 @@ The following information is available i
           supported)
         - Support for the PCI-X standard up to 133MHz
         - Support for the PCI v2.2 standard
-	- Domain Validation
+        - Domain Validation
 
    2.2. Operating System Support:
         - Redhat Linux 7.2, 7.3, 8.0, Advanced Server 2.1
@@ -411,77 +416,53 @@ The following information is available i
           http://www.adaptec.com.
 
 
-5. Contacting Adaptec
+5. Adaptec Customer Support
 
    A Technical Support Identification (TSID) Number is required for 
    Adaptec technical support.
     - The 12-digit TSID can be found on the white barcode-type label
-      included inside the box with your product. The TSID helps us 
+      included inside the box with your product.  The TSID helps us 
       provide more efficient service by accurately identifying your 
       product and support status.
+
    Support Options
     - Search the Adaptec Support Knowledgebase (ASK) at
       http://ask.adaptec.com for articles, troubleshooting tips, and
-      frequently asked questions for your product.
+      frequently asked questions about your product.
     - For support via Email, submit your question to Adaptec's 
-      Technical Support Specialists at http://ask.adaptec.com.
+      Technical Support Specialists at http://ask.adaptec.com/.
      
    North America
-    - Visit our Web site at http://www.adaptec.com.
-    - To speak with a Fibre Channel/RAID/External Storage Technical
-      Support Specialist, call 1-321-207-2000,
-      Hours: Monday-Friday, 3:00 A.M. to 5:00 P.M., PST.
-      (Not open on holidays)
-    - For Technical Support in all other technologies including 
-      SCSI, call 1-408-934-7274,
-      Hours: Monday-Friday, 6:00 A.M. to 5:00 P.M., PST.
-      (Not open on holidays)
-    - For after hours support, call 1-800-416-8066 ($99/call, 
-      $149/call on holidays)
-    - To order Adaptec products including software and cables, call
-      1-800-442-7274 or 1-408-957-7274. You can also visit our 
-      online store at http://www.adaptecstore.com
+    - Visit our Web site at http://www.adaptec.com/.
+    - For information about Adaptec's support options, call
+      408-957-2550, 24 hours a day, 7 days a week.
+    - To speak with a Technical Support Specialist,
+      * For hardware products, call 408-934-7274,
+        Monday to Friday, 3:00 am to 5:00 pm, PDT.
+      * For RAID and Fibre Channel products, call 321-207-2000,
+        Monday to Friday, 3:00 am to 5:00 pm, PDT.
+      To expedite your service, have your computer with you.
+    - To order Adaptec products, including accessories and cables,
+      call 408-957-7274.  To order cables online go to
+      http://www.adaptec.com/buy-cables/.
 
    Europe
-    - Visit our Web site at http://www.adaptec-europe.com.
-    - English and French: To speak with a Technical Support 
-      Specialist, call one of the following numbers:
-        - English: +32-2-352-3470
-        - French:  +32-2-352-3460
-      Hours: Monday-Thursday, 10:00 to 12:30, 13:30 to 17:30 CET 
-             Friday, 10:00 to 12:30, 13:30 to 16:30 CET
-    - German: To speak with a Technical Support Specialist,
-      call +49-89-456-40660
-      Hours: Monday-Thursday, 09:30 to 12:30, 13:30 to 16:30 CET
-             Friday, 09:30 to 12:30, 13:30 to 15:00 CET
-    - To order Adaptec products, including accessories and cables:
-        - UK: +0800-96-65-26 or fax +0800-731-02-95
-        - Other European countries: +32-11-300-379
-
-   Australia and New Zealand
-    - Visit our Web site at http://www.adaptec.com.au.
-    - To speak with a Technical Support Specialist, call 
-      +612-9416-0698
-      Hours: Monday-Friday, 10:00 A.M. to 4:30 P.M., EAT
-      (Not open on holidays)
+    - Visit our Web site at http://www.adaptec-europe.com/.
+    - To speak with a Technical Support Specialist, call, or email,
+      * German:  +49 89 4366 5522, Monday-Friday, 9:00-17:00 CET,
+        http://ask-de.adaptec.com/.
+      * French:  +49 89 4366 5533, Monday-Friday, 9:00-17:00 CET,
+	http://ask-fr.adaptec.com/.
+      * English: +49 89 4366 5544, Monday-Friday, 9:00-17:00 GMT,
+	http://ask.adaptec.com/.
+    - You can order Adaptec cables online at
+      http://www.adaptec.com/buy-cables/.
 
    Japan
+    - Visit our web site at http://www.adaptec.co.jp/.
     - To speak with a Technical Support Specialist, call 
-      +81-3-5308-6120 
-      Hours: Monday-Friday, 9:00 a.m. to 12:00 p.m., 1:00 p.m. to
-      6:00 p.m. TSC
-
-   Hong Kong and China
-    - To speak with a Technical Support Specialist, call 
-      +852-2869-7200
-      Hours: Monday-Friday, 10:00 to 17:00.
-    - Fax Technical Support at +852-2869-7100.
-
-   Singapore
-    - To speak with a Technical Support Specialist, call 
-      +65-245-7470
-      Hours: Monday-Friday, 10:00 to 17:00.
-    - Fax Technical Support at +852-2869-7100
+      +81 3 5308 6120, Monday-Friday, 9:00 a.m. to 12:00 p.m.,
+      1:00 p.m. to 6:00 p.m.
 
 -------------------------------------------------------------------
 /*
diff --git a/Documentation/scsi/aic7xxx.txt b/Documentation/scsi/aic7xxx.txt
index 47e74dd..3481fcd 100644
--- a/Documentation/scsi/aic7xxx.txt
+++ b/Documentation/scsi/aic7xxx.txt
@@ -309,81 +309,57 @@ The following information is available i
    -----------------------------------------------------------------
 
    Example:
-   'options aic7xxx aic7xxx=verbose,no_probe,tag_info:{{},{,,10}},seltime:1"
+   'options aic7xxx aic7xxx=verbose,no_probe,tag_info:{{},{,,10}},seltime:1'
         enables verbose logging, Disable EISA/VLB probing,
         and set tag depth on Controller 1/Target 2 to 10 tags.
 
-3. Contacting Adaptec
+4. Adaptec Customer Support
 
    A Technical Support Identification (TSID) Number is required for 
    Adaptec technical support.
     - The 12-digit TSID can be found on the white barcode-type label
-      included inside the box with your product. The TSID helps us 
+      included inside the box with your product.  The TSID helps us 
       provide more efficient service by accurately identifying your 
       product and support status.
+
    Support Options
     - Search the Adaptec Support Knowledgebase (ASK) at
       http://ask.adaptec.com for articles, troubleshooting tips, and
-      frequently asked questions for your product.
+      frequently asked questions about your product.
     - For support via Email, submit your question to Adaptec's 
-      Technical Support Specialists at http://ask.adaptec.com.
+      Technical Support Specialists at http://ask.adaptec.com/.
      
    North America
-    - Visit our Web site at http://www.adaptec.com.
-    - To speak with a Fibre Channel/RAID/External Storage Technical
-      Support Specialist, call 1-321-207-2000,
-      Hours: Monday-Friday, 3:00 A.M. to 5:00 P.M., PST.
-      (Not open on holidays)
-    - For Technical Support in all other technologies including 
-      SCSI, call 1-408-934-7274,
-      Hours: Monday-Friday, 6:00 A.M. to 5:00 P.M., PST.
-      (Not open on holidays)
-    - For after hours support, call 1-800-416-8066 ($99/call, 
-      $149/call on holidays)
-    - To order Adaptec products including software and cables, call
-      1-800-442-7274 or 1-408-957-7274. You can also visit our 
-      online store at http://www.adaptecstore.com
+    - Visit our Web site at http://www.adaptec.com/.
+    - For information about Adaptec's support options, call
+      408-957-2550, 24 hours a day, 7 days a week.
+    - To speak with a Technical Support Specialist,
+      * For hardware products, call 408-934-7274,
+        Monday to Friday, 3:00 am to 5:00 pm, PDT.
+      * For RAID and Fibre Channel products, call 321-207-2000,
+        Monday to Friday, 3:00 am to 5:00 pm, PDT.
+      To expedite your service, have your computer with you.
+    - To order Adaptec products, including accessories and cables,
+      call 408-957-7274.  To order cables online go to
+      http://www.adaptec.com/buy-cables/.
 
    Europe
-    - Visit our Web site at http://www.adaptec-europe.com.
-    - English and French: To speak with a Technical Support 
-      Specialist, call one of the following numbers:
-        - English: +32-2-352-3470
-        - French:  +32-2-352-3460
-      Hours: Monday-Thursday, 10:00 to 12:30, 13:30 to 17:30 CET 
-             Friday, 10:00 to 12:30, 13:30 to 16:30 CET
-    - German: To speak with a Technical Support Specialist,
-      call +49-89-456-40660
-      Hours: Monday-Thursday, 09:30 to 12:30, 13:30 to 16:30 CET
-             Friday, 09:30 to 12:30, 13:30 to 15:00 CET
-    - To order Adaptec products, including accessories and cables:
-        - UK: +0800-96-65-26 or fax +0800-731-02-95
-        - Other European countries: +32-11-300-379
-
-   Australia and New Zealand
-    - Visit our Web site at http://www.adaptec.com.au.
-    - To speak with a Technical Support Specialist, call 
-      +612-9416-0698
-      Hours: Monday-Friday, 10:00 A.M. to 4:30 P.M., EAT
-      (Not open on holidays)
+    - Visit our Web site at http://www.adaptec-europe.com/.
+    - To speak with a Technical Support Specialist, call, or email,
+      * German:  +49 89 4366 5522, Monday-Friday, 9:00-17:00 CET,
+        http://ask-de.adaptec.com/.
+      * French:  +49 89 4366 5533, Monday-Friday, 9:00-17:00 CET,
+	http://ask-fr.adaptec.com/.
+      * English: +49 89 4366 5544, Monday-Friday, 9:00-17:00 GMT,
+	http://ask.adaptec.com/.
+    - You can order Adaptec cables online at
+      http://www.adaptec.com/buy-cables/.
 
    Japan
+    - Visit our web site at http://www.adaptec.co.jp/.
     - To speak with a Technical Support Specialist, call 
-      +81-3-5308-6120 
-      Hours: Monday-Friday, 9:00 a.m. to 12:00 p.m., 1:00 p.m. to
-      6:00 p.m. TSC
-
-   Hong Kong and China
-    - To speak with a Technical Support Specialist, call 
-      +852-2869-7200
-      Hours: Monday-Friday, 10:00 to 17:00.
-    - Fax Technical Support at +852-2869-7100.
-
-   Singapore
-    - To speak with a Technical Support Specialist, call 
-      +65-245-7470
-      Hours: Monday-Friday, 10:00 to 17:00.
-    - Fax Technical Support at +852-2869-7100
+      +81 3 5308 6120, Monday-Friday, 9:00 a.m. to 12:00 p.m.,
+      1:00 p.m. to 6:00 p.m.
 
 -------------------------------------------------------------------
 /*
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index d257801..36b511c 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -837,8 +837,10 @@ Prior to version 0.9.0rc4 options had a 
 
     Module for AC'97 motherboards from Intel and compatibles.
 			* Intel i810/810E, i815, i820, i830, i84x, MX440
+				ICH5, ICH6, ICH7, ESB2
 			* SiS 7012 (SiS 735)
-			* NVidia NForce, NForce2
+			* NVidia NForce, NForce2, NForce3, MCP04, CK804
+				 CK8, CK8S, MCP501
 			* AMD AMD768, AMD8111
 			* ALi m5455
 
@@ -868,6 +870,12 @@ Prior to version 0.9.0rc4 options had a 
   --------------------
 
     Module for Intel ICH (i8x0) chipset MC97 modems.
+			* Intel i810/810E, i815, i820, i830, i84x, MX440
+				ICH5, ICH6, ICH7
+			* SiS 7013 (SiS 735)
+			* NVidia NForce, NForce2, NForce2s, NForce3
+			* AMD AMD8111
+			* ALi m5455
 
     ac97_clock	  - AC'97 codec clock base (0 = auto-detect)
 
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
index e651ed8..4251085 100644
--- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
@@ -5206,14 +5206,14 @@ struct _snd_pcm_runtime {
         You need to pass the <function>snd_dma_pci_data(pci)</function>,
         where pci is the struct <structname>pci_dev</structname> pointer
         of the chip as well.
-        The <type>snd_sg_buf_t</type> instance is created as
+        The <type>struct snd_sg_buf</type> instance is created as
         substream-&gt;dma_private. You can cast
         the pointer like: 
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  struct snd_sg_buf *sgbuf = (struct snd_sg_buf_t*)substream->dma_private;
+  struct snd_sg_buf *sgbuf = (struct snd_sg_buf *)substream->dma_private;
 ]]>
           </programlisting>
         </informalexample>
diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt
index 6910c01..a46c10f 100644
--- a/Documentation/sysctl/vm.txt
+++ b/Documentation/sysctl/vm.txt
@@ -27,6 +27,8 @@ Currently, these files are in /proc/sys/
 - laptop_mode
 - block_dump
 - drop-caches
+- zone_reclaim_mode
+- zone_reclaim_interval
 
 ==============================================================
 
@@ -120,3 +122,59 @@ set to pcp->high/4.  The upper limit of 
 
 The initial value is zero.  Kernel does not use this value at boot time to set
 the high water marks for each per cpu page list.
+
+===============================================================
+
+zone_reclaim_mode:
+
+Zone_reclaim_mode allows to set more or less agressive approaches to
+reclaim memory when a zone runs out of memory. If it is set to zero then no
+zone reclaim occurs. Allocations will be satisfied from other zones / nodes
+in the system.
+
+This is value ORed together of
+
+1	= Zone reclaim on
+2	= Zone reclaim writes dirty pages out
+4	= Zone reclaim swaps pages
+8	= Also do a global slab reclaim pass
+
+zone_reclaim_mode is set during bootup to 1 if it is determined that pages
+from remote zones will cause a measurable performance reduction. The
+page allocator will then reclaim easily reusable pages (those page
+cache pages that are currently not used) before allocating off node pages.
+
+It may be beneficial to switch off zone reclaim if the system is
+used for a file server and all of memory should be used for caching files
+from disk. In that case the caching effect is more important than
+data locality.
+
+Allowing zone reclaim to write out pages stops processes that are
+writing large amounts of data from dirtying pages on other nodes. Zone
+reclaim will write out dirty pages if a zone fills up and so effectively
+throttle the process. This may decrease the performance of a single process
+since it cannot use all of system memory to buffer the outgoing writes
+anymore but it preserve the memory on other nodes so that the performance
+of other processes running on other nodes will not be affected.
+
+Allowing regular swap effectively restricts allocations to the local
+node unless explicitly overridden by memory policies or cpuset
+configurations.
+
+It may be advisable to allow slab reclaim if the system makes heavy
+use of files and builds up large slab caches. However, the slab
+shrink operation is global, may take a long time and free slabs
+in all nodes of the system.
+
+================================================================
+
+zone_reclaim_interval:
+
+The time allowed for off node allocations after zone reclaim
+has failed to reclaim enough pages to allow a local allocation.
+
+Time is set in seconds and set by default to 30 seconds.
+
+Reduce the interval if undesired off node allocations occur. However, too
+frequent scans will have a negative impact onoff node allocation performance.
+
diff --git a/Documentation/usb/et61x251.txt b/Documentation/usb/et61x251.txt
new file mode 100644
index 0000000..b44dda4
--- /dev/null
+++ b/Documentation/usb/et61x251.txt
@@ -0,0 +1,306 @@
+
+                       ET61X[12]51 PC Camera Controllers
+                                Driver for Linux
+                       =================================
+
+                               - Documentation -
+
+
+Index
+=====
+1.  Copyright
+2.  Disclaimer
+3.  License
+4.  Overview and features
+5.  Module dependencies
+6.  Module loading
+7.  Module parameters
+8.  Optional device control through "sysfs"
+9.  Supported devices
+10. Notes for V4L2 application developers
+11. Contact information
+
+
+1. Copyright
+============
+Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it>
+
+
+2. Disclaimer
+=============
+Etoms is a trademark of Etoms Electronics Corp.
+This software is not developed or sponsored by Etoms Electronics.
+
+
+3. License
+==========
+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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+4. Overview and features
+========================
+This driver supports the video interface of the devices mounting the ET61X151
+or ET61X251 PC Camera Controllers.
+
+It's worth to note that Etoms Electronics has never collaborated with the
+author during the development of this project; despite several requests,
+Etoms Electronics also refused to release enough detailed specifications of
+the video compression engine.
+
+The driver relies on the Video4Linux2 and USB core modules. It has been
+designed to run properly on SMP systems as well.
+
+The latest version of the ET61X[12]51 driver can be found at the following URL:
+http://www.linux-projects.org/
+
+Some of the features of the driver are:
+
+- full compliance with the Video4Linux2 API (see also "Notes for V4L2
+  application developers" paragraph);
+- available mmap or read/poll methods for video streaming through isochronous
+  data transfers;
+- automatic detection of image sensor;
+- support for any window resolutions and optional panning within the maximum
+  pixel area of image sensor;
+- image downscaling with arbitrary scaling factors from 1 and 2 in both
+  directions (see "Notes for V4L2 application developers" paragraph);
+- two different video formats for uncompressed or compressed data in low or
+  high compression quality (see also "Notes for V4L2 application developers"
+  paragraph);
+- full support for the capabilities of every possible image sensors that can
+  be connected to the ET61X[12]51 bridges, including, for istance, red, green,
+  blue and global gain adjustments and exposure control (see "Supported
+  devices" paragraph for details);
+- use of default color settings for sunlight conditions;
+- dynamic I/O interface for both ET61X[12]51 and image sensor control (see
+  "Optional device control through 'sysfs'" paragraph);
+- dynamic driver control thanks to various module parameters (see "Module
+  parameters" paragraph);
+- up to 64 cameras can be handled at the same time; they can be connected and
+  disconnected from the host many times without turning off the computer, if
+  the system supports hotplugging;
+- no known bugs.
+
+
+5. Module dependencies
+======================
+For it to work properly, the driver needs kernel support for Video4Linux and
+USB.
+
+The following options of the kernel configuration file must be enabled and
+corresponding modules must be compiled:
+
+	# Multimedia devices
+	#
+	CONFIG_VIDEO_DEV=m
+
+To enable advanced debugging functionality on the device through /sysfs:
+
+	# Multimedia devices
+	#
+	CONFIG_VIDEO_ADV_DEBUG=y
+
+	# USB support
+	#
+	CONFIG_USB=m
+
+In addition, depending on the hardware being used, the modules below are
+necessary:
+
+	# USB Host Controller Drivers
+	#
+	CONFIG_USB_EHCI_HCD=m
+	CONFIG_USB_UHCI_HCD=m
+	CONFIG_USB_OHCI_HCD=m
+
+And finally:
+
+	# USB Multimedia devices
+	#
+	CONFIG_USB_ET61X251=m
+
+
+6. Module loading
+=================
+To use the driver, it is necessary to load the "et61x251" module into memory
+after every other module required: "videodev", "usbcore" and, depending on
+the USB host controller you have, "ehci-hcd", "uhci-hcd" or "ohci-hcd".
+
+Loading can be done as shown below:
+
+	[root@localhost home]# modprobe et61x251
+
+At this point the devices should be recognized. You can invoke "dmesg" to
+analyze kernel messages and verify that the loading process has gone well:
+
+	[user@localhost home]$ dmesg
+
+
+7. Module parameters
+====================
+Module parameters are listed below:
+-------------------------------------------------------------------------------
+Name:           video_nr
+Type:           short array (min = 0, max = 64)
+Syntax:         <-1|n[,...]>
+Description:    Specify V4L2 minor mode number:
+                -1 = use next available
+                 n = use minor number n
+                You can specify up to 64 cameras this way.
+                For example:
+                video_nr=-1,2,-1 would assign minor number 2 to the second
+                registered camera and use auto for the first one and for every
+                other camera.
+Default:        -1
+-------------------------------------------------------------------------------
+Name:           force_munmap
+Type:           bool array (min = 0, max = 64)
+Syntax:         <0|1[,...]>
+Description:    Force the application to unmap previously mapped buffer memory
+                before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not
+                all the applications support this feature. This parameter is
+                specific for each detected camera.
+                0 = do not force memory unmapping
+                1 = force memory unmapping (save memory)
+Default:        0
+-------------------------------------------------------------------------------
+Name:           debug
+Type:           ushort
+Syntax:         <n>
+Description:    Debugging information level, from 0 to 3:
+                0 = none (use carefully)
+                1 = critical errors
+                2 = significant informations
+                3 = more verbose messages
+                Level 3 is useful for testing only, when only one device
+                is used at the same time. It also shows some more informations
+                about the hardware being detected. This module parameter can be
+                changed at runtime thanks to the /sys filesystem interface.
+Default:        2
+-------------------------------------------------------------------------------
+
+
+8. Optional device control through "sysfs"
+==========================================
+If the kernel has been compiled with the CONFIG_VIDEO_ADV_DEBUG option enabled,
+it is possible to read and write both the ET61X[12]51 and the image sensor
+registers by using the "sysfs" filesystem interface.
+
+There are four files in the /sys/class/video4linux/videoX directory for each
+registered camera: "reg", "val", "i2c_reg" and "i2c_val". The first two files
+control the ET61X[12]51 bridge, while the other two control the sensor chip.
+"reg" and "i2c_reg" hold the values of the current register index where the
+following reading/writing operations are addressed at through "val" and
+"i2c_val". Their use is not intended for end-users, unless you know what you
+are doing. Remember that you must be logged in as root before writing to them.
+
+As an example, suppose we were to want to read the value contained in the
+register number 1 of the sensor register table - which is usually the product
+identifier - of the camera registered as "/dev/video0":
+
+	[root@localhost #] cd /sys/class/video4linux/video0
+	[root@localhost #] echo 1 > i2c_reg
+	[root@localhost #] cat i2c_val
+
+Note that if the sensor registers can not be read, "cat" will fail.
+To avoid race conditions, all the I/O accesses to the files are serialized.
+
+
+9. Supported devices
+====================
+None of the names of the companies as well as their products will be mentioned
+here. They have never collaborated with the author, so no advertising.
+
+From the point of view of a driver, what unambiguously identify a device are
+its vendor and product USB identifiers. Below is a list of known identifiers of
+devices mounting the ET61X[12]51 PC camera controllers:
+
+Vendor ID  Product ID
+---------  ----------
+0x102c     0x6151
+0x102c     0x6251
+0x102c     0x6253
+0x102c     0x6254
+0x102c     0x6255
+0x102c     0x6256
+0x102c     0x6257
+0x102c     0x6258
+0x102c     0x6259
+0x102c     0x625a
+0x102c     0x625b
+0x102c     0x625c
+0x102c     0x625d
+0x102c     0x625e
+0x102c     0x625f
+0x102c     0x6260
+0x102c     0x6261
+0x102c     0x6262
+0x102c     0x6263
+0x102c     0x6264
+0x102c     0x6265
+0x102c     0x6266
+0x102c     0x6267
+0x102c     0x6268
+0x102c     0x6269
+
+The following image sensors are supported:
+
+Model       Manufacturer
+-----       ------------
+TAS5130D1B  Taiwan Advanced Sensor Corporation
+
+All the available control settings of each image sensor are supported through
+the V4L2 interface.
+
+
+10. Notes for V4L2 application developers
+========================================
+This driver follows the V4L2 API specifications. In particular, it enforces two
+rules:
+
+- exactly one I/O method, either "mmap" or "read", is associated with each
+file descriptor. Once it is selected, the application must close and reopen the
+device to switch to the other I/O method;
+
+- although it is not mandatory, previously mapped buffer memory should always
+be unmapped before calling any "VIDIOC_S_CROP" or "VIDIOC_S_FMT" ioctl's.
+The same number of buffers as before will be allocated again to match the size
+of the new video frames, so you have to map the buffers again before any I/O
+attempts on them.
+
+Consistently with the hardware limits, this driver also supports image
+downscaling with arbitrary scaling factors from 1 and 2 in both directions.
+However, the V4L2 API specifications don't correctly define how the scaling
+factor can be chosen arbitrarily by the "negotiation" of the "source" and
+"target" rectangles. To work around this flaw, we have added the convention
+that, during the negotiation, whenever the "VIDIOC_S_CROP" ioctl is issued, the
+scaling factor is restored to 1.
+
+This driver supports two different video formats: the first one is the "8-bit
+Sequential Bayer" format and can be used to obtain uncompressed video data
+from the device through the current I/O method, while the second one provides
+"raw" compressed video data (without frame headers not related to the
+compressed data). The current compression quality may vary from 0 to 1 and can
+be selected or queried thanks to the VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP
+V4L2 ioctl's.
+
+
+11. Contact information
+=======================
+The author may be contacted by e-mail at <luca.risolia@studio.unibo.it>.
+
+GPG/PGP encrypted e-mail's are accepted. The GPG key ID of the author is
+'FCE635A4'; the public 1024-bit key should be available at any keyserver;
+the fingerprint is: '88E8 F32F 7244 68BA 3958  5D40 99DA 5D2A FCE6 35A4'.
diff --git a/Documentation/usb/sn9c102.txt b/Documentation/usb/sn9c102.txt
index 3f8a119..c6b7641 100644
--- a/Documentation/usb/sn9c102.txt
+++ b/Documentation/usb/sn9c102.txt
@@ -17,16 +17,15 @@ Index
 7.  Module parameters
 8.  Optional device control through "sysfs"
 9.  Supported devices
-10. How to add plug-in's for new image sensors
-11. Notes for V4L2 application developers
-12. Video frame formats
-13. Contact information
-14. Credits
+10. Notes for V4L2 application developers
+11. Video frame formats
+12. Contact information
+13. Credits
 
 
 1. Copyright
 ============
-Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it>
+Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it>
 
 
 2. Disclaimer
@@ -54,9 +53,8 @@ Foundation, Inc., 675 Mass Ave, Cambridg
 
 4. Overview and features
 ========================
-This driver attempts to support the video and audio streaming capabilities of
-the devices mounting the SONiX SN9C101, SN9C102 and SN9C103 PC Camera
-Controllers.
+This driver attempts to support the video interface of the devices mounting the
+SONiX SN9C101, SN9C102 and SN9C103 PC Camera Controllers.
 
 It's worth to note that SONiX has never collaborated with the author during the
 development of this project, despite several requests for enough detailed
@@ -78,6 +76,7 @@ Some of the features of the driver are:
 - available mmap or read/poll methods for video streaming through isochronous
   data transfers;
 - automatic detection of image sensor;
+- support for built-in microphone interface;
 - support for any window resolutions and optional panning within the maximum
   pixel area of image sensor;
 - image downscaling with arbitrary scaling factors from 1, 2 and 4 in both
@@ -96,7 +95,7 @@ Some of the features of the driver are:
   parameters" paragraph);
 - up to 64 cameras can be handled at the same time; they can be connected and
   disconnected from the host many times without turning off the computer, if
-  your system supports hotplugging;
+  the system supports hotplugging;
 - no known bugs.
 
 
@@ -112,6 +111,12 @@ corresponding modules must be compiled:
 	#
 	CONFIG_VIDEO_DEV=m
 
+To enable advanced debugging functionality on the device through /sysfs:
+
+	# Multimedia devices
+	#
+	CONFIG_VIDEO_ADV_DEBUG=y
+
 	# USB support
 	#
 	CONFIG_USB=m
@@ -125,6 +130,21 @@ necessary:
 	CONFIG_USB_UHCI_HCD=m
 	CONFIG_USB_OHCI_HCD=m
 
+The SN9C103 controller also provides a built-in microphone interface. It is
+supported by the USB Audio driver thanks to the ALSA API:
+
+	# Sound
+	#
+	CONFIG_SOUND=y
+
+	# Advanced Linux Sound Architecture
+	#
+	CONFIG_SND=m
+
+	# USB devices
+	#
+	CONFIG_SND_USB_AUDIO=m
+
 And finally:
 
 	# USB Multimedia devices
@@ -153,7 +173,7 @@ analyze kernel messages and verify that 
 Module parameters are listed below:
 -------------------------------------------------------------------------------
 Name:           video_nr
-Type:           int array (min = 0, max = 64)
+Type:           short array (min = 0, max = 64)
 Syntax:         <-1|n[,...]> 
 Description:    Specify V4L2 minor mode number:
                 -1 = use next available
@@ -165,19 +185,19 @@ Description:    Specify V4L2 minor mode 
                 other camera.
 Default:        -1
 -------------------------------------------------------------------------------
-Name:           force_munmap;
+Name:           force_munmap
 Type:           bool array (min = 0, max = 64)
 Syntax:         <0|1[,...]> 
 Description:    Force the application to unmap previously mapped buffer memory
                 before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not
                 all the applications support this feature. This parameter is
                 specific for each detected camera.
-                0 = do not force memory unmapping"
-                1 = force memory unmapping (save memory)"
+                0 = do not force memory unmapping
+                1 = force memory unmapping (save memory)
 Default:        0
 -------------------------------------------------------------------------------
 Name:           debug
-Type:           int
+Type:           ushort
 Syntax:         <n> 
 Description:    Debugging information level, from 0 to 3:
                 0 = none (use carefully)
@@ -187,14 +207,15 @@ Description:    Debugging information le
                 Level 3 is useful for testing only, when only one device
                 is used. It also shows some more informations about the
                 hardware being detected. This parameter can be changed at
-                runtime thanks to the /sys filesystem.
+                runtime thanks to the /sys filesystem interface.
 Default:        2
 -------------------------------------------------------------------------------
 
 
 8. Optional device control through "sysfs" [1]
 ==========================================
-It is possible to read and write both the SN9C10x and the image sensor
+If the kernel has been compiled with the CONFIG_VIDEO_ADV_DEBUG option enabled,
+it is possible to read and write both the SN9C10x and the image sensor
 registers by using the "sysfs" filesystem interface.
 
 Every time a supported device is recognized, a write-only file named "green" is
@@ -236,7 +257,7 @@ serialized.
 
 The sysfs interface also provides the "frame_header" entry, which exports the
 frame header of the most recent requested and captured video frame. The header
-is 12-bytes long and is appended to every video frame by the SN9C10x
+is always 18-bytes long and is appended to every video frame by the SN9C10x
 controllers. As an example, this additional information can be used by the user
 application for implementing auto-exposure features via software. 
 
@@ -250,7 +271,8 @@ Byte #  Value         Description
 0x03    0xC4          Frame synchronisation pattern.
 0x04    0xC4          Frame synchronisation pattern.
 0x05    0x96          Frame synchronisation pattern.
-0x06    0x00 or 0x01  Unknown meaning. The exact value depends on the chip.
+0x06    0xXX          Unknown meaning. The exact value depends on the chip;
+                      possible values are 0x00, 0x01 and 0x20.
 0x07    0xXX          Variable value, whose bits are ff00uzzc, where ff is a
                       frame counter, u is unknown, zz is a size indicator
                       (00 = VGA, 01 = SIF, 10 = QSIF) and c stands for
@@ -267,12 +289,23 @@ Byte #  Value         Description
                       times the area outside of the specified AE area. For
                       images that are not pure white, the value scales down
                       according to relative whiteness.
+                      according to relative whiteness.
+
+The following bytes are used by the SN9C103 bridge only:
+
+0x0C    0xXX          Unknown meaning
+0x0D    0xXX          Unknown meaning
+0x0E    0xXX          Unknown meaning
+0x0F    0xXX          Unknown meaning
+0x10    0xXX          Unknown meaning
+0x11    0xXX          Unknown meaning
 
 The AE area (sx, sy, ex, ey) in the active window can be set by programming the
 registers 0x1c, 0x1d, 0x1e and 0x1f of the SN9C10x controllers, where one unit
 corresponds to 32 pixels.
 
-[1] The frame header has been documented by Bertrik Sikken.
+[1] Part of the meaning of the frame header has been documented by Bertrik
+    Sikken.
 
 
 9. Supported devices
@@ -298,6 +331,7 @@ Vendor ID  Product ID
 0x0c45     0x602b
 0x0c45     0x602c
 0x0c45     0x602d
+0x0c45     0x602e
 0x0c45     0x6030
 0x0c45     0x6080
 0x0c45     0x6082
@@ -348,18 +382,7 @@ appreciated. Non-available hardware will
 driver.
 
 
-10. How to add plug-in's for new image sensors
-==============================================
-It should be easy to write plug-in's for new sensors by using the small API
-that has been created for this purpose, which is present in "sn9c102_sensor.h"
-(documentation is included there). As an example, have a look at the code in
-"sn9c102_pas106b.c", which uses the mentioned interface.
-
-At the moment, possible unsupported image sensors are: CIS-VF10 (VGA),
-OV7620 (VGA), OV7630 (VGA).
-
-
-11. Notes for V4L2 application developers
+10. Notes for V4L2 application developers
 =========================================
 This driver follows the V4L2 API specifications. In particular, it enforces two
 rules:
@@ -394,7 +417,7 @@ initialized (as described in the documen
 supplied by this driver).
 
 
-12. Video frame formats [1]
+11. Video frame formats [1]
 =======================
 The SN9C10x PC Camera Controllers can send images in two possible video
 formats over the USB: either native "Sequential RGB Bayer" or Huffman
@@ -455,7 +478,7 @@ The following Huffman codes have been fo
     documented by Bertrik Sikken.
 
 
-13. Contact information
+12. Contact information
 =======================
 The author may be contacted by e-mail at <luca.risolia@studio.unibo.it>.
 
@@ -464,7 +487,7 @@ GPG/PGP encrypted e-mail's are accepted.
 the fingerprint is: '88E8 F32F 7244 68BA 3958  5D40 99DA 5D2A FCE6 35A4'.
 
 
-14. Credits
+13. Credits
 ===========
 Many thanks to following persons for their contribute (listed in alphabetical
 order):
@@ -480,5 +503,5 @@ order):
 - Bertrik Sikken, who reverse-engineered and documented the Huffman compression
   algorithm used in the SN9C10x controllers and implemented the first decoder;
 - Mizuno Takafumi for the donation of a webcam;
-- An "anonymous" donator (who didn't want his name to be revealed) for the
+- an "anonymous" donator (who didn't want his name to be revealed) for the
   donation of a webcam.
diff --git a/Documentation/usb/w9968cf.txt b/Documentation/usb/w9968cf.txt
index 18a4773..9d46cd0 100644
--- a/Documentation/usb/w9968cf.txt
+++ b/Documentation/usb/w9968cf.txt
@@ -57,16 +57,12 @@ based cameras should be supported as wel
 The driver is divided into two modules: the basic one, "w9968cf", is needed for
 the supported devices to work; the second one, "w9968cf-vpp", is an optional
 module, which provides some useful video post-processing functions like video
-decoding, up-scaling and colour conversions. Once the driver is installed,
-every time an application tries to open a recognized device, "w9968cf" checks
-the presence of the "w9968cf-vpp" module and loads it automatically by default.
-
-Please keep in mind that official kernels do not include the second module for
-performance purposes. However it is always recommended to download and install
-the latest and complete release of the driver, replacing the existing one, if
-present: it will be still even possible not to load the "w9968cf-vpp" module at
-all, if you ever want to. Another important missing feature of the version in
-the official Linux 2.4 kernels is the writeable /proc filesystem interface.
+decoding, up-scaling and colour conversions.
+
+Note that the official kernels do neither include nor support the second
+module for performance purposes. Therefore, it is always recommended to
+download and install the latest and complete release of the driver,
+replacing the existing one, if present.
 
 The latest and full-featured version of the W996[87]CF driver can be found at:
 http://www.linux-projects.org. Please refer to the documentation included in
@@ -201,22 +197,6 @@ Note:            The kernel must be comp
                  enabled for the 'ovcamchip' module to be loaded and for
                  this parameter to be present.
 -------------------------------------------------------------------------------
-Name:           vppmod_load
-Type:           bool
-Syntax:         <0|1>
-Description:    Automatic 'w9968cf-vpp' module loading: 0 disabled, 1 enabled.
-                If enabled, every time an application attempts to open a
-                camera, 'insmod' searches for the video post-processing module
-                in the system and loads it automatically (if present).
-                The optional 'w9968cf-vpp' module adds extra image manipulation
-                capabilities to the 'w9968cf' module,like software up-scaling,
-                colour conversions and video decompression for very high frame
-                rates.
-Default:        1
-Note:           The kernel must be compiled with the CONFIG_KMOD option
-                enabled for the 'w9968cf-vpp' module to be loaded and for
-                this parameter to be present.
--------------------------------------------------------------------------------
 Name:           simcams 
 Type:           int 
 Syntax:         <n> 
diff --git a/Documentation/vm/page_migration b/Documentation/vm/page_migration
new file mode 100644
index 0000000..c52820f
--- /dev/null
+++ b/Documentation/vm/page_migration
@@ -0,0 +1,129 @@
+Page migration
+--------------
+
+Page migration allows the moving of the physical location of pages between
+nodes in a numa system while the process is running. This means that the
+virtual addresses that the process sees do not change. However, the
+system rearranges the physical location of those pages.
+
+The main intend of page migration is to reduce the latency of memory access
+by moving pages near to the processor where the process accessing that memory
+is running.
+
+Page migration allows a process to manually relocate the node on which its
+pages are located through the MF_MOVE and MF_MOVE_ALL options while setting
+a new memory policy. The pages of process can also be relocated
+from another process using the sys_migrate_pages() function call. The
+migrate_pages function call takes two sets of nodes and moves pages of a
+process that are located on the from nodes to the destination nodes.
+
+Manual migration is very useful if for example the scheduler has relocated
+a process to a processor on a distant node. A batch scheduler or an
+administrator may detect the situation and move the pages of the process
+nearer to the new processor. At some point in the future we may have
+some mechanism in the scheduler that will automatically move the pages.
+
+Larger installations usually partition the system using cpusets into
+sections of nodes. Paul Jackson has equipped cpusets with the ability to
+move pages when a task is moved to another cpuset. This allows automatic
+control over locality of a process. If a task is moved to a new cpuset
+then also all its pages are moved with it so that the performance of the
+process does not sink dramatically (as is the case today).
+
+Page migration allows the preservation of the relative location of pages
+within a group of nodes for all migration techniques which will preserve a
+particular memory allocation pattern generated even after migrating a
+process. This is necessary in order to preserve the memory latencies.
+Processes will run with similar performance after migration.
+
+Page migration occurs in several steps. First a high level
+description for those trying to use migrate_pages() and then
+a low level description of how the low level details work.
+
+A. Use of migrate_pages()
+-------------------------
+
+1. Remove pages from the LRU.
+
+   Lists of pages to be migrated are generated by scanning over
+   pages and moving them into lists. This is done by
+   calling isolate_lru_page() or __isolate_lru_page().
+   Calling isolate_lru_page increases the references to the page
+   so that it cannot vanish under us.
+
+2. Generate a list of newly allocates page to move the contents
+   of the first list to.
+
+3. The migrate_pages() function is called which attempts
+   to do the migration. It returns the moved pages in the
+   list specified as the third parameter and the failed
+   migrations in the fourth parameter. The first parameter
+   will contain the pages that could still be retried.
+
+4. The leftover pages of various types are returned
+   to the LRU using putback_to_lru_pages() or otherwise
+   disposed of. The pages will still have the refcount as
+   increased by isolate_lru_pages()!
+
+B. Operation of migrate_pages()
+--------------------------------
+
+migrate_pages does several passes over its list of pages. A page is moved
+if all references to a page are removable at the time.
+
+Steps:
+
+1. Lock the page to be migrated
+
+2. Insure that writeback is complete.
+
+3. Make sure that the page has assigned swap cache entry if
+   it is an anonyous page. The swap cache reference is necessary
+   to preserve the information contain in the page table maps.
+
+4. Prep the new page that we want to move to. It is locked
+   and set to not being uptodate so that all accesses to the new
+   page immediately lock while we are moving references.
+
+5. All the page table references to the page are either dropped (file backed)
+   or converted to swap references (anonymous pages). This should decrease the
+   reference count.
+
+6. The radix tree lock is taken
+
+7. The refcount of the page is examined and we back out if references remain
+   otherwise we know that we are the only one referencing this page.
+
+8. The radix tree is checked and if it does not contain the pointer to this
+   page then we back out.
+
+9. The mapping is checked. If the mapping is gone then a truncate action may
+   be in progress and we back out.
+
+10. The new page is prepped with some settings from the old page so that accesses
+   to the new page will be discovered to have the correct settings.
+
+11. The radix tree is changed to point to the new page.
+
+12. The reference count of the old page is dropped because the reference has now
+    been removed.
+
+13. The radix tree lock is dropped.
+
+14. The page contents are copied to the new page.
+
+15. The remaining page flags are copied to the new page.
+
+16. The old page flags are cleared to indicate that the page does
+    not use any information anymore.
+
+17. Queued up writeback on the new page is triggered.
+
+18. If swap pte's were generated for the page then remove them again.
+
+19. The locks are dropped from the old and new page.
+
+20. The new page is moved to the LRU.
+
+Christoph Lameter, December 19, 2005.
+
diff --git a/MAINTAINERS b/MAINTAINERS
index 6d1b048..42955fe 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -867,6 +867,15 @@ L:	ebtables-devel@lists.sourceforge.net
 W:	http://ebtables.sourceforge.net/
 S:	Maintained
 
+EDAC-CORE
+P:      Doug Thompson
+M:      norsk5@xmission.com, dthompson@linuxnetworx.com
+P:      Dave Peterson
+M:      dsp@llnl.gov, dave_peterson@pobox.com
+L:      bluesmoke-devel@lists.sourceforge.net
+W:      bluesmoke.sourceforge.net
+S:      Maintained
+
 EEPRO100 NETWORK DRIVER
 P:	Andrey V. Savochkin
 M:	saw@saw.sw.com.sg
@@ -1167,8 +1176,8 @@ T:	git kernel.org:/pub/scm/linux/kernel/
 S:	Maintained
 
 SN-IA64 (Itanium) SUB-PLATFORM
-P:	Greg Edwards
-M:	edwardsg@sgi.com
+P:	Jes Sorensen
+M:	jes@sgi.com
 L:	linux-altix@sgi.com
 L:	linux-ia64@vger.kernel.org
 W:	http://www.sgi.com/altix
@@ -1398,7 +1407,7 @@ IRDA SUBSYSTEM
 P:	Jean Tourrilhes
 L:	irda-users@lists.sourceforge.net (subscribers-only)
 W:	http://irda.sourceforge.net/
-S:	Maintained
+S:	Odd Fixes
 
 ISAPNP
 P:	Jaroslav Kysela
@@ -1696,11 +1705,13 @@ M: mtk-manpages@gmx.net
 W: ftp://ftp.kernel.org/pub/linux/docs/manpages
 S: Maintained
 
-MARVELL MV64340 ETHERNET DRIVER
+MARVELL MV643XX ETHERNET DRIVER
+P:	Dale Farnsworth
+M:	dale@farnsworth.org
 P:	Manish Lachwani
-L:	linux-mips@linux-mips.org
+M:	mlachwani@mvista.com
 L:	netdev@vger.kernel.org
-S:	Supported
+S:	Odd Fixes for 2.4; Maintained for 2.6.
 
 MATROX FRAMEBUFFER DRIVER
 P:	Petr Vandrovec
@@ -1841,7 +1852,14 @@ M:	yoshfuji@linux-ipv6.org
 P:	Patrick McHardy
 M:	kaber@coreworks.de
 L:	netdev@vger.kernel.org
-T:	git kernel.org:/pub/scm/linux/kernel/davem/net-2.6.git
+T:	git kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6.git
+S:	Maintained
+
+NETWORKING [WIRELESS]
+P:	John W. Linville
+M:	linville@tuxdriver.com
+L:	netdev@vger.kernel.org
+T:	git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-2.6.git
 S:	Maintained
 
 IPVS
@@ -2534,11 +2552,11 @@ S:     Maintained
 
 TIPC NETWORK LAYER
 P:	Per Liden
-M:	per.liden@nospam.ericsson.com
+M:	per.liden@ericsson.com
 P:	Jon Maloy
-M:	jon.maloy@nospam.ericsson.com
+M:	jon.maloy@ericsson.com
 P:	Allan Stephens
-M:	allan.stephens@nospam.windriver.com
+M:	allan.stephens@windriver.com
 L:	tipc-discussion@lists.sourceforge.net
 W:	http://tipc.sourceforge.net/
 W:	http://tipc.cslab.ericsson.net/
@@ -2655,6 +2673,14 @@ M:	dbrownell@users.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
 
+USB ET61X[12]51 DRIVER
+P:	Luca Risolia
+M:	luca.risolia@studio.unibo.it
+L:	linux-usb-devel@lists.sourceforge.net
+L:	video4linux-list@redhat.com
+W:	http://www.linux-projects.org
+S:	Maintained
+
 USB HID/HIDBP DRIVERS
 P:	Vojtech Pavlik
 M:	vojtech@suse.cz
@@ -2818,6 +2844,7 @@ USB SN9C10x DRIVER
 P:	Luca Risolia
 M:	luca.risolia@studio.unibo.it
 L:	linux-usb-devel@lists.sourceforge.net
+L:	video4linux-list@redhat.com
 W:	http://www.linux-projects.org
 S:	Maintained
 
@@ -2847,6 +2874,7 @@ USB W996[87]CF DRIVER
 P:	Luca Risolia
 M:	luca.risolia@studio.unibo.it
 L:	linux-usb-devel@lists.sourceforge.net
+L:	video4linux-list@redhat.com
 W:	http://www.linux-projects.org
 S:	Maintained
 
diff --git a/Makefile b/Makefile
index 252a659..cc274d3 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 16
-EXTRAVERSION =-rc1
+EXTRAVERSION = -rc1-git6
 NAME=Sliding Snow Leopard
 
 # *DOCUMENTATION*
diff --git a/arch/alpha/kernel/asm-offsets.c b/arch/alpha/kernel/asm-offsets.c
index 8f2e5c7..6c56c75 100644
--- a/arch/alpha/kernel/asm-offsets.c
+++ b/arch/alpha/kernel/asm-offsets.c
@@ -28,6 +28,7 @@ void foo(void)
         DEFINE(TASK_GID, offsetof(struct task_struct, gid));
         DEFINE(TASK_EGID, offsetof(struct task_struct, egid));
         DEFINE(TASK_REAL_PARENT, offsetof(struct task_struct, real_parent));
+        DEFINE(TASK_GROUP_LEADER, offsetof(struct task_struct, group_leader));
         DEFINE(TASK_TGID, offsetof(struct task_struct, tgid));
         BLANK();
 
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index e38671c..7af15bf 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -879,17 +879,19 @@ sys_getxpid:
 
 	/* See linux/kernel/timer.c sys_getppid for discussion
 	   about this loop.  */
-	ldq	$3, TASK_REAL_PARENT($2)
-1:	ldl	$1, TASK_TGID($3)
+	ldq	$3, TASK_GROUP_LEADER($2)
+	ldq	$4, TASK_REAL_PARENT($3)
+	ldl	$0, TASK_TGID($2)
+1:	ldl	$1, TASK_TGID($4)
 #ifdef CONFIG_SMP
-	mov	$3, $4
+	mov	$4, $5
 	mb
-	ldq	$3, TASK_REAL_PARENT($2)
-	cmpeq	$3, $4, $4
-	beq	$4, 1b
+	ldq	$3, TASK_GROUP_LEADER($2)
+	ldq	$4, TASK_REAL_PARENT($3)
+	cmpeq	$4, $5, $5
+	beq	$5, 1b
 #endif
 	stq	$1, 80($sp)
-	ldl	$0, TASK_TGID($2)
 	ret
 .end sys_getxpid
 
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index 76be5cf..9006063 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -68,34 +68,32 @@ show_interrupts(struct seq_file *p, void
 #ifdef CONFIG_SMP
 	int j;
 #endif
-	int i = *(loff_t *) v;
+	int irq = *(loff_t *) v;
 	struct irqaction * action;
 	unsigned long flags;
 
 #ifdef CONFIG_SMP
-	if (i == 0) {
+	if (irq == 0) {
 		seq_puts(p, "           ");
-		for (i = 0; i < NR_CPUS; i++)
-			if (cpu_online(i))
-				seq_printf(p, "CPU%d       ", i);
+		for_each_online_cpu(j)
+			seq_printf(p, "CPU%d       ", j);
 		seq_putc(p, '\n');
 	}
 #endif
 
-	if (i < ACTUAL_NR_IRQS) {
-		spin_lock_irqsave(&irq_desc[i].lock, flags);
-		action = irq_desc[i].action;
+	if (irq < ACTUAL_NR_IRQS) {
+		spin_lock_irqsave(&irq_desc[irq].lock, flags);
+		action = irq_desc[irq].action;
 		if (!action) 
 			goto unlock;
-		seq_printf(p, "%3d: ",i);
+		seq_printf(p, "%3d: ", irq);
 #ifndef CONFIG_SMP
-		seq_printf(p, "%10u ", kstat_irqs(i));
+		seq_printf(p, "%10u ", kstat_irqs(irq));
 #else
-		for (j = 0; j < NR_CPUS; j++)
-			if (cpu_online(j))
-				seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+		for_each_online_cpu(j)
+			seq_printf(p, "%10u ", kstat_cpu(j).irqs[irq]);
 #endif
-		seq_printf(p, " %14s", irq_desc[i].handler->typename);
+		seq_printf(p, " %14s", irq_desc[irq].handler->typename);
 		seq_printf(p, "  %c%s",
 			(action->flags & SA_INTERRUPT)?'+':' ',
 			action->name);
@@ -108,13 +106,12 @@ show_interrupts(struct seq_file *p, void
 
 		seq_putc(p, '\n');
 unlock:
-		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
-	} else if (i == ACTUAL_NR_IRQS) {
+		spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
+	} else if (irq == ACTUAL_NR_IRQS) {
 #ifdef CONFIG_SMP
 		seq_puts(p, "IPI: ");
-		for (i = 0; i < NR_CPUS; i++)
-			if (cpu_online(i))
-				seq_printf(p, "%10lu ", cpu_data[i].ipi_count);
+		for_each_online_cpu(j)
+			seq_printf(p, "%10lu ", cpu_data[j].ipi_count);
 		seq_putc(p, '\n');
 #endif
 		seq_printf(p, "ERR: %10lu\n", irq_err_count);
@@ -122,7 +119,6 @@ unlock:
 	return 0;
 }
 
-
 /*
  * handle_irq handles all normal device IRQ's (the special
  * SMP cross-CPU interrupts have their own specific
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 01fe990..7fb14f4 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -960,7 +960,7 @@ osf_utimes(char __user *filename, struct
 			return -EFAULT;
 	}
 
-	return do_utimes(filename, tvs ? ktvs : NULL);
+	return do_utimes(AT_FDCWD, filename, tvs ? ktvs : NULL);
 }
 
 #define MAX_SELECT_SECONDS \
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index aaa4740..db3389d 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -334,7 +334,7 @@ __setup_mmu:	sub	r3, r4, #16384		@ Page 
 		mov	r1, #0x12
 		orr	r1, r1, #3 << 10
 		add	r2, r3, #16384
-1:		cmp	r1, r8			@ if virt > start of RAM
+1:		cmp	r1, r9			@ if virt > start of RAM
 		orrhs	r1, r1, #0x0c		@ set cacheable, bufferable
 		cmp	r1, r10			@ if virt > end of RAM
 		bichs	r1, r1, #0x0c		@ clear cacheable, bufferable
diff --git a/arch/arm/configs/bast_defconfig b/arch/arm/configs/bast_defconfig
index 6886001..4a8564f 100644
--- a/arch/arm/configs/bast_defconfig
+++ b/arch/arm/configs/bast_defconfig
@@ -14,8 +14,7 @@ CONFIG_GENERIC_IOMAP=y
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-# CONFIG_CLEAN_COMPILE is not set
-CONFIG_BROKEN=y
+CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 
 #
@@ -360,7 +359,6 @@ CONFIG_BLK_DEV_IDE_BAST=y
 #
 # IEEE 1394 (FireWire) support
 #
-# CONFIG_IEEE1394 is not set
 
 #
 # I2O device support
@@ -781,7 +779,6 @@ CONFIG_SYSFS=y
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 # CONFIG_TMPFS is not set
-# CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 
diff --git a/arch/arm/configs/collie_defconfig b/arch/arm/configs/collie_defconfig
index 15468a0..c9aa878 100644
--- a/arch/arm/configs/collie_defconfig
+++ b/arch/arm/configs/collie_defconfig
@@ -13,8 +13,7 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-# CONFIG_CLEAN_COMPILE is not set
-CONFIG_BROKEN=y
+CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
@@ -308,9 +307,7 @@ CONFIG_MTD_CFI_I2=y
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
 CONFIG_MTD_OBSOLETE_CHIPS=y
-# CONFIG_MTD_AMDSTD is not set
 CONFIG_MTD_SHARP=y
-# CONFIG_MTD_JEDEC is not set
 
 #
 # Mapping drivers for chip access
@@ -396,7 +393,6 @@ CONFIG_ATA_OVER_ETH=m
 #
 # IEEE 1394 (FireWire) support
 #
-# CONFIG_IEEE1394 is not set
 
 #
 # I2O device support
@@ -741,7 +737,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
-# CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_RELAYFS_FS is not set
diff --git a/arch/arm/configs/ep80219_defconfig b/arch/arm/configs/ep80219_defconfig
index fbe312e..3c73b70 100644
--- a/arch/arm/configs/ep80219_defconfig
+++ b/arch/arm/configs/ep80219_defconfig
@@ -522,6 +522,7 @@ CONFIG_E100=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
 CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/arm/configs/iq31244_defconfig b/arch/arm/configs/iq31244_defconfig
index c07628c..3246716 100644
--- a/arch/arm/configs/iq31244_defconfig
+++ b/arch/arm/configs/iq31244_defconfig
@@ -493,6 +493,7 @@ CONFIG_NETDEVICES=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
 CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/arm/configs/iq80321_defconfig b/arch/arm/configs/iq80321_defconfig
index 18fa161..b000da7 100644
--- a/arch/arm/configs/iq80321_defconfig
+++ b/arch/arm/configs/iq80321_defconfig
@@ -415,6 +415,7 @@ CONFIG_NETDEVICES=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
 CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/arm/configs/iq80331_defconfig b/arch/arm/configs/iq80331_defconfig
index f50035d..46c79e1 100644
--- a/arch/arm/configs/iq80331_defconfig
+++ b/arch/arm/configs/iq80331_defconfig
@@ -496,6 +496,7 @@ CONFIG_NETDEVICES=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
 CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/arm/configs/iq80332_defconfig b/arch/arm/configs/iq80332_defconfig
index 18b3f37..11959b7 100644
--- a/arch/arm/configs/iq80332_defconfig
+++ b/arch/arm/configs/iq80332_defconfig
@@ -496,6 +496,7 @@ CONFIG_NETDEVICES=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
 CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig
index 33f3108..1964ccd 100644
--- a/arch/arm/configs/s3c2410_defconfig
+++ b/arch/arm/configs/s3c2410_defconfig
@@ -13,8 +13,7 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-# CONFIG_CLEAN_COMPILE is not set
-CONFIG_BROKEN=y
+CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 
@@ -473,7 +472,6 @@ CONFIG_BLK_DEV_IDE_BAST=y
 #
 # IEEE 1394 (FireWire) support
 #
-# CONFIG_IEEE1394 is not set
 
 #
 # I2O device support
@@ -896,7 +894,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
-# CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_RELAYFS_FS is not set
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 75e6f9a..d058e7c 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -7,337 +7,334 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
- *  This file is included twice in entry-common.S
+ *  This file is included thrice in entry-common.S
  */
-#ifndef NR_syscalls
-#define NR_syscalls 328
-#else
-
-100:
-/* 0 */		.long	sys_restart_syscall
-		.long	sys_exit
-		.long	sys_fork_wrapper
-		.long	sys_read
-		.long	sys_write
-/* 5 */		.long	sys_open
-		.long	sys_close
-		.long	sys_ni_syscall		/* was sys_waitpid */
-		.long	sys_creat
-		.long	sys_link
-/* 10 */	.long	sys_unlink
-		.long	sys_execve_wrapper
-		.long	sys_chdir
-		.long	OBSOLETE(sys_time)	/* used by libc4 */
-		.long	sys_mknod
-/* 15 */	.long	sys_chmod
-		.long	sys_lchown16
-		.long	sys_ni_syscall		/* was sys_break */
-		.long	sys_ni_syscall		/* was sys_stat */
-		.long	sys_lseek
-/* 20 */	.long	sys_getpid
-		.long	sys_mount
-		.long	OBSOLETE(sys_oldumount)	/* used by libc4 */
-		.long	sys_setuid16
-		.long	sys_getuid16
-/* 25 */	.long	OBSOLETE(sys_stime)
-		.long	sys_ptrace
-		.long	OBSOLETE(sys_alarm)	/* used by libc4 */
-		.long	sys_ni_syscall		/* was sys_fstat */
-		.long	sys_pause
-/* 30 */	.long	OBSOLETE(sys_utime)	/* used by libc4 */
-		.long	sys_ni_syscall		/* was sys_stty */
-		.long	sys_ni_syscall		/* was sys_getty */
-		.long	sys_access
-		.long	sys_nice
-/* 35 */	.long	sys_ni_syscall		/* was sys_ftime */
-		.long	sys_sync
-		.long	sys_kill
-		.long	sys_rename
-		.long	sys_mkdir
-/* 40 */	.long	sys_rmdir
-		.long	sys_dup
-		.long	sys_pipe
-		.long	sys_times
-		.long	sys_ni_syscall		/* was sys_prof */
-/* 45 */	.long	sys_brk
-		.long	sys_setgid16
-		.long	sys_getgid16
-		.long	sys_ni_syscall		/* was sys_signal */
-		.long	sys_geteuid16
-/* 50 */	.long	sys_getegid16
-		.long	sys_acct
-		.long	sys_umount
-		.long	sys_ni_syscall		/* was sys_lock */
-		.long	sys_ioctl
-/* 55 */	.long	sys_fcntl
-		.long	sys_ni_syscall		/* was sys_mpx */
-		.long	sys_setpgid
-		.long	sys_ni_syscall		/* was sys_ulimit */
-		.long	sys_ni_syscall		/* was sys_olduname */
-/* 60 */	.long	sys_umask
-		.long	sys_chroot
-		.long	sys_ustat
-		.long	sys_dup2
-		.long	sys_getppid
-/* 65 */	.long	sys_getpgrp
-		.long	sys_setsid
-		.long	sys_sigaction
-		.long	sys_ni_syscall		/* was sys_sgetmask */
-		.long	sys_ni_syscall		/* was sys_ssetmask */
-/* 70 */	.long	sys_setreuid16
-		.long	sys_setregid16
-		.long	sys_sigsuspend_wrapper
-		.long	sys_sigpending
-		.long	sys_sethostname
-/* 75 */	.long	sys_setrlimit
-		.long	OBSOLETE(sys_old_getrlimit) /* used by libc4 */
-		.long	sys_getrusage
-		.long	sys_gettimeofday
-		.long	sys_settimeofday
-/* 80 */	.long	sys_getgroups16
-		.long	sys_setgroups16
-		.long	OBSOLETE(old_select)	/* used by libc4 */
-		.long	sys_symlink
-		.long	sys_ni_syscall		/* was sys_lstat */
-/* 85 */	.long	sys_readlink
-		.long	sys_uselib
-		.long	sys_swapon
-		.long	sys_reboot
-		.long	OBSOLETE(old_readdir)	/* used by libc4 */
-/* 90 */	.long	OBSOLETE(old_mmap)	/* used by libc4 */
-		.long	sys_munmap
-		.long	sys_truncate
-		.long	sys_ftruncate
-		.long	sys_fchmod
-/* 95 */	.long	sys_fchown16
-		.long	sys_getpriority
-		.long	sys_setpriority
-		.long	sys_ni_syscall		/* was sys_profil */
-		.long	sys_statfs
-/* 100 */	.long	sys_fstatfs
-		.long	sys_ni_syscall
-		.long	OBSOLETE(sys_socketcall)
-		.long	sys_syslog
-		.long	sys_setitimer
-/* 105 */	.long	sys_getitimer
-		.long	sys_newstat
-		.long	sys_newlstat
-		.long	sys_newfstat
-		.long	sys_ni_syscall		/* was sys_uname */
-/* 110 */	.long	sys_ni_syscall		/* was sys_iopl */
-		.long	sys_vhangup
-		.long	sys_ni_syscall
-		.long	OBSOLETE(sys_syscall)	/* call a syscall */
-		.long	sys_wait4
-/* 115 */	.long	sys_swapoff
-		.long	sys_sysinfo
-		.long	OBSOLETE(ABI(sys_ipc, sys_oabi_ipc))
-		.long	sys_fsync
-		.long	sys_sigreturn_wrapper
-/* 120 */	.long	sys_clone_wrapper
-		.long	sys_setdomainname
-		.long	sys_newuname
-		.long	sys_ni_syscall
-		.long	sys_adjtimex
-/* 125 */	.long	sys_mprotect
-		.long	sys_sigprocmask
-		.long	sys_ni_syscall		/* was sys_create_module */
-		.long	sys_init_module
-		.long	sys_delete_module
-/* 130 */	.long	sys_ni_syscall		/* was sys_get_kernel_syms */
-		.long	sys_quotactl
-		.long	sys_getpgid
-		.long	sys_fchdir
-		.long	sys_bdflush
-/* 135 */	.long	sys_sysfs
-		.long	sys_personality
-		.long	sys_ni_syscall		/* .long	_sys_afs_syscall */
-		.long	sys_setfsuid16
-		.long	sys_setfsgid16
-/* 140 */	.long	sys_llseek
-		.long	sys_getdents
-		.long	sys_select
-		.long	sys_flock
-		.long	sys_msync
-/* 145 */	.long	sys_readv
-		.long	sys_writev
-		.long	sys_getsid
-		.long	sys_fdatasync
-		.long	sys_sysctl
-/* 150 */	.long	sys_mlock
-		.long	sys_munlock
-		.long	sys_mlockall
-		.long	sys_munlockall
-		.long	sys_sched_setparam
-/* 155 */	.long	sys_sched_getparam
-		.long	sys_sched_setscheduler
-		.long	sys_sched_getscheduler
-		.long	sys_sched_yield
-		.long	sys_sched_get_priority_max
-/* 160 */	.long	sys_sched_get_priority_min
-		.long	sys_sched_rr_get_interval
-		.long	sys_nanosleep
-		.long	sys_arm_mremap
-		.long	sys_setresuid16
-/* 165 */	.long	sys_getresuid16
-		.long	sys_ni_syscall
-		.long	sys_ni_syscall		/* was sys_query_module */
-		.long	sys_poll
-		.long	sys_nfsservctl
-/* 170 */	.long	sys_setresgid16
-		.long	sys_getresgid16
-		.long	sys_prctl
-		.long	sys_rt_sigreturn_wrapper
-		.long	sys_rt_sigaction
-/* 175 */	.long	sys_rt_sigprocmask
-		.long	sys_rt_sigpending
-		.long	sys_rt_sigtimedwait
-		.long	sys_rt_sigqueueinfo
-		.long	sys_rt_sigsuspend_wrapper
-/* 180 */	.long	ABI(sys_pread64, sys_oabi_pread64)
-		.long	ABI(sys_pwrite64, sys_oabi_pwrite64)
-		.long	sys_chown16
-		.long	sys_getcwd
-		.long	sys_capget
-/* 185 */	.long	sys_capset
-		.long	sys_sigaltstack_wrapper
-		.long	sys_sendfile
-		.long	sys_ni_syscall
-		.long	sys_ni_syscall
-/* 190 */	.long	sys_vfork_wrapper
-		.long	sys_getrlimit
-		.long	sys_mmap2
-		.long	ABI(sys_truncate64, sys_oabi_truncate64)
-		.long	ABI(sys_ftruncate64, sys_oabi_ftruncate64)
-/* 195 */	.long	ABI(sys_stat64, sys_oabi_stat64)
-		.long	ABI(sys_lstat64, sys_oabi_lstat64)
-		.long	ABI(sys_fstat64, sys_oabi_fstat64)
-		.long	sys_lchown
-		.long	sys_getuid
-/* 200 */	.long	sys_getgid
-		.long	sys_geteuid
-		.long	sys_getegid
-		.long	sys_setreuid
-		.long	sys_setregid
-/* 205 */	.long	sys_getgroups
-		.long	sys_setgroups
-		.long	sys_fchown
-		.long	sys_setresuid
-		.long	sys_getresuid
-/* 210 */	.long	sys_setresgid
-		.long	sys_getresgid
-		.long	sys_chown
-		.long	sys_setuid
-		.long	sys_setgid
-/* 215 */	.long	sys_setfsuid
-		.long	sys_setfsgid
-		.long	sys_getdents64
-		.long	sys_pivot_root
-		.long	sys_mincore
-/* 220 */	.long	sys_madvise
-		.long	ABI(sys_fcntl64, sys_oabi_fcntl64)
-		.long	sys_ni_syscall /* TUX */
-		.long	sys_ni_syscall
-		.long	sys_gettid
-/* 225 */	.long	ABI(sys_readahead, sys_oabi_readahead)
-		.long	sys_setxattr
-		.long	sys_lsetxattr
-		.long	sys_fsetxattr
-		.long	sys_getxattr
-/* 230 */	.long	sys_lgetxattr
-		.long	sys_fgetxattr
-		.long	sys_listxattr
-		.long	sys_llistxattr
-		.long	sys_flistxattr
-/* 235 */	.long	sys_removexattr
-		.long	sys_lremovexattr
-		.long	sys_fremovexattr
-		.long	sys_tkill
-		.long	sys_sendfile64
-/* 240 */	.long	sys_futex
-		.long	sys_sched_setaffinity
-		.long	sys_sched_getaffinity
-		.long	sys_io_setup
-		.long	sys_io_destroy
-/* 245 */	.long	sys_io_getevents
-		.long	sys_io_submit
-		.long	sys_io_cancel
-		.long	sys_exit_group
-		.long	sys_lookup_dcookie
-/* 250 */	.long	sys_epoll_create
-		.long	ABI(sys_epoll_ctl, sys_oabi_epoll_ctl)
-		.long	ABI(sys_epoll_wait, sys_oabi_epoll_wait)
-	 	.long	sys_remap_file_pages
-		.long	sys_ni_syscall	/* sys_set_thread_area */
-/* 255 */	.long	sys_ni_syscall	/* sys_get_thread_area */
- 		.long	sys_set_tid_address
-		.long	sys_timer_create
-		.long	sys_timer_settime
-		.long	sys_timer_gettime
-/* 260 */	.long	sys_timer_getoverrun
-		.long	sys_timer_delete
-		.long	sys_clock_settime
-		.long	sys_clock_gettime
-		.long	sys_clock_getres
-/* 265 */	.long	sys_clock_nanosleep
-		.long	sys_statfs64_wrapper
-		.long	sys_fstatfs64_wrapper
-		.long	sys_tgkill
-		.long	sys_utimes
-/* 270 */	.long	sys_arm_fadvise64_64
-		.long	sys_pciconfig_iobase
-		.long	sys_pciconfig_read
-		.long	sys_pciconfig_write
-		.long	sys_mq_open
-/* 275 */	.long	sys_mq_unlink
-		.long	sys_mq_timedsend
-		.long	sys_mq_timedreceive
-		.long	sys_mq_notify
-		.long	sys_mq_getsetattr
-/* 280 */	.long	sys_waitid
-		.long	sys_socket
-		.long	sys_bind
-		.long	sys_connect
-		.long	sys_listen
-/* 285 */	.long	sys_accept
-		.long	sys_getsockname
-		.long	sys_getpeername
-		.long	sys_socketpair
-		.long	sys_send
-/* 290 */	.long	sys_sendto
-		.long	sys_recv
-		.long	sys_recvfrom
-		.long	sys_shutdown
-		.long	sys_setsockopt
-/* 295 */	.long	sys_getsockopt
-		.long	sys_sendmsg
-		.long	sys_recvmsg
-		.long	ABI(sys_semop, sys_oabi_semop)
-		.long	sys_semget
-/* 300 */	.long	sys_semctl
-		.long	sys_msgsnd
-		.long	sys_msgrcv
-		.long	sys_msgget
-		.long	sys_msgctl
-/* 305 */	.long	sys_shmat
-		.long	sys_shmdt
-		.long	sys_shmget
-		.long	sys_shmctl
-		.long	sys_add_key
-/* 310 */	.long	sys_request_key
-		.long	sys_keyctl
-		.long	ABI(sys_semtimedop, sys_oabi_semtimedop)
-/* vserver */	.long	sys_ni_syscall
-		.long	sys_ioprio_set
-/* 315 */	.long	sys_ioprio_get
-		.long	sys_inotify_init
-		.long	sys_inotify_add_watch
-		.long	sys_inotify_rm_watch
-		.long	sys_mbind
-/* 320 */	.long	sys_get_mempolicy
-		.long	sys_set_mempolicy
-
-		.rept	NR_syscalls - (. - 100b) / 4
-			.long	sys_ni_syscall
-		.endr
+/* 0 */		CALL(sys_restart_syscall)
+		CALL(sys_exit)
+		CALL(sys_fork_wrapper)
+		CALL(sys_read)
+		CALL(sys_write)
+/* 5 */		CALL(sys_open)
+		CALL(sys_close)
+		CALL(sys_ni_syscall)		/* was sys_waitpid */
+		CALL(sys_creat)
+		CALL(sys_link)
+/* 10 */	CALL(sys_unlink)
+		CALL(sys_execve_wrapper)
+		CALL(sys_chdir)
+		CALL(OBSOLETE(sys_time))	/* used by libc4 */
+		CALL(sys_mknod)
+/* 15 */	CALL(sys_chmod)
+		CALL(sys_lchown16)
+		CALL(sys_ni_syscall)		/* was sys_break */
+		CALL(sys_ni_syscall)		/* was sys_stat */
+		CALL(sys_lseek)
+/* 20 */	CALL(sys_getpid)
+		CALL(sys_mount)
+		CALL(OBSOLETE(sys_oldumount))	/* used by libc4 */
+		CALL(sys_setuid16)
+		CALL(sys_getuid16)
+/* 25 */	CALL(OBSOLETE(sys_stime))
+		CALL(sys_ptrace)
+		CALL(OBSOLETE(sys_alarm))	/* used by libc4 */
+		CALL(sys_ni_syscall)		/* was sys_fstat */
+		CALL(sys_pause)
+/* 30 */	CALL(OBSOLETE(sys_utime))	/* used by libc4 */
+		CALL(sys_ni_syscall)		/* was sys_stty */
+		CALL(sys_ni_syscall)		/* was sys_getty */
+		CALL(sys_access)
+		CALL(sys_nice)
+/* 35 */	CALL(sys_ni_syscall)		/* was sys_ftime */
+		CALL(sys_sync)
+		CALL(sys_kill)
+		CALL(sys_rename)
+		CALL(sys_mkdir)
+/* 40 */	CALL(sys_rmdir)
+		CALL(sys_dup)
+		CALL(sys_pipe)
+		CALL(sys_times)
+		CALL(sys_ni_syscall)		/* was sys_prof */
+/* 45 */	CALL(sys_brk)
+		CALL(sys_setgid16)
+		CALL(sys_getgid16)
+		CALL(sys_ni_syscall)		/* was sys_signal */
+		CALL(sys_geteuid16)
+/* 50 */	CALL(sys_getegid16)
+		CALL(sys_acct)
+		CALL(sys_umount)
+		CALL(sys_ni_syscall)		/* was sys_lock */
+		CALL(sys_ioctl)
+/* 55 */	CALL(sys_fcntl)
+		CALL(sys_ni_syscall)		/* was sys_mpx */
+		CALL(sys_setpgid)
+		CALL(sys_ni_syscall)		/* was sys_ulimit */
+		CALL(sys_ni_syscall)		/* was sys_olduname */
+/* 60 */	CALL(sys_umask)
+		CALL(sys_chroot)
+		CALL(sys_ustat)
+		CALL(sys_dup2)
+		CALL(sys_getppid)
+/* 65 */	CALL(sys_getpgrp)
+		CALL(sys_setsid)
+		CALL(sys_sigaction)
+		CALL(sys_ni_syscall)		/* was sys_sgetmask */
+		CALL(sys_ni_syscall)		/* was sys_ssetmask */
+/* 70 */	CALL(sys_setreuid16)
+		CALL(sys_setregid16)
+		CALL(sys_sigsuspend_wrapper)
+		CALL(sys_sigpending)
+		CALL(sys_sethostname)
+/* 75 */	CALL(sys_setrlimit)
+		CALL(OBSOLETE(sys_old_getrlimit)) /* used by libc4 */
+		CALL(sys_getrusage)
+		CALL(sys_gettimeofday)
+		CALL(sys_settimeofday)
+/* 80 */	CALL(sys_getgroups16)
+		CALL(sys_setgroups16)
+		CALL(OBSOLETE(old_select))	/* used by libc4 */
+		CALL(sys_symlink)
+		CALL(sys_ni_syscall)		/* was sys_lstat */
+/* 85 */	CALL(sys_readlink)
+		CALL(sys_uselib)
+		CALL(sys_swapon)
+		CALL(sys_reboot)
+		CALL(OBSOLETE(old_readdir))	/* used by libc4 */
+/* 90 */	CALL(OBSOLETE(old_mmap))	/* used by libc4 */
+		CALL(sys_munmap)
+		CALL(sys_truncate)
+		CALL(sys_ftruncate)
+		CALL(sys_fchmod)
+/* 95 */	CALL(sys_fchown16)
+		CALL(sys_getpriority)
+		CALL(sys_setpriority)
+		CALL(sys_ni_syscall)		/* was sys_profil */
+		CALL(sys_statfs)
+/* 100 */	CALL(sys_fstatfs)
+		CALL(sys_ni_syscall)
+		CALL(OBSOLETE(sys_socketcall))
+		CALL(sys_syslog)
+		CALL(sys_setitimer)
+/* 105 */	CALL(sys_getitimer)
+		CALL(sys_newstat)
+		CALL(sys_newlstat)
+		CALL(sys_newfstat)
+		CALL(sys_ni_syscall)		/* was sys_uname */
+/* 110 */	CALL(sys_ni_syscall)		/* was sys_iopl */
+		CALL(sys_vhangup)
+		CALL(sys_ni_syscall)
+		CALL(OBSOLETE(sys_syscall))	/* call a syscall */
+		CALL(sys_wait4)
+/* 115 */	CALL(sys_swapoff)
+		CALL(sys_sysinfo)
+		CALL(OBSOLETE(ABI(sys_ipc, sys_oabi_ipc)))
+		CALL(sys_fsync)
+		CALL(sys_sigreturn_wrapper)
+/* 120 */	CALL(sys_clone_wrapper)
+		CALL(sys_setdomainname)
+		CALL(sys_newuname)
+		CALL(sys_ni_syscall)
+		CALL(sys_adjtimex)
+/* 125 */	CALL(sys_mprotect)
+		CALL(sys_sigprocmask)
+		CALL(sys_ni_syscall)		/* was sys_create_module */
+		CALL(sys_init_module)
+		CALL(sys_delete_module)
+/* 130 */	CALL(sys_ni_syscall)		/* was sys_get_kernel_syms */
+		CALL(sys_quotactl)
+		CALL(sys_getpgid)
+		CALL(sys_fchdir)
+		CALL(sys_bdflush)
+/* 135 */	CALL(sys_sysfs)
+		CALL(sys_personality)
+		CALL(sys_ni_syscall)		/* CALL(_sys_afs_syscall) */
+		CALL(sys_setfsuid16)
+		CALL(sys_setfsgid16)
+/* 140 */	CALL(sys_llseek)
+		CALL(sys_getdents)
+		CALL(sys_select)
+		CALL(sys_flock)
+		CALL(sys_msync)
+/* 145 */	CALL(sys_readv)
+		CALL(sys_writev)
+		CALL(sys_getsid)
+		CALL(sys_fdatasync)
+		CALL(sys_sysctl)
+/* 150 */	CALL(sys_mlock)
+		CALL(sys_munlock)
+		CALL(sys_mlockall)
+		CALL(sys_munlockall)
+		CALL(sys_sched_setparam)
+/* 155 */	CALL(sys_sched_getparam)
+		CALL(sys_sched_setscheduler)
+		CALL(sys_sched_getscheduler)
+		CALL(sys_sched_yield)
+		CALL(sys_sched_get_priority_max)
+/* 160 */	CALL(sys_sched_get_priority_min)
+		CALL(sys_sched_rr_get_interval)
+		CALL(sys_nanosleep)
+		CALL(sys_arm_mremap)
+		CALL(sys_setresuid16)
+/* 165 */	CALL(sys_getresuid16)
+		CALL(sys_ni_syscall)
+		CALL(sys_ni_syscall)		/* was sys_query_module */
+		CALL(sys_poll)
+		CALL(sys_nfsservctl)
+/* 170 */	CALL(sys_setresgid16)
+		CALL(sys_getresgid16)
+		CALL(sys_prctl)
+		CALL(sys_rt_sigreturn_wrapper)
+		CALL(sys_rt_sigaction)
+/* 175 */	CALL(sys_rt_sigprocmask)
+		CALL(sys_rt_sigpending)
+		CALL(sys_rt_sigtimedwait)
+		CALL(sys_rt_sigqueueinfo)
+		CALL(sys_rt_sigsuspend_wrapper)
+/* 180 */	CALL(ABI(sys_pread64, sys_oabi_pread64))
+		CALL(ABI(sys_pwrite64, sys_oabi_pwrite64))
+		CALL(sys_chown16)
+		CALL(sys_getcwd)
+		CALL(sys_capget)
+/* 185 */	CALL(sys_capset)
+		CALL(sys_sigaltstack_wrapper)
+		CALL(sys_sendfile)
+		CALL(sys_ni_syscall)
+		CALL(sys_ni_syscall)
+/* 190 */	CALL(sys_vfork_wrapper)
+		CALL(sys_getrlimit)
+		CALL(sys_mmap2)
+		CALL(ABI(sys_truncate64, sys_oabi_truncate64))
+		CALL(ABI(sys_ftruncate64, sys_oabi_ftruncate64))
+/* 195 */	CALL(ABI(sys_stat64, sys_oabi_stat64))
+		CALL(ABI(sys_lstat64, sys_oabi_lstat64))
+		CALL(ABI(sys_fstat64, sys_oabi_fstat64))
+		CALL(sys_lchown)
+		CALL(sys_getuid)
+/* 200 */	CALL(sys_getgid)
+		CALL(sys_geteuid)
+		CALL(sys_getegid)
+		CALL(sys_setreuid)
+		CALL(sys_setregid)
+/* 205 */	CALL(sys_getgroups)
+		CALL(sys_setgroups)
+		CALL(sys_fchown)
+		CALL(sys_setresuid)
+		CALL(sys_getresuid)
+/* 210 */	CALL(sys_setresgid)
+		CALL(sys_getresgid)
+		CALL(sys_chown)
+		CALL(sys_setuid)
+		CALL(sys_setgid)
+/* 215 */	CALL(sys_setfsuid)
+		CALL(sys_setfsgid)
+		CALL(sys_getdents64)
+		CALL(sys_pivot_root)
+		CALL(sys_mincore)
+/* 220 */	CALL(sys_madvise)
+		CALL(ABI(sys_fcntl64, sys_oabi_fcntl64))
+		CALL(sys_ni_syscall) /* TUX */
+		CALL(sys_ni_syscall)
+		CALL(sys_gettid)
+/* 225 */	CALL(ABI(sys_readahead, sys_oabi_readahead))
+		CALL(sys_setxattr)
+		CALL(sys_lsetxattr)
+		CALL(sys_fsetxattr)
+		CALL(sys_getxattr)
+/* 230 */	CALL(sys_lgetxattr)
+		CALL(sys_fgetxattr)
+		CALL(sys_listxattr)
+		CALL(sys_llistxattr)
+		CALL(sys_flistxattr)
+/* 235 */	CALL(sys_removexattr)
+		CALL(sys_lremovexattr)
+		CALL(sys_fremovexattr)
+		CALL(sys_tkill)
+		CALL(sys_sendfile64)
+/* 240 */	CALL(sys_futex)
+		CALL(sys_sched_setaffinity)
+		CALL(sys_sched_getaffinity)
+		CALL(sys_io_setup)
+		CALL(sys_io_destroy)
+/* 245 */	CALL(sys_io_getevents)
+		CALL(sys_io_submit)
+		CALL(sys_io_cancel)
+		CALL(sys_exit_group)
+		CALL(sys_lookup_dcookie)
+/* 250 */	CALL(sys_epoll_create)
+		CALL(ABI(sys_epoll_ctl, sys_oabi_epoll_ctl))
+		CALL(ABI(sys_epoll_wait, sys_oabi_epoll_wait))
+	 	CALL(sys_remap_file_pages)
+		CALL(sys_ni_syscall)	/* sys_set_thread_area */
+/* 255 */	CALL(sys_ni_syscall)	/* sys_get_thread_area */
+ 		CALL(sys_set_tid_address)
+		CALL(sys_timer_create)
+		CALL(sys_timer_settime)
+		CALL(sys_timer_gettime)
+/* 260 */	CALL(sys_timer_getoverrun)
+		CALL(sys_timer_delete)
+		CALL(sys_clock_settime)
+		CALL(sys_clock_gettime)
+		CALL(sys_clock_getres)
+/* 265 */	CALL(sys_clock_nanosleep)
+		CALL(sys_statfs64_wrapper)
+		CALL(sys_fstatfs64_wrapper)
+		CALL(sys_tgkill)
+		CALL(sys_utimes)
+/* 270 */	CALL(sys_arm_fadvise64_64)
+		CALL(sys_pciconfig_iobase)
+		CALL(sys_pciconfig_read)
+		CALL(sys_pciconfig_write)
+		CALL(sys_mq_open)
+/* 275 */	CALL(sys_mq_unlink)
+		CALL(sys_mq_timedsend)
+		CALL(sys_mq_timedreceive)
+		CALL(sys_mq_notify)
+		CALL(sys_mq_getsetattr)
+/* 280 */	CALL(sys_waitid)
+		CALL(sys_socket)
+		CALL(sys_bind)
+		CALL(sys_connect)
+		CALL(sys_listen)
+/* 285 */	CALL(sys_accept)
+		CALL(sys_getsockname)
+		CALL(sys_getpeername)
+		CALL(sys_socketpair)
+		CALL(sys_send)
+/* 290 */	CALL(sys_sendto)
+		CALL(sys_recv)
+		CALL(sys_recvfrom)
+		CALL(sys_shutdown)
+		CALL(sys_setsockopt)
+/* 295 */	CALL(sys_getsockopt)
+		CALL(sys_sendmsg)
+		CALL(sys_recvmsg)
+		CALL(ABI(sys_semop, sys_oabi_semop))
+		CALL(sys_semget)
+/* 300 */	CALL(sys_semctl)
+		CALL(sys_msgsnd)
+		CALL(sys_msgrcv)
+		CALL(sys_msgget)
+		CALL(sys_msgctl)
+/* 305 */	CALL(sys_shmat)
+		CALL(sys_shmdt)
+		CALL(sys_shmget)
+		CALL(sys_shmctl)
+		CALL(sys_add_key)
+/* 310 */	CALL(sys_request_key)
+		CALL(sys_keyctl)
+		CALL(ABI(sys_semtimedop, sys_oabi_semtimedop))
+/* vserver */	CALL(sys_ni_syscall)
+		CALL(sys_ioprio_set)
+/* 315 */	CALL(sys_ioprio_get)
+		CALL(sys_inotify_init)
+		CALL(sys_inotify_add_watch)
+		CALL(sys_inotify_rm_watch)
+		CALL(sys_mbind)
+/* 320 */	CALL(sys_get_mempolicy)
+		CALL(sys_set_mempolicy)
+#ifndef syscalls_counted
+.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
+#define syscalls_counted
 #endif
+.rept syscalls_padding
+		CALL(sys_ni_syscall)
+.endr
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 874e6bb..d401d90 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -735,8 +735,11 @@ __kuser_cmpxchg:				@ 0xffff0fc0
 	 * The kernel itself must perform the operation.
 	 * A special ghost syscall is used for that (see traps.c).
 	 */
+	stmfd	sp!, {r7, lr}
+	mov	r7, #0xff00		@ 0xfff0 into r7 for EABI
+	orr	r7, r7, #0xf0
 	swi	#0x9ffff0
-	mov	pc, lr
+	ldmfd	sp!, {r7, pc}
 
 #elif __LINUX_ARM_ARCH__ < 6
 
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 2b92ce8..dbcb11a 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -87,7 +87,11 @@ ENTRY(ret_from_fork)
 	b	ret_slow_syscall
 	
 
+	.equ NR_syscalls,0
+#define CALL(x) .equ NR_syscalls,NR_syscalls+1
 #include "calls.S"
+#undef CALL
+#define CALL(x) .long x
 
 /*=============================================================================
  * SWI handler
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 765922b..a0cd0a9 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -30,15 +30,21 @@
 #define SWI_SYS_RT_SIGRETURN	(0xef000000|(__NR_rt_sigreturn))
 
 /*
+ * With EABI, the syscall number has to be loaded into r7.
+ */
+#define MOV_R7_NR_SIGRETURN	(0xe3a07000 | (__NR_sigreturn - __NR_SYSCALL_BASE))
+#define MOV_R7_NR_RT_SIGRETURN	(0xe3a07000 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE))
+
+/*
  * For Thumb syscalls, we pass the syscall number via r7.  We therefore
  * need two 16-bit instructions.
  */
 #define SWI_THUMB_SIGRETURN	(0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE))
 #define SWI_THUMB_RT_SIGRETURN	(0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE))
 
-const unsigned long sigreturn_codes[4] = {
-	SWI_SYS_SIGRETURN,	SWI_THUMB_SIGRETURN,
-	SWI_SYS_RT_SIGRETURN,	SWI_THUMB_RT_SIGRETURN
+const unsigned long sigreturn_codes[7] = {
+	MOV_R7_NR_SIGRETURN,    SWI_SYS_SIGRETURN,    SWI_THUMB_SIGRETURN,
+	MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN,
 };
 
 static int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall);
@@ -189,7 +195,7 @@ struct aux_sigframe {
 struct sigframe {
 	struct sigcontext sc;
 	unsigned long extramask[_NSIG_WORDS-1];
-	unsigned long retcode;
+	unsigned long retcode[2];
 	struct aux_sigframe aux __attribute__((aligned(8)));
 };
 
@@ -198,7 +204,7 @@ struct rt_sigframe {
 	void __user *puc;
 	struct siginfo info;
 	struct ucontext uc;
-	unsigned long retcode;
+	unsigned long retcode[2];
 	struct aux_sigframe aux __attribute__((aligned(8)));
 };
 
@@ -436,12 +442,13 @@ setup_return(struct pt_regs *regs, struc
 	if (ka->sa.sa_flags & SA_RESTORER) {
 		retcode = (unsigned long)ka->sa.sa_restorer;
 	} else {
-		unsigned int idx = thumb;
+		unsigned int idx = thumb << 1;
 
 		if (ka->sa.sa_flags & SA_SIGINFO)
-			idx += 2;
+			idx += 3;
 
-		if (__put_user(sigreturn_codes[idx], rc))
+		if (__put_user(sigreturn_codes[idx],   rc) ||
+		    __put_user(sigreturn_codes[idx+1], rc+1))
 			return 1;
 
 		if (cpsr & MODE32_BIT) {
@@ -456,7 +463,7 @@ setup_return(struct pt_regs *regs, struc
 			 * the return code written onto the stack.
 			 */
 			flush_icache_range((unsigned long)rc,
-					   (unsigned long)(rc + 1));
+					   (unsigned long)(rc + 2));
 
 			retcode = ((unsigned long)rc) + thumb;
 		}
@@ -488,7 +495,7 @@ setup_frame(int usig, struct k_sigaction
 	}
 
 	if (err == 0)
-		err = setup_return(regs, ka, &frame->retcode, frame, usig);
+		err = setup_return(regs, ka, frame->retcode, frame, usig);
 
 	return err;
 }
@@ -522,7 +529,7 @@ setup_rt_frame(int usig, struct k_sigact
 	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 
 	if (err == 0)
-		err = setup_return(regs, ka, &frame->retcode, frame, usig);
+		err = setup_return(regs, ka, frame->retcode, frame, usig);
 
 	if (err == 0) {
 		/*
diff --git a/arch/arm/kernel/signal.h b/arch/arm/kernel/signal.h
index 91d26fa..9991049 100644
--- a/arch/arm/kernel/signal.h
+++ b/arch/arm/kernel/signal.h
@@ -9,4 +9,4 @@
  */
 #define KERN_SIGRETURN_CODE	0xffff0500
 
-extern const unsigned long sigreturn_codes[4];
+extern const unsigned long sigreturn_codes[7];
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 3182017..a0724f2 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -469,7 +469,9 @@ static void cp_clcd_enable(struct clcd_f
 	if (fb->fb.var.bits_per_pixel <= 8)
 		val = CM_CTRL_LCDMUXSEL_VGA_8421BPP;
 	else if (fb->fb.var.bits_per_pixel <= 16)
-		val = CM_CTRL_LCDMUXSEL_VGA_16BPP;
+		val = CM_CTRL_LCDMUXSEL_VGA_16BPP
+			| CM_CTRL_LCDEN0 | CM_CTRL_LCDEN1
+			| CM_CTRL_STATIC1 | CM_CTRL_STATIC2;
 	else
 		val = 0; /* no idea for this, don't trust the docs */
 
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 6b39369..4bdc9d4 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -333,6 +333,7 @@ static struct platform_device *ixp46x_de
 };
 
 unsigned long ixp4xx_exp_bus_size;
+EXPORT_SYMBOL(ixp4xx_exp_bus_size);
 
 void __init ixp4xx_sys_init(void)
 {
@@ -352,7 +353,7 @@ void __init ixp4xx_sys_init(void)
 		}
 	}
 
-	printk("IXP4xx: Using %uMiB expansion bus window size\n",
+	printk("IXP4xx: Using %luMiB expansion bus window size\n",
 			ixp4xx_exp_bus_size >> 20);
 }
 
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index 9d862f8..75110ba 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -50,10 +50,10 @@ static int omap1_clk_enable_dsp_domain(s
 {
 	int retval;
 
-	retval = omap1_clk_use(&api_ck.clk);
+	retval = omap1_clk_enable(&api_ck.clk);
 	if (!retval) {
-		retval = omap1_clk_enable(clk);
-		omap1_clk_unuse(&api_ck.clk);
+		retval = omap1_clk_enable_generic(clk);
+		omap1_clk_disable(&api_ck.clk);
 	}
 
 	return retval;
@@ -61,9 +61,9 @@ static int omap1_clk_enable_dsp_domain(s
 
 static void omap1_clk_disable_dsp_domain(struct clk *clk)
 {
-	if (omap1_clk_use(&api_ck.clk) == 0) {
-		omap1_clk_disable(clk);
-		omap1_clk_unuse(&api_ck.clk);
+	if (omap1_clk_enable(&api_ck.clk) == 0) {
+		omap1_clk_disable_generic(clk);
+		omap1_clk_disable(&api_ck.clk);
 	}
 }
 
@@ -72,7 +72,7 @@ static int omap1_clk_enable_uart_functio
 	int ret;
 	struct uart_clk *uclk;
 
-	ret = omap1_clk_enable(clk);
+	ret = omap1_clk_enable_generic(clk);
 	if (ret == 0) {
 		/* Set smart idle acknowledgement mode */
 		uclk = (struct uart_clk *)clk;
@@ -91,7 +91,7 @@ static void omap1_clk_disable_uart_funct
 	uclk = (struct uart_clk *)clk;
 	omap_writeb((omap_readb(uclk->sysc_addr) & ~0x18), uclk->sysc_addr);
 
-	omap1_clk_disable(clk);
+	omap1_clk_disable_generic(clk);
 }
 
 static void omap1_clk_allow_idle(struct clk *clk)
@@ -230,9 +230,9 @@ static void omap1_ckctl_recalc_dsp_domai
 	 * Note that DSP_CKCTL virt addr = phys addr, so
 	 * we must use __raw_readw() instead of omap_readw().
 	 */
-	omap1_clk_use(&api_ck.clk);
+	omap1_clk_enable(&api_ck.clk);
 	dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset));
-	omap1_clk_unuse(&api_ck.clk);
+	omap1_clk_disable(&api_ck.clk);
 
 	if (unlikely(clk->rate == clk->parent->rate / dsor))
 		return; /* No change, quick exit */
@@ -412,12 +412,12 @@ static void omap1_init_ext_clk(struct cl
 	clk-> rate = 96000000 / dsor;
 }
 
-static int omap1_clk_use(struct clk *clk)
+static int omap1_clk_enable(struct clk *clk)
 {
 	int ret = 0;
 	if (clk->usecount++ == 0) {
 		if (likely(clk->parent)) {
-			ret = omap1_clk_use(clk->parent);
+			ret = omap1_clk_enable(clk->parent);
 
 			if (unlikely(ret != 0)) {
 				clk->usecount--;
@@ -432,7 +432,7 @@ static int omap1_clk_use(struct clk *clk
 		ret = clk->enable(clk);
 
 		if (unlikely(ret != 0) && clk->parent) {
-			omap1_clk_unuse(clk->parent);
+			omap1_clk_disable(clk->parent);
 			clk->usecount--;
 		}
 	}
@@ -440,12 +440,12 @@ static int omap1_clk_use(struct clk *clk
 	return ret;
 }
 
-static void omap1_clk_unuse(struct clk *clk)
+static void omap1_clk_disable(struct clk *clk)
 {
 	if (clk->usecount > 0 && !(--clk->usecount)) {
 		clk->disable(clk);
 		if (likely(clk->parent)) {
-			omap1_clk_unuse(clk->parent);
+			omap1_clk_disable(clk->parent);
 			if (clk->flags & CLOCK_NO_IDLE_PARENT)
 				if (!cpu_is_omap24xx())
 					omap1_clk_allow_idle(clk->parent);
@@ -453,7 +453,7 @@ static void omap1_clk_unuse(struct clk *
 	}
 }
 
-static int omap1_clk_enable(struct clk *clk)
+static int omap1_clk_enable_generic(struct clk *clk)
 {
 	__u16 regval16;
 	__u32 regval32;
@@ -492,7 +492,7 @@ static int omap1_clk_enable(struct clk *
 	return 0;
 }
 
-static void omap1_clk_disable(struct clk *clk)
+static void omap1_clk_disable_generic(struct clk *clk)
 {
 	__u16 regval16;
 	__u32 regval32;
@@ -654,8 +654,8 @@ late_initcall(omap1_late_clk_reset);
 #endif
 
 static struct clk_functions omap1_clk_functions = {
-	.clk_use		= omap1_clk_use,
-	.clk_unuse		= omap1_clk_unuse,
+	.clk_enable		= omap1_clk_enable,
+	.clk_disable		= omap1_clk_disable,
 	.clk_round_rate		= omap1_clk_round_rate,
 	.clk_set_rate		= omap1_clk_set_rate,
 };
@@ -780,9 +780,9 @@ int __init omap1_clk_init(void)
 	 * Only enable those clocks we will need, let the drivers
 	 * enable other clocks as necessary
 	 */
-	clk_use(&armper_ck.clk);
-	clk_use(&armxor_ck.clk);
-	clk_use(&armtim_ck.clk); /* This should be done by timer code */
+	clk_enable(&armper_ck.clk);
+	clk_enable(&armxor_ck.clk);
+	clk_enable(&armtim_ck.clk); /* This should be done by timer code */
 
 	if (cpu_is_omap1510())
 		clk_enable(&arm_gpio_ck);
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h
index f3bdfb5..4f18d1b 100644
--- a/arch/arm/mach-omap1/clock.h
+++ b/arch/arm/mach-omap1/clock.h
@@ -13,8 +13,8 @@
 #ifndef __ARCH_ARM_MACH_OMAP1_CLOCK_H
 #define __ARCH_ARM_MACH_OMAP1_CLOCK_H
 
-static int omap1_clk_enable(struct clk * clk);
-static void omap1_clk_disable(struct clk * clk);
+static int omap1_clk_enable_generic(struct clk * clk);
+static void omap1_clk_disable_generic(struct clk * clk);
 static void omap1_ckctl_recalc(struct clk * clk);
 static void omap1_watchdog_recalc(struct clk * clk);
 static void omap1_ckctl_recalc_dsp_domain(struct clk * clk);
@@ -30,8 +30,8 @@ static long omap1_round_ext_clk_rate(str
 static void omap1_init_ext_clk(struct clk * clk);
 static int omap1_select_table_rate(struct clk * clk, unsigned long rate);
 static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate);
-static int omap1_clk_use(struct clk *clk);
-static void omap1_clk_unuse(struct clk *clk);
+static int omap1_clk_enable(struct clk *clk);
+static void omap1_clk_disable(struct clk *clk);
 
 struct mpu_rate {
 	unsigned long		rate;
@@ -152,8 +152,8 @@ static struct clk ck_ref = {
 	.rate		= 12000000,
 	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
 			  ALWAYS_ENABLED,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk ck_dpll1 = {
@@ -161,8 +161,8 @@ static struct clk ck_dpll1 = {
 	.parent		= &ck_ref,
 	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
 			  RATE_PROPAGATES | ALWAYS_ENABLED,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct arm_idlect1_clk ck_dpll1out = {
@@ -173,8 +173,8 @@ static struct arm_idlect1_clk ck_dpll1ou
 		.enable_reg	= (void __iomem *)ARM_IDLECT2,
 		.enable_bit	= EN_CKOUT_ARM,
 		.recalc		= &followparent_recalc,
-		.enable		= &omap1_clk_enable,
-		.disable	= &omap1_clk_disable,
+		.enable		= &omap1_clk_enable_generic,
+		.disable	= &omap1_clk_disable_generic,
 	},
 	.idlect_shift	= 12,
 };
@@ -186,8 +186,8 @@ static struct clk arm_ck = {
 			  RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
 	.rate_offset	= CKCTL_ARMDIV_OFFSET,
 	.recalc		= &omap1_ckctl_recalc,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct arm_idlect1_clk armper_ck = {
@@ -200,8 +200,8 @@ static struct arm_idlect1_clk armper_ck 
 		.enable_bit	= EN_PERCK,
 		.rate_offset	= CKCTL_PERDIV_OFFSET,
 		.recalc		= &omap1_ckctl_recalc,
-		.enable		= &omap1_clk_enable,
-		.disable	= &omap1_clk_disable,
+		.enable		= &omap1_clk_enable_generic,
+		.disable	= &omap1_clk_disable_generic,
 	},
 	.idlect_shift	= 2,
 };
@@ -213,8 +213,8 @@ static struct clk arm_gpio_ck = {
 	.enable_reg	= (void __iomem *)ARM_IDLECT2,
 	.enable_bit	= EN_GPIOCK,
 	.recalc		= &followparent_recalc,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct arm_idlect1_clk armxor_ck = {
@@ -226,8 +226,8 @@ static struct arm_idlect1_clk armxor_ck 
 		.enable_reg	= (void __iomem *)ARM_IDLECT2,
 		.enable_bit	= EN_XORPCK,
 		.recalc		= &followparent_recalc,
-		.enable		= &omap1_clk_enable,
-		.disable	= &omap1_clk_disable,
+		.enable		= &omap1_clk_enable_generic,
+		.disable	= &omap1_clk_disable_generic,
 	},
 	.idlect_shift	= 1,
 };
@@ -241,8 +241,8 @@ static struct arm_idlect1_clk armtim_ck 
 		.enable_reg	= (void __iomem *)ARM_IDLECT2,
 		.enable_bit	= EN_TIMCK,
 		.recalc		= &followparent_recalc,
-		.enable		= &omap1_clk_enable,
-		.disable	= &omap1_clk_disable,
+		.enable		= &omap1_clk_enable_generic,
+		.disable	= &omap1_clk_disable_generic,
 	},
 	.idlect_shift	= 9,
 };
@@ -256,8 +256,8 @@ static struct arm_idlect1_clk armwdt_ck 
 		.enable_reg	= (void __iomem *)ARM_IDLECT2,
 		.enable_bit	= EN_WDTCK,
 		.recalc		= &omap1_watchdog_recalc,
-		.enable		= &omap1_clk_enable,
-		.disable	= &omap1_clk_disable,
+		.enable		= &omap1_clk_enable_generic,
+		.disable	= &omap1_clk_disable_generic,
 	},
 	.idlect_shift	= 0,
 };
@@ -272,8 +272,8 @@ static struct clk arminth_ck16xx = {
 	 *
 	 * 1510 version is in TC clocks.
 	 */
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk dsp_ck = {
@@ -285,8 +285,8 @@ static struct clk dsp_ck = {
 	.enable_bit	= EN_DSPCK,
 	.rate_offset	= CKCTL_DSPDIV_OFFSET,
 	.recalc		= &omap1_ckctl_recalc,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk dspmmu_ck = {
@@ -296,8 +296,8 @@ static struct clk dspmmu_ck = {
 			  RATE_CKCTL | ALWAYS_ENABLED,
 	.rate_offset	= CKCTL_DSPMMUDIV_OFFSET,
 	.recalc		= &omap1_ckctl_recalc,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk dspper_ck = {
@@ -349,8 +349,8 @@ static struct arm_idlect1_clk tc_ck = {
 				  CLOCK_IDLE_CONTROL,
 		.rate_offset	= CKCTL_TCDIV_OFFSET,
 		.recalc		= &omap1_ckctl_recalc,
-		.enable		= &omap1_clk_enable,
-		.disable	= &omap1_clk_disable,
+		.enable		= &omap1_clk_enable_generic,
+		.disable	= &omap1_clk_disable_generic,
 	},
 	.idlect_shift	= 6,
 };
@@ -364,8 +364,8 @@ static struct clk arminth_ck1510 = {
 	 *
 	 * 16xx version is in MPU clocks.
 	 */
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk tipb_ck = {
@@ -374,8 +374,8 @@ static struct clk tipb_ck = {
 	.parent		= &tc_ck.clk,
 	.flags		= CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
 	.recalc		= &followparent_recalc,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk l3_ocpi_ck = {
@@ -386,8 +386,8 @@ static struct clk l3_ocpi_ck = {
 	.enable_reg	= (void __iomem *)ARM_IDLECT3,
 	.enable_bit	= EN_OCPI_CK,
 	.recalc		= &followparent_recalc,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk tc1_ck = {
@@ -397,8 +397,8 @@ static struct clk tc1_ck = {
 	.enable_reg	= (void __iomem *)ARM_IDLECT3,
 	.enable_bit	= EN_TC1_CK,
 	.recalc		= &followparent_recalc,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk tc2_ck = {
@@ -408,8 +408,8 @@ static struct clk tc2_ck = {
 	.enable_reg	= (void __iomem *)ARM_IDLECT3,
 	.enable_bit	= EN_TC2_CK,
 	.recalc		= &followparent_recalc,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk dma_ck = {
@@ -419,8 +419,8 @@ static struct clk dma_ck = {
 	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
 			  ALWAYS_ENABLED,
 	.recalc		= &followparent_recalc,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk dma_lcdfree_ck = {
@@ -428,8 +428,8 @@ static struct clk dma_lcdfree_ck = {
 	.parent		= &tc_ck.clk,
 	.flags		= CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
 	.recalc		= &followparent_recalc,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct arm_idlect1_clk api_ck = {
@@ -441,8 +441,8 @@ static struct arm_idlect1_clk api_ck = {
 		.enable_reg	= (void __iomem *)ARM_IDLECT2,
 		.enable_bit	= EN_APICK,
 		.recalc		= &followparent_recalc,
-		.enable		= &omap1_clk_enable,
-		.disable	= &omap1_clk_disable,
+		.enable		= &omap1_clk_enable_generic,
+		.disable	= &omap1_clk_disable_generic,
 	},
 	.idlect_shift	= 8,
 };
@@ -455,8 +455,8 @@ static struct arm_idlect1_clk lb_ck = {
 		.enable_reg	= (void __iomem *)ARM_IDLECT2,
 		.enable_bit	= EN_LBCK,
 		.recalc		= &followparent_recalc,
-		.enable		= &omap1_clk_enable,
-		.disable	= &omap1_clk_disable,
+		.enable		= &omap1_clk_enable_generic,
+		.disable	= &omap1_clk_disable_generic,
 	},
 	.idlect_shift	= 4,
 };
@@ -466,8 +466,8 @@ static struct clk rhea1_ck = {
 	.parent		= &tc_ck.clk,
 	.flags		= CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
 	.recalc		= &followparent_recalc,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk rhea2_ck = {
@@ -475,8 +475,8 @@ static struct clk rhea2_ck = {
 	.parent		= &tc_ck.clk,
 	.flags		= CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
 	.recalc		= &followparent_recalc,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk lcd_ck_16xx = {
@@ -487,8 +487,8 @@ static struct clk lcd_ck_16xx = {
 	.enable_bit	= EN_LCDCK,
 	.rate_offset	= CKCTL_LCDDIV_OFFSET,
 	.recalc		= &omap1_ckctl_recalc,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct arm_idlect1_clk lcd_ck_1510 = {
@@ -501,8 +501,8 @@ static struct arm_idlect1_clk lcd_ck_151
 		.enable_bit	= EN_LCDCK,
 		.rate_offset	= CKCTL_LCDDIV_OFFSET,
 		.recalc		= &omap1_ckctl_recalc,
-		.enable		= &omap1_clk_enable,
-		.disable	= &omap1_clk_disable,
+		.enable		= &omap1_clk_enable_generic,
+		.disable	= &omap1_clk_disable_generic,
 	},
 	.idlect_shift	= 3,
 };
@@ -518,8 +518,8 @@ static struct clk uart1_1510 = {
 	.enable_bit	= 29,	/* Chooses between 12MHz and 48MHz */
 	.set_rate	= &omap1_set_uart_rate,
 	.recalc		= &omap1_uart_recalc,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct uart_clk uart1_16xx = {
@@ -550,8 +550,8 @@ static struct clk uart2_ck = {
 	.enable_bit	= 30,	/* Chooses between 12MHz and 48MHz */
 	.set_rate	= &omap1_set_uart_rate,
 	.recalc		= &omap1_uart_recalc,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk uart3_1510 = {
@@ -565,8 +565,8 @@ static struct clk uart3_1510 = {
 	.enable_bit	= 31,	/* Chooses between 12MHz and 48MHz */
 	.set_rate	= &omap1_set_uart_rate,
 	.recalc		= &omap1_uart_recalc,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct uart_clk uart3_16xx = {
@@ -593,8 +593,8 @@ static struct clk usb_clko = {	/* 6 MHz 
 			  RATE_FIXED | ENABLE_REG_32BIT,
 	.enable_reg	= (void __iomem *)ULPD_CLOCK_CTRL,
 	.enable_bit	= USB_MCLK_EN_BIT,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk usb_hhc_ck1510 = {
@@ -605,8 +605,8 @@ static struct clk usb_hhc_ck1510 = {
 			  RATE_FIXED | ENABLE_REG_32BIT,
 	.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
 	.enable_bit	= USB_HOST_HHC_UHOST_EN,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk usb_hhc_ck16xx = {
@@ -618,8 +618,8 @@ static struct clk usb_hhc_ck16xx = {
 			  RATE_FIXED | ENABLE_REG_32BIT,
 	.enable_reg	= (void __iomem *)OTG_BASE + 0x08 /* OTG_SYSCON_2 */,
 	.enable_bit	= 8 /* UHOST_EN */,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk usb_dc_ck = {
@@ -629,8 +629,8 @@ static struct clk usb_dc_ck = {
 	.flags		= CLOCK_IN_OMAP16XX | RATE_FIXED,
 	.enable_reg	= (void __iomem *)SOFT_REQ_REG,
 	.enable_bit	= 4,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk mclk_1510 = {
@@ -638,8 +638,8 @@ static struct clk mclk_1510 = {
 	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
 	.rate		= 12000000,
 	.flags		= CLOCK_IN_OMAP1510 | RATE_FIXED,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk mclk_16xx = {
@@ -651,8 +651,8 @@ static struct clk mclk_16xx = {
 	.set_rate	= &omap1_set_ext_clk_rate,
 	.round_rate	= &omap1_round_ext_clk_rate,
 	.init		= &omap1_init_ext_clk,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk bclk_1510 = {
@@ -660,8 +660,8 @@ static struct clk bclk_1510 = {
 	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
 	.rate		= 12000000,
 	.flags		= CLOCK_IN_OMAP1510 | RATE_FIXED,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk bclk_16xx = {
@@ -673,8 +673,8 @@ static struct clk bclk_16xx = {
 	.set_rate	= &omap1_set_ext_clk_rate,
 	.round_rate	= &omap1_round_ext_clk_rate,
 	.init		= &omap1_init_ext_clk,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk mmc1_ck = {
@@ -686,8 +686,8 @@ static struct clk mmc1_ck = {
 			  RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
 	.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
 	.enable_bit	= 23,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk mmc2_ck = {
@@ -699,8 +699,8 @@ static struct clk mmc2_ck = {
 			  RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
 	.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
 	.enable_bit	= 20,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk virtual_ck_mpu = {
@@ -711,8 +711,8 @@ static struct clk virtual_ck_mpu = {
 	.recalc		= &followparent_recalc,
 	.set_rate	= &omap1_select_table_rate,
 	.round_rate	= &omap1_round_to_table_rate,
-	.enable		= &omap1_clk_enable,
-	.disable	= &omap1_clk_disable,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk * onchip_clks[] = {
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
index 7a68f09..e924e0c 100644
--- a/arch/arm/mach-omap1/serial.c
+++ b/arch/arm/mach-omap1/serial.c
@@ -146,7 +146,7 @@ void __init omap_serial_init(void)
 			if (IS_ERR(uart1_ck))
 				printk("Could not get uart1_ck\n");
 			else {
-				clk_use(uart1_ck);
+				clk_enable(uart1_ck);
 				if (cpu_is_omap1510())
 					clk_set_rate(uart1_ck, 12000000);
 			}
@@ -166,7 +166,7 @@ void __init omap_serial_init(void)
 			if (IS_ERR(uart2_ck))
 				printk("Could not get uart2_ck\n");
 			else {
-				clk_use(uart2_ck);
+				clk_enable(uart2_ck);
 				if (cpu_is_omap1510())
 					clk_set_rate(uart2_ck, 12000000);
 				else
@@ -188,7 +188,7 @@ void __init omap_serial_init(void)
 			if (IS_ERR(uart3_ck))
 				printk("Could not get uart3_ck\n");
 			else {
-				clk_use(uart3_ck);
+				clk_enable(uart3_ck);
 				if (cpu_is_omap1510())
 					clk_set_rate(uart3_ck, 12000000);
 			}
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 5407b95..180f675 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -111,7 +111,7 @@ static void omap2_clk_fixed_enable(struc
 /* Enables clock without considering parent dependencies or use count
  * REVISIT: Maybe change this to use clk->enable like on omap1?
  */
-static int omap2_clk_enable(struct clk * clk)
+static int _omap2_clk_enable(struct clk * clk)
 {
 	u32 regval32;
 
@@ -150,7 +150,7 @@ static void omap2_clk_fixed_disable(stru
 }
 
 /* Disables clock without considering parent dependencies or use count */
-static void omap2_clk_disable(struct clk *clk)
+static void _omap2_clk_disable(struct clk *clk)
 {
 	u32 regval32;
 
@@ -167,23 +167,23 @@ static void omap2_clk_disable(struct clk
 	__raw_writel(regval32, clk->enable_reg);
 }
 
-static int omap2_clk_use(struct clk *clk)
+static int omap2_clk_enable(struct clk *clk)
 {
 	int ret = 0;
 
 	if (clk->usecount++ == 0) {
 		if (likely((u32)clk->parent))
-			ret = omap2_clk_use(clk->parent);
+			ret = omap2_clk_enable(clk->parent);
 
 		if (unlikely(ret != 0)) {
 			clk->usecount--;
 			return ret;
 		}
 
-		ret = omap2_clk_enable(clk);
+		ret = _omap2_clk_enable(clk);
 
 		if (unlikely(ret != 0) && clk->parent) {
-			omap2_clk_unuse(clk->parent);
+			omap2_clk_disable(clk->parent);
 			clk->usecount--;
 		}
 	}
@@ -191,12 +191,12 @@ static int omap2_clk_use(struct clk *clk
 	return ret;
 }
 
-static void omap2_clk_unuse(struct clk *clk)
+static void omap2_clk_disable(struct clk *clk)
 {
 	if (clk->usecount > 0 && !(--clk->usecount)) {
-		omap2_clk_disable(clk);
+		_omap2_clk_disable(clk);
 		if (likely((u32)clk->parent))
-			omap2_clk_unuse(clk->parent);
+			omap2_clk_disable(clk->parent);
 	}
 }
 
@@ -873,7 +873,7 @@ static int omap2_clk_set_parent(struct c
 		reg = (void __iomem *)src_sel;
 
 		if (clk->usecount > 0)
-			omap2_clk_disable(clk);
+			_omap2_clk_disable(clk);
 
 		/* Set new source value (previous dividers if any in effect) */
 		reg_val = __raw_readl(reg) & ~(field_mask << src_off);
@@ -884,7 +884,7 @@ static int omap2_clk_set_parent(struct c
 			__raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL);
 
 		if (clk->usecount > 0)
-			omap2_clk_enable(clk);
+			_omap2_clk_enable(clk);
 
 		clk->parent = new_parent;
 
@@ -999,8 +999,6 @@ static int omap2_select_table_rate(struc
 static struct clk_functions omap2_clk_functions = {
 	.clk_enable		= omap2_clk_enable,
 	.clk_disable		= omap2_clk_disable,
-	.clk_use		= omap2_clk_use,
-	.clk_unuse		= omap2_clk_unuse,
 	.clk_round_rate		= omap2_clk_round_rate,
 	.clk_set_rate		= omap2_clk_set_rate,
 	.clk_set_parent		= omap2_clk_set_parent,
@@ -1045,7 +1043,7 @@ static void __init omap2_disable_unused_
 			continue;
 
 		printk(KERN_INFO "Disabling unused clock \"%s\"\n", ck->name);
-		omap2_clk_disable(ck);
+		_omap2_clk_disable(ck);
 	}
 }
 late_initcall(omap2_disable_unused_clocks);
@@ -1120,10 +1118,10 @@ int __init omap2_clk_init(void)
 	 * Only enable those clocks we will need, let the drivers
 	 * enable other clocks as necessary
 	 */
-	clk_use(&sync_32k_ick);
-	clk_use(&omapctrl_ick);
+	clk_enable(&sync_32k_ick);
+	clk_enable(&omapctrl_ick);
 	if (cpu_is_omap2430())
-		clk_use(&sdrc_ick);
+		clk_enable(&sdrc_ick);
 
 	return 0;
 }
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 4aeab55..6cab20b 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -24,7 +24,7 @@ static void omap2_propagate_rate(struct 
 static void omap2_mpu_recalc(struct clk * clk);
 static int omap2_select_table_rate(struct clk * clk, unsigned long rate);
 static long omap2_round_to_table_rate(struct clk * clk, unsigned long rate);
-static void omap2_clk_unuse(struct clk *clk);
+static void omap2_clk_disable(struct clk *clk);
 static void omap2_sys_clk_recalc(struct clk * clk);
 static u32 omap2_clksel_to_divisor(u32 div_sel, u32 field_val);
 static u32 omap2_clksel_get_divisor(struct clk *clk);
@@ -859,7 +859,7 @@ static struct clk core_l3_ck = {	/* Used
 
 static struct clk usb_l4_ick = {	/* FS-USB interface clock */
 	.name		= "usb_l4_ick",
-	.parent		= &core_ck,
+	.parent		= &core_l3_ck,
 	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
 				RATE_CKCTL | CM_CORE_SEL1 | DELAYED_APP |
 				CONFIG_PARTICIPANT,
@@ -1045,7 +1045,7 @@ static struct clk gpt1_ick = {
 	.name		= "gpt1_ick",
 	.parent		= &l4_ck,
 	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
-	.enable_reg	= (void __iomem *)&CM_ICLKEN_WKUP,	/* Bit4 */
+	.enable_reg	= (void __iomem *)&CM_ICLKEN_WKUP,	/* Bit0 */
 	.enable_bit	= 0,
 	.recalc		= &omap2_followparent_recalc,
 };
@@ -1055,7 +1055,7 @@ static struct clk gpt1_fck = {
 	.parent		= &func_32k_ck,
 	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
 				CM_WKUP_SEL1,
-	.enable_reg	= (void __iomem *)&CM_FCLKEN_WKUP,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN_WKUP,	/* Bit0 */
 	.enable_bit	= 0,
 	.src_offset	= 0,
 	.recalc		= &omap2_followparent_recalc,
@@ -1065,7 +1065,7 @@ static struct clk gpt2_ick = {
 	.name		= "gpt2_ick",
 	.parent		= &l4_ck,
 	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
-	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,	/* bit4 */
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,	/* Bit4 */
 	.enable_bit	= 0,
 	.recalc		= &omap2_followparent_recalc,
 };
@@ -1839,7 +1839,7 @@ static struct clk usb_fck = {
 
 static struct clk usbhs_ick = {
 	.name		= "usbhs_ick",
-	.parent		= &l4_ck,
+	.parent		= &core_l3_ck,
 	.flags		= CLOCK_IN_OMAP243X,
 	.enable_reg	= (void __iomem *)&CM_ICLKEN2_CORE,
 	.enable_bit	= 6,
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index e1bd46a..24dd374 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -119,14 +119,14 @@ void __init omap_serial_init()
 			if (IS_ERR(uart1_ick))
 				printk("Could not get uart1_ick\n");
 			else {
-				clk_use(uart1_ick);
+				clk_enable(uart1_ick);
 			}
 
 			uart1_fck = clk_get(NULL, "uart1_fck");
 			if (IS_ERR(uart1_fck))
 				printk("Could not get uart1_fck\n");
 			else {
-				clk_use(uart1_fck);
+				clk_enable(uart1_fck);
 			}
 			break;
 		case 1:
@@ -134,14 +134,14 @@ void __init omap_serial_init()
 			if (IS_ERR(uart2_ick))
 				printk("Could not get uart2_ick\n");
 			else {
-				clk_use(uart2_ick);
+				clk_enable(uart2_ick);
 			}
 
 			uart2_fck = clk_get(NULL, "uart2_fck");
 			if (IS_ERR(uart2_fck))
 				printk("Could not get uart2_fck\n");
 			else {
-				clk_use(uart2_fck);
+				clk_enable(uart2_fck);
 			}
 			break;
 		case 2:
@@ -149,14 +149,14 @@ void __init omap_serial_init()
 			if (IS_ERR(uart3_ick))
 				printk("Could not get uart3_ick\n");
 			else {
-				clk_use(uart3_ick);
+				clk_enable(uart3_ick);
 			}
 
 			uart3_fck = clk_get(NULL, "uart3_fck");
 			if (IS_ERR(uart3_fck))
 				printk("Could not get uart3_fck\n");
 			else {
-				clk_use(uart3_fck);
+				clk_enable(uart3_fck);
 			}
 			break;
 		}
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
index 23d36b1..1d2f5ac 100644
--- a/arch/arm/mach-omap2/timer-gp.c
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -104,7 +104,7 @@ static void __init omap2_gp_timer_init(v
 	if (IS_ERR(sys_ck))
 		printk(KERN_ERR "Could not get sys_ck\n");
 	else {
-		clk_use(sys_ck);
+		clk_enable(sys_ck);
 		tick_period = clk_get_rate(sys_ck) / 100;
 		clk_put(sys_ck);
 	}
diff --git a/arch/arm/mach-s3c2410/cpu.h b/arch/arm/mach-s3c2410/cpu.h
index 9cbe5ee..fc10677 100644
--- a/arch/arm/mach-s3c2410/cpu.h
+++ b/arch/arm/mach-s3c2410/cpu.h
@@ -17,11 +17,12 @@
  *     14-Jan-2005 BJD  Added s3c24xx_init_clocks() call
  *     10-Mar-2005 LCVR Changed S3C2410_{VA,SZ} to S3C24XX_{VA,SZ} & IODESC_ENT
  *     14-Mar-2005 BJD  Updated for __iomem
+ *     15-Jan-2006 LCVR Updated S3C2410_PA_##x to new S3C24XX_PA_##x macro
 */
 
 /* todo - fix when rmk changes iodescs to use `void __iomem *` */
 
-#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C2410_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
+#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
 
 #ifndef MHZ
 #define MHZ (1000*1000)
diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c
index f58406e..b8d994a 100644
--- a/arch/arm/mach-s3c2410/devs.c
+++ b/arch/arm/mach-s3c2410/devs.c
@@ -10,6 +10,7 @@
  * published by the Free Software Foundation.
  *
  * Modifications:
+ *     15-Jan-2006 LCVR Using S3C24XX_PA_##x macro for common S3C24XX devices
  *     10-Mar-2005 LCVR Changed S3C2410_{VA,SZ} to S3C24XX_{VA,SZ}
  *     10-Feb-2005 BJD  Added camera from guillaume.gourat@nexvision.tv
  *     29-Aug-2004 BJD  Added timers 0 through 3
@@ -46,8 +47,8 @@ struct platform_device *s3c24xx_uart_dev
 
 static struct resource s3c_usb_resource[] = {
 	[0] = {
-		.start = S3C2410_PA_USBHOST,
-		.end   = S3C2410_PA_USBHOST + S3C24XX_SZ_USBHOST - 1,
+		.start = S3C24XX_PA_USBHOST,
+		.end   = S3C24XX_PA_USBHOST + S3C24XX_SZ_USBHOST - 1,
 		.flags = IORESOURCE_MEM,
 	},
 	[1] = {
@@ -76,8 +77,8 @@ EXPORT_SYMBOL(s3c_device_usb);
 
 static struct resource s3c_lcd_resource[] = {
 	[0] = {
-		.start = S3C2410_PA_LCD,
-		.end   = S3C2410_PA_LCD + S3C24XX_SZ_LCD - 1,
+		.start = S3C24XX_PA_LCD,
+		.end   = S3C24XX_PA_LCD + S3C24XX_SZ_LCD - 1,
 		.flags = IORESOURCE_MEM,
 	},
 	[1] = {
@@ -139,8 +140,8 @@ EXPORT_SYMBOL(s3c_device_nand);
 
 static struct resource s3c_usbgadget_resource[] = {
 	[0] = {
-		.start = S3C2410_PA_USBDEV,
-		.end   = S3C2410_PA_USBDEV + S3C24XX_SZ_USBDEV - 1,
+		.start = S3C24XX_PA_USBDEV,
+		.end   = S3C24XX_PA_USBDEV + S3C24XX_SZ_USBDEV - 1,
 		.flags = IORESOURCE_MEM,
 	},
 	[1] = {
@@ -164,8 +165,8 @@ EXPORT_SYMBOL(s3c_device_usbgadget);
 
 static struct resource s3c_wdt_resource[] = {
 	[0] = {
-		.start = S3C2410_PA_WATCHDOG,
-		.end   = S3C2410_PA_WATCHDOG + S3C24XX_SZ_WATCHDOG - 1,
+		.start = S3C24XX_PA_WATCHDOG,
+		.end   = S3C24XX_PA_WATCHDOG + S3C24XX_SZ_WATCHDOG - 1,
 		.flags = IORESOURCE_MEM,
 	},
 	[1] = {
@@ -189,8 +190,8 @@ EXPORT_SYMBOL(s3c_device_wdt);
 
 static struct resource s3c_i2c_resource[] = {
 	[0] = {
-		.start = S3C2410_PA_IIC,
-		.end   = S3C2410_PA_IIC + S3C24XX_SZ_IIC - 1,
+		.start = S3C24XX_PA_IIC,
+		.end   = S3C24XX_PA_IIC + S3C24XX_SZ_IIC - 1,
 		.flags = IORESOURCE_MEM,
 	},
 	[1] = {
@@ -214,8 +215,8 @@ EXPORT_SYMBOL(s3c_device_i2c);
 
 static struct resource s3c_iis_resource[] = {
 	[0] = {
-		.start = S3C2410_PA_IIS,
-		.end   = S3C2410_PA_IIS + S3C24XX_SZ_IIS -1,
+		.start = S3C24XX_PA_IIS,
+		.end   = S3C24XX_PA_IIS + S3C24XX_SZ_IIS -1,
 		.flags = IORESOURCE_MEM,
 	}
 };
@@ -239,8 +240,8 @@ EXPORT_SYMBOL(s3c_device_iis);
 
 static struct resource s3c_rtc_resource[] = {
 	[0] = {
-		.start = S3C2410_PA_RTC,
-		.end   = S3C2410_PA_RTC + 0xff,
+		.start = S3C24XX_PA_RTC,
+		.end   = S3C24XX_PA_RTC + 0xff,
 		.flags = IORESOURCE_MEM,
 	},
 	[1] = {
@@ -268,8 +269,8 @@ EXPORT_SYMBOL(s3c_device_rtc);
 
 static struct resource s3c_adc_resource[] = {
 	[0] = {
-		.start = S3C2410_PA_ADC,
-		.end   = S3C2410_PA_ADC + S3C24XX_SZ_ADC - 1,
+		.start = S3C24XX_PA_ADC,
+		.end   = S3C24XX_PA_ADC + S3C24XX_SZ_ADC - 1,
 		.flags = IORESOURCE_MEM,
 	},
 	[1] = {
@@ -316,8 +317,8 @@ EXPORT_SYMBOL(s3c_device_sdi);
 
 static struct resource s3c_spi0_resource[] = {
 	[0] = {
-		.start = S3C2410_PA_SPI,
-		.end   = S3C2410_PA_SPI + 0x1f,
+		.start = S3C24XX_PA_SPI,
+		.end   = S3C24XX_PA_SPI + 0x1f,
 		.flags = IORESOURCE_MEM,
 	},
 	[1] = {
@@ -341,8 +342,8 @@ EXPORT_SYMBOL(s3c_device_spi0);
 
 static struct resource s3c_spi1_resource[] = {
 	[0] = {
-		.start = S3C2410_PA_SPI + 0x20,
-		.end   = S3C2410_PA_SPI + 0x20 + 0x1f,
+		.start = S3C24XX_PA_SPI + 0x20,
+		.end   = S3C24XX_PA_SPI + 0x20 + 0x1f,
 		.flags = IORESOURCE_MEM,
 	},
 	[1] = {
@@ -366,8 +367,8 @@ EXPORT_SYMBOL(s3c_device_spi1);
 
 static struct resource s3c_timer0_resource[] = {
 	[0] = {
-		.start = S3C2410_PA_TIMER + 0x0C,
-		.end   = S3C2410_PA_TIMER + 0x0C + 0xB,
+		.start = S3C24XX_PA_TIMER + 0x0C,
+		.end   = S3C24XX_PA_TIMER + 0x0C + 0xB,
 		.flags = IORESOURCE_MEM,
 	},
 	[1] = {
@@ -391,8 +392,8 @@ EXPORT_SYMBOL(s3c_device_timer0);
 
 static struct resource s3c_timer1_resource[] = {
 	[0] = {
-		.start = S3C2410_PA_TIMER + 0x18,
-		.end   = S3C2410_PA_TIMER + 0x23,
+		.start = S3C24XX_PA_TIMER + 0x18,
+		.end   = S3C24XX_PA_TIMER + 0x23,
 		.flags = IORESOURCE_MEM,
 	},
 	[1] = {
@@ -416,8 +417,8 @@ EXPORT_SYMBOL(s3c_device_timer1);
 
 static struct resource s3c_timer2_resource[] = {
 	[0] = {
-		.start = S3C2410_PA_TIMER + 0x24,
-		.end   = S3C2410_PA_TIMER + 0x2F,
+		.start = S3C24XX_PA_TIMER + 0x24,
+		.end   = S3C24XX_PA_TIMER + 0x2F,
 		.flags = IORESOURCE_MEM,
 	},
 	[1] = {
@@ -441,8 +442,8 @@ EXPORT_SYMBOL(s3c_device_timer2);
 
 static struct resource s3c_timer3_resource[] = {
 	[0] = {
-		.start = S3C2410_PA_TIMER + 0x30,
-		.end   = S3C2410_PA_TIMER + 0x3B,
+		.start = S3C24XX_PA_TIMER + 0x30,
+		.end   = S3C24XX_PA_TIMER + 0x3B,
 		.flags = IORESOURCE_MEM,
 	},
 	[1] = {
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
index 65feaf2..4dbd8e7 100644
--- a/arch/arm/mach-s3c2410/dma.c
+++ b/arch/arm/mach-s3c2410/dma.c
@@ -1152,7 +1152,7 @@ static int __init s3c2410_init_dma(void)
 
 	printk("S3C2410 DMA Driver, (c) 2003-2004 Simtec Electronics\n");
 
-	dma_base = ioremap(S3C2410_PA_DMA, 0x200);
+	dma_base = ioremap(S3C24XX_PA_DMA, 0x200);
 	if (dma_base == NULL) {
 		printk(KERN_ERR "dma failed to remap register block\n");
 		return -ENOMEM;
diff --git a/arch/arm/mach-s3c2410/sleep.S b/arch/arm/mach-s3c2410/sleep.S
index 61768da..e9a055b 100644
--- a/arch/arm/mach-s3c2410/sleep.S
+++ b/arch/arm/mach-s3c2410/sleep.S
@@ -133,12 +133,12 @@ ENTRY(s3c2410_cpu_resume)
 	@@ load UART to allow us to print the two characters for
 	@@ resume debug
 
-	mov	r2, #S3C2410_PA_UART & 0xff000000
-	orr	r2, r2, #S3C2410_PA_UART & 0xff000
+	mov	r2, #S3C24XX_PA_UART & 0xff000000
+	orr	r2, r2, #S3C24XX_PA_UART & 0xff000
 
 #if 0
 	/* SMDK2440 LED set */
-	mov	r14, #S3C2410_PA_GPIO
+	mov	r14, #S3C24XX_PA_GPIO
 	ldr	r12, [ r14, #0x54 ]
 	bic	r12, r12, #3<<4
 	orr	r12, r12, #1<<7
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index de3ce1e..da9b359 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -142,7 +142,7 @@ __ioremap_pfn(unsigned long pfn, unsigne
  		return NULL;
  	addr = (unsigned long)area->addr;
  	if (remap_area_pages(addr, pfn, size, flags)) {
- 		vfree(addr);
+ 		vfree((void *)addr);
  		return NULL;
  	}
  	return (void __iomem *) (offset + (char *)addr);
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index d0245a3..ef8d30a 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -343,6 +343,12 @@ static struct mem_types mem_types[] __in
 				PMD_SECT_AP_WRITE | PMD_SECT_BUFFERABLE |
 				PMD_SECT_TEX(1),
 		.domain    = DOMAIN_IO,
+	},
+	[MT_NONSHARED_DEVICE] = {
+		.prot_l1   = PMD_TYPE_TABLE,
+		.prot_sect = PMD_TYPE_SECT | PMD_SECT_NONSHARED_DEV |
+				PMD_SECT_AP_WRITE,
+		.domain    = DOMAIN_IO,
 	}
 };
 
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 7ebc5a2..3c2bfc0 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -34,7 +34,7 @@ DEFINE_SPINLOCK(clockfw_lock);
 static struct clk_functions *arch_clock;
 
 /*-------------------------------------------------------------------------
- * Standard clock functions defined in asm/hardware/clock.h
+ * Standard clock functions defined in include/linux/clk.h
  *-------------------------------------------------------------------------*/
 
 struct clk * clk_get(struct device *dev, const char *id)
@@ -60,12 +60,8 @@ int clk_enable(struct clk *clk)
 	int ret = 0;
 
 	spin_lock_irqsave(&clockfw_lock, flags);
-	if (clk->enable)
-		ret = clk->enable(clk);
-	else if (arch_clock->clk_enable)
+	if (arch_clock->clk_enable)
 		ret = arch_clock->clk_enable(clk);
-	else
-		printk(KERN_ERR "Could not enable clock %s\n", clk->name);
 	spin_unlock_irqrestore(&clockfw_lock, flags);
 
 	return ret;
@@ -77,41 +73,12 @@ void clk_disable(struct clk *clk)
 	unsigned long flags;
 
 	spin_lock_irqsave(&clockfw_lock, flags);
-	if (clk->disable)
-		clk->disable(clk);
-	else if (arch_clock->clk_disable)
+	if (arch_clock->clk_disable)
 		arch_clock->clk_disable(clk);
-	else
-		printk(KERN_ERR "Could not disable clock %s\n", clk->name);
 	spin_unlock_irqrestore(&clockfw_lock, flags);
 }
 EXPORT_SYMBOL(clk_disable);
 
-int clk_use(struct clk *clk)
-{
-	unsigned long flags;
-	int ret = 0;
-
-	spin_lock_irqsave(&clockfw_lock, flags);
-	if (arch_clock->clk_use)
-		ret = arch_clock->clk_use(clk);
-	spin_unlock_irqrestore(&clockfw_lock, flags);
-
-	return ret;
-}
-EXPORT_SYMBOL(clk_use);
-
-void clk_unuse(struct clk *clk)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&clockfw_lock, flags);
-	if (arch_clock->clk_unuse)
-		arch_clock->clk_unuse(clk);
-	spin_unlock_irqrestore(&clockfw_lock, flags);
-}
-EXPORT_SYMBOL(clk_unuse);
-
 int clk_get_usecount(struct clk *clk)
 {
 	unsigned long flags;
@@ -146,7 +113,7 @@ void clk_put(struct clk *clk)
 EXPORT_SYMBOL(clk_put);
 
 /*-------------------------------------------------------------------------
- * Optional clock functions defined in asm/hardware/clock.h
+ * Optional clock functions defined in include/linux/clk.h
  *-------------------------------------------------------------------------*/
 
 long clk_round_rate(struct clk *clk, unsigned long rate)
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index ca3681a..b4d5b9e 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -853,19 +853,19 @@ static int __init _omap_gpio_init(void)
 		if (IS_ERR(gpio_ick))
 			printk("Could not get arm_gpio_ck\n");
 		else
-			clk_use(gpio_ick);
+			clk_enable(gpio_ick);
 	}
 	if (cpu_is_omap24xx()) {
 		gpio_ick = clk_get(NULL, "gpios_ick");
 		if (IS_ERR(gpio_ick))
 			printk("Could not get gpios_ick\n");
 		else
-			clk_use(gpio_ick);
+			clk_enable(gpio_ick);
 		gpio_fck = clk_get(NULL, "gpios_fck");
 		if (IS_ERR(gpio_ick))
 			printk("Could not get gpios_fck\n");
 		else
-			clk_use(gpio_fck);
+			clk_enable(gpio_fck);
 	}
 
 #ifdef CONFIG_ARCH_OMAP15XX
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index be0e0f3..1cd2cac 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -190,11 +190,11 @@ static int omap_mcbsp_check(unsigned int
 static void omap_mcbsp_dsp_request(void)
 {
 	if (cpu_is_omap1510() || cpu_is_omap16xx()) {
-		clk_use(mcbsp_dsp_ck);
-		clk_use(mcbsp_api_ck);
+		clk_enable(mcbsp_dsp_ck);
+		clk_enable(mcbsp_api_ck);
 
 		/* enable 12MHz clock to mcbsp 1 & 3 */
-		clk_use(mcbsp_dspxor_ck);
+		clk_enable(mcbsp_dspxor_ck);
 
 		/*
 		 * DSP external peripheral reset
@@ -208,9 +208,9 @@ static void omap_mcbsp_dsp_request(void)
 static void omap_mcbsp_dsp_free(void)
 {
 	if (cpu_is_omap1510() || cpu_is_omap16xx()) {
-		clk_unuse(mcbsp_dspxor_ck);
-		clk_unuse(mcbsp_dsp_ck);
-		clk_unuse(mcbsp_api_ck);
+		clk_disable(mcbsp_dspxor_ck);
+		clk_disable(mcbsp_dsp_ck);
+		clk_disable(mcbsp_api_ck);
 	}
 }
 
diff --git a/arch/arm/plat-omap/ocpi.c b/arch/arm/plat-omap/ocpi.c
index e40fcc8..5cc6775 100644
--- a/arch/arm/plat-omap/ocpi.c
+++ b/arch/arm/plat-omap/ocpi.c
@@ -88,7 +88,7 @@ static int __init omap_ocpi_init(void)
 	if (IS_ERR(ocpi_ck))
 		return PTR_ERR(ocpi_ck);
 
-	clk_use(ocpi_ck);
+	clk_enable(ocpi_ck);
 	ocpi_enable();
 	printk("OMAP OCPI interconnect driver loaded\n");
 
@@ -102,7 +102,7 @@ static void __exit omap_ocpi_exit(void)
 	if (!cpu_is_omap16xx())
 		return;
 
-	clk_unuse(ocpi_ck);
+	clk_disable(ocpi_ck);
 	clk_put(ocpi_ck);
 }
 
diff --git a/arch/arm26/Kconfig b/arch/arm26/Kconfig
index 274e070..dee23d8 100644
--- a/arch/arm26/Kconfig
+++ b/arch/arm26/Kconfig
@@ -53,14 +53,14 @@ config GENERIC_ISA_DMA
 
 config ARCH_MAY_HAVE_PC_FDC
 	bool
-	default y
 
 source "init/Kconfig"
 
 
 menu "System Type"
 
-comment "Archimedes/A5000 Implementations (select only ONE)"
+choice
+	prompt "Archimedes/A5000 Implementations"
 
 config ARCH_ARC
         bool "Archimedes"
@@ -73,6 +73,7 @@ config ARCH_ARC
 
 config ARCH_A5K
         bool "A5000"
+	select ARCH_MAY_HAVE_PC_FDC
         help
           Say Y here to to support the Acorn A5000.
 
@@ -87,6 +88,7 @@ config PAGESIZE_16
           Say Y here if your Archimedes or A5000 system has only 2MB of
           memory, otherwise say N.  The resulting kernel will not run on a
           machine with 4MB of memory.
+endchoice
 endmenu
 
 config ISA_DMA_API
diff --git a/arch/arm26/kernel/fiq.c b/arch/arm26/kernel/fiq.c
index 08a97c9..a24272b 100644
--- a/arch/arm26/kernel/fiq.c
+++ b/arch/arm26/kernel/fiq.c
@@ -104,14 +104,14 @@ void set_fiq_regs(struct pt_regs *regs)
 {
 	register unsigned long tmp, tmp2;
 	__asm__ volatile (
-	"mov	%0, pc
-	bic	%1, %0, #0x3
-	orr	%1, %1, %3
-	teqp	%1, #0		@ select FIQ mode
-	mov	r0, r0
-	ldmia	%2, {r8 - r14}
-	teqp	%0, #0		@ return to SVC mode
-	mov	r0, r0"
+	"mov	%0, pc					\n"
+	"bic	%1, %0, #0x3				\n"
+	"orr	%1, %1, %3				\n"
+	"teqp	%1, #0		@ select FIQ mode	\n"
+	"mov	r0, r0					\n"
+	"ldmia	%2, {r8 - r14}				\n"
+	"teqp	%0, #0		@ return to SVC mode	\n"
+	"mov	r0, r0					"
 	: "=&r" (tmp), "=&r" (tmp2)
 	: "r" (&regs->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | MODE_FIQ26)
 	/* These registers aren't modified by the above code in a way
@@ -125,14 +125,14 @@ void get_fiq_regs(struct pt_regs *regs)
 {
 	register unsigned long tmp, tmp2;
 	__asm__ volatile (
-	"mov	%0, pc
-	bic	%1, %0, #0x3
-	orr	%1, %1, %3
-	teqp	%1, #0		@ select FIQ mode
-	mov	r0, r0
-	stmia	%2, {r8 - r14}
-	teqp	%0, #0		@ return to SVC mode
-	mov	r0, r0"
+	"mov	%0, pc					\n"
+	"bic	%1, %0, #0x3				\n"
+	"orr	%1, %1, %3				\n"
+	"teqp	%1, #0		@ select FIQ mode	\n"
+	"mov	r0, r0					\n"
+	"stmia	%2, {r8 - r14}				\n"
+	"teqp	%0, #0		@ return to SVC mode	\n"
+	"mov	r0, r0					"
 	: "=&r" (tmp), "=&r" (tmp2)
 	: "r" (&regs->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | MODE_FIQ26)
 	/* These registers aren't modified by the above code in a way
diff --git a/arch/arm26/kernel/signal.c b/arch/arm26/kernel/signal.c
index ce2055b..2a48c12 100644
--- a/arch/arm26/kernel/signal.c
+++ b/arch/arm26/kernel/signal.c
@@ -480,6 +480,7 @@ static int do_signal(sigset_t *oldset, s
 {
 	siginfo_t info;
 	int signr;
+	struct k_sigaction ka;
 
 	/*
 	 * We want the common case to go fast, which
@@ -493,7 +494,7 @@ static int do_signal(sigset_t *oldset, s
         if (current->ptrace & PT_SINGLESTEP)
                 ptrace_cancel_bpt(current);
 	
-        signr = get_signal_to_deliver(&info, regs, NULL);
+        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
         if (signr > 0) {
                 handle_signal(signr, &info, oldset, regs, syscall);
                 if (current->ptrace & PT_SINGLESTEP)
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index 5b7146f..679c1d5 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -35,74 +35,22 @@ struct fdpic_func_descriptor {
 	unsigned long	GOT;
 };
 
-static int do_signal(sigset_t *oldset);
-
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
 asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
 {
-	sigset_t saveset;
-
 	mask &= _BLOCKABLE;
 	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
+	current->saved_sigmask = current->blocked;
 	siginitset(&current->blocked, mask);
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
 
-	__frame->gr8 = -EINTR;
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		if (do_signal(&saveset))
-			/* return the signal number as the return value of this function
-			 * - this is an utterly evil hack. syscalls should not invoke do_signal()
-			 *   as entry.S sets regs->gr8 to the return value of the system call
-			 * - we can't just use sigpending() as we'd have to discard SIG_IGN signals
-			 *   and call waitpid() if SIGCHLD needed discarding
-			 * - this only works on the i386 because it passes arguments to the signal
-			 *   handler on the stack, and the return value in EAX is effectively
-			 *   discarded
-			 */
-			return __frame->gr8;
-	}
-}
-
-asmlinkage int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
-{
-	sigset_t saveset, newset;
-
-	/* XXX: Don't preclude handling different sized sigset_t's.  */
-	if (sigsetsize != sizeof(sigset_t))
-		return -EINVAL;
-
-	if (copy_from_user(&newset, unewset, sizeof(newset)))
-		return -EFAULT;
-	sigdelsetmask(&newset, ~_BLOCKABLE);
-
-	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
-	current->blocked = newset;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-
-	__frame->gr8 = -EINTR;
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		if (do_signal(&saveset))
-			/* return the signal number as the return value of this function
-			 * - this is an utterly evil hack. syscalls should not invoke do_signal()
-			 *   as entry.S sets regs->gr8 to the return value of the system call
-			 * - we can't just use sigpending() as we'd have to discard SIG_IGN signals
-			 *   and call waitpid() if SIGCHLD needed discarding
-			 * - this only works on the i386 because it passes arguments to the signal
-			 *   handler on the stack, and the return value in EAX is effectively
-			 *   discarded
-			 */
-			return __frame->gr8;
-	}
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	set_thread_flag(TIF_RESTORE_SIGMASK);
+	return -ERESTARTNOHAND;
 }
 
 asmlinkage int sys_sigaction(int sig,
@@ -372,11 +320,11 @@ static int setup_frame(int sig, struct k
 	       frame->pretcode);
 #endif
 
-	return 1;
+	return 0;
 
 give_sigsegv:
 	force_sig(SIGSEGV, current);
-	return 0;
+	return -EFAULT;
 
 } /* end setup_frame() */
 
@@ -471,11 +419,11 @@ static int setup_rt_frame(int sig, struc
 	       frame->pretcode);
 #endif
 
-	return 1;
+	return 0;
 
 give_sigsegv:
 	force_sig(SIGSEGV, current);
-	return 0;
+	return -EFAULT;
 
 } /* end setup_rt_frame() */
 
@@ -516,7 +464,7 @@ static int handle_signal(unsigned long s
 	else
 		ret = setup_frame(sig, ka, oldset);
 
-	if (ret) {
+	if (ret == 0) {
 		spin_lock_irq(&current->sighand->siglock);
 		sigorsets(&current->blocked, &current->blocked,
 			  &ka->sa.sa_mask);
@@ -536,10 +484,11 @@ static int handle_signal(unsigned long s
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
  * mistake.
  */
-static int do_signal(sigset_t *oldset)
+static void do_signal(void)
 {
 	struct k_sigaction ka;
 	siginfo_t info;
+	sigset_t *oldset;
 	int signr;
 
 	/*
@@ -549,43 +498,62 @@ static int do_signal(sigset_t *oldset)
 	 * if so.
 	 */
 	if (!user_mode(__frame))
-		return 1;
+		return;
 
 	if (try_to_freeze())
 		goto no_signal;
 
-	if (!oldset)
+	if (test_thread_flag(TIF_RESTORE_SIGMASK))
+		oldset = &current->saved_sigmask;
+	else
 		oldset = &current->blocked;
 
 	signr = get_signal_to_deliver(&info, &ka, __frame, NULL);
-	if (signr > 0)
-		return handle_signal(signr, &info, &ka, oldset);
+	if (signr > 0) {
+		if (handle_signal(signr, &info, &ka, oldset) == 0) {
+			/* a signal was successfully delivered; the saved
+			 * sigmask will have been stored in the signal frame,
+			 * and will be restored by sigreturn, so we can simply
+			 * clear the TIF_RESTORE_SIGMASK flag */
+			if (test_thread_flag(TIF_RESTORE_SIGMASK))
+				clear_thread_flag(TIF_RESTORE_SIGMASK);
+		}
+
+		return;
+	}
 
 no_signal:
 	/* Did we come from a system call? */
 	if (__frame->syscallno >= 0) {
 		/* Restart the system call - no handlers present */
-		if (__frame->gr8 == -ERESTARTNOHAND ||
-		    __frame->gr8 == -ERESTARTSYS ||
-		    __frame->gr8 == -ERESTARTNOINTR) {
+		switch (__frame->gr8) {
+		case -ERESTARTNOHAND:
+		case -ERESTARTSYS:
+		case -ERESTARTNOINTR:
 			__frame->gr8 = __frame->orig_gr8;
 			__frame->pc -= 4;
-		}
+			break;
 
-		if (__frame->gr8 == -ERESTART_RESTARTBLOCK){
+		case -ERESTART_RESTARTBLOCK:
 			__frame->gr8 = __NR_restart_syscall;
 			__frame->pc -= 4;
+			break;
 		}
 	}
 
-	return 0;
+	/* if there's no signal to deliver, we just put the saved sigmask
+	 * back */
+	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+		clear_thread_flag(TIF_RESTORE_SIGMASK);
+		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+	}
 
 } /* end do_signal() */
 
 /*****************************************************************************/
 /*
  * notification of userspace execution resumption
- * - triggered by current->work.notify_resume
+ * - triggered by the TIF_WORK_MASK flags
  */
 asmlinkage void do_notify_resume(__u32 thread_info_flags)
 {
@@ -594,7 +562,7 @@ asmlinkage void do_notify_resume(__u32 t
 		clear_thread_flag(TIF_SINGLESTEP);
 
 	/* deal with pending signal delivery */
-	if (thread_info_flags & _TIF_SIGPENDING)
-		do_signal(NULL);
+	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
+		do_signal();
 
 } /* end do_notify_resume() */
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index cbde675..d86c865 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -47,15 +47,6 @@ config DMI
 
 source "init/Kconfig"
 
-config DOUBLEFAULT
-	default y
-	bool "Enable doublefault exception handler" if EMBEDDED
-	help
-          This option allows trapping of rare doublefault exceptions that
-          would otherwise cause a system to silently reboot. Disabling this
-          option saves about 4k and might cause you much additional grey
-          hair.
-
 menu "Processor type and features"
 
 choice
@@ -457,6 +448,43 @@ config HIGHMEM64G
 
 endchoice
 
+choice
+	depends on EXPERIMENTAL && !X86_PAE
+	prompt "Memory split"
+	default VMSPLIT_3G
+	help
+	  Select the desired split between kernel and user memory.
+
+	  If the address range available to the kernel is less than the
+	  physical memory installed, the remaining memory will be available
+	  as "high memory". Accessing high memory is a little more costly
+	  than low memory, as it needs to be mapped into the kernel first.
+	  Note that increasing the kernel address space limits the range
+	  available to user programs, making the address space there
+	  tighter.  Selecting anything other than the default 3G/1G split
+	  will also likely make your kernel incompatible with binary-only
+	  kernel modules.
+
+	  If you are not absolutely sure what you are doing, leave this
+	  option alone!
+
+	config VMSPLIT_3G
+		bool "3G/1G user/kernel split"
+	config VMSPLIT_3G_OPT
+		bool "3G/1G user/kernel split (for full 1G low memory)"
+	config VMSPLIT_2G
+		bool "2G/2G user/kernel split"
+	config VMSPLIT_1G
+		bool "1G/3G user/kernel split"
+endchoice
+
+config PAGE_OFFSET
+	hex
+	default 0xB0000000 if VMSPLIT_3G_OPT
+	default 0x78000000 if VMSPLIT_2G
+	default 0x40000000 if VMSPLIT_1G
+	default 0xC0000000
+
 config HIGHMEM
 	bool
 	depends on HIGHMEM64G || HIGHMEM4G
@@ -711,6 +739,15 @@ config HOTPLUG_CPU
 
 	  Say N.
 
+config DOUBLEFAULT
+	default y
+	bool "Enable doublefault exception handler" if EMBEDDED
+	help
+          This option allows trapping of rare doublefault exceptions that
+          would otherwise cause a system to silently reboot. Disabling this
+          option saves about 4k and might cause you much additional grey
+          hair.
+
 endmenu
 
 
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index 6a431b9..3cbe6e9 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -644,6 +644,8 @@ CONFIG_8139TOO_PIO=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 # CONFIG_E1000 is not set
+# CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/i386/kernel/acpi/Makefile b/arch/i386/kernel/acpi/Makefile
index 267ca48..d51c731 100644
--- a/arch/i386/kernel/acpi/Makefile
+++ b/arch/i386/kernel/acpi/Makefile
@@ -3,6 +3,6 @@ obj-$(CONFIG_X86_IO_APIC)	+= earlyquirk.
 obj-$(CONFIG_ACPI_SLEEP)	+= sleep.o wakeup.o
 
 ifneq ($(CONFIG_ACPI_PROCESSOR),)
-obj-y				+= cstate.o
+obj-y				+= cstate.o processor.o
 endif
 
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index 2111529..f21fa0d 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -464,7 +464,7 @@ int acpi_gsi_to_irq(u32 gsi, unsigned in
  * success: return IRQ number (>=0)
  * failure: return < 0
  */
-int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low)
+int acpi_register_gsi(u32 gsi, int triggering, int polarity)
 {
 	unsigned int irq;
 	unsigned int plat_gsi = gsi;
@@ -476,14 +476,14 @@ int acpi_register_gsi(u32 gsi, int edge_
 	if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) {
 		extern void eisa_set_level_irq(unsigned int irq);
 
-		if (edge_level == ACPI_LEVEL_SENSITIVE)
+		if (triggering == ACPI_LEVEL_SENSITIVE)
 			eisa_set_level_irq(gsi);
 	}
 #endif
 
 #ifdef CONFIG_X86_IO_APIC
 	if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) {
-		plat_gsi = mp_register_gsi(gsi, edge_level, active_high_low);
+		plat_gsi = mp_register_gsi(gsi, triggering, polarity);
 	}
 #endif
 	acpi_gsi_to_irq(plat_gsi, &irq);
diff --git a/arch/i386/kernel/acpi/cstate.c b/arch/i386/kernel/acpi/cstate.c
index 4c3036b..25db49e 100644
--- a/arch/i386/kernel/acpi/cstate.c
+++ b/arch/i386/kernel/acpi/cstate.c
@@ -14,64 +14,6 @@
 #include <acpi/processor.h>
 #include <asm/acpi.h>
 
-static void acpi_processor_power_init_intel_pdc(struct acpi_processor_power
-						*pow)
-{
-	struct acpi_object_list *obj_list;
-	union acpi_object *obj;
-	u32 *buf;
-
-	/* allocate and initialize pdc. It will be used later. */
-	obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
-	if (!obj_list) {
-		printk(KERN_ERR "Memory allocation error\n");
-		return;
-	}
-
-	obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
-	if (!obj) {
-		printk(KERN_ERR "Memory allocation error\n");
-		kfree(obj_list);
-		return;
-	}
-
-	buf = kmalloc(12, GFP_KERNEL);
-	if (!buf) {
-		printk(KERN_ERR "Memory allocation error\n");
-		kfree(obj);
-		kfree(obj_list);
-		return;
-	}
-
-	buf[0] = ACPI_PDC_REVISION_ID;
-	buf[1] = 1;
-	buf[2] = ACPI_PDC_C_CAPABILITY_SMP;
-
-	obj->type = ACPI_TYPE_BUFFER;
-	obj->buffer.length = 12;
-	obj->buffer.pointer = (u8 *) buf;
-	obj_list->count = 1;
-	obj_list->pointer = obj;
-	pow->pdc = obj_list;
-
-	return;
-}
-
-/* Initialize _PDC data based on the CPU vendor */
-void acpi_processor_power_init_pdc(struct acpi_processor_power *pow,
-				   unsigned int cpu)
-{
-	struct cpuinfo_x86 *c = cpu_data + cpu;
-
-	pow->pdc = NULL;
-	if (c->x86_vendor == X86_VENDOR_INTEL)
-		acpi_processor_power_init_intel_pdc(pow);
-
-	return;
-}
-
-EXPORT_SYMBOL(acpi_processor_power_init_pdc);
-
 /*
  * Initialize bm_flags based on the CPU cache properties
  * On SMP it depends on cache configuration
diff --git a/arch/i386/kernel/acpi/processor.c b/arch/i386/kernel/acpi/processor.c
new file mode 100644
index 0000000..9f4cc02
--- /dev/null
+++ b/arch/i386/kernel/acpi/processor.c
@@ -0,0 +1,75 @@
+/*
+ * arch/i386/kernel/acpi/processor.c
+ *
+ * Copyright (C) 2005 Intel Corporation
+ * 	Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ * 	- Added _PDC for platforms with Intel CPUs
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/acpi.h>
+
+#include <acpi/processor.h>
+#include <asm/acpi.h>
+
+static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c)
+{
+	struct acpi_object_list *obj_list;
+	union acpi_object *obj;
+	u32 *buf;
+
+	/* allocate and initialize pdc. It will be used later. */
+	obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
+	if (!obj_list) {
+		printk(KERN_ERR "Memory allocation error\n");
+		return;
+	}
+
+	obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
+	if (!obj) {
+		printk(KERN_ERR "Memory allocation error\n");
+		kfree(obj_list);
+		return;
+	}
+
+	buf = kmalloc(12, GFP_KERNEL);
+	if (!buf) {
+		printk(KERN_ERR "Memory allocation error\n");
+		kfree(obj);
+		kfree(obj_list);
+		return;
+	}
+
+	buf[0] = ACPI_PDC_REVISION_ID;
+	buf[1] = 1;
+	buf[2] = ACPI_PDC_C_CAPABILITY_SMP;
+
+	if (cpu_has(c, X86_FEATURE_EST))
+		buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP;
+
+	obj->type = ACPI_TYPE_BUFFER;
+	obj->buffer.length = 12;
+	obj->buffer.pointer = (u8 *) buf;
+	obj_list->count = 1;
+	obj_list->pointer = obj;
+	pr->pdc = obj_list;
+
+	return;
+}
+
+/* Initialize _PDC data based on the CPU vendor */
+void arch_acpi_processor_init_pdc(struct acpi_processor *pr)
+{
+	unsigned int cpu = pr->id;
+	struct cpuinfo_x86 *c = cpu_data + cpu;
+
+	pr->pdc = NULL;
+	if (c->x86_vendor == X86_VENDOR_INTEL)
+		init_intel_pdc(pr, c);
+
+	return;
+}
+
+EXPORT_SYMBOL(arch_acpi_processor_init_pdc);
diff --git a/arch/i386/kernel/cpu/centaur.c b/arch/i386/kernel/cpu/centaur.c
index 394814e..0dd92a2 100644
--- a/arch/i386/kernel/cpu/centaur.c
+++ b/arch/i386/kernel/cpu/centaur.c
@@ -405,10 +405,6 @@ static void __init init_centaur(struct c
 				winchip2_protect_mcr();
 #endif
 				break;
-			case 10:
-				name="4";
-				/* no info on the WC4 yet */
-				break;
 			default:
 				name="??";
 			}
diff --git a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/i386/kernel/cpu/cpufreq/Kconfig
index 0f1eb50..26892d2 100644
--- a/arch/i386/kernel/cpu/cpufreq/Kconfig
+++ b/arch/i386/kernel/cpu/cpufreq/Kconfig
@@ -96,6 +96,7 @@ config X86_POWERNOW_K8_ACPI
 
 config X86_GX_SUSPMOD
 	tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation"
+	depends on PCI
 	help
 	 This add the CPUFreq driver for NatSemi Geode processors which
 	 support suspend modulation.
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
index 7975e79..3852d0a 100644
--- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -295,68 +295,6 @@ acpi_cpufreq_guess_freq (
 }
 
 
-/* 
- * acpi_processor_cpu_init_pdc_est - let BIOS know about the SMP capabilities
- * of this driver
- * @perf: processor-specific acpi_io_data struct
- * @cpu: CPU being initialized
- *
- * To avoid issues with legacy OSes, some BIOSes require to be informed of
- * the SMP capabilities of OS P-state driver. Here we set the bits in _PDC 
- * accordingly, for Enhanced Speedstep. Actual call to _PDC is done in
- * driver/acpi/processor.c
- */
-static void 
-acpi_processor_cpu_init_pdc_est(
-		struct acpi_processor_performance *perf, 
-		unsigned int cpu,
-		struct acpi_object_list *obj_list
-		)
-{
-	union acpi_object *obj;
-	u32 *buf;
-	struct cpuinfo_x86 *c = cpu_data + cpu;
-	dprintk("acpi_processor_cpu_init_pdc_est\n");
-
-	if (!cpu_has(c, X86_FEATURE_EST))
-		return;
-
-	/* Initialize pdc. It will be used later. */
-	if (!obj_list)
-		return;
-		
-	if (!(obj_list->count && obj_list->pointer))
-		return;
-
-	obj = obj_list->pointer;
-	if ((obj->buffer.length == 12) && obj->buffer.pointer) {
-		buf = (u32 *)obj->buffer.pointer;
-       		buf[0] = ACPI_PDC_REVISION_ID;
-       		buf[1] = 1;
-       		buf[2] = ACPI_PDC_EST_CAPABILITY_SMP;
-		perf->pdc = obj_list;
-	}
-	return;
-}
- 
-
-/* CPU specific PDC initialization */
-static void 
-acpi_processor_cpu_init_pdc(
-		struct acpi_processor_performance *perf, 
-		unsigned int cpu,
-		struct acpi_object_list *obj_list
-		)
-{
-	struct cpuinfo_x86 *c = cpu_data + cpu;
-	dprintk("acpi_processor_cpu_init_pdc\n");
-	perf->pdc = NULL;
-	if (cpu_has(c, X86_FEATURE_EST))
-		acpi_processor_cpu_init_pdc_est(perf, cpu, obj_list);
-	return;
-}
-
-
 static int
 acpi_cpufreq_cpu_init (
 	struct cpufreq_policy   *policy)
@@ -367,14 +305,7 @@ acpi_cpufreq_cpu_init (
 	unsigned int		result = 0;
 	struct cpuinfo_x86 *c = &cpu_data[policy->cpu];
 
-	union acpi_object		arg0 = {ACPI_TYPE_BUFFER};
-	u32				arg0_buf[3];
-	struct acpi_object_list 	arg_list = {1, &arg0};
-
 	dprintk("acpi_cpufreq_cpu_init\n");
-	/* setup arg_list for _PDC settings */
-        arg0.buffer.length = 12;
-        arg0.buffer.pointer = (u8 *) arg0_buf;
 
 	data = kzalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL);
 	if (!data)
@@ -382,9 +313,7 @@ acpi_cpufreq_cpu_init (
 
 	acpi_io_data[cpu] = data;
 
-	acpi_processor_cpu_init_pdc(&data->acpi_data, cpu, &arg_list);
 	result = acpi_processor_register_performance(&data->acpi_data, cpu);
-	data->acpi_data.pdc = NULL;
 
 	if (result)
 		goto err_free;
diff --git a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
index 270f218..cc73a7a 100644
--- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
+++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
@@ -52,6 +52,7 @@ enum {
 
 
 static int has_N44_O17_errata[NR_CPUS];
+static int has_N60_errata[NR_CPUS];
 static unsigned int stock_freq;
 static struct cpufreq_driver p4clockmod_driver;
 static unsigned int cpufreq_p4_get(unsigned int cpu);
@@ -226,6 +227,12 @@ static int cpufreq_p4_cpu_init(struct cp
 	case 0x0f12:
 		has_N44_O17_errata[policy->cpu] = 1;
 		dprintk("has errata -- disabling low frequencies\n");
+		break;
+
+	case 0x0f29:
+		has_N60_errata[policy->cpu] = 1;
+		dprintk("has errata -- disabling frequencies lower than 2ghz\n");
+		break;
 	}
 	
 	/* get max frequency */
@@ -237,6 +244,8 @@ static int cpufreq_p4_cpu_init(struct cp
 	for (i=1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) {
 		if ((i<2) && (has_N44_O17_errata[policy->cpu]))
 			p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+		else if (has_N60_errata[policy->cpu] && p4clockmod_table[i].frequency < 2000000)
+			p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID;
 		else
 			p4clockmod_table[i].frequency = (stock_freq * i)/8;
 	}
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
index 9a826cd..c173c0f 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -362,22 +362,10 @@ static struct acpi_processor_performance
  */
 static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
 {
-	union acpi_object		arg0 = {ACPI_TYPE_BUFFER};
-	u32				arg0_buf[3];
-	struct acpi_object_list		arg_list = {1, &arg0};
 	unsigned long			cur_freq;
 	int				result = 0, i;
 	unsigned int			cpu = policy->cpu;
 
-	/* _PDC settings */
-	arg0.buffer.length = 12;
-	arg0.buffer.pointer = (u8 *) arg0_buf;
-	arg0_buf[0] = ACPI_PDC_REVISION_ID;
-	arg0_buf[1] = 1;
-	arg0_buf[2] = ACPI_PDC_EST_CAPABILITY_SMP_MSR;
-
-	p.pdc = &arg_list;
-
 	/* register with ACPI core */
 	if (acpi_processor_register_performance(&p, cpu)) {
 		dprintk(KERN_INFO PFX "obtaining ACPI data failed\n");
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c
index fbfd374..af591c7 100644
--- a/arch/i386/kernel/cpu/intel_cacheinfo.c
+++ b/arch/i386/kernel/cpu/intel_cacheinfo.c
@@ -43,13 +43,23 @@ static struct _cache_table cache_table[]
 	{ 0x2c, LVL_1_DATA, 32 },	/* 8-way set assoc, 64 byte line size */
 	{ 0x30, LVL_1_INST, 32 },	/* 8-way set assoc, 64 byte line size */
 	{ 0x39, LVL_2,      128 },	/* 4-way set assoc, sectored cache, 64 byte line size */
+	{ 0x3a, LVL_2,      192 },	/* 6-way set assoc, sectored cache, 64 byte line size */
 	{ 0x3b, LVL_2,      128 },	/* 2-way set assoc, sectored cache, 64 byte line size */
 	{ 0x3c, LVL_2,      256 },	/* 4-way set assoc, sectored cache, 64 byte line size */
+	{ 0x3d, LVL_2,      384 },	/* 6-way set assoc, sectored cache, 64 byte line size */
+	{ 0x3e, LVL_2,      512 },	/* 4-way set assoc, sectored cache, 64 byte line size */
 	{ 0x41, LVL_2,      128 },	/* 4-way set assoc, 32 byte line size */
 	{ 0x42, LVL_2,      256 },	/* 4-way set assoc, 32 byte line size */
 	{ 0x43, LVL_2,      512 },	/* 4-way set assoc, 32 byte line size */
 	{ 0x44, LVL_2,      1024 },	/* 4-way set assoc, 32 byte line size */
 	{ 0x45, LVL_2,      2048 },	/* 4-way set assoc, 32 byte line size */
+	{ 0x46, LVL_3,      4096 },	/* 4-way set assoc, 64 byte line size */
+	{ 0x47, LVL_3,      8192 },	/* 8-way set assoc, 64 byte line size */
+	{ 0x49, LVL_3,      4096 },	/* 16-way set assoc, 64 byte line size */
+	{ 0x4a, LVL_3,      6144 },	/* 12-way set assoc, 64 byte line size */
+	{ 0x4b, LVL_3,      8192 },	/* 16-way set assoc, 64 byte line size */
+	{ 0x4c, LVL_3,     12288 },	/* 12-way set assoc, 64 byte line size */
+	{ 0x4d, LVL_3,     16384 },	/* 16-way set assoc, 64 byte line size */
 	{ 0x60, LVL_1_DATA, 16 },	/* 8-way set assoc, sectored cache, 64 byte line size */
 	{ 0x66, LVL_1_DATA, 8 },	/* 4-way set assoc, sectored cache, 64 byte line size */
 	{ 0x67, LVL_1_DATA, 16 },	/* 4-way set assoc, sectored cache, 64 byte line size */
@@ -57,6 +67,7 @@ static struct _cache_table cache_table[]
 	{ 0x70, LVL_TRACE,  12 },	/* 8-way set assoc */
 	{ 0x71, LVL_TRACE,  16 },	/* 8-way set assoc */
 	{ 0x72, LVL_TRACE,  32 },	/* 8-way set assoc */
+	{ 0x73, LVL_TRACE,  64 },	/* 8-way set assoc */
 	{ 0x78, LVL_2,    1024 },	/* 4-way set assoc, 64 byte line size */
 	{ 0x79, LVL_2,     128 },	/* 8-way set assoc, sectored cache, 64 byte line size */
 	{ 0x7a, LVL_2,     256 },	/* 8-way set assoc, sectored cache, 64 byte line size */
diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c
index 1e9db19..3b4618b 100644
--- a/arch/i386/kernel/cpu/mtrr/main.c
+++ b/arch/i386/kernel/cpu/mtrr/main.c
@@ -44,12 +44,10 @@
 #include <asm/msr.h>
 #include "mtrr.h"
 
-#define MTRR_VERSION            "2.0 (20020519)"
-
 u32 num_var_ranges = 0;
 
 unsigned int *usage_table;
-static DECLARE_MUTEX(main_lock);
+static DECLARE_MUTEX(mtrr_sem);
 
 u32 size_or_mask, size_and_mask;
 
@@ -335,7 +333,7 @@ int mtrr_add_page(unsigned long base, un
 	/* No CPU hotplug when we change MTRR entries */
 	lock_cpu_hotplug();
 	/*  Search for existing MTRR  */
-	down(&main_lock);
+	down(&mtrr_sem);
 	for (i = 0; i < num_var_ranges; ++i) {
 		mtrr_if->get(i, &lbase, &lsize, &ltype);
 		if (base >= lbase + lsize)
@@ -373,7 +371,7 @@ int mtrr_add_page(unsigned long base, un
 		printk(KERN_INFO "mtrr: no more MTRRs available\n");
 	error = i;
  out:
-	up(&main_lock);
+	up(&mtrr_sem);
 	unlock_cpu_hotplug();
 	return error;
 }
@@ -466,7 +464,7 @@ int mtrr_del_page(int reg, unsigned long
 	max = num_var_ranges;
 	/* No CPU hotplug when we change MTRR entries */
 	lock_cpu_hotplug();
-	down(&main_lock);
+	down(&mtrr_sem);
 	if (reg < 0) {
 		/*  Search for existing MTRR  */
 		for (i = 0; i < max; ++i) {
@@ -505,7 +503,7 @@ int mtrr_del_page(int reg, unsigned long
 		set_mtrr(reg, 0, 0, 0);
 	error = reg;
  out:
-	up(&main_lock);
+	up(&mtrr_sem);
 	unlock_cpu_hotplug();
 	return error;
 }
@@ -671,7 +669,6 @@ void __init mtrr_bp_init(void)
 			break;
 		}
 	}
-	printk(KERN_INFO "mtrr: v%s\n",MTRR_VERSION);
 
 	if (mtrr_if) {
 		set_num_var_ranges();
@@ -688,7 +685,7 @@ void mtrr_ap_init(void)
 	if (!mtrr_if || !use_intel())
 		return;
 	/*
-	 * Ideally we should hold main_lock here to avoid mtrr entries changed,
+	 * Ideally we should hold mtrr_sem here to avoid mtrr entries changed,
 	 * but this routine will be called in cpu boot time, holding the lock
 	 * breaks it. This routine is called in two cases: 1.very earily time
 	 * of software resume, when there absolutely isn't mtrr entry changes;
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 91a6401..0102f3d 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -1080,7 +1080,7 @@ void __init mp_config_acpi_legacy_irqs (
 
 #define MAX_GSI_NUM	4096
 
-int mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
+int mp_register_gsi (u32 gsi, int triggering, int polarity)
 {
 	int			ioapic = -1;
 	int			ioapic_pin = 0;
@@ -1129,7 +1129,7 @@ int mp_register_gsi (u32 gsi, int edge_l
 
 	mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
 
-	if (edge_level) {
+	if (triggering == ACPI_LEVEL_SENSITIVE) {
 		/*
 		 * For PCI devices assign IRQs in order, avoiding gaps
 		 * due to unused I/O APIC pins.
@@ -1151,8 +1151,8 @@ int mp_register_gsi (u32 gsi, int edge_l
 	}
 
 	io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
-		    edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1,
-		    active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1);
+		    triggering == ACPI_EDGE_SENSITIVE ? 0 : 1,
+		    polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
 	return gsi;
 }
 
diff --git a/arch/i386/kernel/quirks.c b/arch/i386/kernel/quirks.c
index aaf89cb..87ccdac 100644
--- a/arch/i386/kernel/quirks.c
+++ b/arch/i386/kernel/quirks.c
@@ -25,8 +25,7 @@ static void __devinit quirk_intel_irqbal
 
 	/* enable access to config space*/
 	pci_read_config_byte(dev, 0xf4, &config);
-	config |= 0x2;
-	pci_write_config_byte(dev, 0xf4, config);
+	pci_write_config_byte(dev, 0xf4, config|0x2);
 
 	/* read xTPR register */
 	raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word);
@@ -42,9 +41,9 @@ static void __devinit quirk_intel_irqbal
 #endif
 	}
 
-	config &= ~0x2;
-	/* disable access to config space*/
-	pci_write_config_byte(dev, 0xf4, config);
+	/* put back the original value for config space*/
+	if (!(config & 0x2))
+		pci_write_config_byte(dev, 0xf4, config);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_E7320_MCH,	quirk_intel_irqbalance);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_E7525_MCH,	quirk_intel_irqbalance);
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
index adcd069..963616d 100644
--- a/arch/i386/kernel/signal.c
+++ b/arch/i386/kernel/signal.c
@@ -37,51 +37,17 @@
 asmlinkage int
 sys_sigsuspend(int history0, int history1, old_sigset_t mask)
 {
-	struct pt_regs * regs = (struct pt_regs *) &history0;
-	sigset_t saveset;
-
 	mask &= _BLOCKABLE;
 	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
+	current->saved_sigmask = current->blocked;
 	siginitset(&current->blocked, mask);
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
 
-	regs->eax = -EINTR;
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		if (do_signal(regs, &saveset))
-			return -EINTR;
-	}
-}
-
-asmlinkage int
-sys_rt_sigsuspend(struct pt_regs regs)
-{
-	sigset_t saveset, newset;
-
-	/* XXX: Don't preclude handling different sized sigset_t's.  */
-	if (regs.ecx != sizeof(sigset_t))
-		return -EINVAL;
-
-	if (copy_from_user(&newset, (sigset_t __user *)regs.ebx, sizeof(newset)))
-		return -EFAULT;
-	sigdelsetmask(&newset, ~_BLOCKABLE);
-
-	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
-	current->blocked = newset;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-
-	regs.eax = -EINTR;
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		if (do_signal(&regs, &saveset))
-			return -EINTR;
-	}
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	set_thread_flag(TIF_RESTORE_SIGMASK);
+	return -ERESTARTNOHAND;
 }
 
 asmlinkage int 
@@ -433,11 +399,11 @@ static int setup_frame(int sig, struct k
 		current->comm, current->pid, frame, regs->eip, frame->pretcode);
 #endif
 
-	return 1;
+	return 0;
 
 give_sigsegv:
 	force_sigsegv(sig, current);
-	return 0;
+	return -EFAULT;
 }
 
 static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
@@ -527,11 +493,11 @@ static int setup_rt_frame(int sig, struc
 		current->comm, current->pid, frame, regs->eip, frame->pretcode);
 #endif
 
-	return 1;
+	return 0;
 
 give_sigsegv:
 	force_sigsegv(sig, current);
-	return 0;
+	return -EFAULT;
 }
 
 /*
@@ -581,7 +547,7 @@ handle_signal(unsigned long sig, siginfo
 	else
 		ret = setup_frame(sig, ka, oldset, regs);
 
-	if (ret) {
+	if (ret == 0) {
 		spin_lock_irq(&current->sighand->siglock);
 		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 		if (!(ka->sa.sa_flags & SA_NODEFER))
@@ -598,11 +564,12 @@ handle_signal(unsigned long sig, siginfo
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
  * mistake.
  */
-int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset)
+static void fastcall do_signal(struct pt_regs *regs)
 {
 	siginfo_t info;
 	int signr;
 	struct k_sigaction ka;
+	sigset_t *oldset;
 
 	/*
 	 * We want the common case to go fast, which
@@ -613,12 +580,14 @@ int fastcall do_signal(struct pt_regs *r
  	 * CS suffices.
 	 */
 	if (!user_mode(regs))
-		return 1;
+		return;
 
 	if (try_to_freeze())
 		goto no_signal;
 
-	if (!oldset)
+	if (test_thread_flag(TIF_RESTORE_SIGMASK))
+		oldset = &current->saved_sigmask;
+	else
 		oldset = &current->blocked;
 
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
@@ -628,38 +597,55 @@ int fastcall do_signal(struct pt_regs *r
 		 * have been cleared if the watchpoint triggered
 		 * inside the kernel.
 		 */
-		if (unlikely(current->thread.debugreg[7])) {
+		if (unlikely(current->thread.debugreg[7]))
 			set_debugreg(current->thread.debugreg[7], 7);
-		}
 
 		/* Whee!  Actually deliver the signal.  */
-		return handle_signal(signr, &info, &ka, oldset, regs);
+		if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
+			/* a signal was successfully delivered; the saved
+			 * sigmask will have been stored in the signal frame,
+			 * and will be restored by sigreturn, so we can simply
+			 * clear the TIF_RESTORE_SIGMASK flag */
+			if (test_thread_flag(TIF_RESTORE_SIGMASK))
+				clear_thread_flag(TIF_RESTORE_SIGMASK);
+		}
+
+		return;
 	}
 
- no_signal:
+no_signal:
 	/* Did we come from a system call? */
 	if (regs->orig_eax >= 0) {
 		/* Restart the system call - no handlers present */
-		if (regs->eax == -ERESTARTNOHAND ||
-		    regs->eax == -ERESTARTSYS ||
-		    regs->eax == -ERESTARTNOINTR) {
+		switch (regs->eax) {
+		case -ERESTARTNOHAND:
+		case -ERESTARTSYS:
+		case -ERESTARTNOINTR:
 			regs->eax = regs->orig_eax;
 			regs->eip -= 2;
-		}
-		if (regs->eax == -ERESTART_RESTARTBLOCK){
+			break;
+
+		case -ERESTART_RESTARTBLOCK:
 			regs->eax = __NR_restart_syscall;
 			regs->eip -= 2;
+			break;
 		}
 	}
-	return 0;
+
+	/* if there's no signal to deliver, we just put the saved sigmask
+	 * back */
+	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+		clear_thread_flag(TIF_RESTORE_SIGMASK);
+		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+	}
 }
 
 /*
  * notification of userspace execution resumption
- * - triggered by current->work.notify_resume
+ * - triggered by the TIF_WORK_MASK flags
  */
 __attribute__((regparm(3)))
-void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
+void do_notify_resume(struct pt_regs *regs, void *_unused,
 		      __u32 thread_info_flags)
 {
 	/* Pending single-step? */
@@ -667,9 +653,10 @@ void do_notify_resume(struct pt_regs *re
 		regs->eflags |= TF_MASK;
 		clear_thread_flag(TIF_SINGLESTEP);
 	}
+
 	/* deal with pending signal delivery */
-	if (thread_info_flags & _TIF_SIGPENDING)
-		do_signal(regs,oldset);
+	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
+		do_signal(regs);
 	
 	clear_thread_flag(TIF_IRET);
 }
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S
index 6ff3e52..1b66592 100644
--- a/arch/i386/kernel/syscall_table.S
+++ b/arch/i386/kernel/syscall_table.S
@@ -294,3 +294,18 @@ ENTRY(sys_call_table)
 	.long sys_inotify_add_watch
 	.long sys_inotify_rm_watch
 	.long sys_migrate_pages
+	.long sys_openat		/* 295 */
+	.long sys_mkdirat
+	.long sys_mknodat
+	.long sys_fchownat
+	.long sys_futimesat
+	.long sys_newfstatat		/* 300 */
+	.long sys_unlinkat
+	.long sys_renameat
+	.long sys_linkat
+	.long sys_symlinkat
+	.long sys_readlinkat		/* 305 */
+	.long sys_fchmodat
+	.long sys_faccessat
+	.long sys_pselect6
+	.long sys_ppoll
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
index 47675bb..7c86e3c 100644
--- a/arch/i386/kernel/timers/timer_tsc.c
+++ b/arch/i386/kernel/timers/timer_tsc.c
@@ -45,6 +45,15 @@ static unsigned long last_tsc_high; /* m
 static unsigned long long monotonic_base;
 static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED;
 
+/* Avoid compensating for lost ticks before TSCs are synched */
+static int detect_lost_ticks;
+static int __init start_lost_tick_compensation(void)
+{
+	detect_lost_ticks = 1;
+	return 0;
+}
+late_initcall(start_lost_tick_compensation);
+
 /* convert from cycles(64bits) => nanoseconds (64bits)
  *  basic equation:
  *		ns = cycles / (freq / ns_per_sec)
@@ -196,7 +205,8 @@ static void mark_offset_tsc_hpet(void)
 
 	/* lost tick compensation */
 	offset = hpet_readl(HPET_T0_CMP) - hpet_tick;
-	if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0))) {
+	if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0))
+					&& detect_lost_ticks) {
 		int lost_ticks = (offset - hpet_last) / hpet_tick;
 		jiffies_64 += lost_ticks;
 	}
@@ -421,7 +431,7 @@ static void mark_offset_tsc(void)
 	delta += delay_at_last_interrupt;
 	lost = delta/(1000000/HZ);
 	delay = delta%(1000000/HZ);
-	if (lost >= 2) {
+	if (lost >= 2 && detect_lost_ticks) {
 		jiffies_64 += lost-1;
 
 		/* sanity check to ensure we're not always losing ticks */
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
index e715aa9..3ca59ca 100644
--- a/arch/i386/pci/irq.c
+++ b/arch/i386/pci/irq.c
@@ -539,6 +539,11 @@ static __init int intel_router_probe(str
 		case PCI_DEVICE_ID_INTEL_ICH7_30:
 		case PCI_DEVICE_ID_INTEL_ICH7_31:
 		case PCI_DEVICE_ID_INTEL_ESB2_0:
+		case PCI_DEVICE_ID_INTEL_ICH8_0:
+		case PCI_DEVICE_ID_INTEL_ICH8_1:
+		case PCI_DEVICE_ID_INTEL_ICH8_2:
+		case PCI_DEVICE_ID_INTEL_ICH8_3:
+		case PCI_DEVICE_ID_INTEL_ICH8_4:
 			r->name = "PIIX/ICH";
 			r->get = pirq_piix_get;
 			r->set = pirq_piix_set;
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c
index 4bb4d4b..0ee8a98 100644
--- a/arch/i386/pci/mmconfig.c
+++ b/arch/i386/pci/mmconfig.c
@@ -36,8 +36,7 @@ static u32 get_base_addr(unsigned int se
 	while (1) {
 		++cfg_num;
 		if (cfg_num >= pci_mmcfg_config_num) {
-			/* Not found - fallback to type 1 */
-			return 0;
+			break;
 		}
 		cfg = &pci_mmcfg_config[cfg_num];
 		if (cfg->pci_segment_group_number != seg)
@@ -46,6 +45,18 @@ static u32 get_base_addr(unsigned int se
 		    (cfg->end_bus_number >= bus))
 			return cfg->base_address;
 	}
+
+	/* Handle more broken MCFG tables on Asus etc.
+	   They only contain a single entry for bus 0-0. Assume
+ 	   this applies to all busses. */
+	cfg = &pci_mmcfg_config[0];
+	if (pci_mmcfg_config_num == 1 &&
+		cfg->pci_segment_group_number == 0 &&
+		(cfg->start_bus_number | cfg->end_bus_number) == 0)
+		return cfg->base_address;
+
+	/* Fall back to type 0 */
+	return 0;
 }
 
 static inline void pci_exp_set_dev_base(unsigned int base, int bus, int devfn)
diff --git a/arch/ia64/configs/gensparse_defconfig b/arch/ia64/configs/gensparse_defconfig
index 1d07d80..991c07b 100644
--- a/arch/ia64/configs/gensparse_defconfig
+++ b/arch/ia64/configs/gensparse_defconfig
@@ -557,6 +557,7 @@ CONFIG_E100=m
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
 # CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig
index b1e8f09..6859119 100644
--- a/arch/ia64/configs/tiger_defconfig
+++ b/arch/ia64/configs/tiger_defconfig
@@ -565,6 +565,7 @@ CONFIG_E100=m
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
 # CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig
index 0856ca6..53899dc 100644
--- a/arch/ia64/configs/zx1_defconfig
+++ b/arch/ia64/configs/zx1_defconfig
@@ -548,6 +548,7 @@ CONFIG_E100=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
 # CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig
index 275a26c..dcbc78a 100644
--- a/arch/ia64/defconfig
+++ b/arch/ia64/defconfig
@@ -565,6 +565,7 @@ CONFIG_E100=m
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
 # CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index 3945d37..70dba1f 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -52,9 +52,9 @@
 #include <linux/compat.h>
 #include <linux/vfs.h>
 #include <linux/mman.h>
+#include <linux/mutex.h>
 
 #include <asm/intrinsics.h>
-#include <asm/semaphore.h>
 #include <asm/types.h>
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -86,7 +86,7 @@
  * while doing so.
  */
 /* XXX make per-mm: */
-static DECLARE_MUTEX(ia32_mmap_sem);
+static DEFINE_MUTEX(ia32_mmap_mutex);
 
 asmlinkage long
 sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __user *envp,
@@ -895,11 +895,11 @@ ia32_do_mmap (struct file *file, unsigne
 	prot = get_prot32(prot);
 
 #if PAGE_SHIFT > IA32_PAGE_SHIFT
-	down(&ia32_mmap_sem);
+	mutex_lock(&ia32_mmap_mutex);
 	{
 		addr = emulate_mmap(file, addr, len, prot, flags, offset);
 	}
-	up(&ia32_mmap_sem);
+	mutex_unlock(&ia32_mmap_mutex);
 #else
 	down_write(&current->mm->mmap_sem);
 	{
@@ -1000,11 +1000,9 @@ sys32_munmap (unsigned int start, unsign
 	if (start >= end)
 		return 0;
 
-	down(&ia32_mmap_sem);
-	{
-		ret = sys_munmap(start, end - start);
-	}
-	up(&ia32_mmap_sem);
+	mutex_lock(&ia32_mmap_mutex);
+	ret = sys_munmap(start, end - start);
+	mutex_unlock(&ia32_mmap_mutex);
 #endif
 	return ret;
 }
@@ -1056,7 +1054,7 @@ sys32_mprotect (unsigned int start, unsi
 	if (retval < 0)
 		return retval;
 
-	down(&ia32_mmap_sem);
+	mutex_lock(&ia32_mmap_mutex);
 	{
 		if (offset_in_page(start)) {
 			/* start address is 4KB aligned but not page aligned. */
@@ -1080,7 +1078,7 @@ sys32_mprotect (unsigned int start, unsi
 		retval = sys_mprotect(start, end - start, prot);
 	}
   out:
-	up(&ia32_mmap_sem);
+	mutex_unlock(&ia32_mmap_mutex);
 	return retval;
 #endif
 }
@@ -1124,11 +1122,9 @@ sys32_mremap (unsigned int addr, unsigne
 	old_len = PAGE_ALIGN(old_end) - addr;
 	new_len = PAGE_ALIGN(new_end) - addr;
 
-	down(&ia32_mmap_sem);
-	{
-		ret = sys_mremap(addr, old_len, new_len, flags, new_addr);
-	}
-	up(&ia32_mmap_sem);
+	mutex_lock(&ia32_mmap_mutex);
+	ret = sys_mremap(addr, old_len, new_len, flags, new_addr);
+	mutex_unlock(&ia32_mmap_mutex);
 
 	if ((ret >= 0) && (old_len < new_len)) {
 		/* mremap expanded successfully */
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index 307514f..09a0dbc 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -13,6 +13,11 @@ obj-$(CONFIG_IA64_BRL_EMU)	+= brl_emu.o
 obj-$(CONFIG_IA64_GENERIC)	+= acpi-ext.o
 obj-$(CONFIG_IA64_HP_ZX1)	+= acpi-ext.o
 obj-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += acpi-ext.o
+
+ifneq ($(CONFIG_ACPI_PROCESSOR),)
+obj-y				+= acpi-processor.o
+endif
+
 obj-$(CONFIG_IA64_PALINFO)	+= palinfo.o
 obj-$(CONFIG_IOSAPIC)		+= iosapic.o
 obj-$(CONFIG_MODULES)		+= module.o
diff --git a/arch/ia64/kernel/acpi-ext.c b/arch/ia64/kernel/acpi-ext.c
index 13a5b3b..4a5574f 100644
--- a/arch/ia64/kernel/acpi-ext.c
+++ b/arch/ia64/kernel/acpi-ext.c
@@ -33,33 +33,33 @@ acpi_vendor_resource_match(struct acpi_r
 	struct acpi_vendor_info *info = (struct acpi_vendor_info *)context;
 	struct acpi_resource_vendor *vendor;
 	struct acpi_vendor_descriptor *descriptor;
-	u32 length;
+	u32 byte_length;
 
-	if (resource->id != ACPI_RSTYPE_VENDOR)
+	if (resource->type != ACPI_RESOURCE_TYPE_VENDOR)
 		return AE_OK;
 
 	vendor = (struct acpi_resource_vendor *)&resource->data;
-	descriptor = (struct acpi_vendor_descriptor *)vendor->reserved;
-	if (vendor->length <= sizeof(*info->descriptor) ||
+	descriptor = (struct acpi_vendor_descriptor *)vendor->byte_data;
+	if (vendor->byte_length <= sizeof(*info->descriptor) ||
 	    descriptor->guid_id != info->descriptor->guid_id ||
 	    efi_guidcmp(descriptor->guid, info->descriptor->guid))
 		return AE_OK;
 
-	length = vendor->length - sizeof(struct acpi_vendor_descriptor);
-	info->data = acpi_os_allocate(length);
+	byte_length = vendor->byte_length - sizeof(struct acpi_vendor_descriptor);
+	info->data = acpi_os_allocate(byte_length);
 	if (!info->data)
 		return AE_NO_MEMORY;
 
 	memcpy(info->data,
-	       vendor->reserved + sizeof(struct acpi_vendor_descriptor),
-	       length);
-	info->length = length;
+	       vendor->byte_data + sizeof(struct acpi_vendor_descriptor),
+	       byte_length);
+	info->length = byte_length;
 	return AE_CTRL_TERMINATE;
 }
 
 acpi_status
 acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor * id,
-			  u8 ** data, u32 * length)
+			  u8 ** data, u32 * byte_length)
 {
 	struct acpi_vendor_info info;
 
@@ -72,7 +72,7 @@ acpi_find_vendor_resource(acpi_handle ob
 		return AE_NOT_FOUND;
 
 	*data = info.data;
-	*length = info.length;
+	*byte_length = info.length;
 	return AE_OK;
 }
 
diff --git a/arch/ia64/kernel/acpi-processor.c b/arch/ia64/kernel/acpi-processor.c
new file mode 100644
index 0000000..e683630
--- /dev/null
+++ b/arch/ia64/kernel/acpi-processor.c
@@ -0,0 +1,67 @@
+/*
+ * arch/ia64/kernel/cpufreq/processor.c
+ *
+ * Copyright (C) 2005 Intel Corporation
+ * 	Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ * 	- Added _PDC for platforms with Intel CPUs
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/acpi.h>
+
+#include <acpi/processor.h>
+#include <asm/acpi.h>
+
+static void init_intel_pdc(struct acpi_processor *pr)
+{
+	struct acpi_object_list *obj_list;
+	union acpi_object *obj;
+	u32 *buf;
+
+	/* allocate and initialize pdc. It will be used later. */
+	obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
+	if (!obj_list) {
+		printk(KERN_ERR "Memory allocation error\n");
+		return;
+	}
+
+	obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
+	if (!obj) {
+		printk(KERN_ERR "Memory allocation error\n");
+		kfree(obj_list);
+		return;
+	}
+
+	buf = kmalloc(12, GFP_KERNEL);
+	if (!buf) {
+		printk(KERN_ERR "Memory allocation error\n");
+		kfree(obj);
+		kfree(obj_list);
+		return;
+	}
+
+	buf[0] = ACPI_PDC_REVISION_ID;
+	buf[1] = 1;
+	buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP;
+
+	obj->type = ACPI_TYPE_BUFFER;
+	obj->buffer.length = 12;
+	obj->buffer.pointer = (u8 *) buf;
+	obj_list->count = 1;
+	obj_list->pointer = obj;
+	pr->pdc = obj_list;
+
+	return;
+}
+
+/* Initialize _PDC data based on the CPU vendor */
+void arch_acpi_processor_init_pdc(struct acpi_processor *pr)
+{
+	pr->pdc = NULL;
+	init_intel_pdc(pr);
+	return;
+}
+
+EXPORT_SYMBOL(arch_acpi_processor_init_pdc);
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index 9ad94dd..d2702c4 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -567,16 +567,16 @@ void __init acpi_numa_arch_fixup(void)
  * success: return IRQ number (>=0)
  * failure: return < 0
  */
-int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low)
+int acpi_register_gsi(u32 gsi, int triggering, int polarity)
 {
 	if (has_8259 && gsi < 16)
 		return isa_irq_to_vector(gsi);
 
 	return iosapic_register_intr(gsi,
-				     (active_high_low ==
+				     (polarity ==
 				      ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH :
 				     IOSAPIC_POL_LOW,
-				     (edge_level ==
+				     (triggering ==
 				      ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE :
 				     IOSAPIC_LEVEL);
 }
diff --git a/arch/ia64/kernel/cpufreq/Makefile b/arch/ia64/kernel/cpufreq/Makefile
index f748d34..4838f2a 100644
--- a/arch/ia64/kernel/cpufreq/Makefile
+++ b/arch/ia64/kernel/cpufreq/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_IA64_ACPI_CPUFREQ)		+= acpi-cpufreq.o
+
diff --git a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c
index da4d5cf..5a1bf81 100644
--- a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c
+++ b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c
@@ -269,48 +269,6 @@ acpi_cpufreq_verify (
 }
 
 
-/*
- * processor_init_pdc - let BIOS know about the SMP capabilities
- * of this driver
- * @perf: processor-specific acpi_io_data struct
- * @cpu: CPU being initialized
- *
- * To avoid issues with legacy OSes, some BIOSes require to be informed of
- * the SMP capabilities of OS P-state driver. Here we set the bits in _PDC
- * accordingly. Actual call to _PDC is done in driver/acpi/processor.c
- */
-static void
-processor_init_pdc (
-		struct acpi_processor_performance *perf,
-		unsigned int cpu,
-		struct acpi_object_list *obj_list
-		)
-{
-	union acpi_object *obj;
-	u32 *buf;
-
-	dprintk("processor_init_pdc\n");
-
-	perf->pdc = NULL;
-	/* Initialize pdc. It will be used later. */
-	if (!obj_list)
-		return;
-
-	if (!(obj_list->count && obj_list->pointer))
-		return;
-
-	obj = obj_list->pointer;
-	if ((obj->buffer.length == 12) && obj->buffer.pointer) {
-		buf = (u32 *)obj->buffer.pointer;
-       		buf[0] = ACPI_PDC_REVISION_ID;
-       		buf[1] = 1;
-       		buf[2] = ACPI_PDC_EST_CAPABILITY_SMP;
-		perf->pdc = obj_list;
-	}
-	return;
-}
-
-
 static int
 acpi_cpufreq_cpu_init (
 	struct cpufreq_policy   *policy)
@@ -320,14 +278,7 @@ acpi_cpufreq_cpu_init (
 	struct cpufreq_acpi_io	*data;
 	unsigned int		result = 0;
 
-	union acpi_object		arg0 = {ACPI_TYPE_BUFFER};
-	u32				arg0_buf[3];
-	struct acpi_object_list 	arg_list = {1, &arg0};
-
 	dprintk("acpi_cpufreq_cpu_init\n");
-	/* setup arg_list for _PDC settings */
-        arg0.buffer.length = 12;
-        arg0.buffer.pointer = (u8 *) arg0_buf;
 
 	data = kmalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL);
 	if (!data)
@@ -337,9 +288,7 @@ acpi_cpufreq_cpu_init (
 
 	acpi_io_data[cpu] = data;
 
-	processor_init_pdc(&data->acpi_data, cpu, &arg_list);
 	result = acpi_processor_register_performance(&data->acpi_data, cpu);
-	data->acpi_data.pdc = NULL;
 
 	if (result)
 		goto err_free;
diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S
index 403a80a..60a464b 100644
--- a/arch/ia64/kernel/mca_asm.S
+++ b/arch/ia64/kernel/mca_asm.S
@@ -512,7 +512,7 @@ ia64_state_save:
 	st8 [temp1]=r12		// os_status, default is cold boot
 	mov r6=IA64_MCA_SAME_CONTEXT
 	;;
-	st8 [temp1]=r6		// context, default is same context
+	st8 [temp2]=r6		// context, default is same context
 
 	// Save the pt_regs data that is not in minstate.  The previous code
 	// left regs at sos.
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 2ea4b39..9c5194b 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -40,6 +40,7 @@
 #include <linux/bitops.h>
 #include <linux/capability.h>
 #include <linux/rcupdate.h>
+#include <linux/completion.h>
 
 #include <asm/errno.h>
 #include <asm/intrinsics.h>
@@ -286,7 +287,7 @@ typedef struct pfm_context {
 
 	unsigned long		ctx_ovfl_regs[4];	/* which registers overflowed (notification) */
 
-	struct semaphore	ctx_restart_sem;   	/* use for blocking notification mode */
+	struct completion	ctx_restart_done;  	/* use for blocking notification mode */
 
 	unsigned long		ctx_used_pmds[4];	/* bitmask of PMD used            */
 	unsigned long		ctx_all_pmds[4];	/* bitmask of all accessible PMDs */
@@ -1991,7 +1992,7 @@ pfm_close(struct inode *inode, struct fi
 		/*
 		 * force task to wake up from MASKED state
 		 */
-		up(&ctx->ctx_restart_sem);
+		complete(&ctx->ctx_restart_done);
 
 		DPRINT(("waking up ctx_state=%d\n", state));
 
@@ -2706,7 +2707,7 @@ pfm_context_create(pfm_context_t *ctx, v
 	/*
 	 * init restart semaphore to locked
 	 */
-	sema_init(&ctx->ctx_restart_sem, 0);
+	init_completion(&ctx->ctx_restart_done);
 
 	/*
 	 * activation is used in SMP only
@@ -3687,7 +3688,7 @@ pfm_restart(pfm_context_t *ctx, void *ar
 	 */
 	if (CTX_OVFL_NOBLOCK(ctx) == 0 && state == PFM_CTX_MASKED) {
 		DPRINT(("unblocking [%d] \n", task->pid));
-		up(&ctx->ctx_restart_sem);
+		complete(&ctx->ctx_restart_done);
 	} else {
 		DPRINT(("[%d] armed exit trap\n", task->pid));
 
@@ -5089,7 +5090,7 @@ pfm_handle_work(void)
 	 * may go through without blocking on SMP systems
 	 * if restart has been received already by the time we call down()
 	 */
-	ret = down_interruptible(&ctx->ctx_restart_sem);
+	ret = wait_for_completion_interruptible(&ctx->ctx_restart_done);
 
 	DPRINT(("after block sleeping ret=%d\n", ret));
 
diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c
index 43b45b6..f9e0ae9 100644
--- a/arch/ia64/kernel/unaligned.c
+++ b/arch/ia64/kernel/unaligned.c
@@ -1283,8 +1283,9 @@ within_logging_rate_limit (void)
 
 	if (jiffies - last_time > 5*HZ)
 		count = 0;
-	if (++count < 5) {
+	if (count < 5) {
 		last_time = jiffies;
+		count++;
 		return 1;
 	}
 	return 0;
diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c
index b631cf8..fcd2bad 100644
--- a/arch/ia64/kernel/uncached.c
+++ b/arch/ia64/kernel/uncached.c
@@ -210,6 +210,7 @@ uncached_build_memmap(unsigned long star
 
 	dprintk(KERN_ERR "uncached_build_memmap(%lx %lx)\n", start, end);
 
+	touch_softlockup_watchdog();
 	memset((char *)start, 0, length);
 
 	node = paddr_to_nid(start - __IA64_UNCACHED_OFFSET);
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index d27ecdc..0b30ca0 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -193,12 +193,12 @@ add_io_space (struct pci_root_info *info
 		goto free_resource;
 	}
 
-	min = addr->min_address_range;
+	min = addr->minimum;
 	max = min + addr->address_length - 1;
-	if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION)
+	if (addr->info.io.translation_type == ACPI_SPARSE_TRANSLATION)
 		sparse = 1;
 
-	space_nr = new_space(addr->address_translation_offset, sparse);
+	space_nr = new_space(addr->translation_offset, sparse);
 	if (space_nr == ~0)
 		goto free_name;
 
@@ -285,7 +285,7 @@ static __devinit acpi_status add_window(
 	if (addr.resource_type == ACPI_MEMORY_RANGE) {
 		flags = IORESOURCE_MEM;
 		root = &iomem_resource;
-		offset = addr.address_translation_offset;
+		offset = addr.translation_offset;
 	} else if (addr.resource_type == ACPI_IO_RANGE) {
 		flags = IORESOURCE_IO;
 		root = &ioport_resource;
@@ -298,7 +298,7 @@ static __devinit acpi_status add_window(
 	window = &info->controller->window[info->controller->windows++];
 	window->resource.name = info->name;
 	window->resource.flags = flags;
-	window->resource.start = addr.min_address_range + offset;
+	window->resource.start = addr.minimum + offset;
 	window->resource.end = window->resource.start + addr.address_length - 1;
 	window->resource.child = NULL;
 	window->offset = offset;
diff --git a/arch/ia64/sn/include/xtalk/hubdev.h b/arch/ia64/sn/include/xtalk/hubdev.h
index 7c88e9a..8182583 100644
--- a/arch/ia64/sn/include/xtalk/hubdev.h
+++ b/arch/ia64/sn/include/xtalk/hubdev.h
@@ -51,6 +51,15 @@ struct sn_flush_device_kernel {
 	struct sn_flush_device_common *common;
 };
 
+/* 01/16/06 This struct is the old PROM/kernel struct and needs to be included
+ * for older official PROMs to function on the new kernel base.  This struct
+ * will be removed when the next official PROM release occurs. */
+
+struct sn_flush_device_war {
+	struct sn_flush_device_common common;
+	u32 filler; /* older PROMs expect the default size of a spinlock_t */
+};
+
 /*
  * **widget_p - Used as an array[wid_num][device] of sn_flush_device_kernel.
  */
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 233d551..a4c7815 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -10,6 +10,7 @@
 #include <linux/nodemask.h>
 #include <asm/sn/types.h>
 #include <asm/sn/addrs.h>
+#include <asm/sn/sn_feature_sets.h>
 #include <asm/sn/geo.h>
 #include <asm/sn/io.h>
 #include <asm/sn/pcibr_provider.h>
@@ -165,8 +166,46 @@ sn_pcidev_info_get(struct pci_dev *dev)
 	return NULL;
 }
 
+/* Older PROM flush WAR
+ *
+ * 01/16/06 -- This war will be in place until a new official PROM is released.
+ * Additionally note that the struct sn_flush_device_war also has to be
+ * removed from arch/ia64/sn/include/xtalk/hubdev.h
+ */
+static u8 war_implemented = 0;
+
+static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device,
+			       struct sn_flush_device_common *common)
+{
+	struct sn_flush_device_war *war_list;
+	struct sn_flush_device_war *dev_entry;
+	struct ia64_sal_retval isrv = {0,0,0,0};
+
+	if (!war_implemented) {
+		printk(KERN_WARNING "PROM version < 4.50 -- implementing old "
+		       "PROM flush WAR\n");
+		war_implemented = 1;
+	}
+
+	war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL);
+	if (!war_list)
+		BUG();
+
+	SAL_CALL_NOLOCK(isrv, SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST,
+			nasid, widget, __pa(war_list), 0, 0, 0 ,0);
+	if (isrv.status)
+		panic("sn_device_fixup_war failed: %s\n",
+		      ia64_sal_strerror(isrv.status));
+
+	dev_entry = war_list + device;
+	memcpy(common,dev_entry, sizeof(*common));
+	kfree(war_list);
+
+	return isrv.status;
+}
+
 /*
- * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for 
+ * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for
  *	each node in the system.
  */
 static void sn_fixup_ionodes(void)
@@ -242,12 +281,21 @@ static void sn_fixup_ionodes(void)
 				memset(dev_entry->common, 0x0, sizeof(struct
 					     	       sn_flush_device_common));
 
-				status = sal_get_device_dmaflush_list(nasid,
-									widget,
-								       	device,
+				if (sn_prom_feature_available(
+						       PRF_DEVICE_FLUSH_LIST))
+					status = sal_get_device_dmaflush_list(
+									  nasid,
+									 widget,
+								       	 device,
 						      (u64)(dev_entry->common));
-				if (status)
-					BUG();
+				else
+					status = sn_device_fixup_war(nasid,
+								     widget,
+							    	     device,
+							     dev_entry->common);
+				if (status != SALRET_OK)
+					panic("SAL call failed: %s\n",
+					      ia64_sal_strerror(status));
 
 				spin_lock_init(&dev_entry->sfdl_flush_lock);
 			}
diff --git a/arch/ia64/sn/kernel/mca.c b/arch/ia64/sn/kernel/mca.c
index 6546db6..9ab684d 100644
--- a/arch/ia64/sn/kernel/mca.c
+++ b/arch/ia64/sn/kernel/mca.c
@@ -10,6 +10,7 @@
 #include <linux/kernel.h>
 #include <linux/timer.h>
 #include <linux/vmalloc.h>
+#include <linux/mutex.h>
 #include <asm/mca.h>
 #include <asm/sal.h>
 #include <asm/sn/sn_sal.h>
@@ -27,7 +28,7 @@ void sn_init_cpei_timer(void);
 /* Printing oemdata from mca uses data that is not passed through SAL, it is
  * global.  Only one user at a time.
  */
-static DECLARE_MUTEX(sn_oemdata_mutex);
+static DEFINE_MUTEX(sn_oemdata_mutex);
 static u8 **sn_oemdata;
 static u64 *sn_oemdata_size, sn_oemdata_bufsize;
 
@@ -89,7 +90,7 @@ static int
 sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata,
 				    u64 * oemdata_size)
 {
-	down(&sn_oemdata_mutex);
+	mutex_lock(&sn_oemdata_mutex);
 	sn_oemdata = oemdata;
 	sn_oemdata_size = oemdata_size;
 	sn_oemdata_bufsize = 0;
@@ -107,7 +108,7 @@ sn_platform_plat_specific_err_print(cons
 		*sn_oemdata_size = 0;
 		ia64_sn_plat_specific_err_print(print_hook, (char *)sect_header);
 	}
-	up(&sn_oemdata_mutex);
+	mutex_unlock(&sn_oemdata_mutex);
 	return 0;
 }
 
diff --git a/arch/ia64/sn/kernel/xp_main.c b/arch/ia64/sn/kernel/xp_main.c
index 3be52a3..b7ea466 100644
--- a/arch/ia64/sn/kernel/xp_main.c
+++ b/arch/ia64/sn/kernel/xp_main.c
@@ -19,6 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/sn_sal.h>
 #include <asm/sn/xp.h>
@@ -136,13 +137,13 @@ xpc_connect(int ch_number, xpc_channel_f
 
 	registration = &xpc_registrations[ch_number];
 
-	if (down_interruptible(&registration->sema) != 0) {
+	if (mutex_lock_interruptible(&registration->mutex) != 0) {
 		return xpcInterrupted;
 	}
 
 	/* if XPC_CHANNEL_REGISTERED(ch_number) */
 	if (registration->func != NULL) {
-		up(&registration->sema);
+		mutex_unlock(&registration->mutex);
 		return xpcAlreadyRegistered;
 	}
 
@@ -154,7 +155,7 @@ xpc_connect(int ch_number, xpc_channel_f
 	registration->key = key;
 	registration->func = func;
 
-	up(&registration->sema);
+	mutex_unlock(&registration->mutex);
 
 	xpc_interface.connect(ch_number);
 
@@ -190,11 +191,11 @@ xpc_disconnect(int ch_number)
 	 * figured XPC's users will just turn around and call xpc_disconnect()
 	 * again anyways, so we might as well wait, if need be.
 	 */
-	down(&registration->sema);
+	mutex_lock(&registration->mutex);
 
 	/* if !XPC_CHANNEL_REGISTERED(ch_number) */
 	if (registration->func == NULL) {
-		up(&registration->sema);
+		mutex_unlock(&registration->mutex);
 		return;
 	}
 
@@ -208,7 +209,7 @@ xpc_disconnect(int ch_number)
 
 	xpc_interface.disconnect(ch_number);
 
-	up(&registration->sema);
+	mutex_unlock(&registration->mutex);
 
 	return;
 }
@@ -250,9 +251,9 @@ xp_init(void)
 		xp_nofault_PIOR_target = SH1_IPI_ACCESS;
 	}
 
-	/* initialize the connection registration semaphores */
+	/* initialize the connection registration mutex */
 	for (ch_number = 0; ch_number < XPC_NCHANNELS; ch_number++) {
-		sema_init(&xpc_registrations[ch_number].sema, 1);  /* mutex */
+		mutex_init(&xpc_registrations[ch_number].mutex);
 	}
 
 	return 0;
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c
index 0c0a689..36e5437 100644
--- a/arch/ia64/sn/kernel/xpc_channel.c
+++ b/arch/ia64/sn/kernel/xpc_channel.c
@@ -22,6 +22,8 @@
 #include <linux/cache.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/completion.h>
 #include <asm/sn/bte.h>
 #include <asm/sn/sn_sal.h>
 #include <asm/sn/xpc.h>
@@ -56,8 +58,8 @@ xpc_initialize_channels(struct xpc_parti
 		atomic_set(&ch->n_to_notify, 0);
 
 		spin_lock_init(&ch->lock);
-		sema_init(&ch->msg_to_pull_sema, 1);	/* mutex */
-		sema_init(&ch->wdisconnect_sema, 0);	/* event wait */
+		mutex_init(&ch->msg_to_pull_mutex);
+		init_completion(&ch->wdisconnect_wait);
 
 		atomic_set(&ch->n_on_msg_allocate_wq, 0);
 		init_waitqueue_head(&ch->msg_allocate_wq);
@@ -445,7 +447,7 @@ xpc_allocate_local_msgqueue(struct xpc_c
 
 		nbytes = nentries * ch->msg_size;
 		ch->local_msgqueue = xpc_kmalloc_cacheline_aligned(nbytes,
-						(GFP_KERNEL | GFP_DMA),
+						GFP_KERNEL,
 						&ch->local_msgqueue_base);
 		if (ch->local_msgqueue == NULL) {
 			continue;
@@ -453,7 +455,7 @@ xpc_allocate_local_msgqueue(struct xpc_c
 		memset(ch->local_msgqueue, 0, nbytes);
 
 		nbytes = nentries * sizeof(struct xpc_notify);
-		ch->notify_queue = kmalloc(nbytes, (GFP_KERNEL | GFP_DMA));
+		ch->notify_queue = kmalloc(nbytes, GFP_KERNEL);
 		if (ch->notify_queue == NULL) {
 			kfree(ch->local_msgqueue_base);
 			ch->local_msgqueue = NULL;
@@ -500,7 +502,7 @@ xpc_allocate_remote_msgqueue(struct xpc_
 
 		nbytes = nentries * ch->msg_size;
 		ch->remote_msgqueue = xpc_kmalloc_cacheline_aligned(nbytes,
-						(GFP_KERNEL | GFP_DMA),
+						GFP_KERNEL,
 						&ch->remote_msgqueue_base);
 		if (ch->remote_msgqueue == NULL) {
 			continue;
@@ -534,7 +536,6 @@ static enum xpc_retval
 xpc_allocate_msgqueues(struct xpc_channel *ch)
 {
 	unsigned long irq_flags;
-	int i;
 	enum xpc_retval ret;
 
 
@@ -552,11 +553,6 @@ xpc_allocate_msgqueues(struct xpc_channe
 		return ret;
 	}
 
-	for (i = 0; i < ch->local_nentries; i++) {
-		/* use a semaphore as an event wait queue */
-		sema_init(&ch->notify_queue[i].sema, 0);
-	}
-
 	spin_lock_irqsave(&ch->lock, irq_flags);
 	ch->flags |= XPC_C_SETUP;
 	spin_unlock_irqrestore(&ch->lock, irq_flags);
@@ -799,10 +795,8 @@ xpc_process_disconnect(struct xpc_channe
 	}
 
 	if (ch->flags & XPC_C_WDISCONNECT) {
-		spin_unlock_irqrestore(&ch->lock, *irq_flags);
-		up(&ch->wdisconnect_sema);
-		spin_lock_irqsave(&ch->lock, *irq_flags);
-
+		/* we won't lose the CPU since we're holding ch->lock */
+		complete(&ch->wdisconnect_wait);
 	} else if (ch->delayed_IPI_flags) {
 		if (part->act_state != XPC_P_DEACTIVATING) {
 			/* time to take action on any delayed IPI flags */
@@ -1092,12 +1086,12 @@ xpc_connect_channel(struct xpc_channel *
 	struct xpc_registration *registration = &xpc_registrations[ch->number];
 
 
-	if (down_trylock(&registration->sema) != 0) {
+	if (mutex_trylock(&registration->mutex) == 0) {
 		return xpcRetry;
 	}
 
 	if (!XPC_CHANNEL_REGISTERED(ch->number)) {
-		up(&registration->sema);
+		mutex_unlock(&registration->mutex);
 		return xpcUnregistered;
 	}
 
@@ -1108,7 +1102,7 @@ xpc_connect_channel(struct xpc_channel *
 
 	if (ch->flags & XPC_C_DISCONNECTING) {
 		spin_unlock_irqrestore(&ch->lock, irq_flags);
-		up(&registration->sema);
+		mutex_unlock(&registration->mutex);
 		return ch->reason;
 	}
 
@@ -1140,7 +1134,7 @@ xpc_connect_channel(struct xpc_channel *
 			 * channel lock be locked and will unlock and relock
 			 * the channel lock as needed.
 			 */
-			up(&registration->sema);
+			mutex_unlock(&registration->mutex);
 			XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes,
 								&irq_flags);
 			spin_unlock_irqrestore(&ch->lock, irq_flags);
@@ -1155,7 +1149,7 @@ xpc_connect_channel(struct xpc_channel *
 		atomic_inc(&xpc_partitions[ch->partid].nchannels_active);
 	}
 
-	up(&registration->sema);
+	mutex_unlock(&registration->mutex);
 
 
 	/* initiate the connection */
@@ -2089,7 +2083,7 @@ xpc_pull_remote_msg(struct xpc_channel *
 	enum xpc_retval ret;
 
 
-	if (down_interruptible(&ch->msg_to_pull_sema) != 0) {
+	if (mutex_lock_interruptible(&ch->msg_to_pull_mutex) != 0) {
 		/* we were interrupted by a signal */
 		return NULL;
 	}
@@ -2125,7 +2119,7 @@ xpc_pull_remote_msg(struct xpc_channel *
 
 			XPC_DEACTIVATE_PARTITION(part, ret);
 
-			up(&ch->msg_to_pull_sema);
+			mutex_unlock(&ch->msg_to_pull_mutex);
 			return NULL;
 		}
 
@@ -2134,7 +2128,7 @@ xpc_pull_remote_msg(struct xpc_channel *
 		ch->next_msg_to_pull += nmsgs;
 	}
 
-	up(&ch->msg_to_pull_sema);
+	mutex_unlock(&ch->msg_to_pull_mutex);
 
 	/* return the message we were looking for */
 	msg_offset = (get % ch->remote_nentries) * ch->msg_size;
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
index 8930586..c75f8ae 100644
--- a/arch/ia64/sn/kernel/xpc_main.c
+++ b/arch/ia64/sn/kernel/xpc_main.c
@@ -55,6 +55,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/reboot.h>
+#include <linux/completion.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/sn_sal.h>
 #include <asm/kdebug.h>
@@ -177,10 +178,10 @@ static DECLARE_WAIT_QUEUE_HEAD(xpc_act_I
 static unsigned long xpc_hb_check_timeout;
 
 /* notification that the xpc_hb_checker thread has exited */
-static DECLARE_MUTEX_LOCKED(xpc_hb_checker_exited);
+static DECLARE_COMPLETION(xpc_hb_checker_exited);
 
 /* notification that the xpc_discovery thread has exited */
-static DECLARE_MUTEX_LOCKED(xpc_discovery_exited);
+static DECLARE_COMPLETION(xpc_discovery_exited);
 
 
 static struct timer_list xpc_hb_timer;
@@ -321,7 +322,7 @@ xpc_hb_checker(void *ignore)
 
 
 	/* mark this thread as having exited */
-	up(&xpc_hb_checker_exited);
+	complete(&xpc_hb_checker_exited);
 	return 0;
 }
 
@@ -341,7 +342,7 @@ xpc_initiate_discovery(void *ignore)
 	dev_dbg(xpc_part, "discovery thread is exiting\n");
 
 	/* mark this thread as having exited */
-	up(&xpc_discovery_exited);
+	complete(&xpc_discovery_exited);
 	return 0;
 }
 
@@ -893,7 +894,7 @@ xpc_disconnect_wait(int ch_number)
 			continue;
 		}
 
-		(void) down(&ch->wdisconnect_sema);
+		wait_for_completion(&ch->wdisconnect_wait);
 
 		spin_lock_irqsave(&ch->lock, irq_flags);
 		DBUG_ON(!(ch->flags & XPC_C_DISCONNECTED));
@@ -946,10 +947,10 @@ xpc_do_exit(enum xpc_retval reason)
 	free_irq(SGI_XPC_ACTIVATE, NULL);
 
 	/* wait for the discovery thread to exit */
-	down(&xpc_discovery_exited);
+	wait_for_completion(&xpc_discovery_exited);
 
 	/* wait for the heartbeat checker thread to exit */
-	down(&xpc_hb_checker_exited);
+	wait_for_completion(&xpc_hb_checker_exited);
 
 
 	/* sleep for a 1/3 of a second or so */
@@ -1367,7 +1368,7 @@ xpc_init(void)
 		dev_err(xpc_part, "failed while forking discovery thread\n");
 
 		/* mark this new thread as a non-starter */
-		up(&xpc_discovery_exited);
+		complete(&xpc_discovery_exited);
 
 		xpc_do_exit(xpcUnloading);
 		return -EBUSY;
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index 9bf9f23..5a36292 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -90,14 +90,14 @@ void *sn_dma_alloc_coherent(struct devic
 	 */
 	node = pcibus_to_node(pdev->bus);
 	if (likely(node >=0)) {
-		struct page *p = alloc_pages_node(node, GFP_ATOMIC, get_order(size));
+		struct page *p = alloc_pages_node(node, flags, get_order(size));
 
 		if (likely(p))
 			cpuaddr = page_address(p);
 		else
 			return NULL;
 	} else
-		cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size));
+		cpuaddr = (void *)__get_free_pages(flags, get_order(size));
 
 	if (unlikely(!cpuaddr))
 		return NULL;
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
index 77a1262..2fac270 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
@@ -24,13 +24,15 @@ sal_pcibr_slot_enable(struct pcibus_info
 {
 	struct ia64_sal_retval ret_stuff;
 	u64 busnum;
+	u64 segment;
 
 	ret_stuff.status = 0;
 	ret_stuff.v0 = 0;
 
+	segment = soft->pbi_buscommon.bs_persist_segment;
 	busnum = soft->pbi_buscommon.bs_persist_busnum;
-	SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_ENABLE, (u64) busnum,
-			(u64) device, (u64) resp, 0, 0, 0, 0);
+	SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_ENABLE, segment,
+			busnum, (u64) device, (u64) resp, 0, 0, 0);
 
 	return (int)ret_stuff.v0;
 }
@@ -41,14 +43,16 @@ sal_pcibr_slot_disable(struct pcibus_inf
 {
 	struct ia64_sal_retval ret_stuff;
 	u64 busnum;
+	u64 segment;
 
 	ret_stuff.status = 0;
 	ret_stuff.v0 = 0;
 
+	segment = soft->pbi_buscommon.bs_persist_segment;
 	busnum = soft->pbi_buscommon.bs_persist_busnum;
 	SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_DISABLE,
-			(u64) busnum, (u64) device, (u64) action,
-			(u64) resp, 0, 0, 0);
+			segment, busnum, (u64) device, (u64) action,
+			(u64) resp, 0, 0);
 
 	return (int)ret_stuff.v0;
 }
diff --git a/arch/mips/kernel/gdb-stub.c b/arch/mips/kernel/gdb-stub.c
index 96d18c4..d4f88e0 100644
--- a/arch/mips/kernel/gdb-stub.c
+++ b/arch/mips/kernel/gdb-stub.c
@@ -178,7 +178,7 @@ int kgdb_enabled;
  */
 static DEFINE_SPINLOCK(kgdb_lock);
 static raw_spinlock_t kgdb_cpulock[NR_CPUS] = {
-	[0 ... NR_CPUS-1] = __RAW_SPIN_LOCK_UNLOCKED;
+	[0 ... NR_CPUS-1] = __RAW_SPIN_LOCK_UNLOCKED,
 };
 
 /*
diff --git a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig
index 955ef50..959ad3c 100644
--- a/arch/parisc/configs/a500_defconfig
+++ b/arch/parisc/configs/a500_defconfig
@@ -602,6 +602,7 @@ CONFIG_ACENIC_OMIT_TIGON_I=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=m
 CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig
index 9d86b6b..0b1c8c1 100644
--- a/arch/parisc/configs/c3000_defconfig
+++ b/arch/parisc/configs/c3000_defconfig
@@ -626,6 +626,7 @@ CONFIG_ACENIC=m
 # CONFIG_DL2K is not set
 CONFIG_E1000=m
 # CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig
index b657f7e..063b84f 100644
--- a/arch/powerpc/configs/cell_defconfig
+++ b/arch/powerpc/configs/cell_defconfig
@@ -533,6 +533,7 @@ CONFIG_MII=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=m
 # CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig
index 3c22ccb..d6fed3f 100644
--- a/arch/powerpc/configs/g5_defconfig
+++ b/arch/powerpc/configs/g5_defconfig
@@ -675,6 +675,7 @@ CONFIG_ACENIC_OMIT_TIGON_I=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
 # CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/powerpc/configs/iseries_defconfig b/arch/powerpc/configs/iseries_defconfig
index 751a622..c775027 100644
--- a/arch/powerpc/configs/iseries_defconfig
+++ b/arch/powerpc/configs/iseries_defconfig
@@ -567,6 +567,7 @@ CONFIG_ACENIC=m
 # CONFIG_DL2K is not set
 CONFIG_E1000=m
 # CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/powerpc/configs/maple_defconfig b/arch/powerpc/configs/maple_defconfig
index 07b6d3d..68194c0 100644
--- a/arch/powerpc/configs/maple_defconfig
+++ b/arch/powerpc/configs/maple_defconfig
@@ -454,6 +454,7 @@ CONFIG_AMD8111_ETH=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
 # CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index 0b2b55a..6f6c6be 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -724,6 +724,7 @@ CONFIG_ACENIC_OMIT_TIGON_I=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
 # CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index a50ce0f..aa9893a 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -671,6 +671,7 @@ CONFIG_ACENIC_OMIT_TIGON_I=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
 # CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index d8da2a3..f20a672 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -227,7 +227,7 @@ ret_from_syscall:
 	MTMSRD(r10)
 	lwz	r9,TI_FLAGS(r12)
 	li	r8,-_LAST_ERRNO
-	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL)
+	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_RESTORE_SIGMASK)
 	bne-	syscall_exit_work
 	cmplw	0,r3,r8
 	blt+	syscall_exit_cont
@@ -357,7 +357,7 @@ save_user_nvgprs_cont:
 	lwz	r5,_MSR(r1)
 	andi.	r5,r5,MSR_PR
 	beq	ret_from_except
-	andi.	r0,r9,_TIF_SIGPENDING
+	andi.	r0,r9,_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK
 	beq	ret_from_except
 	b	do_user_signal
 8:
@@ -683,7 +683,7 @@ user_exc_return:		/* r10 contains MSR_KE
 	/* Check current_thread_info()->flags */
 	rlwinm	r9,r1,0,0,(31-THREAD_SHIFT)
 	lwz	r9,TI_FLAGS(r9)
-	andi.	r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL)
+	andi.	r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_RESTORE_SIGMASK)
 	bne	do_work
 
 restore_user:
@@ -917,7 +917,7 @@ recheck:
 	lwz	r9,TI_FLAGS(r9)
 	andi.	r0,r9,_TIF_NEED_RESCHED
 	bne-	do_resched
-	andi.	r0,r9,_TIF_SIGPENDING
+	andi.	r0,r9,_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK
 	beq	restore_user
 do_user_signal:			/* r10 contains MSR_KERNEL here */
 	ori	r10,r10,MSR_EE
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 5420363..388f861 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -160,7 +160,7 @@ syscall_exit:
 	mtmsrd	r10,1
 	ld	r9,TI_FLAGS(r12)
 	li	r11,-_LAST_ERRNO
-	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_SAVE_NVGPRS|_TIF_NOERROR)
+	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_SAVE_NVGPRS|_TIF_NOERROR|_TIF_RESTORE_SIGMASK)
 	bne-	syscall_exit_work
 	cmpld	r3,r11
 	ld	r5,_CCR(r1)
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index f970ace..c7a799a 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -134,7 +134,6 @@ static int __init add_legacy_soc_port(st
 	return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags);
 }
 
-#ifdef CONFIG_ISA
 static int __init add_legacy_isa_port(struct device_node *np,
 				      struct device_node *isa_brg)
 {
@@ -168,7 +167,6 @@ static int __init add_legacy_isa_port(st
 	return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr, NO_IRQ, UPF_BOOT_AUTOCONF);
 
 }
-#endif
 
 #ifdef CONFIG_PCI
 static int __init add_legacy_pci_port(struct device_node *np,
@@ -276,7 +274,6 @@ void __init find_legacy_serial_ports(voi
 		of_node_put(soc);
 	}
 
-#ifdef CONFIG_ISA
 	/* First fill our array with ISA ports */
 	for (np = NULL; (np = of_find_node_by_type(np, "serial"));) {
 		struct device_node *isa = of_get_parent(np);
@@ -287,7 +284,6 @@ void __init find_legacy_serial_ports(voi
 		}
 		of_node_put(isa);
 	}
-#endif
 
 #ifdef CONFIG_PCI
 	/* Next, try to locate PCI ports */
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 177bba7..c6d0595 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -252,67 +252,19 @@ int do_signal(sigset_t *oldset, struct p
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
-long sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
-	       struct pt_regs *regs)
+long sys_sigsuspend(old_sigset_t mask)
 {
-	sigset_t saveset;
-
 	mask &= _BLOCKABLE;
 	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
+	current->saved_sigmask = current->blocked;
 	siginitset(&current->blocked, mask);
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
 
-	regs->result = -EINTR;
-	regs->gpr[3] = EINTR;
-	regs->ccr |= 0x10000000;
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		if (do_signal(&saveset, regs)) {
-			set_thread_flag(TIF_RESTOREALL);
-			return 0;
-		}
-	}
-}
-
-long sys_rt_sigsuspend(
-#ifdef CONFIG_PPC64
-		compat_sigset_t __user *unewset,
-#else
-		sigset_t __user *unewset,
-#endif
-		size_t sigsetsize, int p3, int p4,
-		int p6, int p7, struct pt_regs *regs)
-{
-	sigset_t saveset, newset;
-
-	/* XXX: Don't preclude handling different sized sigset_t's.  */
-	if (sigsetsize != sizeof(sigset_t))
-		return -EINVAL;
-
-	if (get_sigset_t(&newset, unewset))
-		return -EFAULT;
-	sigdelsetmask(&newset, ~_BLOCKABLE);
-
-	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
-	current->blocked = newset;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-
-	regs->result = -EINTR;
-	regs->gpr[3] = EINTR;
-	regs->ccr |= 0x10000000;
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		if (do_signal(&saveset, regs)) {
-			set_thread_flag(TIF_RESTOREALL);
-			return 0;
-		}
-	}
+ 	current->state = TASK_INTERRUPTIBLE;
+ 	schedule();
+ 	set_thread_flag(TIF_RESTORE_SIGMASK);
+ 	return -ERESTARTNOHAND;
 }
 
 #ifdef CONFIG_PPC32
@@ -1174,7 +1126,7 @@ int do_signal(sigset_t *oldset, struct p
 {
 	siginfo_t info;
 	struct k_sigaction ka;
-	unsigned int frame, newsp;
+	unsigned int newsp;
 	int signr, ret;
 
 #ifdef CONFIG_PPC32
@@ -1185,11 +1137,11 @@ int do_signal(sigset_t *oldset, struct p
 	}
 #endif
 
-	if (!oldset)
+	if (test_thread_flag(TIF_RESTORE_SIGMASK))
+		oldset = &current->saved_sigmask;
+	else if (!oldset)
 		oldset = &current->blocked;
 
-	newsp = frame = 0;
-
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 #ifdef CONFIG_PPC32
 no_signal:
@@ -1219,8 +1171,14 @@ no_signal:
 		}
 	}
 
-	if (signr == 0)
+	if (signr == 0) {
+		/* No signal to deliver -- put the saved sigmask back */
+		if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+			clear_thread_flag(TIF_RESTORE_SIGMASK);
+			sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+		}
 		return 0;		/* no signals delivered */
+	}
 
 	if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size
 	    && !on_sig_stack(regs->gpr[1]))
@@ -1253,6 +1211,10 @@ no_signal:
 			sigaddset(&current->blocked, signr);
 		recalc_sigpending();
 		spin_unlock_irq(&current->sighand->siglock);
+		/* A signal was successfully delivered; the saved sigmask is in
+		   its frame, and we can clear the TIF_RESTORE_SIGMASK flag */
+		if (test_thread_flag(TIF_RESTORE_SIGMASK))
+			clear_thread_flag(TIF_RESTORE_SIGMASK);
 	}
 
 	return ret;
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 7b9d999..b319311 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -67,42 +67,6 @@ struct rt_sigframe {
 	char abigap[288];
 } __attribute__ ((aligned (16)));
 
-
-/*
- * Atomically swap in the new signal mask, and wait for a signal.
- */
-long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, int p3, int p4,
-		       int p6, int p7, struct pt_regs *regs)
-{
-	sigset_t saveset, newset;
-
-	/* XXX: Don't preclude handling different sized sigset_t's.  */
-	if (sigsetsize != sizeof(sigset_t))
-		return -EINVAL;
-
-	if (copy_from_user(&newset, unewset, sizeof(newset)))
-		return -EFAULT;
-	sigdelsetmask(&newset, ~_BLOCKABLE);
-
-	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
-	current->blocked = newset;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-
-	regs->result = -EINTR;
-	regs->gpr[3] = EINTR;
-	regs->ccr |= 0x10000000;
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		if (do_signal(&saveset, regs)) {
-			set_thread_flag(TIF_RESTOREALL);
-			return 0;
-		}
-	}
-}
-
 long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, unsigned long r5,
 		     unsigned long r6, unsigned long r7, unsigned long r8,
 		     struct pt_regs *regs)
@@ -556,11 +520,15 @@ int do_signal(sigset_t *oldset, struct p
 	if (test_thread_flag(TIF_32BIT))
 		return do_signal32(oldset, regs);
 
-	if (!oldset)
+	if (test_thread_flag(TIF_RESTORE_SIGMASK))
+		oldset = &current->saved_sigmask;
+	else if (!oldset)
 		oldset = &current->blocked;
 
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 	if (signr > 0) {
+		int ret;
+
 		/* Whee!  Actually deliver the signal.  */
 		if (TRAP(regs) == 0x0C00)
 			syscall_restart(regs, &ka);
@@ -573,7 +541,14 @@ int do_signal(sigset_t *oldset, struct p
 		if (current->thread.dabr)
 			set_dabr(current->thread.dabr);
 
-		return handle_signal(signr, &ka, &info, oldset, regs);
+		ret = handle_signal(signr, &ka, &info, oldset, regs);
+
+		/* If a signal was successfully delivered, the saved sigmask is in
+		   its frame, and we can clear the TIF_RESTORE_SIGMASK flag */
+		if (ret && test_thread_flag(TIF_RESTORE_SIGMASK))
+			clear_thread_flag(TIF_RESTORE_SIGMASK);
+
+		return ret;
 	}
 
 	if (TRAP(regs) == 0x0C00) {	/* System Call! */
@@ -589,6 +564,11 @@ int do_signal(sigset_t *oldset, struct p
 			regs->result = 0;
 		}
 	}
+	/* No signal to deliver -- put the saved sigmask back */
+	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+		clear_thread_flag(TIF_RESTORE_SIGMASK);
+		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+	}
 
 	return 0;
 }
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S
index 6801317..007b15e 100644
--- a/arch/powerpc/kernel/systbl.S
+++ b/arch/powerpc/kernel/systbl.S
@@ -321,3 +321,5 @@ SYSCALL(inotify_add_watch)
 SYSCALL(inotify_rm_watch)
 SYSCALL(spu_run)
 SYSCALL(spu_create)
+COMPAT_SYS(pselect6)
+COMPAT_SYS(ppoll)
diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c
index c32c623..356a739 100644
--- a/arch/powerpc/platforms/powermac/pfunc_core.c
+++ b/arch/powerpc/platforms/powermac/pfunc_core.c
@@ -862,21 +862,28 @@ int pmf_register_irq_client(struct devic
 		spin_unlock_irqrestore(&pmf_lock, flags);
 		return -ENODEV;
 	}
+	if (list_empty(&func->irq_clients))
+		func->dev->handlers->irq_enable(func);
 	list_add(&client->link, &func->irq_clients);
+	client->func = func;
 	spin_unlock_irqrestore(&pmf_lock, flags);
 
 	return 0;
 }
 EXPORT_SYMBOL_GPL(pmf_register_irq_client);
 
-void pmf_unregister_irq_client(struct device_node *np,
-			      const char *name,
-			      struct pmf_irq_client *client)
+void pmf_unregister_irq_client(struct pmf_irq_client *client)
 {
+	struct pmf_function *func = client->func;
 	unsigned long flags;
 
+	BUG_ON(func == NULL);
+
 	spin_lock_irqsave(&pmf_lock, flags);
+	client->func = NULL;
 	list_del(&client->link);
+	if (list_empty(&func->irq_clients))
+		func->dev->handlers->irq_disable(func);
 	spin_unlock_irqrestore(&pmf_lock, flags);
 }
 EXPORT_SYMBOL_GPL(pmf_unregister_irq_client);
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index 2193478..bdaa8aa 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -58,6 +58,7 @@ pcibios_find_pci_bus(struct device_node 
 
 	return find_bus_among_children(pdn->phb->bus, dn);
 }
+EXPORT_SYMBOL_GPL(pcibios_find_pci_bus);
 
 /**
  * pcibios_remove_pci_devices - remove all devices under this bus
@@ -106,6 +107,7 @@ pcibios_fixup_new_pci_devices(struct pci
 		}
 	}
 }
+EXPORT_SYMBOL_GPL(pcibios_fixup_new_pci_devices);
 
 static int
 pcibios_pci_config_bridge(struct pci_dev *dev)
@@ -172,3 +174,4 @@ pcibios_add_pci_devices(struct pci_bus *
 			pcibios_pci_config_bridge(dev);
 	}
 }
+EXPORT_SYMBOL_GPL(pcibios_add_pci_devices);
diff --git a/arch/ppc/configs/bamboo_defconfig b/arch/ppc/configs/bamboo_defconfig
index 0ba4e70..41fd393 100644
--- a/arch/ppc/configs/bamboo_defconfig
+++ b/arch/ppc/configs/bamboo_defconfig
@@ -499,6 +499,7 @@ CONFIG_NATSEMI=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
 # CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/ppc/configs/katana_defconfig b/arch/ppc/configs/katana_defconfig
index 0f3bb9a..7311fe6 100644
--- a/arch/ppc/configs/katana_defconfig
+++ b/arch/ppc/configs/katana_defconfig
@@ -488,6 +488,7 @@ CONFIG_E100=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
 # CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/ppc/configs/mpc834x_sys_defconfig b/arch/ppc/configs/mpc834x_sys_defconfig
index 673dc64..b96a6d6 100644
--- a/arch/ppc/configs/mpc834x_sys_defconfig
+++ b/arch/ppc/configs/mpc834x_sys_defconfig
@@ -402,6 +402,7 @@ CONFIG_E100=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
 # CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/ppc/configs/power3_defconfig b/arch/ppc/configs/power3_defconfig
index 93da595..a1ef929 100644
--- a/arch/ppc/configs/power3_defconfig
+++ b/arch/ppc/configs/power3_defconfig
@@ -442,6 +442,7 @@ CONFIG_E100=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
 # CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c
index 94ea346..1f01b7e 100644
--- a/arch/ppc/syslib/mv64x60.c
+++ b/arch/ppc/syslib/mv64x60.c
@@ -313,7 +313,7 @@ static struct platform_device mpsc1_devi
 };
 #endif
 
-#ifdef CONFIG_MV643XX_ETH
+#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE)
 static struct resource mv64x60_eth_shared_resources[] = {
 	[0] = {
 		.name	= "ethernet shared base",
@@ -456,7 +456,7 @@ static struct platform_device *mv64x60_p
 	&mpsc0_device,
 	&mpsc1_device,
 #endif
-#ifdef CONFIG_MV643XX_ETH
+#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE)
 	&mv64x60_eth_shared_device,
 #endif
 #ifdef CONFIG_MV643XX_ETH_0
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index 7d23edc..3525c91 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -1,13 +1,12 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Mon Nov 21 13:51:30 2005
+# Linux kernel version: 2.6.16-rc1
+# Thu Jan 19 10:58:53 2006
 #
 CONFIG_MMU=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_S390=y
-CONFIG_UID16=y
 
 #
 # Code maturity level options
@@ -29,18 +28,20 @@ CONFIG_POSIX_MQUEUE=y
 CONFIG_SYSCTL=y
 CONFIG_AUDIT=y
 # CONFIG_AUDITSYSCALL is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 # CONFIG_CPUSETS is not set
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -49,8 +50,10 @@ CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -76,11 +79,11 @@ CONFIG_IOSCHED_NOOP=y
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_AS is not set
+CONFIG_DEFAULT_DEADLINE=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="deadline"
 
 #
 # Base setup
@@ -193,6 +196,11 @@ CONFIG_IPV6=y
 # SCTP Configuration (EXPERIMENTAL)
 #
 # CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_VLAN_8021Q is not set
@@ -362,6 +370,7 @@ CONFIG_DM_MULTIPATH=y
 #
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=2048
+# CONFIG_HANGCHECK_TIMER is not set
 
 #
 # Watchdog Cards
@@ -488,6 +497,7 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -520,6 +530,7 @@ CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -584,6 +595,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 
 #
@@ -592,7 +604,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_NLS is not set
 
 #
-# Profiling support
+# Instrumentation Support
 #
 # CONFIG_PROFILING is not set
 
@@ -600,19 +612,21 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=17
-CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_DETECT_SOFTLOCKUP is not set
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
-CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 
 #
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index fa2b3bc..ef70669 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -1,8 +1,7 @@
 /*
- *  arch/s390/kernel/signal32.c
+ *  arch/s390/kernel/compat_signal.c
  *
- *  S390 version
- *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Copyright (C) IBM Corp. 2000,2006
  *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
  *               Gerhard Tonn (ton@de.ibm.com)                  
  *
@@ -52,8 +51,6 @@ typedef struct 
 	struct ucontext32 uc;
 } rt_sigframe32;
 
-asmlinkage int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset));
-
 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
 {
 	int err;
@@ -161,66 +158,6 @@ int copy_siginfo_from_user32(siginfo_t *
 	return err;
 }
 
-/*
- * Atomically swap in the new signal mask, and wait for a signal.
- */
-asmlinkage int
-sys32_sigsuspend(struct pt_regs * regs,int history0, int history1, old_sigset_t mask)
-{
-	sigset_t saveset;
-
-	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
-	siginitset(&current->blocked, mask);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-	regs->gprs[2] = -EINTR;
-
-	while (1) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule();
-		if (do_signal(regs, &saveset))
-			return -EINTR;
-	}
-}
-
-asmlinkage int
-sys32_rt_sigsuspend(struct pt_regs * regs, compat_sigset_t __user *unewset,
-								size_t sigsetsize)
-{
-	sigset_t saveset, newset;
-	compat_sigset_t set32;
-
-	/* XXX: Don't preclude handling different sized sigset_t's.  */
-	if (sigsetsize != sizeof(sigset_t))
-		return -EINVAL;
-
-	if (copy_from_user(&set32, unewset, sizeof(set32)))
-		return -EFAULT;
-	switch (_NSIG_WORDS) {
-	case 4: newset.sig[3] = set32.sig[6] + (((long)set32.sig[7]) << 32);
-	case 3: newset.sig[2] = set32.sig[4] + (((long)set32.sig[5]) << 32);
-	case 2: newset.sig[1] = set32.sig[2] + (((long)set32.sig[3]) << 32);
-	case 1: newset.sig[0] = set32.sig[0] + (((long)set32.sig[1]) << 32);
-	}
-        sigdelsetmask(&newset, ~_BLOCKABLE);
-
-        spin_lock_irq(&current->sighand->siglock);
-        saveset = current->blocked;
-        current->blocked = newset;
-        recalc_sigpending();
-        spin_unlock_irq(&current->sighand->siglock);
-        regs->gprs[2] = -EINTR;
-
-        while (1) {
-                set_current_state(TASK_INTERRUPTIBLE);
-                schedule();
-                if (do_signal(regs, &saveset))
-                        return -EINTR;
-        }
-}
-
 asmlinkage long
 sys32_sigaction(int sig, const struct old_sigaction32 __user *act,
 		 struct old_sigaction32 __user *oact)
@@ -520,7 +457,7 @@ static inline int map_signal(int sig)
 		return sig;
 }
 
-static void setup_frame32(int sig, struct k_sigaction *ka,
+static int setup_frame32(int sig, struct k_sigaction *ka,
 			sigset_t *set, struct pt_regs * regs)
 {
 	sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(sigframe32));
@@ -565,13 +502,14 @@ static void setup_frame32(int sig, struc
 	/* Place signal number on stack to allow backtrace from handler.  */
 	if (__put_user(regs->gprs[2], (int __user *) &frame->signo))
 		goto give_sigsegv;
-	return;
+	return 0;
 
 give_sigsegv:
 	force_sigsegv(sig, current);
+	return -EFAULT;
 }
 
-static void setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
+static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
 			   sigset_t *set, struct pt_regs * regs)
 {
 	int err = 0;
@@ -615,31 +553,37 @@ static void setup_rt_frame32(int sig, st
 	regs->gprs[2] = map_signal(sig);
 	regs->gprs[3] = (__u64) &frame->info;
 	regs->gprs[4] = (__u64) &frame->uc;
-	return;
+	return 0;
 
 give_sigsegv:
 	force_sigsegv(sig, current);
+	return -EFAULT;
 }
 
 /*
  * OK, we're invoking a handler
  */	
 
-void
+int
 handle_signal32(unsigned long sig, struct k_sigaction *ka,
 		siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
 {
+	int ret;
+
 	/* Set up the stack frame */
 	if (ka->sa.sa_flags & SA_SIGINFO)
-		setup_rt_frame32(sig, ka, info, oldset, regs);
+		ret = setup_rt_frame32(sig, ka, info, oldset, regs);
 	else
-		setup_frame32(sig, ka, oldset, regs);
+		ret = setup_frame32(sig, ka, oldset, regs);
 
-	spin_lock_irq(&current->sighand->siglock);
-	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NODEFER))
-		sigaddset(&current->blocked,sig);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	if (ret == 0) {
+		spin_lock_irq(&current->sighand->siglock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		if (!(ka->sa.sa_flags & SA_NODEFER))
+			sigaddset(&current->blocked,sig);
+		recalc_sigpending();
+		spin_unlock_irq(&current->sighand->siglock);
+	}
+	return ret;
 }
 
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index cfde190..6e27ac6 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -1,9 +1,8 @@
 /*
-*  arch/s390/kernel/sys_wrapper31.S
+*  arch/s390/kernel/compat_wrapper.S
 *    wrapper for 31 bit compatible system calls.
 *
-*  S390 version
-*    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
+*    Copyright (C) IBM Corp. 2000,2006
 *    Author(s): Gerhard Tonn (ton@de.ibm.com),
 *               Thomas Spatzier (tspat@de.ibm.com)
 */ 
@@ -288,7 +287,12 @@ sys32_setregid16_wrapper:
 	llgfr	%r3,%r3			# __kernel_old_gid_emu31_t 
 	jg	sys32_setregid16	# branch to system call
 
-#sys32_sigsuspend_wrapper		# done in sigsuspend_glue 
+	.globl sys_sigsuspend_wrapper
+sys_sigsuspend_wrapper:
+	lgfr	%r2,%r2			# int
+	lgfr	%r3,%r3			# int
+	llgfr	%r4,%r4			# old_sigset_t
+	jg	sys_sigsuspend
 
 	.globl  compat_sys_sigpending_wrapper 
 compat_sys_sigpending_wrapper:
@@ -855,7 +859,11 @@ sys32_rt_sigqueueinfo_wrapper:
 	llgtr	%r4,%r4			# siginfo_emu31_t *
 	jg	sys32_rt_sigqueueinfo	# branch to system call
 
-#sys32_rt_sigsuspend_wrapper		# done in rt_sigsuspend_glue 
+	.globl compat_sys_rt_sigsuspend_wrapper
+compat_sys_rt_sigsuspend_wrapper:
+	llgtr	%r2,%r2			# compat_sigset_t *
+	llgfr	%r3,%r3			# compat_size_t
+	jg	compat_sys_rt_sigsuspend
 
 	.globl  sys32_pread64_wrapper 
 sys32_pread64_wrapper:
@@ -1475,3 +1483,122 @@ sys_inotify_rm_watch_wrapper:
 	lgfr	%r2,%r2			# int
 	llgfr	%r3,%r3			# u32
 	jg	sys_inotify_rm_watch
+
+	.globl compat_sys_openat_wrapper
+compat_sys_openat_wrapper:
+	lgfr	%r2,%r2			# int
+	llgtr	%r3,%r3			# const char *
+	lgfr	%r4,%r4			# int
+	lgfr	%r5,%r5			# int
+	jg	compat_sys_openat
+
+	.globl sys_mkdirat_wrapper
+sys_mkdirat_wrapper:
+	lgfr	%r2,%r2			# int
+	llgtr	%r3,%r3			# const char *
+	lgfr	%r4,%r4			# int
+	jg	sys_mkdirat
+
+	.globl sys_mknodat_wrapper
+sys_mknodat_wrapper:
+	lgfr	%r2,%r2			# int
+	llgtr	%r3,%r3			# const char *
+	lgfr	%r4,%r4			# int
+	llgfr	%r5,%r5			# unsigned int
+	jg	sys_mknodat
+
+	.globl sys_fchownat_wrapper
+sys_fchownat_wrapper:
+	lgfr	%r2,%r2			# int
+	llgtr	%r3,%r3			# const char *
+	llgfr	%r4,%r4			# uid_t
+	llgfr	%r5,%r5			# gid_t
+	lgfr	%r6,%r6			# int
+	jg	sys_fchownat
+
+	.globl compat_sys_futimesat_wrapper
+compat_sys_futimesat_wrapper:
+	lgfr	%r2,%r2			# int
+	llgtr	%r3,%r3			# char *
+	llgtr	%r4,%r4			# struct timeval *
+	jg	compat_sys_futimesat
+
+	.globl compat_sys_newfstatat_wrapper
+compat_sys_newfstatat_wrapper:
+	lgfr	%r2,%r2			# int
+	llgtr	%r3,%r3			# char *
+	llgtr	%r4,%r4			# struct stat *
+	lgfr	%r5,%r5			# int
+	jg	compat_sys_newfstatat
+
+	.globl sys_unlinkat_wrapper
+sys_unlinkat_wrapper:
+	lgfr	%r2,%r2			# int
+	llgtr	%r3,%r3			# const char *
+	lgfr	%r4,%r4			# int
+	jg	sys_unlinkat
+
+	.globl sys_renameat_wrapper
+sys_renameat_wrapper:
+	lgfr	%r2,%r2			# int
+	llgtr	%r3,%r3			# const char *
+	lgfr	%r4,%r4			# int
+	llgtr	%r5,%r5			# const char *
+	jg	sys_renameat
+
+	.globl sys_linkat_wrapper
+sys_linkat_wrapper:
+	lgfr	%r2,%r2			# int
+	llgtr	%r3,%r3			# const char *
+	lgfr	%r4,%r4			# int
+	llgtr	%r5,%r5			# const char *
+	jg	sys_linkat
+
+	.globl sys_symlinkat_wrapper
+sys_symlinkat_wrapper:
+	llgtr	%r2,%r2			# const char *
+	lgfr	%r3,%r3			# int
+	llgtr	%r4,%r4			# const char *
+	jg	sys_symlinkat
+
+	.globl sys_readlinkat_wrapper
+sys_readlinkat_wrapper:
+	lgfr	%r2,%r2			# int
+	llgtr	%r3,%r3			# const char *
+	llgtr	%r4,%r4			# char *
+	lgfr	%r5,%r5			# int
+	jg	sys_readlinkat
+
+	.globl sys_fchmodat_wrapper
+sys_fchmodat_wrapper:
+	lgfr	%r2,%r2			# int
+	llgtr	%r3,%r3			# const char *
+	llgfr	%r4,%r4			# mode_t
+	jg	sys_fchmodat
+
+	.globl sys_faccessat_wrapper
+sys_faccessat_wrapper:
+	lgfr	%r2,%r2			# int
+	llgtr	%r3,%r3			# const char *
+	lgfr	%r4,%r4			# int
+	jg	sys_faccessat
+
+	.globl compat_sys_pselect6_wrapper
+compat_sys_pselect6_wrapper:
+	lgfr	%r2,%r2			# int
+	llgtr	%r3,%r3			# fd_set *
+	llgtr	%r4,%r4			# fd_set *
+	llgtr	%r5,%r5			# fd_set *
+	llgtr	%r6,%r6			# struct timespec *
+	llgt	%r0,164(%r15)		# void *
+	stg	%r0,160(%r15)
+	jg	compat_sys_pselect6
+
+	.globl compat_sys_ppoll_wrapper
+compat_sys_ppoll_wrapper:
+	llgtr	%r2,%r2			# struct pollfd *
+	llgfr	%r3,%r3			# unsigned int
+	llgtr	%r4,%r4			# struct timespec *
+	llgtr	%r5,%r5			# const sigset_t *
+	llgfr	%r6,%r6			# size_t
+	jg	compat_sys_ppoll
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 27b0773..b244848 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -2,8 +2,7 @@
  *  arch/s390/kernel/entry.S
  *    S390 low-level entry points.
  *
- *  S390 version
- *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Copyright (C) IBM Corp. 1999,2006
  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
  *               Hartmut Penner (hp@de.ibm.com),
  *               Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
@@ -50,9 +49,10 @@ SP_ILC       =  STACK_FRAME_OVERHEAD + _
 SP_TRAP      =  STACK_FRAME_OVERHEAD + __PT_TRAP
 SP_SIZE      =  STACK_FRAME_OVERHEAD + __PT_SIZE
 
-_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING | \
-		 _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
-_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
+_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
+		 _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
+_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
+		 _TIF_MCCK_PENDING)
 
 STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
 STACK_SIZE  = 1 << STACK_SHIFT
@@ -251,8 +251,8 @@ sysc_work:
 	bo	BASED(sysc_mcck_pending)
 	tm	__TI_flags+3(%r9),_TIF_NEED_RESCHED
 	bo	BASED(sysc_reschedule)
-	tm	__TI_flags+3(%r9),_TIF_SIGPENDING
-	bo	BASED(sysc_sigpending)
+	tm	__TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)
+	bnz	BASED(sysc_sigpending)
 	tm	__TI_flags+3(%r9),_TIF_RESTART_SVC
 	bo	BASED(sysc_restart)
 	tm	__TI_flags+3(%r9),_TIF_SINGLE_STEP
@@ -276,12 +276,11 @@ sysc_mcck_pending:
 	br	%r1			# TIF bit will be cleared by handler
 
 #
-# _TIF_SIGPENDING is set, call do_signal
+# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal
 #
 sysc_sigpending:     
 	ni	__TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
         la      %r2,SP_PTREGS(%r15)    # load pt_regs
-        sr      %r3,%r3                # clear *oldset
         l       %r1,BASED(.Ldo_signal)
 	basr	%r14,%r1               # call do_signal
 	tm	__TI_flags+3(%r9),_TIF_RESTART_SVC
@@ -397,30 +396,6 @@ sys_rt_sigreturn_glue:     
         l       %r1,BASED(.Lrt_sigreturn)
         br      %r1                   # branch to sys_sigreturn
 
-#
-# sigsuspend and rt_sigsuspend need pt_regs as an additional
-# parameter and they have to skip the store of %r2 into the
-# user register %r2 because the return value was set in 
-# sigsuspend and rt_sigsuspend already and must not be overwritten!
-#
-
-sys_sigsuspend_glue:    
-        lr      %r5,%r4               # move mask back
-        lr      %r4,%r3               # move history1 parameter
-        lr      %r3,%r2               # move history0 parameter
-        la      %r2,SP_PTREGS(%r15)   # load pt_regs as first parameter
-        l       %r1,BASED(.Lsigsuspend)
-	la      %r14,4(%r14)          # skip store of return value
-        br      %r1                   # branch to sys_sigsuspend
-
-sys_rt_sigsuspend_glue: 
-        lr      %r4,%r3               # move sigsetsize parameter
-        lr      %r3,%r2               # move unewset parameter
-        la      %r2,SP_PTREGS(%r15)   # load pt_regs as first parameter
-        l       %r1,BASED(.Lrt_sigsuspend)
-	la      %r14,4(%r14)          # skip store of return value
-        br      %r1                   # branch to sys_rt_sigsuspend
-
 sys_sigaltstack_glue:
         la      %r4,SP_PTREGS(%r15)   # load pt_regs as parameter
         l       %r1,BASED(.Lsigaltstack)
@@ -604,15 +579,16 @@ io_work:
 	lr	%r15,%r1
 #
 # One of the work bits is on. Find out which one.
-# Checked are: _TIF_SIGPENDING, _TIF_NEED_RESCHED and _TIF_MCCK_PENDING
+# Checked are: _TIF_SIGPENDING, _TIF_RESTORE_SIGMASK, _TIF_NEED_RESCHED
+#	        and _TIF_MCCK_PENDING
 #
 io_work_loop:
 	tm	__TI_flags+3(%r9),_TIF_MCCK_PENDING
 	bo      BASED(io_mcck_pending)
 	tm	__TI_flags+3(%r9),_TIF_NEED_RESCHED
 	bo	BASED(io_reschedule)
-	tm	__TI_flags+3(%r9),_TIF_SIGPENDING
-	bo	BASED(io_sigpending)
+	tm	__TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)
+	bnz	BASED(io_sigpending)
 	b	BASED(io_leave)
 
 #
@@ -636,12 +612,11 @@ io_reschedule:        
 	b	BASED(io_work_loop)
 
 #
-# _TIF_SIGPENDING is set, call do_signal
+# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal
 #
 io_sigpending:     
         stosm   __SF_EMPTY(%r15),0x03  # reenable interrupts
         la      %r2,SP_PTREGS(%r15)    # load pt_regs
-        sr      %r3,%r3                # clear *oldset
         l       %r1,BASED(.Ldo_signal)
 	basr    %r14,%r1	       # call do_signal
         stnsm   __SF_EMPTY(%r15),0xfc  # disable I/O and ext. interrupts
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 369ab44..2ac095b 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -1,9 +1,8 @@
 /*
- *  arch/s390/kernel/entry.S
+ *  arch/s390/kernel/entry64.S
  *    S390 low-level entry points.
  *
- *  S390 version
- *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Copyright (C) IBM Corp. 1999,2006
  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
  *               Hartmut Penner (hp@de.ibm.com),
  *               Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
@@ -53,9 +52,10 @@ SP_SIZE      =  STACK_FRAME_OVERHEAD + _
 STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
 STACK_SIZE  = 1 << STACK_SHIFT
 
-_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING | \
-		 _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
-_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
+_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
+		 _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
+_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
+		 _TIF_MCCK_PENDING)
 
 #define BASED(name) name-system_call(%r13)
 
@@ -249,8 +249,8 @@ sysc_work:
 	jo	sysc_mcck_pending
 	tm	__TI_flags+7(%r9),_TIF_NEED_RESCHED
 	jo	sysc_reschedule
-	tm	__TI_flags+7(%r9),_TIF_SIGPENDING
-	jo	sysc_sigpending
+	tm	__TI_flags+7(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)
+	jnz	sysc_sigpending
 	tm	__TI_flags+7(%r9),_TIF_RESTART_SVC
 	jo	sysc_restart
 	tm	__TI_flags+7(%r9),_TIF_SINGLE_STEP
@@ -272,12 +272,11 @@ sysc_mcck_pending:
 	jg	s390_handle_mcck    # TIF bit will be cleared by handler
 
 #
-# _TIF_SIGPENDING is set, call do_signal
+# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal
 #
 sysc_sigpending:     
 	ni	__TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
         la      %r2,SP_PTREGS(%r15) # load pt_regs
-        sgr     %r3,%r3           # clear *oldset
 	brasl	%r14,do_signal    # call do_signal
 	tm	__TI_flags+7(%r9),_TIF_RESTART_SVC
 	jo	sysc_restart
@@ -414,52 +413,6 @@ sys32_rt_sigreturn_glue:     
         jg      sys32_rt_sigreturn    # branch to sys32_sigreturn
 #endif
 
-#
-# sigsuspend and rt_sigsuspend need pt_regs as an additional
-# parameter and they have to skip the store of %r2 into the
-# user register %r2 because the return value was set in 
-# sigsuspend and rt_sigsuspend already and must not be overwritten!
-#
-
-sys_sigsuspend_glue:    
-        lgr     %r5,%r4               # move mask back
-        lgr     %r4,%r3               # move history1 parameter
-        lgr     %r3,%r2               # move history0 parameter
-        la      %r2,SP_PTREGS(%r15)   # load pt_regs as first parameter
-	la      %r14,6(%r14)          # skip store of return value
-        jg      sys_sigsuspend        # branch to sys_sigsuspend
-
-#ifdef CONFIG_COMPAT
-sys32_sigsuspend_glue:    
-	llgfr	%r4,%r4               # unsigned long			
-        lgr     %r5,%r4               # move mask back
-	lgfr	%r3,%r3               # int			
-        lgr     %r4,%r3               # move history1 parameter
-	lgfr	%r2,%r2               # int			
-        lgr     %r3,%r2               # move history0 parameter
-        la      %r2,SP_PTREGS(%r15)   # load pt_regs as first parameter
-	la      %r14,6(%r14)          # skip store of return value
-        jg      sys32_sigsuspend      # branch to sys32_sigsuspend
-#endif
-
-sys_rt_sigsuspend_glue: 
-        lgr     %r4,%r3               # move sigsetsize parameter
-        lgr     %r3,%r2               # move unewset parameter
-        la      %r2,SP_PTREGS(%r15)   # load pt_regs as first parameter
-	la      %r14,6(%r14)          # skip store of return value
-        jg      sys_rt_sigsuspend     # branch to sys_rt_sigsuspend
-
-#ifdef CONFIG_COMPAT
-sys32_rt_sigsuspend_glue: 
-	llgfr	%r3,%r3               # size_t			
-        lgr     %r4,%r3               # move sigsetsize parameter
-	llgtr	%r2,%r2               # sigset_emu31_t *
-        lgr     %r3,%r2               # move unewset parameter
-        la      %r2,SP_PTREGS(%r15)   # load pt_regs as first parameter
-	la      %r14,6(%r14)          # skip store of return value
-        jg      sys32_rt_sigsuspend   # branch to sys32_rt_sigsuspend
-#endif
-
 sys_sigaltstack_glue:
         la      %r4,SP_PTREGS(%r15)   # load pt_regs as parameter
         jg      sys_sigaltstack       # branch to sys_sigreturn
@@ -646,15 +599,16 @@ io_work:
 	lgr	%r15,%r1
 #
 # One of the work bits is on. Find out which one.
-# Checked are: _TIF_SIGPENDING, _TIF_NEED_RESCHED and _TIF_MCCK_PENDING
+# Checked are: _TIF_SIGPENDING, _TIF_RESTORE_SIGPENDING, _TIF_NEED_RESCHED
+#	       and _TIF_MCCK_PENDING
 #
 io_work_loop:
 	tm	__TI_flags+7(%r9),_TIF_MCCK_PENDING
 	jo	io_mcck_pending
 	tm	__TI_flags+7(%r9),_TIF_NEED_RESCHED
 	jo	io_reschedule
-	tm	__TI_flags+7(%r9),_TIF_SIGPENDING
-	jo	io_sigpending
+	tm	__TI_flags+7(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)
+	jnz	io_sigpending
 	j	io_leave
 
 #
@@ -676,12 +630,11 @@ io_reschedule:        
 	j	io_work_loop
 
 #
-# _TIF_SIGPENDING is set, call do_signal
+# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal
 #
 io_sigpending:     
 	stosm   __SF_EMPTY(%r15),0x03	# reenable interrupts
 	la      %r2,SP_PTREGS(%r15)	# load pt_regs
-	slgr    %r3,%r3			# clear *oldset
 	brasl	%r14,do_signal		# call do_signal
 	stnsm   __SF_EMPTY(%r15),0xfc	# disable I/O and ext. interrupts
 	j	io_work_loop
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 6ae4a77..ae1927e 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -1,8 +1,7 @@
 /*
  *  arch/s390/kernel/signal.c
  *
- *  S390 version
- *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Copyright (C) IBM Corp. 1999,2006
  *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
  *
  *    Based on Intel version
@@ -51,60 +50,24 @@ typedef struct 
 	struct ucontext uc;
 } rt_sigframe;
 
-int do_signal(struct pt_regs *regs, sigset_t *oldset);
-
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
 asmlinkage int
-sys_sigsuspend(struct pt_regs * regs, int history0, int history1,
-	       old_sigset_t mask)
+sys_sigsuspend(int history0, int history1, old_sigset_t mask)
 {
-	sigset_t saveset;
-
 	mask &= _BLOCKABLE;
 	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
+	current->saved_sigmask = current->blocked;
 	siginitset(&current->blocked, mask);
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
-	regs->gprs[2] = -EINTR;
-
-	while (1) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule();
-		if (do_signal(regs, &saveset))
-			return -EINTR;
-	}
-}
-
-asmlinkage long
-sys_rt_sigsuspend(struct pt_regs *regs, sigset_t __user *unewset,
-						size_t sigsetsize)
-{
-	sigset_t saveset, newset;
 
-	/* XXX: Don't preclude handling different sized sigset_t's.  */
-	if (sigsetsize != sizeof(sigset_t))
-		return -EINVAL;
-
-	if (copy_from_user(&newset, unewset, sizeof(newset)))
-		return -EFAULT;
-	sigdelsetmask(&newset, ~_BLOCKABLE);
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	set_thread_flag(TIF_RESTORE_SIGMASK);
 
-	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
-	current->blocked = newset;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-	regs->gprs[2] = -EINTR;
-
-	while (1) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule();
-		if (do_signal(regs, &saveset))
-			return -EINTR;
-	}
+	return -ERESTARTNOHAND;
 }
 
 asmlinkage long
@@ -306,8 +269,8 @@ static inline int map_signal(int sig)
 		return sig;
 }
 
-static void setup_frame(int sig, struct k_sigaction *ka,
-			sigset_t *set, struct pt_regs * regs)
+static int setup_frame(int sig, struct k_sigaction *ka,
+		       sigset_t *set, struct pt_regs * regs)
 {
 	sigframe __user *frame;
 
@@ -355,13 +318,14 @@ static void setup_frame(int sig, struct 
 	/* Place signal number on stack to allow backtrace from handler.  */
 	if (__put_user(regs->gprs[2], (int __user *) &frame->signo))
 		goto give_sigsegv;
-	return;
+	return 0;
 
 give_sigsegv:
 	force_sigsegv(sig, current);
+	return -EFAULT;
 }
 
-static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 			   sigset_t *set, struct pt_regs * regs)
 {
 	int err = 0;
@@ -409,32 +373,39 @@ static void setup_rt_frame(int sig, stru
 	regs->gprs[2] = map_signal(sig);
 	regs->gprs[3] = (unsigned long) &frame->info;
 	regs->gprs[4] = (unsigned long) &frame->uc;
-	return;
+	return 0;
 
 give_sigsegv:
 	force_sigsegv(sig, current);
+	return -EFAULT;
 }
 
 /*
  * OK, we're invoking a handler
  */	
 
-static void
+static int
 handle_signal(unsigned long sig, struct k_sigaction *ka,
 	      siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
 {
+	int ret;
+
 	/* Set up the stack frame */
 	if (ka->sa.sa_flags & SA_SIGINFO)
-		setup_rt_frame(sig, ka, info, oldset, regs);
+		ret = setup_rt_frame(sig, ka, info, oldset, regs);
 	else
-		setup_frame(sig, ka, oldset, regs);
+		ret = setup_frame(sig, ka, oldset, regs);
 
-	spin_lock_irq(&current->sighand->siglock);
-	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NODEFER))
-		sigaddset(&current->blocked,sig);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	if (ret == 0) {
+		spin_lock_irq(&current->sighand->siglock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		if (!(ka->sa.sa_flags & SA_NODEFER))
+			sigaddset(&current->blocked,sig);
+		recalc_sigpending();
+		spin_unlock_irq(&current->sighand->siglock);
+	}
+
+	return ret;
 }
 
 /*
@@ -446,12 +417,13 @@ handle_signal(unsigned long sig, struct 
  * the kernel can handle, and then we build all the user-level signal handling
  * stack-frames in one go after that.
  */
-int do_signal(struct pt_regs *regs, sigset_t *oldset)
+void do_signal(struct pt_regs *regs)
 {
 	unsigned long retval = 0, continue_addr = 0, restart_addr = 0;
 	siginfo_t info;
 	int signr;
 	struct k_sigaction ka;
+	sigset_t *oldset;
 
 	/*
 	 * We want the common case to go fast, which
@@ -460,9 +432,11 @@ int do_signal(struct pt_regs *regs, sigs
 	 * if so.
 	 */
 	if (!user_mode(regs))
-		return 1;
+		return;
 
-	if (!oldset)
+	if (test_thread_flag(TIF_RESTORE_SIGMASK))
+		oldset = &current->saved_sigmask;
+	else
 		oldset = &current->blocked;
 
 	/* Are we from a system call? */
@@ -473,12 +447,14 @@ int do_signal(struct pt_regs *regs, sigs
 
 		/* Prepare for system call restart.  We do this here so that a
 		   debugger will see the already changed PSW. */
-		if (retval == -ERESTARTNOHAND ||
-		    retval == -ERESTARTSYS ||
-		    retval == -ERESTARTNOINTR) {
+		switch (retval) {
+		case -ERESTARTNOHAND:
+		case -ERESTARTSYS:
+		case -ERESTARTNOINTR:
 			regs->gprs[2] = regs->orig_gpr2;
 			regs->psw.addr = restart_addr;
-		} else if (retval == -ERESTART_RESTARTBLOCK) {
+			break;
+		case -ERESTART_RESTARTBLOCK:
 			regs->gprs[2] = -EINTR;
 		}
 	}
@@ -503,17 +479,38 @@ int do_signal(struct pt_regs *regs, sigs
 		/* Whee!  Actually deliver the signal.  */
 #ifdef CONFIG_COMPAT
 		if (test_thread_flag(TIF_31BIT)) {
-			extern void handle_signal32(unsigned long sig,
-						    struct k_sigaction *ka,
-						    siginfo_t *info,
-						    sigset_t *oldset,
-						    struct pt_regs *regs);
-			handle_signal32(signr, &ka, &info, oldset, regs);
-			return 1;
+			extern int handle_signal32(unsigned long sig,
+						   struct k_sigaction *ka,
+						   siginfo_t *info,
+						   sigset_t *oldset,
+						   struct pt_regs *regs);
+			if (handle_signal32(
+				    signr, &ka, &info, oldset, regs) == 0) {
+				if (test_thread_flag(TIF_RESTORE_SIGMASK))
+					clear_thread_flag(TIF_RESTORE_SIGMASK);
+			}
+			return;
 	        }
 #endif
-		handle_signal(signr, &ka, &info, oldset, regs);
-		return 1;
+		if (handle_signal(signr, &ka, &info, oldset, regs) == 0) {
+			/*
+			 * A signal was successfully delivered; the saved
+			 * sigmask will have been stored in the signal frame,
+			 * and will be restored by sigreturn, so we can simply
+			 * clear the TIF_RESTORE_SIGMASK flag.
+			 */
+			if (test_thread_flag(TIF_RESTORE_SIGMASK))
+				clear_thread_flag(TIF_RESTORE_SIGMASK);
+		}
+		return;
+	}
+
+	/*
+	 * If there's no signal to deliver, we just put the saved sigmask back.
+	 */
+	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+		clear_thread_flag(TIF_RESTORE_SIGMASK);
+		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
 	}
 
 	/* Restart a different system call. */
@@ -522,5 +519,4 @@ int do_signal(struct pt_regs *regs, sigs
 		regs->gprs[2] = __NR_restart_syscall;
 		set_thread_flag(TIF_RESTART_SVC);
 	}
-	return 0;
 }
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
index 426d7ca..3280345 100644
--- a/arch/s390/kernel/syscalls.S
+++ b/arch/s390/kernel/syscalls.S
@@ -80,7 +80,7 @@ NI_SYSCALL							/* old sgetmask syscall
 NI_SYSCALL							/* old ssetmask syscall*/
 SYSCALL(sys_setreuid16,sys_ni_syscall,sys32_setreuid16_wrapper)	/* old setreuid16 syscall */
 SYSCALL(sys_setregid16,sys_ni_syscall,sys32_setregid16_wrapper)	/* old setregid16 syscall */
-SYSCALL(sys_sigsuspend_glue,sys_sigsuspend_glue,sys32_sigsuspend_glue)
+SYSCALL(sys_sigsuspend,sys_sigsuspend,sys_sigsuspend_wrapper)
 SYSCALL(sys_sigpending,sys_sigpending,compat_sys_sigpending_wrapper)
 SYSCALL(sys_sethostname,sys_sethostname,sys32_sethostname_wrapper)
 SYSCALL(sys_setrlimit,sys_setrlimit,compat_sys_setrlimit_wrapper)	/* 75 */
@@ -187,7 +187,7 @@ SYSCALL(sys_rt_sigprocmask,sys_rt_sigpro
 SYSCALL(sys_rt_sigpending,sys_rt_sigpending,sys32_rt_sigpending_wrapper)
 SYSCALL(sys_rt_sigtimedwait,sys_rt_sigtimedwait,compat_sys_rt_sigtimedwait_wrapper)
 SYSCALL(sys_rt_sigqueueinfo,sys_rt_sigqueueinfo,sys32_rt_sigqueueinfo_wrapper)
-SYSCALL(sys_rt_sigsuspend_glue,sys_rt_sigsuspend_glue,sys32_rt_sigsuspend_glue)
+SYSCALL(sys_rt_sigsuspend,sys_rt_sigsuspend,compat_sys_rt_sigsuspend_wrapper)
 SYSCALL(sys_pread64,sys_pread64,sys32_pread64_wrapper)		/* 180 */
 SYSCALL(sys_pwrite64,sys_pwrite64,sys32_pwrite64_wrapper)
 SYSCALL(sys_chown16,sys_ni_syscall,sys32_chown16_wrapper)	/* old chown16 syscall */
@@ -293,5 +293,21 @@ SYSCALL(sys_waitid,sys_waitid,compat_sys
 SYSCALL(sys_ioprio_set,sys_ioprio_set,sys_ioprio_set_wrapper)
 SYSCALL(sys_ioprio_get,sys_ioprio_get,sys_ioprio_get_wrapper)
 SYSCALL(sys_inotify_init,sys_inotify_init,sys_inotify_init)
-SYSCALL(sys_inotify_add_watch,sys_inotify_add_watch,sys_inotify_add_watch_wrapper)
+SYSCALL(sys_inotify_add_watch,sys_inotify_add_watch,sys_inotify_add_watch_wrapper)	/* 285 */
 SYSCALL(sys_inotify_rm_watch,sys_inotify_rm_watch,sys_inotify_rm_watch_wrapper)
+NI_SYSCALL							/* 287 sys_migrate_pages */
+SYSCALL(sys_openat,sys_openat,compat_sys_openat_wrapper)
+SYSCALL(sys_mkdirat,sys_mkdirat,sys_mkdirat_wrapper)
+SYSCALL(sys_mknodat,sys_mknodat,sys_mknodat_wrapper)	/* 290 */
+SYSCALL(sys_fchownat,sys_fchownat,sys_fchownat_wrapper)
+SYSCALL(sys_futimesat,sys_futimesat,compat_sys_futimesat_wrapper)
+SYSCALL(sys_newfstatat,sys_newfstatat,compat_sys_newfstatat_wrapper)
+SYSCALL(sys_unlinkat,sys_unlinkat,sys_unlinkat_wrapper)
+SYSCALL(sys_renameat,sys_renameat,sys_renameat_wrapper)	/* 295 */
+SYSCALL(sys_linkat,sys_linkat,sys_linkat_wrapper)
+SYSCALL(sys_symlinkat,sys_symlinkat,sys_symlinkat_wrapper)
+SYSCALL(sys_readlinkat,sys_readlinkat,sys_readlinkat_wrapper)
+SYSCALL(sys_fchmodat,sys_fchmodat,sys_fchmodat_wrapper)
+SYSCALL(sys_faccessat,sys_faccessat,sys_faccessat_wrapper)	/* 300 */
+SYSCALL(sys_pselect6,sys_pselect6,compat_sys_pselect6_wrapper)
+SYSCALL(sys_ppoll,sys_ppoll,compat_sys_ppoll_wrapper)
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 7c0fe15..fea043b 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -61,9 +61,18 @@ extern unsigned long wall_jiffies;
  */
 unsigned long long sched_clock(void)
 {
-	return ((get_clock() - jiffies_timer_cc) * 1000) >> 12;
+	return ((get_clock() - jiffies_timer_cc) * 125) >> 9;
 }
 
+/*
+ * Monotonic_clock - returns # of nanoseconds passed since time_init()
+ */
+unsigned long long monotonic_clock(void)
+{
+	return sched_clock();
+}
+EXPORT_SYMBOL(monotonic_clock);
+
 void tod_to_timeval(__u64 todval, struct timespec *xtime)
 {
 	unsigned long long sec;
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
index f20b51f..e05d087 100644
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -6,4 +6,4 @@ EXTRA_AFLAGS := -traditional
 
 lib-y += delay.o string.o
 lib-y += $(if $(CONFIG_64BIT),uaccess64.o,uaccess.o)
-lib-$(CONFIG_SMP) += spinlock.o
\ No newline at end of file
+lib-$(CONFIG_SMP) += spinlock.o
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 01bc7d5..504d56f 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -396,14 +396,8 @@ source "arch/sh/boards/renesas/hs7751rvo
 
 source "arch/sh/boards/renesas/rts7751r2d/Kconfig"
 
-config SH_PCLK_FREQ_BOOL
-	bool "Set default pclk frequency"
-	default y if !SH_RTC
-	default n
-
 config SH_PCLK_FREQ
 	int "Peripheral clock frequency (in Hz)"
-	depends on SH_PCLK_FREQ_BOOL
 	default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780
 	default "60000000" if CPU_SUBTYPE_SH7751
 	default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || CPU_SUBTYPE_SH7760
diff --git a/arch/sh/boards/superh/microdev/io.c b/arch/sh/boards/superh/microdev/io.c
index fe83b2c..1ed7f88 100644
--- a/arch/sh/boards/superh/microdev/io.c
+++ b/arch/sh/boards/superh/microdev/io.c
@@ -16,7 +16,7 @@
 #include <linux/pci.h>
 #include <linux/wait.h>
 #include <asm/io.h>
-#include <asm/mach/io.h>
+#include <asm/microdev.h>
 
 	/*
 	 *	we need to have a 'safe' address to re-direct all I/O requests
@@ -52,8 +52,90 @@
 #define	IO_ISP1161_PHYS		0xa7700000ul	/* Physical address of Philips ISP1161x USB chip */
 #define	IO_SUPERIO_PHYS		0xa7800000ul	/* Physical address of SMSC FDC37C93xAPM SuperIO chip */
 
-#define PORT2ADDR(x) (microdev_isa_port2addr(x))
+/*
+ * map I/O ports to memory-mapped addresses
+ */
+static unsigned long microdev_isa_port2addr(unsigned long offset)
+{
+	unsigned long result;
+
+	if ((offset >= IO_LAN91C111_BASE) &&
+	    (offset <  IO_LAN91C111_BASE + IO_LAN91C111_EXTENT)) {
+			/*
+			 *	SMSC LAN91C111 Ethernet chip
+			 */
+		result = IO_LAN91C111_PHYS + offset - IO_LAN91C111_BASE;
+	} else if ((offset >= IO_SUPERIO_BASE) &&
+		   (offset <  IO_SUPERIO_BASE + IO_SUPERIO_EXTENT)) {
+			/*
+			 *	SMSC FDC37C93xAPM SuperIO chip
+			 *
+			 *	Configuration Registers
+			 */
+		result = IO_SUPERIO_PHYS + (offset << 1);
+#if 0
+	} else if (offset == KBD_DATA_REG || offset == KBD_CNTL_REG ||
+		   offset == KBD_STATUS_REG) {
+			/*
+			 *	SMSC FDC37C93xAPM SuperIO chip
+			 *
+			 *	PS/2 Keyboard + Mouse (ports 0x60 and 0x64).
+			 */
+	        result = IO_SUPERIO_PHYS + (offset << 1);
+#endif
+	} else if (((offset >= IO_IDE1_BASE) &&
+		    (offset <  IO_IDE1_BASE + IO_IDE_EXTENT)) ||
+		    (offset == IO_IDE1_MISC)) {
+			/*
+			 *	SMSC FDC37C93xAPM SuperIO chip
+			 *
+			 *	IDE #1
+			 */
+	        result = IO_SUPERIO_PHYS + (offset << 1);
+	} else if (((offset >= IO_IDE2_BASE) &&
+		    (offset <  IO_IDE2_BASE + IO_IDE_EXTENT)) ||
+		    (offset == IO_IDE2_MISC)) {
+			/*
+			 *	SMSC FDC37C93xAPM SuperIO chip
+			 *
+			 *	IDE #2
+			 */
+	        result = IO_SUPERIO_PHYS + (offset << 1);
+	} else if ((offset >= IO_SERIAL1_BASE) &&
+		   (offset <  IO_SERIAL1_BASE + IO_SERIAL_EXTENT)) {
+			/*
+			 *	SMSC FDC37C93xAPM SuperIO chip
+			 *
+			 *	Serial #1
+			 */
+		result = IO_SUPERIO_PHYS + (offset << 1);
+	} else if ((offset >= IO_SERIAL2_BASE) &&
+		   (offset <  IO_SERIAL2_BASE + IO_SERIAL_EXTENT)) {
+			/*
+			 *	SMSC FDC37C93xAPM SuperIO chip
+			 *
+			 *	Serial #2
+			 */
+		result = IO_SUPERIO_PHYS + (offset << 1);
+	} else if ((offset >= IO_ISP1161_BASE) &&
+		   (offset < IO_ISP1161_BASE + IO_ISP1161_EXTENT)) {
+			/*
+			 *	Philips USB ISP1161x chip
+			 */
+		result = IO_ISP1161_PHYS + offset - IO_ISP1161_BASE;
+	} else {
+			/*
+			 *	safe default.
+			 */
+		printk("Warning: unexpected port in %s( offset = 0x%lx )\n",
+		       __FUNCTION__, offset);
+		result = PVR;
+	}
+
+	return result;
+}
 
+#define PORT2ADDR(x) (microdev_isa_port2addr(x))
 
 static inline void delay(void)
 {
@@ -94,6 +176,17 @@ unsigned int microdev_inl(unsigned long 
 	return *(volatile unsigned int*)PORT2ADDR(port);
 }
 
+void microdev_outw(unsigned short b, unsigned long port)
+{
+#ifdef CONFIG_PCI
+	if (port >= PCIBIOS_MIN_IO) {
+		microdev_pci_outw(b, port);
+		return;
+	}
+#endif
+	*(volatile unsigned short*)PORT2ADDR(port) = b;
+}
+
 void microdev_outb(unsigned char b, unsigned long port)
 {
 #ifdef CONFIG_PCI
@@ -158,17 +251,6 @@ void microdev_outb(unsigned char b, unsi
 	}
 }
 
-void microdev_outw(unsigned short b, unsigned long port)
-{
-#ifdef CONFIG_PCI
-	if (port >= PCIBIOS_MIN_IO) {
-		microdev_pci_outw(b, port);
-		return;
-	}
-#endif
-	*(volatile unsigned short*)PORT2ADDR(port) = b;
-}
-
 void microdev_outl(unsigned int b, unsigned long port)
 {
 #ifdef CONFIG_PCI
@@ -284,87 +366,3 @@ void microdev_outsl(unsigned long port, 
 	while (count--)
 		*port_addr = *buf++;
 }
-
-/*
- * map I/O ports to memory-mapped addresses
- */
-unsigned long microdev_isa_port2addr(unsigned long offset)
-{
-	unsigned long result;
-
-	if ((offset >= IO_LAN91C111_BASE) &&
-	    (offset <  IO_LAN91C111_BASE + IO_LAN91C111_EXTENT)) {
-			/*
-			 *	SMSC LAN91C111 Ethernet chip
-			 */
-		result = IO_LAN91C111_PHYS + offset - IO_LAN91C111_BASE;
-	} else if ((offset >= IO_SUPERIO_BASE) &&
-		   (offset <  IO_SUPERIO_BASE + IO_SUPERIO_EXTENT)) {
-			/*
-			 *	SMSC FDC37C93xAPM SuperIO chip
-			 *
-			 *	Configuration Registers
-			 */
-		result = IO_SUPERIO_PHYS + (offset << 1);
-#if 0
-	} else if (offset == KBD_DATA_REG || offset == KBD_CNTL_REG ||
-		   offset == KBD_STATUS_REG) {
-			/*
-			 *	SMSC FDC37C93xAPM SuperIO chip
-			 *
-			 *	PS/2 Keyboard + Mouse (ports 0x60 and 0x64).
-			 */
-	        result = IO_SUPERIO_PHYS + (offset << 1);
-#endif
-	} else if (((offset >= IO_IDE1_BASE) &&
-		    (offset <  IO_IDE1_BASE + IO_IDE_EXTENT)) ||
-		    (offset == IO_IDE1_MISC)) {
-			/*
-			 *	SMSC FDC37C93xAPM SuperIO chip
-			 *
-			 *	IDE #1
-			 */
-	        result = IO_SUPERIO_PHYS + (offset << 1);
-	} else if (((offset >= IO_IDE2_BASE) &&
-		    (offset <  IO_IDE2_BASE + IO_IDE_EXTENT)) ||
-		    (offset == IO_IDE2_MISC)) {
-			/*
-			 *	SMSC FDC37C93xAPM SuperIO chip
-			 *
-			 *	IDE #2
-			 */
-	        result = IO_SUPERIO_PHYS + (offset << 1);
-	} else if ((offset >= IO_SERIAL1_BASE) &&
-		   (offset <  IO_SERIAL1_BASE + IO_SERIAL_EXTENT)) {
-			/*
-			 *	SMSC FDC37C93xAPM SuperIO chip
-			 *
-			 *	Serial #1
-			 */
-		result = IO_SUPERIO_PHYS + (offset << 1);
-	} else if ((offset >= IO_SERIAL2_BASE) &&
-		   (offset <  IO_SERIAL2_BASE + IO_SERIAL_EXTENT)) {
-			/*
-			 *	SMSC FDC37C93xAPM SuperIO chip
-			 *
-			 *	Serial #2
-			 */
-		result = IO_SUPERIO_PHYS + (offset << 1);
-	} else if ((offset >= IO_ISP1161_BASE) &&
-		   (offset < IO_ISP1161_BASE + IO_ISP1161_EXTENT)) {
-			/*
-			 *	Philips USB ISP1161x chip
-			 */
-		result = IO_ISP1161_PHYS + offset - IO_ISP1161_BASE;
-	} else {
-			/*
-			 *	safe default.
-			 */
-		printk("Warning: unexpected port in %s( offset = 0x%lx )\n",
-		       __FUNCTION__, offset);
-		result = PVR;
-	}
-
-	return result;
-}
-
diff --git a/arch/sh/boards/superh/microdev/irq.c b/arch/sh/boards/superh/microdev/irq.c
index 1395c1e..efcbd86 100644
--- a/arch/sh/boards/superh/microdev/irq.c
+++ b/arch/sh/boards/superh/microdev/irq.c
@@ -15,7 +15,7 @@
 
 #include <asm/system.h>
 #include <asm/io.h>
-#include <asm/mach/irq.h>
+#include <asm/microdev.h>
 
 #define NUM_EXTERNAL_IRQS 16	/* IRL0 .. IRL15 */
 
diff --git a/arch/sh/boards/superh/microdev/setup.c b/arch/sh/boards/superh/microdev/setup.c
index 1c1d65f..892b14d 100644
--- a/arch/sh/boards/superh/microdev/setup.c
+++ b/arch/sh/boards/superh/microdev/setup.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
  * Copyright (C) 2003, 2004 SuperH, Inc.
- * Copyright (C) 2004 Paul Mundt
+ * Copyright (C) 2004, 2005 Paul Mundt
  *
  * SuperH SH4-202 MicroDev board support.
  *
@@ -15,11 +15,10 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/ioport.h>
+#include <video/s1d13xxxfb.h>
+#include <asm/microdev.h>
 #include <asm/io.h>
-#include <asm/mach/irq.h>
-#include <asm/mach/io.h>
 #include <asm/machvec.h>
-#include <asm/machvec_init.h>
 
 extern void microdev_heartbeat(void);
 
@@ -51,8 +50,6 @@ struct sh_machine_vector mv_sh4202_micro
 	.mv_outsw		= microdev_outsw,
 	.mv_outsl		= microdev_outsl,
 
-	.mv_isa_port2addr	= microdev_isa_port2addr,
-
 	.mv_init_irq		= init_microdev_irq,
 
 #ifdef CONFIG_HEARTBEAT
@@ -142,16 +139,161 @@ static struct platform_device smc91x_dev
 	.resource	= smc91x_resources,
 };
 
-static int __init smc91x_setup(void)
+#ifdef CONFIG_FB_S1D13XXX
+static struct s1d13xxxfb_regval s1d13806_initregs[] = {
+	{ S1DREG_MISC,			0x00 },
+	{ S1DREG_COM_DISP_MODE,		0x00 },
+	{ S1DREG_GPIO_CNF0,		0x00 },
+	{ S1DREG_GPIO_CNF1,		0x00 },
+	{ S1DREG_GPIO_CTL0,		0x00 },
+	{ S1DREG_GPIO_CTL1,		0x00 },
+	{ S1DREG_CLK_CNF,		0x02 },
+	{ S1DREG_LCD_CLK_CNF,		0x01 },
+	{ S1DREG_CRT_CLK_CNF,		0x03 },
+	{ S1DREG_MPLUG_CLK_CNF,		0x03 },
+	{ S1DREG_CPU2MEM_WST_SEL,	0x02 },
+	{ S1DREG_SDRAM_REF_RATE,	0x03 },
+	{ S1DREG_SDRAM_TC0,		0x00 },
+	{ S1DREG_SDRAM_TC1,		0x01 },
+	{ S1DREG_MEM_CNF,		0x80 },
+	{ S1DREG_PANEL_TYPE,		0x25 },
+	{ S1DREG_MOD_RATE,		0x00 },
+	{ S1DREG_LCD_DISP_HWIDTH,	0x63 },
+	{ S1DREG_LCD_NDISP_HPER,	0x1e },
+	{ S1DREG_TFT_FPLINE_START,	0x06 },
+	{ S1DREG_TFT_FPLINE_PWIDTH,	0x03 },
+	{ S1DREG_LCD_DISP_VHEIGHT0,	0x57 },
+	{ S1DREG_LCD_DISP_VHEIGHT1,	0x02 },
+	{ S1DREG_LCD_NDISP_VPER,	0x00 },
+	{ S1DREG_TFT_FPFRAME_START,	0x0a },
+	{ S1DREG_TFT_FPFRAME_PWIDTH,	0x81 },
+	{ S1DREG_LCD_DISP_MODE,		0x03 },
+	{ S1DREG_LCD_MISC,		0x00 },
+	{ S1DREG_LCD_DISP_START0,	0x00 },
+	{ S1DREG_LCD_DISP_START1,	0x00 },
+	{ S1DREG_LCD_DISP_START2,	0x00 },
+	{ S1DREG_LCD_MEM_OFF0,		0x90 },
+	{ S1DREG_LCD_MEM_OFF1,		0x01 },
+	{ S1DREG_LCD_PIX_PAN,		0x00 },
+	{ S1DREG_LCD_DISP_FIFO_HTC,	0x00 },
+	{ S1DREG_LCD_DISP_FIFO_LTC,	0x00 },
+	{ S1DREG_CRT_DISP_HWIDTH,	0x63 },
+	{ S1DREG_CRT_NDISP_HPER,	0x1f },
+	{ S1DREG_CRT_HRTC_START,	0x04 },
+	{ S1DREG_CRT_HRTC_PWIDTH,	0x8f },
+	{ S1DREG_CRT_DISP_VHEIGHT0,	0x57 },
+	{ S1DREG_CRT_DISP_VHEIGHT1,	0x02 },
+	{ S1DREG_CRT_NDISP_VPER,	0x1b },
+	{ S1DREG_CRT_VRTC_START,	0x00 },
+	{ S1DREG_CRT_VRTC_PWIDTH,	0x83 },
+	{ S1DREG_TV_OUT_CTL,		0x10 },
+	{ S1DREG_CRT_DISP_MODE,		0x05 },
+	{ S1DREG_CRT_DISP_START0,	0x00 },
+	{ S1DREG_CRT_DISP_START1,	0x00 },
+	{ S1DREG_CRT_DISP_START2,	0x00 },
+	{ S1DREG_CRT_MEM_OFF0,		0x20 },
+	{ S1DREG_CRT_MEM_OFF1,		0x03 },
+	{ S1DREG_CRT_PIX_PAN,		0x00 },
+	{ S1DREG_CRT_DISP_FIFO_HTC,	0x00 },
+	{ S1DREG_CRT_DISP_FIFO_LTC,	0x00 },
+	{ S1DREG_LCD_CUR_CTL,		0x00 },
+	{ S1DREG_LCD_CUR_START,		0x01 },
+	{ S1DREG_LCD_CUR_XPOS0,		0x00 },
+	{ S1DREG_LCD_CUR_XPOS1,		0x00 },
+	{ S1DREG_LCD_CUR_YPOS0,		0x00 },
+	{ S1DREG_LCD_CUR_YPOS1,		0x00 },
+	{ S1DREG_LCD_CUR_BCTL0,		0x00 },
+	{ S1DREG_LCD_CUR_GCTL0,		0x00 },
+	{ S1DREG_LCD_CUR_RCTL0,		0x00 },
+	{ S1DREG_LCD_CUR_BCTL1,		0x1f },
+	{ S1DREG_LCD_CUR_GCTL1,		0x3f },
+	{ S1DREG_LCD_CUR_RCTL1,		0x1f },
+	{ S1DREG_LCD_CUR_FIFO_HTC,	0x00 },
+	{ S1DREG_CRT_CUR_CTL,		0x00 },
+	{ S1DREG_CRT_CUR_START,		0x01 },
+	{ S1DREG_CRT_CUR_XPOS0,		0x00 },
+	{ S1DREG_CRT_CUR_XPOS1,		0x00 },
+	{ S1DREG_CRT_CUR_YPOS0,		0x00 },
+	{ S1DREG_CRT_CUR_YPOS1,		0x00 },
+	{ S1DREG_CRT_CUR_BCTL0,		0x00 },
+	{ S1DREG_CRT_CUR_GCTL0,		0x00 },
+	{ S1DREG_CRT_CUR_RCTL0,		0x00 },
+	{ S1DREG_CRT_CUR_BCTL1,		0x1f },
+	{ S1DREG_CRT_CUR_GCTL1,		0x3f },
+	{ S1DREG_CRT_CUR_RCTL1,		0x1f },
+	{ S1DREG_CRT_CUR_FIFO_HTC,	0x00 },
+	{ S1DREG_BBLT_CTL0,		0x00 },
+	{ S1DREG_BBLT_CTL1,		0x00 },
+	{ S1DREG_BBLT_CC_EXP,		0x00 },
+	{ S1DREG_BBLT_OP,		0x00 },
+	{ S1DREG_BBLT_SRC_START0,	0x00 },
+	{ S1DREG_BBLT_SRC_START1,	0x00 },
+	{ S1DREG_BBLT_SRC_START2,	0x00 },
+	{ S1DREG_BBLT_DST_START0,	0x00 },
+	{ S1DREG_BBLT_DST_START1,	0x00 },
+	{ S1DREG_BBLT_DST_START2,	0x00 },
+	{ S1DREG_BBLT_MEM_OFF0,		0x00 },
+	{ S1DREG_BBLT_MEM_OFF1,		0x00 },
+	{ S1DREG_BBLT_WIDTH0,		0x00 },
+	{ S1DREG_BBLT_WIDTH1,		0x00 },
+	{ S1DREG_BBLT_HEIGHT0,		0x00 },
+	{ S1DREG_BBLT_HEIGHT1,		0x00 },
+	{ S1DREG_BBLT_BGC0,		0x00 },
+	{ S1DREG_BBLT_BGC1,		0x00 },
+	{ S1DREG_BBLT_FGC0,		0x00 },
+	{ S1DREG_BBLT_FGC1,		0x00 },
+	{ S1DREG_LKUP_MODE,		0x00 },
+	{ S1DREG_LKUP_ADDR,		0x00 },
+	{ S1DREG_PS_CNF,		0x10 },
+	{ S1DREG_PS_STATUS,		0x00 },
+	{ S1DREG_CPU2MEM_WDOGT,		0x00 },
+	{ S1DREG_COM_DISP_MODE,		0x02 },
+};
+
+static struct s1d13xxxfb_pdata s1d13806_platform_data = {
+	.initregs	= s1d13806_initregs,
+	.initregssize	= ARRAY_SIZE(s1d13806_initregs),
+};
+
+static struct resource s1d13806_resources[] = {
+	[0] = {
+		.start		= 0x07200000,
+		.end		= 0x07200000 + 0x00200000 - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start		= 0x07000000,
+		.end		= 0x07000000 + 0x00200000 - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device s1d13806_device = {
+	.name		= "s1d13806fb",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(s1d13806_resources),
+	.resource	= s1d13806_resources,
+
+	.dev = {
+		.platform_data	= &s1d13806_platform_data,
+	},
+};
+#endif
+
+static struct platform_device *microdev_devices[] __initdata = {
+	&smc91x_device,
+#ifdef CONFIG_FB_S1D13XXX
+	&s1d13806_device,
+#endif
+};
+
+static int __init microdev_devices_setup(void)
 {
-	return platform_device_register(&smc91x_device);
+	return platform_add_devices(microdev_devices, ARRAY_SIZE(microdev_devices));
 }
 
-__initcall(smc91x_setup);
+__initcall(microdev_devices_setup);
 
-	/*
-	 * Initialize the board
-	 */
 void __init platform_setup(void)
 {
 	int * const fpgaRevisionRegister = (int*)(MICRODEV_FPGA_GP_BASE + 0x8ul);
diff --git a/arch/sh/boards/unknown/Makefile b/arch/sh/boards/unknown/Makefile
index cffc210..7d18f40 100644
--- a/arch/sh/boards/unknown/Makefile
+++ b/arch/sh/boards/unknown/Makefile
@@ -2,5 +2,5 @@
 # Makefile for unknown SH boards 
 #
 
-obj-y	 := mach.o io.o setup.o
+obj-y	 := setup.o
 
diff --git a/arch/sh/boards/unknown/io.c b/arch/sh/boards/unknown/io.c
deleted file mode 100644
index 8f3f172..0000000
--- a/arch/sh/boards/unknown/io.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * linux/arch/sh/kernel/io_unknown.c
- *
- * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * I/O routine for unknown hardware.
- */
-
-static unsigned int unknown_handler(void)
-{
-	return 0;
-}
-
-#define UNKNOWN_ALIAS(fn) \
-	void unknown_##fn(void) __attribute__ ((alias ("unknown_handler")));
-
-UNKNOWN_ALIAS(inb)
-UNKNOWN_ALIAS(inw)
-UNKNOWN_ALIAS(inl)
-UNKNOWN_ALIAS(outb)
-UNKNOWN_ALIAS(outw)
-UNKNOWN_ALIAS(outl)
-UNKNOWN_ALIAS(inb_p)
-UNKNOWN_ALIAS(inw_p)
-UNKNOWN_ALIAS(inl_p)
-UNKNOWN_ALIAS(outb_p)
-UNKNOWN_ALIAS(outw_p)
-UNKNOWN_ALIAS(outl_p)
-UNKNOWN_ALIAS(insb)
-UNKNOWN_ALIAS(insw)
-UNKNOWN_ALIAS(insl)
-UNKNOWN_ALIAS(outsb)
-UNKNOWN_ALIAS(outsw)
-UNKNOWN_ALIAS(outsl)
-UNKNOWN_ALIAS(readb)
-UNKNOWN_ALIAS(readw)
-UNKNOWN_ALIAS(readl)
-UNKNOWN_ALIAS(writeb)
-UNKNOWN_ALIAS(writew)
-UNKNOWN_ALIAS(writel)
-UNKNOWN_ALIAS(isa_port2addr)
-UNKNOWN_ALIAS(ioremap)
-UNKNOWN_ALIAS(iounmap)
diff --git a/arch/sh/boards/unknown/mach.c b/arch/sh/boards/unknown/mach.c
deleted file mode 100644
index ad0bcc6..0000000
--- a/arch/sh/boards/unknown/mach.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * linux/arch/sh/kernel/mach_unknown.c
- *
- * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * Machine specific code for an unknown machine (internal peripherials only)
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-
-#include <asm/machvec.h>
-#include <asm/machvec_init.h>
-
-#include <asm/io_unknown.h>
-
-#include <asm/rtc.h>
-/*
- * The Machine Vector
- */
-
-struct sh_machine_vector mv_unknown __initmv = {
-#if defined(CONFIG_CPU_SH4)
-	.mv_nr_irqs		= 48,
-#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
-	.mv_nr_irqs		= 32,
-#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
-	.mv_nr_irqs		= 61,
-#endif
-
-	.mv_inb			= unknown_inb,
-	.mv_inw			= unknown_inw,
-	.mv_inl			= unknown_inl,
-	.mv_outb		= unknown_outb,
-	.mv_outw		= unknown_outw,
-	.mv_outl		= unknown_outl,
-
-	.mv_inb_p		= unknown_inb_p,
-	.mv_inw_p		= unknown_inw_p,
-	.mv_inl_p		= unknown_inl_p,
-	.mv_outb_p		= unknown_outb_p,
-	.mv_outw_p		= unknown_outw_p,
-	.mv_outl_p		= unknown_outl_p,
-
-	.mv_insb		= unknown_insb,
-	.mv_insw		= unknown_insw,
-	.mv_insl		= unknown_insl,
-	.mv_outsb		= unknown_outsb,
-	.mv_outsw		= unknown_outsw,
-	.mv_outsl		= unknown_outsl,
-
-	.mv_readb		= unknown_readb,
-	.mv_readw		= unknown_readw,
-	.mv_readl		= unknown_readl,
-	.mv_writeb		= unknown_writeb,
-	.mv_writew		= unknown_writew,
-	.mv_writel		= unknown_writel,
-
-	.mv_ioremap		= unknown_ioremap,
-	.mv_iounmap		= unknown_iounmap,
-
-	.mv_isa_port2addr	= unknown_isa_port2addr,
-};
-ALIAS_MV(unknown)
diff --git a/arch/sh/boards/unknown/setup.c b/arch/sh/boards/unknown/setup.c
index 7d772a6..02e84f0 100644
--- a/arch/sh/boards/unknown/setup.c
+++ b/arch/sh/boards/unknown/setup.c
@@ -7,10 +7,20 @@
  * License.  See linux/COPYING for more information.
  *
  * Setup code for an unknown machine (internal peripherials only)
+ *
+ * This is the simplest of all boards, and serves only as a quick and dirty
+ * method to start debugging a new board during bring-up until proper board
+ * setup code is written.
  */
-
 #include <linux/config.h>
 #include <linux/init.h>
+#include <asm/machvec.h>
+#include <asm/irq.h>
+
+struct sh_machine_vector mv_unknown __initmv = {
+	.mv_nr_irqs		= NR_IRQS,
+};
+ALIAS_MV(unknown)
 
 const char *get_system_type(void)
 {
diff --git a/arch/sh/cchips/voyagergx/consistent.c b/arch/sh/cchips/voyagergx/consistent.c
index 3d9a02c..07e8b9c 100644
--- a/arch/sh/cchips/voyagergx/consistent.c
+++ b/arch/sh/cchips/voyagergx/consistent.c
@@ -15,7 +15,7 @@
 #include <linux/module.h>
 #include <linux/device.h>
 #include <asm/io.h>
-#include <asm/bus-sh.h>
+
 
 struct voya_alloc_entry {
 	struct list_head list;
@@ -30,12 +30,13 @@ static LIST_HEAD(voya_alloc_list);
 #define OHCI_HCCA_SIZE	0x100
 #define OHCI_SRAM_SIZE	0x10000
 
+#define VOYAGER_OHCI_NAME	"voyager-ohci"
+
 void *voyagergx_consistent_alloc(struct device *dev, size_t size,
 				 dma_addr_t *handle, gfp_t flag)
 {
 	struct list_head *list = &voya_alloc_list;
 	struct voya_alloc_entry *entry;
-	struct sh_dev *shdev = to_sh_dev(dev);
 	unsigned long start, end;
 	unsigned long flags;
 
@@ -46,9 +47,7 @@ void *voyagergx_consistent_alloc(struct 
 	 *
 	 * Everything else goes through consistent_alloc().
 	 */
-	if (!dev || dev->bus != &sh_bus_types[SH_BUS_VIRT] ||
-		   (dev->bus == &sh_bus_types[SH_BUS_VIRT] &&
-		    shdev->dev_id != SH_DEV_ID_USB_OHCI))
+	if (!dev || strcmp(dev->driver->name, VOYAGER_OHCI_NAME))
 		return NULL;
 
 	start = OHCI_SRAM_START + OHCI_HCCA_SIZE;
@@ -98,12 +97,9 @@ int voyagergx_consistent_free(struct dev
 			      void *vaddr, dma_addr_t handle)
 {
 	struct voya_alloc_entry *entry;
-	struct sh_dev *shdev = to_sh_dev(dev);
 	unsigned long flags;
 
-	if (!dev || dev->bus != &sh_bus_types[SH_BUS_VIRT] ||
-		   (dev->bus == &sh_bus_types[SH_BUS_VIRT] &&
-		    shdev->dev_id != SH_DEV_ID_USB_OHCI))
+	if (!dev || strcmp(dev->driver->name, VOYAGER_OHCI_NAME))
 		return -EINVAL;
 
 	spin_lock_irqsave(&voya_list_lock, flags);
@@ -123,4 +119,3 @@ int voyagergx_consistent_free(struct dev
 
 EXPORT_SYMBOL(voyagergx_consistent_alloc);
 EXPORT_SYMBOL(voyagergx_consistent_free);
-
diff --git a/arch/sh/cchips/voyagergx/irq.c b/arch/sh/cchips/voyagergx/irq.c
index 1b6ac52..2ee330b 100644
--- a/arch/sh/cchips/voyagergx/irq.c
+++ b/arch/sh/cchips/voyagergx/irq.c
@@ -163,7 +163,12 @@ int voyagergx_irq_demux(int irq)
 	return irq;
 }
 
-static struct irqaction irq0  = { voyagergx_interrupt, SA_INTERRUPT, 0, "VOYAGERGX", NULL, NULL};
+static struct irqaction irq0  = {
+	.name		= "voyagergx",
+	.handler	= voyagergx_interrupt,
+	.flags		= SA_INTERRUPT,
+	.mask		= CPU_MASK_NONE,
+};
 
 void __init setup_voyagergx_irq(void)
 {
diff --git a/arch/sh/configs/microdev_defconfig b/arch/sh/configs/microdev_defconfig
index a3bd280..ab3db76 100644
--- a/arch/sh/configs/microdev_defconfig
+++ b/arch/sh/configs/microdev_defconfig
@@ -1,10 +1,9 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-sh
-# Wed Mar  2 15:09:41 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 19:43:20 2006
 #
 CONFIG_SUPERH=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
@@ -17,11 +16,13 @@ CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 # CONFIG_SYSVIPC is not set
 # CONFIG_POSIX_MQUEUE is not set
@@ -29,22 +30,29 @@ CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -52,6 +60,24 @@ CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_MODULES is not set
 
 #
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # System type
 #
 # CONFIG_SH_SOLUTION_ENGINE is not set
@@ -61,9 +87,7 @@ CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_SH_7751_SYSTEMH is not set
 # CONFIG_SH_STB1_HARP is not set
 # CONFIG_SH_STB1_OVERDRIVE is not set
-# CONFIG_SH_HP620 is not set
-# CONFIG_SH_HP680 is not set
-# CONFIG_SH_HP690 is not set
+# CONFIG_SH_HP6XX is not set
 # CONFIG_SH_CQREEK is not set
 # CONFIG_SH_DMIDA is not set
 # CONFIG_SH_EC3104 is not set
@@ -78,45 +102,94 @@ CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_SH_SECUREEDGE5410 is not set
 # CONFIG_SH_HS7751RVOIP is not set
 # CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
 # CONFIG_SH_EDOSK7705 is not set
 CONFIG_SH_SH4202_MICRODEV=y
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
 # CONFIG_SH_UNKNOWN is not set
-# CONFIG_CPU_SH2 is not set
-# CONFIG_CPU_SH3 is not set
+
+#
+# Processor selection
+#
 CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7604 is not set
+
+#
+# SH-3 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7300 is not set
 # CONFIG_CPU_SUBTYPE_SH7705 is not set
 # CONFIG_CPU_SUBTYPE_SH7707 is not set
 # CONFIG_CPU_SUBTYPE_SH7708 is not set
 # CONFIG_CPU_SUBTYPE_SH7709 is not set
+
+#
+# SH-4 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
 # CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
+CONFIG_CPU_SUBTYPE_SH4_202=y
+
+#
+# ST40 Processor Support
+#
 # CONFIG_CPU_SUBTYPE_ST40STB1 is not set
 # CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-CONFIG_CPU_SUBTYPE_SH4_202=y
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+
+#
+# Memory management options
+#
 CONFIG_MMU=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC0,115200"
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x04000000
-CONFIG_MEMORY_SET=y
-# CONFIG_MEMORY_OVERRIDE is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_SH_RTC=y
 CONFIG_SH_FPU=y
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_PREEMPT=y
-# CONFIG_UBC_WAKEUP is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
 # CONFIG_SH_STORE_QUEUES is not set
-# CONFIG_SMP is not set
-CONFIG_SH_PCLK_CALC=y
-CONFIG_SH_PCLK_FREQ=65986048
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer support
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_PCLK_FREQ=66000000
 
 #
 # CPU Frequency scaling
@@ -137,20 +210,31 @@ CONFIG_NR_ONCHIP_DMA_CHANNELS=4
 CONFIG_HEARTBEAT=y
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Kernel features
 #
-CONFIG_ISA=y
-# CONFIG_PCI is not set
+# CONFIG_KEXEC is not set
+CONFIG_PREEMPT=y
+# CONFIG_SMP is not set
 
 #
-# PCCARD (PCMCIA/CardBus) support
+# Boot options
 #
-# CONFIG_PCCARD is not set
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC0,115200"
 
 #
-# PC-card bridges
+# Bus options
 #
-CONFIG_PCMCIA_PROBE=y
+# CONFIG_SUPERHYWAY is not set
+# CONFIG_PCI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
 
 #
 # PCI Hotplug Support
@@ -164,9 +248,79 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 
 #
-# SH initrd options
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_UNIX is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
 #
-# CONFIG_EMBEDDED_RAMDISK is not set
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
 
 #
 # Device Drivers
@@ -180,6 +334,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
 
 #
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
 # Memory Technology Devices (MTD)
 #
 # CONFIG_MTD is not set
@@ -192,13 +351,10 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 #
 # Plug and Play support
 #
-# CONFIG_PNP is not set
 
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
@@ -206,17 +362,7 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -241,9 +387,7 @@ CONFIG_BLK_DEV_IDECD=y
 # IDE chipset support/bugfixes
 #
 CONFIG_IDE_GENERIC=y
-CONFIG_IDE_SH=y
 # CONFIG_IDE_ARM is not set
-# CONFIG_IDE_CHIPSETS is not set
 # CONFIG_BLK_DEV_IDEDMA is not set
 # CONFIG_IDEDMA_AUTO is not set
 # CONFIG_BLK_DEV_HD is not set
@@ -251,14 +395,10 @@ CONFIG_IDE_SH=y
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 
 #
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
 # Multi-device support (RAID and LVM)
 #
 # CONFIG_MD is not set
@@ -266,6 +406,7 @@ CONFIG_IDE_SH=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -276,69 +417,8 @@ CONFIG_IDE_SH=y
 #
 
 #
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV is not set
-# CONFIG_UNIX is not set
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
+# Network device support
 #
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -346,9 +426,9 @@ CONFIG_NETDEVICES=y
 # CONFIG_TUN is not set
 
 #
-# ARCnet devices
+# PHY device support
 #
-# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -356,17 +436,7 @@ CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_STNIC is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
 CONFIG_SMC91X=y
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_AT1700 is not set
-# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
-# CONFIG_NET_PCI is not set
-# CONFIG_NET_POCKET is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -379,7 +449,6 @@ CONFIG_SMC91X=y
 #
 # Token Ring devices
 #
-# CONFIG_TR is not set
 
 #
 # Wireless LAN (non-hamradio)
@@ -394,6 +463,8 @@ CONFIG_SMC91X=y
 # CONFIG_SLIP is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -411,20 +482,10 @@ CONFIG_SMC91X=y
 # CONFIG_INPUT is not set
 
 #
-# Userland interfaces
-#
-
-#
-# Input I/O drivers
+# Hardware I/O ports
 #
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 # CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
-# Input Device Drivers
-#
+# CONFIG_GAMEPORT is not set
 
 #
 # Character devices
@@ -464,24 +525,46 @@ CONFIG_RTC=y
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
 
 #
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
 # Dallas's 1-wire bus
 #
 # CONFIG_W1 is not set
 
 #
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
 # Misc devices
 #
 
 #
+# Multimedia Capabilities Port drivers
+#
+
+#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
@@ -508,7 +591,7 @@ CONFIG_RTC=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
 #
@@ -524,13 +607,21 @@ CONFIG_RTC=y
 #
 # InfiniBand support
 #
-# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
+# EDAC - error detection and reporting (RAS)
+#
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -540,17 +631,17 @@ CONFIG_JBD=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -574,16 +665,12 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS_XATTR=y
-# CONFIG_DEVPTS_FS_SECURITY is not set
 CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -607,12 +694,14 @@ CONFIG_RAMFS=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
 # CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
@@ -622,6 +711,7 @@ CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -681,8 +771,10 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_PREEMPT=y
+CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
@@ -706,6 +798,7 @@ CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
@@ -730,5 +823,6 @@ CONFIG_CRYPTO_DES=y
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 7a86eeb..f05cd96 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -8,7 +8,7 @@ obj-y	:= process.o signal.o entry.o trap
 	ptrace.o setup.o time.o sys_sh.o semaphore.o \
 	io.o io_generic.o sh_ksyms.o
 
-obj-y				+= cpu/
+obj-y				+= cpu/ timers/
 
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_CF_ENABLER)	+= cf-enabler.o
diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile
index 5bfc33b..59d5b74 100644
--- a/arch/sh/kernel/cpu/Makefile
+++ b/arch/sh/kernel/cpu/Makefile
@@ -2,7 +2,7 @@
 # Makefile for the Linux/SuperH CPU-specifc backends.
 #
 
-obj-y	+= irq/ init.o bus.o clock.o
+obj-y	+= irq/ init.o clock.o
 
 obj-$(CONFIG_CPU_SH2)		+= sh2/
 obj-$(CONFIG_CPU_SH3)		+= sh3/
diff --git a/arch/sh/kernel/cpu/bus.c b/arch/sh/kernel/cpu/bus.c
deleted file mode 100644
index fc6c4bd..0000000
--- a/arch/sh/kernel/cpu/bus.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * arch/sh/kernel/cpu/bus.c
- *
- * Virtual bus for SuperH.
- *
- * Copyright (C) 2004 Paul Mundt
- *
- * Shamelessly cloned from arch/arm/mach-omap/bus.c, which was written
- * by:
- *
- *  	Copyright (C) 2003 - 2004 Nokia Corporation
- *  	Written by Tony Lindgren <tony@atomide.com>
- *  	Portions of code based on sa1111.c.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <asm/bus-sh.h>
-
-static int sh_bus_match(struct device *dev, struct device_driver *drv)
-{
-	struct sh_driver *shdrv = to_sh_driver(drv);
-	struct sh_dev *shdev = to_sh_dev(dev);
-
-	return shdev->dev_id == shdrv->dev_id;
-}
-
-static int sh_bus_suspend(struct device *dev, pm_message_t state)
-{
-	struct sh_dev *shdev = to_sh_dev(dev);
-	struct sh_driver *shdrv = to_sh_driver(dev->driver);
-
-	if (shdrv && shdrv->suspend)
-		return shdrv->suspend(shdev, state);
-
-	return 0;
-}
-
-static int sh_bus_resume(struct device *dev)
-{
-	struct sh_dev *shdev = to_sh_dev(dev);
-	struct sh_driver *shdrv = to_sh_driver(dev->driver);
-
-	if (shdrv && shdrv->resume)
-		return shdrv->resume(shdev);
-
-	return 0;
-}
-
-static int sh_device_probe(struct device *dev)
-{
-	struct sh_dev *shdev = to_sh_dev(dev);
-	struct sh_driver *shdrv = to_sh_driver(dev->driver);
-
-	if (shdrv && shdrv->probe)
-		return shdrv->probe(shdev);
-
-	return -ENODEV;
-}
-
-static int sh_device_remove(struct device *dev)
-{
-	struct sh_dev *shdev = to_sh_dev(dev);
-	struct sh_driver *shdrv = to_sh_driver(dev->driver);
-
-	if (shdrv && shdrv->remove)
-		return shdrv->remove(shdev);
-
-	return 0;
-}
-
-static struct device sh_bus_devices[SH_NR_BUSES] = {
-	{
-		.bus_id		= SH_BUS_NAME_VIRT,
-	},
-};
-
-struct bus_type sh_bus_types[SH_NR_BUSES] = {
-	{
-		.name		= SH_BUS_NAME_VIRT,
-		.match		= sh_bus_match,
-		.probe		= sh_bus_probe,
-		.remove		= sh_bus_remove,
-		.suspend	= sh_bus_suspend,
-		.resume		= sh_bus_resume,
-	},
-};
-
-int sh_device_register(struct sh_dev *dev)
-{
-	if (!dev)
-		return -EINVAL;
-
-	if (dev->bus_id < 0 || dev->bus_id >= SH_NR_BUSES) {
-		printk(KERN_ERR "%s: bus_id invalid: %s bus: %d\n",
-		       __FUNCTION__, dev->name, dev->bus_id);
-		return -EINVAL;
-	}
-
-	dev->dev.parent = &sh_bus_devices[dev->bus_id];
-	dev->dev.bus    = &sh_bus_types[dev->bus_id];
-
-	/* This is needed for USB OHCI to work */
-	if (dev->dma_mask)
-		dev->dev.dma_mask = dev->dma_mask;
-	if (dev->coherent_dma_mask)
-		dev->dev.coherent_dma_mask = dev->coherent_dma_mask;
-
-	snprintf(dev->dev.bus_id, BUS_ID_SIZE, "%s%u",
-		 dev->name, dev->dev_id);
-
-	printk(KERN_INFO "Registering SH device '%s'. Parent at %s\n",
-	       dev->dev.bus_id, dev->dev.parent->bus_id);
-
-	return device_register(&dev->dev);
-}
-
-void sh_device_unregister(struct sh_dev *dev)
-{
-	device_unregister(&dev->dev);
-}
-
-int sh_driver_register(struct sh_driver *drv)
-{
-	if (!drv)
-		return -EINVAL;
-
-	if (drv->bus_id < 0 || drv->bus_id >= SH_NR_BUSES) {
-		printk(KERN_ERR "%s: bus_id invalid: bus: %d device %d\n",
-		       __FUNCTION__, drv->bus_id, drv->dev_id);
-		return -EINVAL;
-	}
-
-	drv->drv.bus    = &sh_bus_types[drv->bus_id];
-
-	return driver_register(&drv->drv);
-}
-
-void sh_driver_unregister(struct sh_driver *drv)
-{
-	driver_unregister(&drv->drv);
-}
-
-static int __init sh_bus_init(void)
-{
-	int i, ret = 0;
-
-	for (i = 0; i < SH_NR_BUSES; i++) {
-		ret = device_register(&sh_bus_devices[i]);
-		if (ret != 0) {
-			printk(KERN_ERR "Unable to register bus device %s\n",
-			       sh_bus_devices[i].bus_id);
-			continue;
-		}
-
-		ret = bus_register(&sh_bus_types[i]);
-		if (ret != 0) {
-			printk(KERN_ERR "Unable to register bus %s\n",
-			       sh_bus_types[i].name);
-			device_unregister(&sh_bus_devices[i]);
-		}
-	}
-
-	printk(KERN_INFO "SH Virtual Bus initialized\n");
-
-	return ret;
-}
-
-static void __exit sh_bus_exit(void)
-{
-	int i;
-
-	for (i = 0; i < SH_NR_BUSES; i++) {
-		bus_unregister(&sh_bus_types[i]);
-		device_unregister(&sh_bus_devices[i]);
-	}
-}
-
-module_init(sh_bus_init);
-module_exit(sh_bus_exit);
-
-MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
-MODULE_DESCRIPTION("SH Virtual Bus");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(sh_bus_types);
-EXPORT_SYMBOL(sh_device_register);
-EXPORT_SYMBOL(sh_device_unregister);
-EXPORT_SYMBOL(sh_driver_register);
-EXPORT_SYMBOL(sh_driver_unregister);
-
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index 989e7fd..97fa37f 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -38,9 +38,7 @@ static DECLARE_MUTEX(clock_list_sem);
 static struct clk master_clk = {
 	.name		= "master_clk",
 	.flags		= CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES,
-#ifdef CONFIG_SH_PCLK_FREQ_BOOL
 	.rate		= CONFIG_SH_PCLK_FREQ,
-#endif
 };
 
 static struct clk module_clk = {
@@ -227,16 +225,7 @@ int __init clk_init(void)
 {
 	int i, ret = 0;
 
-	if (unlikely(!master_clk.rate))
-		/*
-		 * NOTE: This will break if the default divisor has been
-		 * changed.
-		 *
-		 * No one should be changing the default on us however,
-		 * expect that a sane value for CONFIG_SH_PCLK_FREQ will
-		 * be defined in the event of a different divisor.
-		 */
-		master_clk.rate = get_timer_frequency() * 4;
+	BUG_ON(unlikely(!master_clk.rate));
 
 	for (i = 0; i < ARRAY_SIZE(onchip_clocks); i++) {
 		struct clk *clk = onchip_clocks[i];
diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c
index fdbd718..e55150e 100644
--- a/arch/sh/kernel/cpu/irq/ipr.c
+++ b/arch/sh/kernel/cpu/irq/ipr.c
@@ -108,8 +108,7 @@ static void end_ipr_irq(unsigned int irq
 		enable_ipr_irq(irq);
 }
 
-void make_ipr_irq(unsigned int irq, unsigned int addr, int pos,
-		  int priority, int maskpos)
+void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority)
 {
 	disable_irq_nosync(irq);
 	ipr_data[irq].addr = addr;
@@ -123,44 +122,44 @@ void make_ipr_irq(unsigned int irq, unsi
 void __init init_IRQ(void)
 {
 #ifndef CONFIG_CPU_SUBTYPE_SH7780
-	make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY, 0);
-	make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY, 0);
+	make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY);
+	make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY);
 #if defined(CONFIG_SH_RTC)
-	make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY, 0);
+	make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY);
 #endif
 
 #ifdef SCI_ERI_IRQ
-	make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY, 0);
-	make_ipr_irq(SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY, 0);
-	make_ipr_irq(SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY, 0);
+	make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
+	make_ipr_irq(SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
+	make_ipr_irq(SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
 #endif
 
 #ifdef SCIF1_ERI_IRQ
-	make_ipr_irq(SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY, 0);
-	make_ipr_irq(SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY, 0);
-	make_ipr_irq(SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY, 0);
-	make_ipr_irq(SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY, 0);
+	make_ipr_irq(SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
+	make_ipr_irq(SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
+	make_ipr_irq(SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
+	make_ipr_irq(SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
 #endif
 
 #if defined(CONFIG_CPU_SUBTYPE_SH7300)
-	make_ipr_irq(SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY, 0);
-	make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY, 0);
-	make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY, 0);
-	make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY, 0);
+	make_ipr_irq(SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY);
+	make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
+	make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
+	make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
 #endif
 
 #ifdef SCIF_ERI_IRQ
-	make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY, 0);
-	make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY, 0);
-	make_ipr_irq(SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY, 0);
-	make_ipr_irq(SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY, 0);
+	make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
+	make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
+	make_ipr_irq(SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
+	make_ipr_irq(SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
 #endif
 
 #ifdef IRDA_ERI_IRQ
-	make_ipr_irq(IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY, 0);
-	make_ipr_irq(IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY, 0);
-	make_ipr_irq(IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY, 0);
-	make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY, 0);
+	make_ipr_irq(IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
+	make_ipr_irq(IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
+	make_ipr_irq(IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
+	make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
 #endif
 
 #if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
@@ -175,12 +174,12 @@ void __init init_IRQ(void)
 	 * You should set corresponding bits of PFC to "00"
 	 * to enable these interrupts.
 	 */
-	make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY, 0);
-	make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY, 0);
-	make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY, 0);
-	make_ipr_irq(IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY, 0);
-	make_ipr_irq(IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY, 0);
-	make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY, 0);
+	make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY);
+	make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY);
+	make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY);
+	make_ipr_irq(IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY);
+	make_ipr_irq(IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY);
+	make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY);
 #endif
 #endif
 
diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S
index fb63681..a440d36 100644
--- a/arch/sh/kernel/entry.S
+++ b/arch/sh/kernel/entry.S
@@ -16,6 +16,7 @@
 #include <linux/config.h>
 #include <asm/asm-offsets.h>
 #include <asm/thread_info.h>
+#include <asm/cpu/mmu_context.h>
 #include <asm/unistd.h>
 
 #if !defined(CONFIG_NFSD) && !defined(CONFIG_NFSD_MODULE)
@@ -75,23 +76,6 @@
 ENOSYS = 38
 EINVAL = 22
 
-#if defined(CONFIG_CPU_SH3)
-TRA     = 0xffffffd0
-EXPEVT  = 0xffffffd4
-#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
-INTEVT  = 0xa4000000		! INTEVTE2(0xa4000000)
-#else
-INTEVT  = 0xffffffd8
-#endif
-MMU_TEA = 0xfffffffc		! TLB Exception Address Register
-#elif defined(CONFIG_CPU_SH4)
-TRA     = 0xff000020
-EXPEVT  = 0xff000024
-INTEVT  = 0xff000028
-MMU_TEA = 0xff00000c		! TLB Exception Address Register
-#endif
-
 #if defined(CONFIG_KGDB_NMI)
 NMI_VEC = 0x1c0			! Must catch early for debounce
 #endif
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index a4dc2b5..9fd1723 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -15,21 +15,18 @@
 #include <linux/unistd.h>
 #include <linux/mm.h>
 #include <linux/elfcore.h>
-#include <linux/slab.h>
 #include <linux/a.out.h>
+#include <linux/slab.h>
+#include <linux/pm.h>
 #include <linux/ptrace.h>
 #include <linux/platform.h>
 #include <linux/kallsyms.h>
+#include <linux/kexec.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 #include <asm/elf.h>
-#if defined(CONFIG_SH_HS7751RVOIP)
-#include <asm/hs7751rvoip/hs7751rvoip.h>
-#elif defined(CONFIG_SH_RTS7751R2D)
-#include <asm/rts7751r2d/rts7751r2d.h>
-#endif
 
 static int hlt_counter=0;
 
@@ -37,6 +34,11 @@ int ubc_usercnt = 0;
 
 #define HARD_IDLE_TIMEOUT (HZ / 3)
 
+void (*pm_idle)(void);
+
+void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
+
 void disable_hlt(void)
 {
 	hlt_counter++;
@@ -51,17 +53,25 @@ void enable_hlt(void)
 
 EXPORT_SYMBOL(enable_hlt);
 
+void default_idle(void)
+{
+	if (!hlt_counter)
+		cpu_sleep();
+	else
+		cpu_relax();
+}
+
 void cpu_idle(void)
 {
 	/* endless idle loop with no priority at all */
 	while (1) {
-		if (hlt_counter) {
-			while (!need_resched())
-				cpu_relax();
-		} else {
-			while (!need_resched())
-				cpu_sleep();
-		}
+		void (*idle)(void) = pm_idle;
+
+		if (!idle)
+			idle = default_idle;
+
+		while (!need_resched())
+			idle();
 
 		preempt_enable_no_resched();
 		schedule();
@@ -88,28 +98,16 @@ void machine_restart(char * __unused)
 
 void machine_halt(void)
 {
-#if defined(CONFIG_SH_HS7751RVOIP)
-	unsigned short value;
+	local_irq_disable();
 
-	value = ctrl_inw(PA_OUTPORTR);
-	ctrl_outw((value & 0xffdf), PA_OUTPORTR);
-#elif defined(CONFIG_SH_RTS7751R2D)
-	ctrl_outw(0x0001, PA_POWOFF);
-#endif
 	while (1)
 		cpu_sleep();
 }
 
 void machine_power_off(void)
 {
-#if defined(CONFIG_SH_HS7751RVOIP)
-	unsigned short value;
-
-	value = ctrl_inw(PA_OUTPORTR);
-	ctrl_outw((value & 0xffdf), PA_OUTPORTR);
-#elif defined(CONFIG_SH_RTS7751R2D)
-	ctrl_outw(0x0001, PA_POWOFF);
-#endif
+	if (pm_power_off)
+		pm_power_off();
 }
 
 void show_regs(struct pt_regs * regs)
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 036050b..a067a34 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -22,10 +22,10 @@
 #include <linux/cpu.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
-#include <asm/io_generic.h>
 #include <asm/sections.h>
 #include <asm/irq.h>
 #include <asm/setup.h>
+#include <asm/clock.h>
 
 #ifdef CONFIG_SH_KGDB
 #include <asm/kgdb.h>
@@ -41,7 +41,7 @@ extern void * __rd_start, * __rd_end;
  * This value will be used at the very early stage of serial setup.
  * The bigger value means no problem.
  */
-struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 0, 10000000, };
+struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 10000000, };
 struct screen_info screen_info;
 
 #if defined(CONFIG_SH_UNKNOWN)
@@ -186,7 +186,7 @@ static inline void parse_cmdline (char *
 
 static int __init sh_mv_setup(char **cmdline_p)
 {
-#if defined(CONFIG_SH_UNKNOWN)
+#ifdef CONFIG_SH_UNKNOWN
 	extern struct sh_machine_vector mv_unknown;
 #endif
 	struct sh_machine_vector *mv = NULL;
@@ -196,7 +196,7 @@ static int __init sh_mv_setup(char **cmd
 
 	parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base, &mv_mmio_enable);
 
-#ifdef CONFIG_SH_GENERIC
+#ifdef CONFIG_SH_UNKNOWN
 	if (mv == NULL) {
 		mv = &mv_unknown;
 		if (*mv_name != '\0') {
@@ -206,9 +206,6 @@ static int __init sh_mv_setup(char **cmd
 	}
 	sh_mv = *mv;
 #endif
-#ifdef CONFIG_SH_UNKNOWN
-	sh_mv = mv_unknown;
-#endif
 
 	/*
 	 * Manually walk the vec, fill in anything that the board hasn't yet
@@ -231,10 +228,8 @@ static int __init sh_mv_setup(char **cmd
 	mv_set(readb);	mv_set(readw);	mv_set(readl);
 	mv_set(writeb);	mv_set(writew);	mv_set(writel);
 
-	mv_set(ioremap);
-	mv_set(iounmap);
-
-	mv_set(isa_port2addr);
+	mv_set(ioport_map);
+	mv_set(ioport_unmap);
 	mv_set(irq_demux);
 
 #ifdef CONFIG_SH_UNKNOWN
@@ -273,10 +268,10 @@ void __init setup_arch(char **cmdline_p)
 	init_mm.end_data = (unsigned long) _edata;
 	init_mm.brk = (unsigned long) _end;
 
-	code_resource.start = virt_to_bus(_text);
-	code_resource.end = virt_to_bus(_etext)-1;
-	data_resource.start = virt_to_bus(_etext);
-	data_resource.end = virt_to_bus(_edata)-1;
+	code_resource.start = (unsigned long)virt_to_phys(_text);
+	code_resource.end = (unsigned long)virt_to_phys(_etext)-1;
+	data_resource.start = (unsigned long)virt_to_phys(_etext);
+	data_resource.end = (unsigned long)virt_to_phys(_edata)-1;
 
 	sh_mv_setup(cmdline_p);
 
@@ -435,6 +430,9 @@ static const char *cpu_name[] = {
 	[CPU_ST40GX1]	= "ST40GX1",
 	[CPU_SH4_202]	= "SH4-202",
 	[CPU_SH4_501]	= "SH4-501",
+	[CPU_SH7770]	= "SH7770",
+	[CPU_SH7780]	= "SH7780",
+	[CPU_SH7781]	= "SH7781",
 	[CPU_SH_NONE]	= "Unknown"
 };
 
@@ -445,7 +443,7 @@ const char *get_cpu_subtype(void)
 
 #ifdef CONFIG_PROC_FS
 static const char *cpu_flags[] = {
-	"none", "fpu", "p2flush", "mmuassoc", "dsp", "perfctr",
+	"none", "fpu", "p2flush", "mmuassoc", "dsp", "perfctr", "ptea", NULL
 };
 
 static void show_cpuflags(struct seq_file *m)
@@ -459,7 +457,7 @@ static void show_cpuflags(struct seq_fil
 		return;
 	}
 
-	for (i = 0; i < cpu_data->flags; i++)
+	for (i = 0; cpu_flags[i]; i++)
 		if ((cpu_data->flags & (1 << i)))
 			seq_printf(m, " %s", cpu_flags[i+1]);
 
@@ -472,7 +470,8 @@ static void show_cacheinfo(struct seq_fi
 
 	cache_size = info.ways * info.sets * info.linesz;
 
-	seq_printf(m, "%s size\t: %dKiB\n", type, cache_size >> 10);
+	seq_printf(m, "%s size\t: %2dKiB (%d-way)\n",
+		   type, cache_size >> 10, info.ways);
 }
 
 /*
@@ -511,21 +510,9 @@ static int show_cpuinfo(struct seq_file 
 		     boot_cpu_data.loops_per_jiffy/(500000/HZ),
 		     (boot_cpu_data.loops_per_jiffy/(5000/HZ)) % 100);
 
-#define PRINT_CLOCK(name, value) \
-	seq_printf(m, name " clock\t: %d.%02dMHz\n", \
-		     ((value) / 1000000), ((value) % 1000000)/10000)
-	
-	PRINT_CLOCK("cpu", boot_cpu_data.cpu_clock);
-	PRINT_CLOCK("bus", boot_cpu_data.bus_clock);
-#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
-	PRINT_CLOCK("memory", boot_cpu_data.memory_clock);
-#endif
-	PRINT_CLOCK("module", boot_cpu_data.module_clock);
-
-	return 0;
+	return show_clocks(m);
 }
 
-
 static void *c_start(struct seq_file *m, loff_t *pos)
 {
 	return *pos < NR_CPUS ? cpu_data + *pos : NULL;
@@ -596,7 +583,7 @@ static int __init kgdb_parse_options(cha
 		options += map->namelen + 1;
 
 		options = (*options == ',') ? options+1 : options;
-		
+
 		/* Read optional parameters (baud/parity/bits) */
 		baud = simple_strtoul(options, &options, 10);
 		if (baud != 0) {
diff --git a/arch/sh64/kernel/time.c b/arch/sh64/kernel/time.c
index 1195af3..0773c9f 100644
--- a/arch/sh64/kernel/time.c
+++ b/arch/sh64/kernel/time.c
@@ -29,6 +29,7 @@
 #include <linux/init.h>
 #include <linux/profile.h>
 #include <linux/smp.h>
+#include <linux/module.h>
 
 #include <asm/registers.h>	 /* required by inline __asm__ stmt. */
 
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 03ecb4e..267ec8f 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -38,7 +38,7 @@
 
 #define curptr      g6
 
-#define NR_SYSCALLS 284      /* Each OS is different... */
+#define NR_SYSCALLS 299      /* Each OS is different... */
 
 /* These are just handy. */
 #define _SV	save	%sp, -STACKFRAME_SZ, %sp
@@ -1277,62 +1277,6 @@ sys_sigstack:
 	 mov	%l5, %o7
 
 	.align	4
-	.globl	sys_sigpause
-sys_sigpause:
-	/* Note: %o0 already has correct value... */
-	call	do_sigpause
-	 add	%sp, STACKFRAME_SZ, %o1
-
-	ld	[%curptr + TI_FLAGS], %l5
-	andcc	%l5, _TIF_SYSCALL_TRACE, %g0
-	be	1f
-	 nop
-
-	call	syscall_trace
-	 nop
-
-1:
-	/* We are returning to a signal handler. */
-	RESTORE_ALL
-
-	.align	4
-	.globl	sys_sigsuspend
-sys_sigsuspend:
-	call	do_sigsuspend
-	 add	%sp, STACKFRAME_SZ, %o0
-
-	ld	[%curptr + TI_FLAGS], %l5
-	andcc	%l5, _TIF_SYSCALL_TRACE, %g0
-	be	1f
-	 nop
-
-	call	syscall_trace
-	 nop
-
-1:
-	/* We are returning to a signal handler. */
-	RESTORE_ALL
-
-	.align	4
-	.globl	sys_rt_sigsuspend
-sys_rt_sigsuspend:
-	/* Note: %o0, %o1 already have correct value... */
-	call	do_rt_sigsuspend
-	 add	%sp, STACKFRAME_SZ, %o2
-
-	ld	[%curptr + TI_FLAGS], %l5
-	andcc	%l5, _TIF_SYSCALL_TRACE, %g0
-	be	1f
-	 nop
-
-	call	syscall_trace
-	 nop
-
-1:
-	/* We are returning to a signal handler. */
-	RESTORE_ALL
-
-	.align	4
 	.globl	sys_sigreturn
 sys_sigreturn:
 	call	do_sigreturn
diff --git a/arch/sparc/kernel/rtrap.S b/arch/sparc/kernel/rtrap.S
index f7460d8..77ca6fd 100644
--- a/arch/sparc/kernel/rtrap.S
+++ b/arch/sparc/kernel/rtrap.S
@@ -68,15 +68,14 @@ ret_trap_lockless_ipi:
 
 	ld	[%curptr + TI_FLAGS], %g2
 signal_p:
-	andcc	%g2, (_TIF_NOTIFY_RESUME|_TIF_SIGPENDING), %g0
+	andcc	%g2, (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK), %g0
 	bz,a	ret_trap_continue
 	 ld	[%sp + STACKFRAME_SZ + PT_PSR], %t_psr
 
-	clr	%o0
-	mov	%l5, %o2
-	mov	%l6, %o3
+	mov	%l5, %o1
+	mov	%l6, %o2
 	call	do_signal
-	 add	%sp, STACKFRAME_SZ, %o1	! pt_regs ptr
+	 add	%sp, STACKFRAME_SZ, %o0	! pt_regs ptr
 
 	/* Fall through. */
 	ld	[%sp + STACKFRAME_SZ + PT_PSR], %t_psr
diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
index 5f34d7d..0748d81 100644
--- a/arch/sparc/kernel/signal.c
+++ b/arch/sparc/kernel/signal.c
@@ -35,9 +35,6 @@ extern void fpsave(unsigned long *fpregs
 		   void *fpqueue, unsigned long *fpqdepth);
 extern void fpload(unsigned long *fpregs, unsigned long *fsr);
 
-asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
-			 unsigned long orig_o0, int restart_syscall);
-
 /* Signal frames: the original one (compatible with SunOS):
  *
  * Set up a signal frame... Make the stack look the way SunOS
@@ -95,98 +92,30 @@ struct rt_signal_frame {
 #define NF_ALIGNEDSZ  (((sizeof(struct new_signal_frame) + 7) & (~7)))
 #define RT_ALIGNEDSZ  (((sizeof(struct rt_signal_frame) + 7) & (~7)))
 
-/*
- * atomically swap in the new signal mask, and wait for a signal.
- * This is really tricky on the Sparc, watch out...
- */
-asmlinkage void _sigpause_common(old_sigset_t set, struct pt_regs *regs)
+static int _sigpause_common(old_sigset_t set)
 {
-	sigset_t saveset;
-
 	set &= _BLOCKABLE;
 	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
+	current->saved_sigmask = current->blocked;
 	siginitset(&current->blocked, set);
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
 
-	regs->pc = regs->npc;
-	regs->npc += 4;
-
-	/* Condition codes and return value where set here for sigpause,
-	 * and so got used by setup_frame, which again causes sigreturn()
-	 * to return -EINTR.
-	 */
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		/*
-		 * Return -EINTR and set condition code here,
-		 * so the interrupted system call actually returns
-		 * these.
-		 */
-		regs->psr |= PSR_C;
-		regs->u_regs[UREG_I0] = EINTR;
-		if (do_signal(&saveset, regs, 0, 0))
-			return;
-	}
-}
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	set_thread_flag(TIF_RESTORE_SIGMASK);
 
-asmlinkage void do_sigpause(unsigned int set, struct pt_regs *regs)
-{
-	_sigpause_common(set, regs);
+	return -ERESTARTNOHAND;
 }
 
-asmlinkage void do_sigsuspend (struct pt_regs *regs)
+asmlinkage int sys_sigpause(unsigned int set)
 {
-	_sigpause_common(regs->u_regs[UREG_I0], regs);
+	return _sigpause_common(set);
 }
 
-asmlinkage void do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize,
-				 struct pt_regs *regs)
+asmlinkage int sys_sigsuspend(old_sigset_t set)
 {
-	sigset_t oldset, set;
-
-	/* XXX: Don't preclude handling different sized sigset_t's.  */
-	if (sigsetsize != sizeof(sigset_t)) {
-		regs->psr |= PSR_C;
-		regs->u_regs[UREG_I0] = EINVAL;
-		return;
-	}
-
-	if (copy_from_user(&set, uset, sizeof(set))) {
-		regs->psr |= PSR_C;
-		regs->u_regs[UREG_I0] = EFAULT;
-		return;
-	}
-
-	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	oldset = current->blocked;
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-
-	regs->pc = regs->npc;
-	regs->npc += 4;
-
-	/* Condition codes and return value where set here for sigpause,
-	 * and so got used by setup_frame, which again causes sigreturn()
-	 * to return -EINTR.
-	 */
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		/*
-		 * Return -EINTR and set condition code here,
-		 * so the interrupted system call actually returns
-		 * these.
-		 */
-		regs->psr |= PSR_C;
-		regs->u_regs[UREG_I0] = EINTR;
-		if (do_signal(&oldset, regs, 0, 0))
-			return;
-	}
+	return _sigpause_common(set);
 }
 
 static inline int
@@ -1067,13 +996,13 @@ static inline void syscall_restart(unsig
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
  * mistake.
  */
-asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
-			 unsigned long orig_i0, int restart_syscall)
+asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int restart_syscall)
 {
 	siginfo_t info;
 	struct sparc_deliver_cookie cookie;
 	struct k_sigaction ka;
 	int signr;
+	sigset_t *oldset;
 
 	/*
 	 * XXX Disable svr4 signal handling until solaris emulation works.
@@ -1089,7 +1018,9 @@ asmlinkage int do_signal(sigset_t *oldse
 	cookie.restart_syscall = restart_syscall;
 	cookie.orig_i0 = orig_i0;
 
-	if (!oldset)
+	if (test_thread_flag(TIF_RESTORE_SIGMASK))
+		oldset = &current->saved_sigmask;
+	else
 		oldset = &current->blocked;
 
 	signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
@@ -1098,7 +1029,14 @@ asmlinkage int do_signal(sigset_t *oldse
 			syscall_restart(cookie.orig_i0, regs, &ka.sa);
 		handle_signal(signr, &ka, &info, oldset,
 			      regs, svr4_signal);
-		return 1;
+		/* a signal was successfully delivered; the saved
+		 * sigmask will have been stored in the signal frame,
+		 * and will be restored by sigreturn, so we can simply
+		 * clear the TIF_RESTORE_SIGMASK flag.
+		 */
+		if (test_thread_flag(TIF_RESTORE_SIGMASK))
+			clear_thread_flag(TIF_RESTORE_SIGMASK);
+		return;
 	}
 	if (cookie.restart_syscall &&
 	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
@@ -1115,7 +1053,14 @@ asmlinkage int do_signal(sigset_t *oldse
 		regs->pc -= 4;
 		regs->npc -= 4;
 	}
-	return 0;
+
+	/* if there's no signal to deliver, we just put the saved sigmask
+	 * back
+	 */
+	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+		clear_thread_flag(TIF_RESTORE_SIGMASK);
+		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+	}
 }
 
 asmlinkage int
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
index 0b0d492..19b2539 100644
--- a/arch/sparc/kernel/sparc_ksyms.c
+++ b/arch/sparc/kernel/sparc_ksyms.c
@@ -66,7 +66,6 @@ struct poll {
 
 extern int svr4_getcontext (svr4_ucontext_t *, struct pt_regs *);
 extern int svr4_setcontext (svr4_ucontext_t *, struct pt_regs *);
-void _sigpause_common (unsigned int set, struct pt_regs *);
 extern void (*__copy_1page)(void *, const void *);
 extern void __memmove(void *, const void *, __kernel_size_t);
 extern void (*bzero_1page)(void *);
@@ -227,7 +226,6 @@ EXPORT_SYMBOL(kunmap_atomic);
 /* Solaris/SunOS binary compatibility */
 EXPORT_SYMBOL(svr4_setcontext);
 EXPORT_SYMBOL(svr4_getcontext);
-EXPORT_SYMBOL(_sigpause_common);
 
 EXPORT_SYMBOL(dump_thread);
 
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S
index e457a40..6877ae4 100644
--- a/arch/sparc/kernel/systbls.S
+++ b/arch/sparc/kernel/systbls.S
@@ -75,7 +75,10 @@ sys_call_table:
 /*265*/	.long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
 /*270*/	.long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
 /*275*/	.long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
-/*280*/	.long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl
+/*280*/	.long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat
+/*285*/	.long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_newfstatat
+/*290*/	.long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
+/*295*/	.long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll
 
 #ifdef CONFIG_SUNOS_EMUL
 	/* Now the SunOS syscall table. */
@@ -181,6 +184,11 @@ sunos_sys_table:
 	.long sunos_nosys, sunos_nosys, sunos_nosys
 	.long sunos_nosys
 /*280*/	.long sunos_nosys, sunos_nosys, sunos_nosys
+	.long sunos_nosys, sunos_nosys, sunos_nosys
+	.long sunos_nosys, sunos_nosys, sunos_nosys
 	.long sunos_nosys
+/*290*/	.long sunos_nosys, sunos_nosys, sunos_nosys
+	.long sunos_nosys, sunos_nosys, sunos_nosys
+	.long sunos_nosys, sunos_nosys, sunos_nosys
 
 #endif
diff --git a/arch/sparc/math-emu/math.c b/arch/sparc/math-emu/math.c
index be2c809..8613b3e 100644
--- a/arch/sparc/math-emu/math.c
+++ b/arch/sparc/math-emu/math.c
@@ -323,11 +323,6 @@ static int do_one_mathemu(u32 insn, unsi
 		case FMOVS:
 		case FABSS:
 		case FNEGS: TYPE(2,1,0,1,0,0,0); break;
-		default:
-#ifdef DEBUG_MATHEMU
-			printk("unknown FPop1: %03lx\n",(insn>>5)&0x1ff);
-#endif
-			break;
 		}
 	} else if ((insn & 0xc1f80000) == 0x81a80000)	/* FPOP2 */ {
 		switch ((insn >> 5) & 0x1ff) {
@@ -337,11 +332,6 @@ static int do_one_mathemu(u32 insn, unsi
 		case FCMPED: TYPE(3,0,0,2,1,2,1); break;
 		case FCMPQ: TYPE(3,0,0,3,1,3,1); break;
 		case FCMPEQ: TYPE(3,0,0,3,1,3,1); break;
-		default:
-#ifdef DEBUG_MATHEMU
-			printk("unknown FPop2: %03lx\n",(insn>>5)&0x1ff);
-#endif
-			break;
 		}
 	}
 
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index 489bf68..77840c8 100644
--- a/arch/sparc/mm/iommu.c
+++ b/arch/sparc/mm/iommu.c
@@ -295,8 +295,7 @@ static void iommu_release_one(u32 busa, 
 	int ioptex;
 	int i;
 
-	if (busa < iommu->start)
-		BUG();
+	BUG_ON(busa < iommu->start);
 	ioptex = (busa - iommu->start) >> PAGE_SHIFT;
 	for (i = 0; i < npages; i++) {
 		iopte_val(iommu->page_table[ioptex + i]) = 0;
@@ -340,9 +339,9 @@ static int iommu_map_dma_area(dma_addr_t
 	iopte_t *first;
 	int ioptex;
 
-	if ((va & ~PAGE_MASK) != 0) BUG();
-	if ((addr & ~PAGE_MASK) != 0) BUG();
-	if ((len & ~PAGE_MASK) != 0) BUG();
+	BUG_ON((va & ~PAGE_MASK) != 0);
+	BUG_ON((addr & ~PAGE_MASK) != 0);
+	BUG_ON((len & ~PAGE_MASK) != 0);
 
 	/* page color = physical address */
 	ioptex = bit_map_string_get(&iommu->usemap, len >> PAGE_SHIFT,
@@ -405,8 +404,8 @@ static void iommu_unmap_dma_area(unsigne
 	unsigned long end;
 	int ioptex = (busa - iommu->start) >> PAGE_SHIFT;
 
-	if ((busa & ~PAGE_MASK) != 0) BUG();
-	if ((len & ~PAGE_MASK) != 0) BUG();
+	BUG_ON((busa & ~PAGE_MASK) != 0);
+	BUG_ON((len & ~PAGE_MASK) != 0);
 
 	iopte += ioptex;
 	end = busa + len;
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index a3fb337..9ceddad 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15
-# Mon Jan  9 14:36:29 2006
+# Linux kernel version: 2.6.16-rc1
+# Wed Jan 18 13:41:02 2006
 #
 CONFIG_SPARC=y
 CONFIG_SPARC64=y
@@ -233,6 +233,11 @@ CONFIG_VLAN_8021Q=m
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -420,8 +425,7 @@ CONFIG_ISCSI_TCP=m
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLOGICPTI is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE is not set
+# CONFIG_SCSI_QLA_FC is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -529,6 +533,7 @@ CONFIG_NET_PCI=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=m
 CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -652,7 +657,6 @@ CONFIG_SERIAL_SUNSU_CONSOLE=y
 CONFIG_SERIAL_SUNSAB=m
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
 
@@ -738,6 +742,12 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_DEBUG_CHIP is not set
 
 #
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
 # Dallas's 1-wire bus
 #
 # CONFIG_W1 is not set
@@ -1014,6 +1024,7 @@ CONFIG_USB_UHCI_HCD=m
 #
 CONFIG_USB_HID=y
 CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
 # CONFIG_HID_FF is not set
 CONFIG_USB_HIDDEV=y
 # CONFIG_USB_AIPTEK is not set
@@ -1268,12 +1279,13 @@ CONFIG_KPROBES=y
 # Kernel hacking
 #
 CONFIG_PRINTK_TIME=y
-CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=18
 CONFIG_DETECT_SOFTLOCKUP=y
 CONFIG_SCHEDSTATS=y
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_MUTEXES is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -1281,6 +1293,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_VM is not set
+CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_DCFLUSH is not set
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index 7100029..12911e7 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -25,7 +25,7 @@
 
 #define curptr      g6
 
-#define NR_SYSCALLS 284      /* Each OS is different... */
+#define NR_SYSCALLS 299      /* Each OS is different... */
 
 	.text
 	.align		32
@@ -1416,7 +1416,6 @@ execve_merge:
 	 add		%sp, PTREGS_OFF, %o0
 
 	.globl	sys_pipe, sys_sigpause, sys_nis_syscall
-	.globl	sys_sigsuspend, sys_rt_sigsuspend
 	.globl	sys_rt_sigreturn
 	.globl	sys_ptrace
 	.globl	sys_sigaltstack
@@ -1440,28 +1439,6 @@ sys32_sigaltstack:
 		 mov		%i6, %o2
 #endif
 		.align		32
-sys_sigsuspend:	add		%sp, PTREGS_OFF, %o0
-		call		do_sigsuspend
-		 add		%o7, 1f-.-4, %o7
-		nop
-sys_rt_sigsuspend: /* NOTE: %o0,%o1 have a correct value already */
-		add		%sp, PTREGS_OFF, %o2
-		call		do_rt_sigsuspend
-		 add		%o7, 1f-.-4, %o7
-		nop
-#ifdef CONFIG_COMPAT
-	.globl	sys32_rt_sigsuspend
-sys32_rt_sigsuspend: /* NOTE: %o0,%o1 have a correct value already */
-		srl		%o0, 0, %o0
-		add		%sp, PTREGS_OFF, %o2
-		call		do_rt_sigsuspend32
-		 add		%o7, 1f-.-4, %o7
-#endif
-		/* NOTE: %o0 has a correct value already */
-sys_sigpause:	add		%sp, PTREGS_OFF, %o1
-		call		do_sigpause
-		 add		%o7, 1f-.-4, %o7
-		nop
 #ifdef CONFIG_COMPAT
 	.globl	sys32_sigreturn
 sys32_sigreturn:
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 1dc3650..059b0d0 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -164,6 +164,7 @@ void machine_restart(char * cmd)
 	panic("Reboot failed!");
 }
 
+#ifdef CONFIG_COMPAT
 static void show_regwindow32(struct pt_regs *regs)
 {
 	struct reg_window32 __user *rw;
@@ -189,6 +190,9 @@ static void show_regwindow32(struct pt_r
 	       r_w.ins[0], r_w.ins[1], r_w.ins[2], r_w.ins[3],
 	       r_w.ins[4], r_w.ins[5], r_w.ins[6], r_w.ins[7]);
 }
+#else
+#define show_regwindow32(regs)	do { } while (0)
+#endif
 
 static void show_regwindow(struct pt_regs *regs)
 {
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
index 090dcca..b80eba0 100644
--- a/arch/sparc64/kernel/rtrap.S
+++ b/arch/sparc64/kernel/rtrap.S
@@ -53,14 +53,13 @@ __handle_user_windows:
 		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
 		ldx			[%g6 + TI_FLAGS], %l0
 
-1:		andcc			%l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0
+1:		andcc			%l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0
 		be,pt			%xcc, __handle_user_windows_continue
 		 nop
-		clr			%o0
-		mov			%l5, %o2
-		mov			%l6, %o3
-		add			%sp, PTREGS_OFF, %o1
-		mov			%l0, %o4
+		mov			%l5, %o1
+		mov			%l6, %o2
+		add			%sp, PTREGS_OFF, %o0
+		mov			%l0, %o3
 
 		call			do_notify_resume
 		 wrpr			%g0, RTRAP_PSTATE, %pstate
@@ -96,15 +95,14 @@ __handle_perfctrs:
 		 wrpr			%g0, RTRAP_PSTATE, %pstate
 		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
 		ldx			[%g6 + TI_FLAGS], %l0
-1:		andcc			%l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0
+1:		andcc			%l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0
 
 		be,pt			%xcc, __handle_perfctrs_continue
 		 sethi			%hi(TSTATE_PEF), %o0
-		clr			%o0
-		mov			%l5, %o2
-		mov			%l6, %o3
-		add			%sp, PTREGS_OFF, %o1
-		mov			%l0, %o4
+		mov			%l5, %o1
+		mov			%l6, %o2
+		add			%sp, PTREGS_OFF, %o0
+		mov			%l0, %o3
 		call			do_notify_resume
 
 		 wrpr			%g0, RTRAP_PSTATE, %pstate
@@ -129,11 +127,10 @@ __handle_userfpu:
 		ba,a,pt			%xcc, __handle_userfpu_continue
 
 __handle_signal:
-		clr			%o0
-		mov			%l5, %o2
-		mov			%l6, %o3
-		add			%sp, PTREGS_OFF, %o1
-		mov			%l0, %o4
+		mov			%l5, %o1
+		mov			%l6, %o2
+		add			%sp, PTREGS_OFF, %o0
+		mov			%l0, %o3
 		call			do_notify_resume
 		 wrpr			%g0, RTRAP_PSTATE, %pstate
 		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
@@ -200,7 +197,7 @@ __handle_preemption_continue:
 		 andcc			%l1, %o0, %g0
 		andcc			%l0, _TIF_NEED_RESCHED, %g0
 		bne,pn			%xcc, __handle_preemption
-		 andcc			%l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0
+		 andcc			%l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0
 		bne,pn			%xcc, __handle_signal
 __handle_signal_continue:
 		 ldub			[%g6 + TI_WSAVED], %o2
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index 2507458..054461e 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -561,6 +561,8 @@ static int __init set_preferred_console(
 		serial_console = 1;
 	} else if (idev == PROMDEV_ITTYB && odev == PROMDEV_OTTYB) {
 		serial_console = 2;
+	} else if (idev == PROMDEV_IRSC && odev == PROMDEV_ORSC) {
+		serial_console = 3;
 	} else {
 		prom_printf("Inconsistent console: "
 			    "input %d, output %d\n",
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index 60f5dfa..ca11a4c 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -36,9 +36,6 @@
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-static int do_signal(sigset_t *oldset, struct pt_regs * regs,
-		     unsigned long orig_o0, int ret_from_syscall);
-
 /* {set, get}context() needed for 64-bit SparcLinux userland. */
 asmlinkage void sparc64_set_context(struct pt_regs *regs)
 {
@@ -242,114 +239,29 @@ struct rt_signal_frame {
 /* Align macros */
 #define RT_ALIGNEDSZ  (((sizeof(struct rt_signal_frame) + 7) & (~7)))
 
-/*
- * atomically swap in the new signal mask, and wait for a signal.
- * This is really tricky on the Sparc, watch out...
- */
-asmlinkage void _sigpause_common(old_sigset_t set, struct pt_regs *regs)
+static long _sigpause_common(old_sigset_t set)
 {
-	sigset_t saveset;
-
-#ifdef CONFIG_SPARC32_COMPAT
-	if (test_thread_flag(TIF_32BIT)) {
-		extern asmlinkage void _sigpause32_common(compat_old_sigset_t,
-							  struct pt_regs *);
-		_sigpause32_common(set, regs);
-		return;
-	}
-#endif
 	set &= _BLOCKABLE;
 	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
+	current->saved_sigmask = current->blocked;
 	siginitset(&current->blocked, set);
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
-	
-	if (test_thread_flag(TIF_32BIT)) {
-		regs->tpc = (regs->tnpc & 0xffffffff);
-		regs->tnpc = (regs->tnpc + 4) & 0xffffffff;
-	} else {
-		regs->tpc = regs->tnpc;
-		regs->tnpc += 4;
-	}
 
-	/* Condition codes and return value where set here for sigpause,
-	 * and so got used by setup_frame, which again causes sigreturn()
-	 * to return -EINTR.
-	 */
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		/*
-		 * Return -EINTR and set condition code here,
-		 * so the interrupted system call actually returns
-		 * these.
-		 */
-		regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
-		regs->u_regs[UREG_I0] = EINTR;
-		if (do_signal(&saveset, regs, 0, 0))
-			return;
-	}
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	set_thread_flag(TIF_RESTORE_SIGMASK);
+	return -ERESTARTNOHAND;
 }
 
-asmlinkage void do_sigpause(unsigned int set, struct pt_regs *regs)
+asmlinkage long sys_sigpause(unsigned int set)
 {
-	_sigpause_common(set, regs);
+	return _sigpause_common(set);
 }
 
-asmlinkage void do_sigsuspend(struct pt_regs *regs)
+asmlinkage long sys_sigsuspend(old_sigset_t set)
 {
-	_sigpause_common(regs->u_regs[UREG_I0], regs);
-}
-
-asmlinkage void do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, struct pt_regs *regs)
-{
-	sigset_t oldset, set;
-        
-	/* XXX: Don't preclude handling different sized sigset_t's.  */
-	if (sigsetsize != sizeof(sigset_t)) {
-		regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
-		regs->u_regs[UREG_I0] = EINVAL;
-		return;
-	}
-	if (copy_from_user(&set, uset, sizeof(set))) {
-		regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
-		regs->u_regs[UREG_I0] = EFAULT;
-		return;
-	}
-                                                                
-	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	oldset = current->blocked;
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-	
-	if (test_thread_flag(TIF_32BIT)) {
-		regs->tpc = (regs->tnpc & 0xffffffff);
-		regs->tnpc = (regs->tnpc + 4) & 0xffffffff;
-	} else {
-		regs->tpc = regs->tnpc;
-		regs->tnpc += 4;
-	}
-
-	/* Condition codes and return value where set here for sigpause,
-	 * and so got used by setup_frame, which again causes sigreturn()
-	 * to return -EINTR.
-	 */
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		/*
-		 * Return -EINTR and set condition code here,
-		 * so the interrupted system call actually returns
-		 * these.
-		 */
-		regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
-		regs->u_regs[UREG_I0] = EINTR;
-		if (do_signal(&oldset, regs, 0, 0))
-			return;
-	}
+	return _sigpause_common(set);
 }
 
 static inline int
@@ -607,26 +519,29 @@ static inline void syscall_restart(unsig
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
  * mistake.
  */
-static int do_signal(sigset_t *oldset, struct pt_regs * regs,
-		     unsigned long orig_i0, int restart_syscall)
+static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int restart_syscall)
 {
 	siginfo_t info;
 	struct signal_deliver_cookie cookie;
 	struct k_sigaction ka;
 	int signr;
+	sigset_t *oldset;
 	
 	cookie.restart_syscall = restart_syscall;
 	cookie.orig_i0 = orig_i0;
 
-	if (!oldset)
+	if (test_thread_flag(TIF_RESTORE_SIGMASK))
+		oldset = &current->saved_sigmask;
+	else
 		oldset = &current->blocked;
 
 #ifdef CONFIG_SPARC32_COMPAT
 	if (test_thread_flag(TIF_32BIT)) {
-		extern int do_signal32(sigset_t *, struct pt_regs *,
-				       unsigned long, int);
-		return do_signal32(oldset, regs, orig_i0,
-				   cookie.restart_syscall);
+		extern void do_signal32(sigset_t *, struct pt_regs *,
+					unsigned long, int);
+		do_signal32(oldset, regs, orig_i0,
+			    cookie.restart_syscall);
+		return;
 	}
 #endif	
 
@@ -635,7 +550,15 @@ static int do_signal(sigset_t *oldset, s
 		if (cookie.restart_syscall)
 			syscall_restart(orig_i0, regs, &ka.sa);
 		handle_signal(signr, &ka, &info, oldset, regs);
-		return 1;
+
+		/* a signal was successfully delivered; the saved
+		 * sigmask will have been stored in the signal frame,
+		 * and will be restored by sigreturn, so we can simply
+		 * clear the TIF_RESTORE_SIGMASK flag.
+		 */
+		if (test_thread_flag(TIF_RESTORE_SIGMASK))
+			clear_thread_flag(TIF_RESTORE_SIGMASK);
+		return;
 	}
 	if (cookie.restart_syscall &&
 	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
@@ -652,15 +575,21 @@ static int do_signal(sigset_t *oldset, s
 		regs->tpc -= 4;
 		regs->tnpc -= 4;
 	}
-	return 0;
+
+	/* if there's no signal to deliver, we just put the saved sigmask
+	 * back
+	 */
+	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+		clear_thread_flag(TIF_RESTORE_SIGMASK);
+		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+	}
 }
 
-void do_notify_resume(sigset_t *oldset, struct pt_regs *regs,
-		      unsigned long orig_i0, int restart_syscall,
+void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, int restart_syscall,
 		      unsigned long thread_info_flags)
 {
-	if (thread_info_flags & _TIF_SIGPENDING)
-		do_signal(oldset, regs, orig_i0, restart_syscall);
+	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
+		do_signal(regs, orig_i0, restart_syscall);
 }
 
 void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index 009a86e..708ba9b 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -32,9 +32,6 @@
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-int do_signal32(sigset_t *oldset, struct pt_regs *regs,
-		unsigned long orig_o0, int ret_from_syscall);
-
 /* Signal frames: the original one (compatible with SunOS):
  *
  * Set up a signal frame... Make the stack look the way SunOS
@@ -226,102 +223,6 @@ int copy_siginfo_from_user32(siginfo_t *
 	return 0;
 }
 
-/*
- * atomically swap in the new signal mask, and wait for a signal.
- * This is really tricky on the Sparc, watch out...
- */
-asmlinkage void _sigpause32_common(compat_old_sigset_t set, struct pt_regs *regs)
-{
-	sigset_t saveset;
-
-	set &= _BLOCKABLE;
-	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
-	siginitset(&current->blocked, set);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-	
-	regs->tpc = regs->tnpc;
-	regs->tnpc += 4;
-	if (test_thread_flag(TIF_32BIT)) {
-		regs->tpc &= 0xffffffff;
-		regs->tnpc &= 0xffffffff;
-	}
-
-	/* Condition codes and return value where set here for sigpause,
-	 * and so got used by setup_frame, which again causes sigreturn()
-	 * to return -EINTR.
-	 */
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		/*
-		 * Return -EINTR and set condition code here,
-		 * so the interrupted system call actually returns
-		 * these.
-		 */
-		regs->tstate |= TSTATE_ICARRY;
-		regs->u_regs[UREG_I0] = EINTR;
-		if (do_signal32(&saveset, regs, 0, 0))
-			return;
-	}
-}
-
-asmlinkage void do_rt_sigsuspend32(u32 uset, size_t sigsetsize, struct pt_regs *regs)
-{
-	sigset_t oldset, set;
-	compat_sigset_t set32;
-        
-	/* XXX: Don't preclude handling different sized sigset_t's.  */
-	if (((compat_size_t)sigsetsize) != sizeof(sigset_t)) {
-		regs->tstate |= TSTATE_ICARRY;
-		regs->u_regs[UREG_I0] = EINVAL;
-		return;
-	}
-	if (copy_from_user(&set32, compat_ptr(uset), sizeof(set32))) {
-		regs->tstate |= TSTATE_ICARRY;
-		regs->u_regs[UREG_I0] = EFAULT;
-		return;
-	}
-	switch (_NSIG_WORDS) {
-	case 4: set.sig[3] = set32.sig[6] + (((long)set32.sig[7]) << 32);
-	case 3: set.sig[2] = set32.sig[4] + (((long)set32.sig[5]) << 32);
-	case 2: set.sig[1] = set32.sig[2] + (((long)set32.sig[3]) << 32);
-	case 1: set.sig[0] = set32.sig[0] + (((long)set32.sig[1]) << 32);
-	}
-	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	oldset = current->blocked;
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-	
-	regs->tpc = regs->tnpc;
-	regs->tnpc += 4;
-	if (test_thread_flag(TIF_32BIT)) {
-		regs->tpc &= 0xffffffff;
-		regs->tnpc &= 0xffffffff;
-	}
-
-	/* Condition codes and return value where set here for sigpause,
-	 * and so got used by setup_frame, which again causes sigreturn()
-	 * to return -EINTR.
-	 */
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		/*
-		 * Return -EINTR and set condition code here,
-		 * so the interrupted system call actually returns
-		 * these.
-		 */
-		regs->tstate |= TSTATE_ICARRY;
-		regs->u_regs[UREG_I0] = EINTR;
-		if (do_signal32(&oldset, regs, 0, 0))
-			return;
-	}
-}
-
 static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
 {
 	unsigned long *fpregs = current_thread_info()->fpregs;
@@ -1362,8 +1263,8 @@ static inline void syscall_restart32(uns
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
  * mistake.
  */
-int do_signal32(sigset_t *oldset, struct pt_regs * regs,
-		unsigned long orig_i0, int restart_syscall)
+void do_signal32(sigset_t *oldset, struct pt_regs * regs,
+		 unsigned long orig_i0, int restart_syscall)
 {
 	siginfo_t info;
 	struct signal_deliver_cookie cookie;
@@ -1380,7 +1281,15 @@ int do_signal32(sigset_t *oldset, struct
 			syscall_restart32(orig_i0, regs, &ka.sa);
 		handle_signal32(signr, &ka, &info, oldset,
 				regs, svr4_signal);
-		return 1;
+
+		/* a signal was successfully delivered; the saved
+		 * sigmask will have been stored in the signal frame,
+		 * and will be restored by sigreturn, so we can simply
+		 * clear the TIF_RESTORE_SIGMASK flag.
+		 */
+		if (test_thread_flag(TIF_RESTORE_SIGMASK))
+			clear_thread_flag(TIF_RESTORE_SIGMASK);
+		return;
 	}
 	if (cookie.restart_syscall &&
 	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
@@ -1397,7 +1306,14 @@ int do_signal32(sigset_t *oldset, struct
 		regs->tpc -= 4;
 		regs->tnpc -= 4;
 	}
-	return 0;
+
+	/* if there's no signal to deliver, we just put the saved sigmask
+	 * back
+	 */
+	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+		clear_thread_flag(TIF_RESTORE_SIGMASK);
+		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+	}
 }
 
 struct sigstack32 {
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index d177d7e..3c06bfb 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -69,7 +69,6 @@ struct poll {
 
 extern void die_if_kernel(char *str, struct pt_regs *regs);
 extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-void _sigpause_common (unsigned int set, struct pt_regs *);
 extern void *__bzero(void *, size_t);
 extern void *__memscan_zero(void *, size_t);
 extern void *__memscan_generic(void *, int, size_t);
@@ -236,9 +235,10 @@ EXPORT_SYMBOL(pci_dma_supported);
 /* I/O device mmaping on Sparc64. */
 EXPORT_SYMBOL(io_remap_pfn_range);
 
+#ifdef CONFIG_COMPAT
 /* Solaris/SunOS binary compatibility */
-EXPORT_SYMBOL(_sigpause_common);
 EXPORT_SYMBOL(verify_compat_iovec);
+#endif
 
 EXPORT_SYMBOL(dump_fpu);
 EXPORT_SYMBOL(pte_alloc_one_kernel);
diff --git a/arch/sparc64/kernel/sys32.S b/arch/sparc64/kernel/sys32.S
index 9cd272a..60b5937 100644
--- a/arch/sparc64/kernel/sys32.S
+++ b/arch/sparc64/kernel/sys32.S
@@ -84,7 +84,6 @@ SIGN2(sys32_fadvise64_64, compat_sys_fad
 SIGN2(sys32_bdflush, sys_bdflush, %o0, %o1)
 SIGN1(sys32_mlockall, sys_mlockall, %o0)
 SIGN1(sys32_nfsservctl, compat_sys_nfsservctl, %o0)
-SIGN1(sys32_clock_settime, compat_sys_clock_settime, %o1)
 SIGN1(sys32_clock_nanosleep, compat_sys_clock_nanosleep, %o1)
 SIGN1(sys32_timer_settime, compat_sys_timer_settime, %o1)
 SIGN1(sys32_io_submit, compat_sys_io_submit, %o1)
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index d4b7a10..9264ccb 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -821,7 +821,7 @@ asmlinkage long sys32_utimes(char __user
 			return -EFAULT;
 	}
 
-	return do_utimes(filename, (tvs ? &ktvs[0] : NULL));
+	return do_utimes(AT_FDCWD, filename, (tvs ? &ktvs[0] : NULL));
 }
 
 /* These are here just in case some old sparc32 binary calls it. */
@@ -1003,7 +1003,7 @@ asmlinkage long sys32_adjtimex(struct ti
 asmlinkage long sparc32_open(const char __user *filename,
 			     int flags, int mode)
 {
-	return do_sys_open(filename, flags, mode);
+	return do_sys_open(AT_FDCWD, filename, flags, mode);
 }
 
 extern unsigned long do_mremap(unsigned long addr,
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index 98d24bc..2881faf 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -41,7 +41,7 @@ sys_call_table32:
 /*90*/	.word sys_dup2, sys_setfsuid, compat_sys_fcntl, sys32_select, sys_setfsgid
 	.word sys_fsync, sys32_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
 /*100*/ .word sys32_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending
-	.word compat_sys_rt_sigtimedwait, sys32_rt_sigqueueinfo, sys32_rt_sigsuspend, sys_setresuid, sys_getresuid
+	.word compat_sys_rt_sigtimedwait, sys32_rt_sigqueueinfo, compat_sys_rt_sigsuspend, sys_setresuid, sys_getresuid
 /*110*/	.word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall
 	.word sys32_getgroups, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd
 /*120*/	.word compat_sys_readv, compat_sys_writev, sys32_settimeofday, sys32_fchown16, sys_fchmod
@@ -71,12 +71,15 @@ sys_call_table32:
 /*240*/	.word sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys32_sched_setscheduler, sys32_sched_getscheduler
 	.word sys_sched_yield, sys32_sched_get_priority_max, sys32_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep
 /*250*/	.word sys32_mremap, sys32_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl
-	.word sys_ni_syscall, sys32_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep
+	.word sys_ni_syscall, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep
 /*260*/	.word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun
 	.word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
 /*270*/	.word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink
 	.word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid
-/*280*/	.word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl
+/*280*/	.word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat
+	.word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_newfstatat
+/*285*/	.word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
+	.word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll
 
 #endif /* CONFIG_COMPAT */
 
@@ -142,7 +145,10 @@ sys_call_table:
 	.word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy
 /*270*/	.word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
 	.word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
-/*280*/	.word sys_nis_syscall, sys_add_key, sys_request_key, sys_keyctl
+/*280*/	.word sys_nis_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat
+	.word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, compat_sys_newfstatat
+/*285*/	.word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
+	.word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll
 
 #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
     defined(CONFIG_SOLARIS_EMUL_MODULE)
@@ -239,13 +245,20 @@ sunos_sys_table:
 /*250*/	.word sunos_nosys, sunos_nosys, sunos_nosys
 	.word sunos_nosys, sunos_nosys, sunos_nosys
 	.word sunos_nosys, sunos_nosys, sunos_nosys
+	.word sunos_nosys
+/*260*/	.word sunos_nosys, sunos_nosys, sunos_nosys
 	.word sunos_nosys, sunos_nosys, sunos_nosys
 	.word sunos_nosys, sunos_nosys, sunos_nosys
+	.word sunos_nosys
+/*270*/	.word sunos_nosys, sunos_nosys, sunos_nosys
 	.word sunos_nosys, sunos_nosys, sunos_nosys
 	.word sunos_nosys, sunos_nosys, sunos_nosys
+	.word sunos_nosys
+/*280*/	.word sunos_nosys, sunos_nosys, sunos_nosys
 	.word sunos_nosys, sunos_nosys, sunos_nosys
 	.word sunos_nosys, sunos_nosys, sunos_nosys
+	.word sunos_nosys
+/*290*/	.word sunos_nosys, sunos_nosys, sunos_nosys
 	.word sunos_nosys, sunos_nosys, sunos_nosys
 	.word sunos_nosys, sunos_nosys, sunos_nosys
-	.word sunos_nosys
 #endif
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index 459c8fb..a22930d 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -280,9 +280,9 @@ static struct sparc64_tick_ops stick_ope
  * Since STICK is constantly updating, we have to access it carefully.
  *
  * The sequence we use to read is:
- * 1) read low
- * 2) read high
- * 3) read low again, if it rolled over increment high by 1
+ * 1) read high
+ * 2) read low
+ * 3) read high again, if it rolled re-read both low and high again.
  *
  * Writing STICK safely is also tricky:
  * 1) write low to zero
@@ -295,18 +295,18 @@ static struct sparc64_tick_ops stick_ope
 static unsigned long __hbird_read_stick(void)
 {
 	unsigned long ret, tmp1, tmp2, tmp3;
-	unsigned long addr = HBIRD_STICK_ADDR;
+	unsigned long addr = HBIRD_STICK_ADDR+8;
 
-	__asm__ __volatile__("ldxa	[%1] %5, %2\n\t"
-			     "add	%1, 0x8, %1\n\t"
-			     "ldxa	[%1] %5, %3\n\t"
+	__asm__ __volatile__("ldxa	[%1] %5, %2\n"
+			     "1:\n\t"
 			     "sub	%1, 0x8, %1\n\t"
+			     "ldxa	[%1] %5, %3\n\t"
+			     "add	%1, 0x8, %1\n\t"
 			     "ldxa	[%1] %5, %4\n\t"
 			     "cmp	%4, %2\n\t"
-			     "blu,a,pn	%%xcc, 1f\n\t"
-			     " add	%3, 1, %3\n"
-			     "1:\n\t"
-			     "sllx	%3, 32, %3\n\t"
+			     "bne,a,pn	%%xcc, 1b\n\t"
+			     " mov	%4, %2\n\t"
+			     "sllx	%4, 32, %4\n\t"
 			     "or	%3, %4, %0\n\t"
 			     : "=&r" (ret), "=&r" (addr),
 			       "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3)
diff --git a/arch/sparc64/prom/console.c b/arch/sparc64/prom/console.c
index eae5db8..ac6d035 100644
--- a/arch/sparc64/prom/console.c
+++ b/arch/sparc64/prom/console.c
@@ -99,8 +99,12 @@ prom_query_input_device(void)
 	if (!strncmp(propb, "keyboard", 8))
 		return PROMDEV_ITTYA;
 
+	if (!strncmp (propb, "rsc", 3))
+		return PROMDEV_IRSC;
+
 	if (strncmp (propb, "tty", 3) || !propb[3])
 		return PROMDEV_I_UNK;
+
 	switch (propb[3]) {
 		case 'a': return PROMDEV_ITTYA;
 		case 'b': return PROMDEV_ITTYB;
@@ -136,8 +140,12 @@ prom_query_output_device(void)
 	if (!strncmp(propb, "screen", 6))
 		return PROMDEV_OTTYA;
 
+	if (!strncmp (propb, "rsc", 3))
+		return PROMDEV_ORSC;
+
 	if (strncmp (propb, "tty", 3) || !propb[3])
 		return PROMDEV_O_UNK;
+
 	switch (propb[3]) {
 		case 'a': return PROMDEV_OTTYA;
 		case 'b': return PROMDEV_OTTYB;
diff --git a/arch/sparc64/solaris/entry64.S b/arch/sparc64/solaris/entry64.S
index 4b6ae58..eb314ed 100644
--- a/arch/sparc64/solaris/entry64.S
+++ b/arch/sparc64/solaris/entry64.S
@@ -180,6 +180,8 @@ solaris_sigsuspend:
 	 nop
 	call		sys_sigsuspend
 	 stx		%o0, [%sp + PTREGS_OFF + PT_V9_I0]
+	b,pt		%xcc, ret_from_solaris
+	 nop
 
 	.globl		solaris_getpid
 solaris_getpid:
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 8ff3bcb..5982fe2 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -143,6 +143,7 @@ config HOSTFS
 
 config HPPFS
 	tristate "HoneyPot ProcFS (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
 	help
 	hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc
 	entries to be overridden, removed, or fabricated from the host.
@@ -155,10 +156,6 @@ config HPPFS
 	You only need this if you are setting up a UML honeypot.  Otherwise,
 	it is safe to say 'N' here.
 
-	If you are actively using it, please report any problems, since it's
-	getting fixed. In this moment, it is experimental on 2.6 (it works on
-	2.4).
-
 config MCONSOLE
 	bool "Management console"
 	default y
@@ -243,8 +240,16 @@ config NEST_LEVEL
         Only change this if you are running nested UMLs.
 
 config HIGHMEM
-	bool "Highmem support"
-	depends on !64BIT
+	bool "Highmem support (EXPERIMENTAL)"
+	depends on !64BIT && EXPERIMENTAL
+	default n
+	help
+	This was used to allow UML to run with big amounts of memory.
+	Currently it is unstable, so if unsure say N.
+
+	To use big amounts of memory, it is recommended to disable TT mode (i.e.
+	CONFIG_MODE_TT) and enable static linking (i.e. CONFIG_STATIC_LINK) -
+	this should allow the guest to use up to 2.75G of memory.
 
 config KERNEL_STACK_ORDER
 	int "Kernel stack size order"
@@ -269,17 +274,13 @@ endmenu
 
 source "init/Kconfig"
 
-source "net/Kconfig"
-
-source "drivers/base/Kconfig"
+source "drivers/block/Kconfig"
 
 source "arch/um/Kconfig.char"
 
-source "drivers/block/Kconfig"
+source "drivers/base/Kconfig"
 
-config NETDEVICES
-	bool
-	default NET
+source "net/Kconfig"
 
 source "arch/um/Kconfig.net"
 
diff --git a/arch/um/Kconfig.i386 b/arch/um/Kconfig.i386
index c71b39a..ef79ed2 100644
--- a/arch/um/Kconfig.i386
+++ b/arch/um/Kconfig.i386
@@ -22,13 +22,17 @@ config TOP_ADDR
  	default 0x80000000 if HOST_2G_2G
 
 config 3_LEVEL_PGTABLES
-	bool "Three-level pagetables"
+	bool "Three-level pagetables (EXPERIMENTAL)"
 	default n
+	depends on EXPERIMENTAL
 	help
 	Three-level pagetables will let UML have more than 4G of physical
 	memory.  All the memory that can't be mapped directly will be treated
 	as high memory.
 
+	However, this it experimental on 32-bit architectures, so if unsure say
+	N (on x86-64 it's automatically enabled, instead, as it's safe there).
+
 config STUB_CODE
 	hex
 	default 0xbfffe000
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 45435ff..c58b657 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -32,7 +32,7 @@ um-modes-$(CONFIG_MODE_TT) += tt
 um-modes-$(CONFIG_MODE_SKAS) += skas
 
 MODE_INCLUDE	+= $(foreach mode,$(um-modes-y),\
-		   -I$(srctree)/$(ARCH_DIR)/kernel/$(mode)/include)
+		   -I$(srctree)/$(ARCH_DIR)/include/$(mode))
 
 MAKEFILES-INCL	+= $(foreach mode,$(um-modes-y),\
 		   $(srctree)/$(ARCH_DIR)/Makefile-$(mode))
@@ -47,13 +47,16 @@ ARCH_INCLUDE	+= -I$(srctree)/$(ARCH_DIR)
 endif
 SYS_DIR		:= $(ARCH_DIR)/include/sysdep-$(SUBARCH)
 
-# -Dvmap=kernel_vmap affects everything, and prevents anything from
-# referencing the libpcap.o symbol so named.
+# -Dvmap=kernel_vmap prevents anything from referencing the libpcap.o symbol so
+# named - it's a common symbol in libpcap, so we get a binary which crashes.
 #
-# Same things for in6addr_loopback - found in libc.
+# Same things for in6addr_loopback and mktime - found in libc. For these two we
+# only get link-time error, luckily.
+#
+# These apply to USER_CFLAGS to.
 
-CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
-	$(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \
+CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\"	\
+	$(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap	\
 	-Din6addr_loopback=kernel_in6addr_loopback
 
 AFLAGS += $(ARCH_INCLUDE)
@@ -66,6 +69,7 @@ USER_CFLAGS := $(patsubst -D__KERNEL__,,
 # kernel_errno to separate them from the libc errno.  This allows -fno-common
 # in CFLAGS.  Otherwise, it would cause ld to complain about the two different
 # errnos.
+# These apply to kernelspace only.
 
 CFLAGS += -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \
 	-Dmktime=kernel_mktime
@@ -168,10 +172,13 @@ else
 	$(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch
 endif
 
-$(ARCH_DIR)/include/sysdep:
+$(objtree)/$(ARCH_DIR)/include:
+	@echo '  MKDIR $@'
+	$(Q)mkdir -p $@
+
+$(ARCH_DIR)/include/sysdep: $(objtree)/$(ARCH_DIR)/include
 	@echo '  SYMLINK $@'
 ifneq ($(KBUILD_SRC),)
-	$(Q)mkdir -p $(ARCH_DIR)/include
 	$(Q)ln -fsn $(srctree)/$(ARCH_DIR)/include/sysdep-$(SUBARCH) $(ARCH_DIR)/include/sysdep
 else
 	$(Q)cd $(ARCH_DIR)/include && ln -sf sysdep-$(SUBARCH) sysdep
@@ -214,7 +221,7 @@ $(ARCH_DIR)/include/user_constants.h: $(
 
 CLEAN_FILES += $(ARCH_DIR)/user-offsets.s
 
-$(ARCH_DIR)/include/kern_constants.h:
+$(ARCH_DIR)/include/kern_constants.h: $(objtree)/$(ARCH_DIR)/include
 	@echo '  SYMLINK $@'
 	$(Q) ln -sf ../../../include/asm-um/asm-offsets.h $@
 
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index ab0d0b1..7218c75 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -403,7 +403,7 @@ int chan_window_size(struct list_head *c
 	return 0;
 }
 
-void free_one_chan(struct chan *chan, int delay_free_irq)
+static void free_one_chan(struct chan *chan, int delay_free_irq)
 {
 	list_del(&chan->list);
 
@@ -416,7 +416,7 @@ void free_one_chan(struct chan *chan, in
 	kfree(chan);
 }
 
-void free_chan(struct list_head *chans, int delay_free_irq)
+static void free_chan(struct list_head *chans, int delay_free_irq)
 {
 	struct list_head *ele, *next;
 	struct chan *chan;
@@ -497,7 +497,7 @@ struct chan_type {
 	struct chan_ops *ops;
 };
 
-struct chan_type chan_table[] = {
+static struct chan_type chan_table[] = {
 	{ "fd", &fd_ops },
 
 #ifdef CONFIG_NULL_CHAN
diff --git a/arch/um/drivers/daemon_kern.c b/arch/um/drivers/daemon_kern.c
index 30d285b..a61b7b4 100644
--- a/arch/um/drivers/daemon_kern.c
+++ b/arch/um/drivers/daemon_kern.c
@@ -18,7 +18,7 @@ struct daemon_init {
 	char *ctl_sock;
 };
 
-void daemon_init(struct net_device *dev, void *data)
+static void daemon_init(struct net_device *dev, void *data)
 {
 	struct uml_net_private *pri;
 	struct daemon_data *dpri;
@@ -31,6 +31,10 @@ void daemon_init(struct net_device *dev,
 	dpri->fd = -1;
 	dpri->control = -1;
 	dpri->dev = dev;
+	/* We will free this pointer. If it contains crap we're burned. */
+	dpri->ctl_addr = NULL;
+	dpri->data_addr = NULL;
+	dpri->local_addr = NULL;
 
 	printk("daemon backend (uml_switch version %d) - %s:%s", 
 	       SWITCH_VERSION, dpri->sock_type, dpri->ctl_sock);
@@ -60,7 +64,7 @@ static struct net_kern_info daemon_kern_
 	.write			= daemon_write,
 };
 
-int daemon_setup(char *str, char **mac_out, void *data)
+static int daemon_setup(char *str, char **mac_out, void *data)
 {
 	struct daemon_init *init = data;
 	char *remain;
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
index 1bb085b..c944265 100644
--- a/arch/um/drivers/daemon_user.c
+++ b/arch/um/drivers/daemon_user.c
@@ -158,10 +158,16 @@ static void daemon_remove(void *data)
 	struct daemon_data *pri = data;
 
 	os_close_file(pri->fd);
+	pri->fd = -1;
 	os_close_file(pri->control);
+	pri->control = -1;
+
 	kfree(pri->data_addr);
+	pri->data_addr = NULL;
 	kfree(pri->ctl_addr);
+	pri->ctl_addr = NULL;
 	kfree(pri->local_addr);
+	pri->local_addr = NULL;
 }
 
 int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri)
diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c
index 3296e86..c41f75e 100644
--- a/arch/um/drivers/fd.c
+++ b/arch/um/drivers/fd.c
@@ -11,6 +11,7 @@
 #include "user.h"
 #include "user_util.h"
 #include "chan_user.h"
+#include "os.h"
 
 struct fd_chan {
 	int fd;
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 46ceb25..6c2d4cc 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -714,7 +714,7 @@ struct winch {
 	struct tty_struct *tty;
 };
 
-irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
+static irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
 {
 	struct winch *winch = data;
 	struct tty_struct *tty;
diff --git a/arch/um/drivers/mcast_kern.c b/arch/um/drivers/mcast_kern.c
index 217438c..c9b078f 100644
--- a/arch/um/drivers/mcast_kern.c
+++ b/arch/um/drivers/mcast_kern.c
@@ -26,7 +26,7 @@ struct mcast_init {
 	int ttl;
 };
 
-void mcast_init(struct net_device *dev, void *data)
+static void mcast_init(struct net_device *dev, void *data)
 {
 	struct uml_net_private *pri;
 	struct mcast_data *dpri;
@@ -40,7 +40,7 @@ void mcast_init(struct net_device *dev, 
 	dpri->dev = dev;
 
 	printk("mcast backend ");
-	printk("multicast adddress: %s:%u, TTL:%u ",
+	printk("multicast address: %s:%u, TTL:%u ",
 	       dpri->addr, dpri->port, dpri->ttl);
 
 	printk("\n");
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index e3d5765..54388d1 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -273,7 +273,7 @@ void mconsole_proc(struct mc_request *re
     config <dev> - Query the configuration of a device \n\
     remove <dev> - Remove a device from UML \n\
     sysrq <letter> - Performs the SysRq action controlled by the letter \n\
-    cad - invoke the Ctl-Alt-Del handler \n\
+    cad - invoke the Ctrl-Alt-Del handler \n\
     stop - pause the UML; it will do nothing until it receives a 'go' \n\
     go - continue the UML after a 'stop' \n\
     log <string> - make UML enter <string> into the kernel log\n\
@@ -327,7 +327,7 @@ void mconsole_stop(struct mc_request *re
 
 /* This list is populated by __initcall routines. */
 
-LIST_HEAD(mconsole_devices);
+static LIST_HEAD(mconsole_devices);
 
 void mconsole_register_dev(struct mc_device *new)
 {
@@ -561,6 +561,8 @@ void mconsole_sysrq(struct mc_request *r
 }
 #endif
 
+#ifdef CONFIG_MODE_SKAS
+
 static void stack_proc(void *arg)
 {
 	struct task_struct *from = current, *to = arg;
@@ -574,7 +576,7 @@ static void stack_proc(void *arg)
  *  Dumps a stacks registers to the linux console.
  *  Usage stack <pid>.
  */
-void do_stack(struct mc_request *req)
+static void do_stack_trace(struct mc_request *req)
 {
 	char *ptr = req->request.data;
 	int pid_requested= -1;
@@ -605,6 +607,7 @@ void do_stack(struct mc_request *req)
 	}
 	with_console(req, stack_proc, to);
 }
+#endif /* CONFIG_MODE_SKAS */
 
 void mconsole_stack(struct mc_request *req)
 {
@@ -613,7 +616,7 @@ void mconsole_stack(struct mc_request *r
 	 */
 	CHOOSE_MODE(mconsole_reply(req, "Sorry, this doesn't work in TT mode",
 				   1, 0),
-		    do_stack(req));
+		    do_stack_trace(req));
 }
 
 /* Changed by mconsole_setup, which is __setup, and called before SMP is
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index fb1f9fb..8ebb224 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -68,6 +68,11 @@ static int uml_net_rx(struct net_device 
 	return pkt_len;
 }
 
+static void uml_dev_close(void* dev)
+{
+	dev_close( (struct net_device *) dev);
+}
+
 irqreturn_t uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct net_device *dev = dev_id;
@@ -80,15 +85,21 @@ irqreturn_t uml_net_interrupt(int irq, v
 	spin_lock(&lp->lock);
 	while((err = uml_net_rx(dev)) > 0) ;
 	if(err < 0) {
+		DECLARE_WORK(close_work, uml_dev_close, dev);
 		printk(KERN_ERR 
 		       "Device '%s' read returned %d, shutting it down\n", 
 		       dev->name, err);
-		dev_close(dev);
+		/* dev_close can't be called in interrupt context, and takes
+		 * again lp->lock.
+		 * And dev_close() can be safely called multiple times on the
+		 * same device, since it tests for (dev->flags & IFF_UP). So
+		 * there's no harm in delaying the device shutdown. */
+		schedule_work(&close_work);
 		goto out;
 	}
 	reactivate_fd(lp->fd, UM_ETH_IRQ);
 
- out:
+out:
 	spin_unlock(&lp->lock);
 	return(IRQ_HANDLED);
 }
@@ -317,6 +328,11 @@ static int eth_configure(int n, void *in
 		return 1;
 	}
 
+	lp = dev->priv;
+	/* This points to the transport private data. It's still clear, but we
+	 * must memset it to 0 *now*. Let's help the drivers. */
+	memset(lp, 0, size);
+
 	/* sysfs register */
 	if (!driver_registered) {
 		platform_driver_register(&uml_net_driver);
@@ -358,7 +374,6 @@ static int eth_configure(int n, void *in
 		free_netdev(dev);
 		return 1;
 	}
-	lp = dev->priv;
 
 	/* lp.user is the first four bytes of the transport data, which
 	 * has already been initialized.  This structure assignment will
diff --git a/arch/um/drivers/slip_common.h b/arch/um/drivers/slip_common.h
index 2ae76d8..d574e0a 100644
--- a/arch/um/drivers/slip_common.h
+++ b/arch/um/drivers/slip_common.h
@@ -88,12 +88,13 @@ struct slip_proto {
 	int esc;
 };
 
-#define SLIP_PROTO_INIT { \
-	.ibuf  	= { '\0' }, \
-	.obuf  	= { '\0' }, \
-        .more	= 0, \
-	.pos	= 0, \
-	.esc	= 0 \
+static inline void slip_proto_init(struct slip_proto * slip)
+{
+	memset(slip->ibuf, 0, sizeof(slip->ibuf));
+	memset(slip->obuf, 0, sizeof(slip->obuf));
+	slip->more = 0;
+	slip->pos = 0;
+	slip->esc = 0;
 }
 
 extern int slip_proto_read(int fd, void *buf, int len,
diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c
index 9a6f5c8..a62f5ef 100644
--- a/arch/um/drivers/slip_kern.c
+++ b/arch/um/drivers/slip_kern.c
@@ -21,13 +21,14 @@ void slip_init(struct net_device *dev, v
 
 	private = dev->priv;
 	spri = (struct slip_data *) private->user;
-	*spri = ((struct slip_data)
-		{ .name 	= { '\0' },
-		  .addr		= NULL,
-		  .gate_addr 	= init->gate_addr,
-		  .slave  	= -1,
-		  .slip		= SLIP_PROTO_INIT,
-		  .dev 		= dev });
+
+	memset(spri->name, 0, sizeof(spri->name));
+	spri->addr = NULL;
+	spri->gate_addr = init->gate_addr;
+	spri->slave = -1;
+	spri->dev = dev;
+
+	slip_proto_init(&spri->slip);
 
 	dev->init = NULL;
 	dev->header_cache_update = NULL;
diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c
index 9864d27..33d7982 100644
--- a/arch/um/drivers/slirp_kern.c
+++ b/arch/um/drivers/slirp_kern.c
@@ -21,12 +21,13 @@ void slirp_init(struct net_device *dev, 
 
 	private = dev->priv;
 	spri = (struct slirp_data *) private->user;
-	*spri = ((struct slirp_data)
-		{ .argw 	= init->argw,
-		  .pid  	= -1,
-		  .slave  	= -1,
-		  .slip		= SLIP_PROTO_INIT,
-		  .dev 		= dev });
+
+	spri->argw = init->argw;
+	spri->pid = -1;
+	spri->slave = -1;
+	spri->dev = dev;
+
+	slip_proto_init(&spri->slip);
 
 	dev->init = NULL;
 	dev->hard_header_len = 0;
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index a32ef55..a4d6415 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -33,7 +33,7 @@ static struct tty_driver *ssl_driver;
 
 #define NR_PORTS 64
 
-void ssl_announce(char *dev_name, int dev)
+static void ssl_announce(char *dev_name, int dev)
 {
 	printk(KERN_INFO "Serial line %d assigned device '%s'\n", dev,
 	       dev_name);
@@ -98,7 +98,7 @@ static int ssl_remove(int n)
 	return line_remove(serial_lines, ARRAY_SIZE(serial_lines), n);
 }
 
-int ssl_open(struct tty_struct *tty, struct file *filp)
+static int ssl_open(struct tty_struct *tty, struct file *filp)
 {
 	return line_open(serial_lines, tty);
 }
@@ -182,7 +182,7 @@ static struct console ssl_cons = {
 	.index		= -1,
 };
 
-int ssl_init(void)
+static int ssl_init(void)
 {
 	char *new_title;
 
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 7696f8d..101efd2 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -1103,31 +1103,33 @@ static int ubd_ioctl(struct inode * inod
 	return(-EINVAL);
 }
 
-static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
+static int path_requires_switch(char *from_cmdline, char *from_cow, char *cow)
 {
 	struct uml_stat buf1, buf2;
 	int err;
 
-	if(from_cmdline == NULL) return(1);
-	if(!strcmp(from_cmdline, from_cow)) return(1);
+	if(from_cmdline == NULL)
+		return 0;
+	if(!strcmp(from_cmdline, from_cow))
+		return 0;
 
 	err = os_stat_file(from_cmdline, &buf1);
 	if(err < 0){
 		printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err);
-		return(1);
+		return 0;
 	}
 	err = os_stat_file(from_cow, &buf2);
 	if(err < 0){
 		printk("Couldn't stat '%s', err = %d\n", from_cow, -err);
-		return(1);
+		return 1;
 	}
 	if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino))
-		return(1);
+		return 0;
 
 	printk("Backing file mismatch - \"%s\" requested,\n"
 	       "\"%s\" specified in COW header of \"%s\"\n",
 	       from_cmdline, from_cow, cow);
-	return(0);
+	return 1;
 }
 
 static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
@@ -1189,18 +1191,19 @@ int open_ubd_file(char *file, struct ope
 	unsigned long long size;
 	__u32 version, align;
 	char *backing_file;
-	int fd, err, sectorsize, same, mode = 0644;
+	int fd, err, sectorsize, asked_switch, mode = 0644;
 
 	fd = os_open_file(file, *openflags, mode);
-	if(fd < 0){
-		if((fd == -ENOENT) && (create_cow_out != NULL))
+	if (fd < 0) {
+		if ((fd == -ENOENT) && (create_cow_out != NULL))
 			*create_cow_out = 1;
-                if(!openflags->w ||
-                   ((fd != -EROFS) && (fd != -EACCES))) return(fd);
+                if (!openflags->w ||
+                   ((fd != -EROFS) && (fd != -EACCES)))
+			return fd;
 		openflags->w = 0;
 		fd = os_open_file(file, *openflags, mode);
-		if(fd < 0)
-			return(fd);
+		if (fd < 0)
+			return fd;
         }
 
 	err = os_lock_file(fd, openflags->w);
@@ -1209,7 +1212,9 @@ int open_ubd_file(char *file, struct ope
 		goto out_close;
 	}
 
-	if(backing_file_out == NULL) return(fd);
+	/* Succesful return case! */
+	if(backing_file_out == NULL)
+		return(fd);
 
 	err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
 			      &size, &sectorsize, &align, bitmap_offset_out);
@@ -1218,34 +1223,34 @@ int open_ubd_file(char *file, struct ope
 		       "errno = %d\n", file, -err);
 		goto out_close;
 	}
-	if(err) return(fd);
-
-	if(backing_file_out == NULL) return(fd);
+	if(err)
+		return(fd);
 
-	same = same_backing_files(*backing_file_out, backing_file, file);
+	asked_switch = path_requires_switch(*backing_file_out, backing_file, file);
 
-	if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){
+	/* Allow switching only if no mismatch. */
+	if (asked_switch && !backing_file_mismatch(*backing_file_out, size, mtime)) {
 		printk("Switching backing file to '%s'\n", *backing_file_out);
 		err = write_cow_header(file, fd, *backing_file_out,
 				       sectorsize, align, &size);
-		if(err){
+		if (err) {
 			printk("Switch failed, errno = %d\n", -err);
-			return(err);
+			goto out_close;
 		}
-	}
-	else {
+	} else {
 		*backing_file_out = backing_file;
 		err = backing_file_mismatch(*backing_file_out, size, mtime);
-		if(err) goto out_close;
+		if (err)
+			goto out_close;
 	}
 
 	cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
 		  bitmap_len_out, data_offset_out);
 
-        return(fd);
+        return fd;
  out_close:
 	os_close_file(fd);
-	return(err);
+	return err;
 }
 
 int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index 8f4e46d..07176d9 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -31,8 +31,6 @@ extern int timer_irq_inited;
 extern int jail;
 extern int nsyscalls;
 
-extern struct task_struct *idle_threads[NR_CPUS];
-
 #define UML_ROUND_DOWN(addr) ((void *)(((unsigned long) addr) & PAGE_MASK))
 #define UML_ROUND_UP(addr) \
 	UML_ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1)
@@ -120,8 +118,10 @@ extern void machine_halt(void);
 extern int is_syscall(unsigned long addr);
 extern void arch_switch(void);
 extern void free_irq(unsigned int, void *);
-extern int um_in_interrupt(void);
 extern int cpu(void);
+
+/* Are we disallowed to sleep? Used to choose between GFP_KERNEL and GFP_ATOMIC. */
+extern int __cant_sleep(void);
 extern void segv_handler(int sig, union uml_pt_regs *regs);
 extern void sigio_handler(int sig, union uml_pt_regs *regs);
 
diff --git a/arch/um/include/longjmp.h b/arch/um/include/longjmp.h
new file mode 100644
index 0000000..018b381
--- /dev/null
+++ b/arch/um/include/longjmp.h
@@ -0,0 +1,19 @@
+#ifndef __UML_LONGJMP_H
+#define __UML_LONGJMP_H
+
+#include <setjmp.h>
+#include "os.h"
+
+#define UML_SIGLONGJMP(buf, val) do { \
+	longjmp(*buf, val);	\
+} while(0)
+
+#define UML_SIGSETJMP(buf, enable) ({ \
+	int n; \
+	enable = get_signals(); \
+	n = setjmp(*buf); \
+	if(n != 0) \
+		set_signals(enable); \
+	n; })
+
+#endif
diff --git a/arch/um/include/mode_kern.h b/arch/um/include/mode_kern.h
index 2d88afd..e7539a8 100644
--- a/arch/um/include/mode_kern.h
+++ b/arch/um/include/mode_kern.h
@@ -9,22 +9,11 @@
 #include "linux/config.h"
 
 #ifdef CONFIG_MODE_TT
-#include "mode_kern-tt.h"
+#include "mode_kern_tt.h"
 #endif
 
 #ifdef CONFIG_MODE_SKAS
-#include "mode_kern-skas.h"
+#include "mode_kern_skas.h"
 #endif
 
 #endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index dd72d66..eb1710b 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -11,6 +11,7 @@
 #include "../os/include/file.h"
 #include "sysdep/ptrace.h"
 #include "kern_util.h"
+#include "skas/mm_id.h"
 
 #define OS_TYPE_FILE 1 
 #define OS_TYPE_DIR 2 
@@ -190,11 +191,12 @@ extern int os_protect_memory(void *addr,
 			     int r, int w, int x);
 extern int os_unmap_memory(void *addr, int len);
 extern void os_flush_stdout(void);
-extern unsigned long long os_usecs(void);
 
 /* tt.c
  * for tt mode only (will be deleted in future...)
  */
+extern void stop(void);
+extern int wait_for_stop(int pid, int sig, int cont_type, void *relay);
 extern int protect_memory(unsigned long addr, unsigned long len,
 			  int r, int w, int x, int must_succeed);
 extern void forward_pending_sigio(int target);
@@ -230,9 +232,63 @@ extern void block_signals(void);
 extern void unblock_signals(void);
 extern int get_signals(void);
 extern int set_signals(int enable);
+extern void os_usr1_signal(int on);
 
 /* trap.c */
 extern void os_fill_handlinfo(struct kern_handlers h);
 extern void do_longjmp(void *p, int val);
 
+/* util.c */
+extern void stack_protections(unsigned long address);
+extern void task_protections(unsigned long address);
+extern int raw(int fd);
+extern void setup_machinename(char *machine_out);
+extern void setup_hostinfo(void);
+extern int setjmp_wrapper(void (*proc)(void *, void *), ...);
+
+/* time.c */
+#define BILLION (1000 * 1000 * 1000)
+
+extern void switch_timers(int to_real);
+extern void idle_sleep(int secs);
+extern void enable_timer(void);
+extern void disable_timer(void);
+extern void user_time_init(void);
+extern void uml_idle_timer(void);
+extern unsigned long long os_nsecs(void);
+
+/* skas/mem.c */
+extern long run_syscall_stub(struct mm_id * mm_idp,
+			     int syscall, unsigned long *args, long expected,
+			     void **addr, int done);
+extern long syscall_stub_data(struct mm_id * mm_idp,
+			      unsigned long *data, int data_count,
+			      void **addr, void **stub_addr);
+extern int map(struct mm_id * mm_idp, unsigned long virt,
+	       unsigned long len, int r, int w, int x, int phys_fd,
+	       unsigned long long offset, int done, void **data);
+extern int unmap(struct mm_id * mm_idp, void *addr, unsigned long len,
+		 int done, void **data);
+extern int protect(struct mm_id * mm_idp, unsigned long addr,
+		   unsigned long len, int r, int w, int x, int done,
+		   void **data);
+
+/* skas/process.c */
+extern int is_skas_winch(int pid, int fd, void *data);
+extern int start_userspace(unsigned long stub_stack);
+extern int copy_context_skas0(unsigned long stack, int pid);
+extern void userspace(union uml_pt_regs *regs);
+extern void map_stub_pages(int fd, unsigned long code,
+			   unsigned long data, unsigned long stack);
+extern void new_thread(void *stack, void **switch_buf_ptr,
+			 void **fork_buf_ptr, void (*handler)(int));
+extern void thread_wait(void *sw, void *fb);
+extern void switch_threads(void *me, void *next);
+extern int start_idle_thread(void *stack, void *switch_buf_ptr,
+			     void **fork_buf_ptr);
+extern void initial_thread_cb_skas(void (*proc)(void *),
+				 void *arg);
+extern void halt_skas(void);
+extern void reboot_skas(void);
+
 #endif
diff --git a/arch/um/include/skas/mm_id.h b/arch/um/include/skas/mm_id.h
new file mode 100644
index 0000000..48dd098
--- /dev/null
+++ b/arch/um/include/skas/mm_id.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2005 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __MM_ID_H
+#define __MM_ID_H
+
+struct mm_id {
+	union {
+		int mm_fd;
+		int pid;
+	} u;
+	unsigned long stack;
+};
+
+#endif
diff --git a/arch/um/include/skas/mmu-skas.h b/arch/um/include/skas/mmu-skas.h
new file mode 100644
index 0000000..d8869a6
--- /dev/null
+++ b/arch/um/include/skas/mmu-skas.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __SKAS_MMU_H
+#define __SKAS_MMU_H
+
+#include "linux/config.h"
+#include "mm_id.h"
+#include "asm/ldt.h"
+
+struct mmu_context_skas {
+	struct mm_id id;
+	unsigned long last_page_table;
+#ifdef CONFIG_3_LEVEL_PGTABLES
+	unsigned long last_pmd;
+#endif
+	uml_ldt_t ldt;
+};
+
+extern void switch_mm_skas(struct mm_id * mm_idp);
+
+#endif
diff --git a/arch/um/include/skas/mode-skas.h b/arch/um/include/skas/mode-skas.h
new file mode 100644
index 0000000..260065c
--- /dev/null
+++ b/arch/um/include/skas/mode-skas.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __MODE_SKAS_H__
+#define __MODE_SKAS_H__
+
+#include <sysdep/ptrace.h>
+
+extern unsigned long exec_regs[];
+extern unsigned long exec_fp_regs[];
+extern unsigned long exec_fpx_regs[];
+extern int have_fpx_regs;
+
+extern void sig_handler_common_skas(int sig, void *sc_ptr);
+extern void kill_off_processes_skas(void);
+
+#endif
diff --git a/arch/um/include/skas/mode_kern_skas.h b/arch/um/include/skas/mode_kern_skas.h
new file mode 100644
index 0000000..63c5873
--- /dev/null
+++ b/arch/um/include/skas/mode_kern_skas.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __SKAS_MODE_KERN_H__
+#define __SKAS_MODE_KERN_H__
+
+#include "linux/sched.h"
+#include "asm/page.h"
+#include "asm/ptrace.h"
+
+extern void flush_thread_skas(void);
+extern void switch_to_skas(void *prev, void *next);
+extern void start_thread_skas(struct pt_regs *regs, unsigned long eip,
+			      unsigned long esp);
+extern int copy_thread_skas(int nr, unsigned long clone_flags,
+			    unsigned long sp, unsigned long stack_top,
+			    struct task_struct *p, struct pt_regs *regs);
+extern void release_thread_skas(struct task_struct *task);
+extern void init_idle_skas(void);
+extern void flush_tlb_kernel_range_skas(unsigned long start,
+					unsigned long end);
+extern void flush_tlb_kernel_vm_skas(void);
+extern void __flush_tlb_one_skas(unsigned long addr);
+extern void flush_tlb_range_skas(struct vm_area_struct *vma,
+				 unsigned long start, unsigned long end);
+extern void flush_tlb_mm_skas(struct mm_struct *mm);
+extern void force_flush_all_skas(void);
+extern long execute_syscall_skas(void *r);
+extern void before_mem_skas(unsigned long unused);
+extern unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
+					 unsigned long *task_size_out);
+extern int start_uml_skas(void);
+extern int external_pid_skas(struct task_struct *task);
+extern int thread_pid_skas(struct task_struct *task);
+
+#define kmem_end_skas (host_task_size - 1024 * 1024)
+
+#endif
diff --git a/arch/um/include/skas/proc_mm.h b/arch/um/include/skas/proc_mm.h
new file mode 100644
index 0000000..9028092
--- /dev/null
+++ b/arch/um/include/skas/proc_mm.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __SKAS_PROC_MM_H
+#define __SKAS_PROC_MM_H
+
+#define MM_MMAP 54
+#define MM_MUNMAP 55
+#define MM_MPROTECT 56
+#define MM_COPY_SEGMENTS 57
+
+struct mm_mmap {
+	unsigned long addr;
+	unsigned long len;
+	unsigned long prot;
+	unsigned long flags;
+	unsigned long fd;
+	unsigned long offset;
+};
+
+struct mm_munmap {
+	unsigned long addr;
+	unsigned long len;
+};
+
+struct mm_mprotect {
+	unsigned long addr;
+	unsigned long len;
+	unsigned int prot;
+};
+
+struct proc_mm_op {
+	int op;
+	union {
+		struct mm_mmap mmap;
+		struct mm_munmap munmap;
+	        struct mm_mprotect mprotect;
+		int copy_segments;
+	} u;
+};
+
+#endif
diff --git a/arch/um/include/skas/skas.h b/arch/um/include/skas/skas.h
new file mode 100644
index 0000000..8635728
--- /dev/null
+++ b/arch/um/include/skas/skas.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __SKAS_H
+#define __SKAS_H
+
+#include "mm_id.h"
+#include "sysdep/ptrace.h"
+
+extern int userspace_pid[];
+extern int proc_mm, ptrace_faultinfo, ptrace_ldt;
+extern int skas_needs_stub;
+
+extern int user_thread(unsigned long stack, int flags);
+extern void new_thread_proc(void *stack, void (*handler)(int sig));
+extern void new_thread_handler(int sig);
+extern void handle_syscall(union uml_pt_regs *regs);
+extern void user_signal(int sig, union uml_pt_regs *regs, int pid);
+extern int new_mm(unsigned long stack);
+extern void get_skas_faultinfo(int pid, struct faultinfo * fi);
+extern long execute_syscall_skas(void *r);
+extern unsigned long current_stub_stack(void);
+
+#endif
diff --git a/arch/um/include/skas/stub-data.h b/arch/um/include/skas/stub-data.h
new file mode 100644
index 0000000..f6ed92c
--- /dev/null
+++ b/arch/um/include/skas/stub-data.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2005 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __STUB_DATA_H
+#define __STUB_DATA_H
+
+#include <sys/time.h>
+
+struct stub_data {
+	long offset;
+	int fd;
+	struct itimerval timer;
+	long err;
+};
+
+#endif
diff --git a/arch/um/include/skas/uaccess-skas.h b/arch/um/include/skas/uaccess-skas.h
new file mode 100644
index 0000000..224a75f
--- /dev/null
+++ b/arch/um/include/skas/uaccess-skas.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __SKAS_UACCESS_H
+#define __SKAS_UACCESS_H
+
+#include "asm/errno.h"
+
+/* No SKAS-specific checking. */
+#define access_ok_skas(type, addr, size) 0
+
+extern int copy_from_user_skas(void *to, const void __user *from, int n);
+extern int copy_to_user_skas(void __user *to, const void *from, int n);
+extern int strncpy_from_user_skas(char *dst, const char __user *src, int count);
+extern int __clear_user_skas(void __user *mem, int len);
+extern int clear_user_skas(void __user *mem, int len);
+extern int strnlen_user_skas(const void __user *str, int len);
+
+#endif
diff --git a/arch/um/include/time_user.h b/arch/um/include/time_user.h
deleted file mode 100644
index 17d7ef2..0000000
--- a/arch/um/include/time_user.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __TIME_USER_H__
-#define __TIME_USER_H__
-
-extern void timer(void);
-extern void switch_timers(int to_real);
-extern void idle_sleep(int secs);
-extern void enable_timer(void);
-extern void prepare_timer(void * ptr);
-extern void disable_timer(void);
-extern unsigned long time_lock(void);
-extern void time_unlock(unsigned long);
-extern void user_time_init(void);
-
-#endif
diff --git a/arch/um/include/tt/debug.h b/arch/um/include/tt/debug.h
new file mode 100644
index 0000000..9778fa8
--- /dev/null
+++ b/arch/um/include/tt/debug.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2000, 2001, 2002  Jeff Dike (jdike@karaya.com) and
+ * Lars Brinkhoff.
+ * Licensed under the GPL
+ */
+
+#ifndef __UML_TT_DEBUG_H
+#define __UML_TT_DEBUG_H
+
+extern int debugger_proxy(int status, pid_t pid);
+extern void child_proxy(pid_t pid, int status);
+extern void init_proxy (pid_t pid, int waiting, int status);
+extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd);
+extern void fake_child_exit(void);
+extern int gdb_config(char *str);
+extern int gdb_remove(int unused);
+
+#endif
diff --git a/arch/um/include/tt/mmu-tt.h b/arch/um/include/tt/mmu-tt.h
new file mode 100644
index 0000000..572a78b
--- /dev/null
+++ b/arch/um/include/tt/mmu-tt.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __TT_MMU_H
+#define __TT_MMU_H
+
+struct mmu_context_tt {
+};
+
+#endif
diff --git a/arch/um/include/tt/mode-tt.h b/arch/um/include/tt/mode-tt.h
new file mode 100644
index 0000000..2823cd5
--- /dev/null
+++ b/arch/um/include/tt/mode-tt.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __MODE_TT_H__
+#define __MODE_TT_H__
+
+#include "sysdep/ptrace.h"
+
+enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
+
+extern int tracing_pid;
+
+extern int tracer(int (*init_proc)(void *), void *sp);
+extern void sig_handler_common_tt(int sig, void *sc);
+extern void syscall_handler_tt(int sig, union uml_pt_regs *regs);
+extern void reboot_tt(void);
+extern void halt_tt(void);
+extern int is_tracer_winch(int pid, int fd, void *data);
+extern void kill_off_processes_tt(void);
+
+#endif
diff --git a/arch/um/include/tt/mode_kern_tt.h b/arch/um/include/tt/mode_kern_tt.h
new file mode 100644
index 0000000..efa0012
--- /dev/null
+++ b/arch/um/include/tt/mode_kern_tt.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __TT_MODE_KERN_H__
+#define __TT_MODE_KERN_H__
+
+#include "linux/sched.h"
+#include "asm/page.h"
+#include "asm/ptrace.h"
+#include "asm/uaccess.h"
+
+extern void switch_to_tt(void *prev, void *next);
+extern void flush_thread_tt(void);
+extern void start_thread_tt(struct pt_regs *regs, unsigned long eip,
+			   unsigned long esp);
+extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
+			  unsigned long stack_top, struct task_struct *p,
+			  struct pt_regs *regs);
+extern void release_thread_tt(struct task_struct *task);
+extern void initial_thread_cb_tt(void (*proc)(void *), void *arg);
+extern void init_idle_tt(void);
+extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end);
+extern void flush_tlb_kernel_vm_tt(void);
+extern void __flush_tlb_one_tt(unsigned long addr);
+extern void flush_tlb_range_tt(struct vm_area_struct *vma,
+			       unsigned long start, unsigned long end);
+extern void flush_tlb_mm_tt(struct mm_struct *mm);
+extern void force_flush_all_tt(void);
+extern long execute_syscall_tt(void *r);
+extern void before_mem_tt(unsigned long brk_start);
+extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out,
+				       unsigned long *task_size_out);
+extern int start_uml_tt(void);
+extern int external_pid_tt(struct task_struct *task);
+extern int thread_pid_tt(struct task_struct *task);
+
+#define kmem_end_tt (host_task_size - ABOVE_KMEM)
+
+#endif
diff --git a/arch/um/include/tt/tt.h b/arch/um/include/tt/tt.h
new file mode 100644
index 0000000..8085219
--- /dev/null
+++ b/arch/um/include/tt/tt.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __TT_H__
+#define __TT_H__
+
+#include "sysdep/ptrace.h"
+
+extern int gdb_pid;
+extern int debug;
+extern int debug_stop;
+extern int debug_trace;
+
+extern int honeypot;
+
+extern int fork_tramp(void *sig_stack);
+extern int do_proc_op(void *t, int proc_id);
+extern int tracer(int (*init_proc)(void *), void *sp);
+extern void attach_process(int pid);
+extern void tracer_panic(char *format, ...);
+extern void set_init_pid(int pid);
+extern int set_user_mode(void *task);
+extern void set_tracing(void *t, int tracing);
+extern int is_tracing(void *task);
+extern void syscall_handler(int sig, union uml_pt_regs *regs);
+extern void exit_kernel(int pid, void *task);
+extern void do_syscall(void *task, int pid, int local_using_sysemu);
+extern void do_sigtrap(void *task);
+extern int is_valid_pid(int pid);
+extern void remap_data(void *segment_start, void *segment_end, int w);
+extern long execute_syscall_tt(void *r);
+
+#endif
+
diff --git a/arch/um/include/tt/uaccess-tt.h b/arch/um/include/tt/uaccess-tt.h
new file mode 100644
index 0000000..b19645f
--- /dev/null
+++ b/arch/um/include/tt/uaccess-tt.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __TT_UACCESS_H
+#define __TT_UACCESS_H
+
+#include "linux/string.h"
+#include "linux/sched.h"
+#include "asm/processor.h"
+#include "asm/errno.h"
+#include "asm/current.h"
+#include "asm/a.out.h"
+#include "uml_uaccess.h"
+
+#define ABOVE_KMEM (16 * 1024 * 1024)
+
+extern unsigned long end_vm;
+extern unsigned long uml_physmem;
+
+#define is_stack(addr, size) \
+	(((unsigned long) (addr) < STACK_TOP) && \
+	 ((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \
+	 (((unsigned long) (addr) + (size)) <= STACK_TOP))
+
+#define access_ok_tt(type, addr, size) \
+	(is_stack(addr, size))
+
+extern unsigned long get_fault_addr(void);
+
+extern int __do_copy_from_user(void *to, const void *from, int n,
+			       void **fault_addr, void **fault_catcher);
+extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
+				  void **fault_addr, void **fault_catcher);
+extern int __do_clear_user(void *mem, size_t len, void **fault_addr,
+			   void **fault_catcher);
+extern int __do_strnlen_user(const char *str, unsigned long n,
+			     void **fault_addr, void **fault_catcher);
+
+extern int copy_from_user_tt(void *to, const void __user *from, int n);
+extern int copy_to_user_tt(void __user *to, const void *from, int n);
+extern int strncpy_from_user_tt(char *dst, const char __user *src, int count);
+extern int __clear_user_tt(void __user *mem, int len);
+extern int clear_user_tt(void __user *mem, int len);
+extern int strnlen_user_tt(const void __user *str, int len);
+
+#endif
diff --git a/arch/um/include/user.h b/arch/um/include/user.h
index 0f865ef..91b0ac4 100644
--- a/arch/um/include/user.h
+++ b/arch/um/include/user.h
@@ -18,6 +18,7 @@ extern int open_gdb_chan(void);
 extern unsigned long strlcpy(char *, const char *, unsigned long);
 extern unsigned long strlcat(char *, const char *, unsigned long);
 extern void *um_vmalloc(int size);
+extern void *um_vmalloc_atomic(int size);
 extern void vfree(void *ptr);
 
 #endif
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h
index c1dbd77..a6f1f17 100644
--- a/arch/um/include/user_util.h
+++ b/arch/um/include/user_util.h
@@ -44,10 +44,6 @@ extern unsigned long brk_start;
 extern int pty_output_sigio;
 extern int pty_close_sigio;
 
-extern void stop(void);
-extern void stack_protections(unsigned long address);
-extern void task_protections(unsigned long address);
-extern int wait_for_stop(int pid, int sig, int cont_type, void *relay);
 extern void *add_signal_handler(int sig, void (*handler)(int));
 extern int linux_main(int argc, char **argv);
 extern void set_cmdline(char *cmd);
@@ -55,8 +51,6 @@ extern void input_cb(void (*proc)(void *
 extern int get_pty(void);
 extern void *um_kmalloc(int size);
 extern int switcheroo(int fd, int prot, void *from, void *to, int size);
-extern void setup_machinename(char *machine_out);
-extern void setup_hostinfo(void);
 extern void do_exec(int old_pid, int new_pid);
 extern void tracer_panic(char *msg, ...);
 extern int detach(int pid, int sig);
@@ -70,18 +64,6 @@ extern int cpu_feature(char *what, char 
 extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
 extern int arch_fixup(unsigned long address, void *sc_ptr);
 extern void arch_init_thread(void);
-extern int setjmp_wrapper(void (*proc)(void *, void *), ...);
 extern int raw(int fd);
 
 #endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index 193cc2b..693018b 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -9,9 +9,8 @@ clean-files :=
 obj-y = config.o exec_kern.o exitcode.o \
 	init_task.o irq.o irq_user.o ksyms.o mem.o physmem.o \
 	process_kern.o ptrace.o reboot.o resource.o sigio_user.o sigio_kern.o \
-	signal_kern.o smp.o syscall_kern.o sysrq.o time.o \
-	time_kern.o tlb.o trap_kern.o uaccess.o um_arch.o umid.o \
-	user_util.o
+	signal_kern.o smp.o syscall_kern.o sysrq.o \
+	time_kern.o tlb.o trap_kern.o uaccess.o um_arch.o umid.o
 
 obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
 obj-$(CONFIG_GPROF)	+= gprof_syms.o
@@ -24,7 +23,7 @@ obj-$(CONFIG_MODE_SKAS) += skas/
 
 user-objs-$(CONFIG_TTY_LOG) += tty_log.o
 
-USER_OBJS := $(user-objs-y) config.o time.o tty_log.o user_util.o
+USER_OBJS := $(user-objs-y) config.o tty_log.o
 
 include arch/um/scripts/Makefile.rules
 
diff --git a/arch/um/kernel/exec_kern.c b/arch/um/kernel/exec_kern.c
index efd222f..c264e1c 100644
--- a/arch/um/kernel/exec_kern.c
+++ b/arch/um/kernel/exec_kern.c
@@ -17,7 +17,6 @@
 #include "irq_user.h"
 #include "tlb.h"
 #include "os.h"
-#include "time_user.h"
 #include "choose-mode.h"
 #include "mode_kern.h"
 
@@ -34,7 +33,7 @@ void start_thread(struct pt_regs *regs, 
 extern void log_exec(char **argv, void *tty);
 
 static long execve1(char *file, char __user * __user *argv,
-		    char *__user __user *env)
+		    char __user *__user *env)
 {
         long error;
 
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index f3b583a..544665e 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -265,7 +265,7 @@ int init_maps(unsigned long physmem, uns
 	highmem_len = highmem_pages * sizeof(struct page);
 
 	total_pages = phys_pages + iomem_pages + highmem_pages;
-	total_len = phys_len + iomem_pages + highmem_len;
+	total_len = phys_len + iomem_len + highmem_len;
 
 	if(kmalloc_ok){
 		map = kmalloc(total_len, GFP_KERNEL);
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index 7f13b85..3113cab 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -39,7 +39,6 @@
 #include "init.h"
 #include "irq_user.h"
 #include "mem_user.h"
-#include "time_user.h"
 #include "tlb.h"
 #include "frame_kern.h"
 #include "sigcontext.h"
@@ -288,17 +287,27 @@ EXPORT_SYMBOL(disable_hlt);
 
 void *um_kmalloc(int size)
 {
-	return(kmalloc(size, GFP_KERNEL));
+	return kmalloc(size, GFP_KERNEL);
 }
 
 void *um_kmalloc_atomic(int size)
 {
-	return(kmalloc(size, GFP_ATOMIC));
+	return kmalloc(size, GFP_ATOMIC);
 }
 
 void *um_vmalloc(int size)
 {
-	return(vmalloc(size));
+	return vmalloc(size);
+}
+
+void *um_vmalloc_atomic(int size)
+{
+	return __vmalloc(size, GFP_ATOMIC | __GFP_HIGHMEM, PAGE_KERNEL);
+}
+
+int __cant_sleep(void) {
+	return in_atomic() || irqs_disabled() || in_interrupt();
+	/* Is in_interrupt() really needed? */
 }
 
 unsigned long get_fault_addr(void)
@@ -370,11 +379,6 @@ int smp_sigio_handler(void)
 	return(0);
 }
 
-int um_in_interrupt(void)
-{
-	return(in_interrupt());
-}
-
 int cpu(void)
 {
 	return(current_thread->cpu);
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index 6f1a3a2..3ef73bf 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -5,6 +5,7 @@
 
 #include "linux/module.h"
 #include "linux/sched.h"
+#include "asm/smp.h"
 #include "user_util.h"
 #include "kern_util.h"
 #include "kern.h"
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c
index 62e5cfd..f7b18e1 100644
--- a/arch/um/kernel/sigio_user.c
+++ b/arch/um/kernel/sigio_user.c
@@ -337,70 +337,103 @@ int ignore_sigio_fd(int fd)
 	return(err);
 }
 
-static int setup_initial_poll(int fd)
+static struct pollfd* setup_initial_poll(int fd)
 {
 	struct pollfd *p;
 
-	p = um_kmalloc_atomic(sizeof(struct pollfd));
-	if(p == NULL){
+	p = um_kmalloc(sizeof(struct pollfd));
+	if (p == NULL) {
 		printk("setup_initial_poll : failed to allocate poll\n");
-		return(-1);
+		return NULL;
 	}
 	*p = ((struct pollfd) { .fd  	= fd,
 				.events 	= POLLIN,
 				.revents 	= 0 });
-	current_poll = ((struct pollfds) { .poll 	= p,
-					   .used 	= 1,
-					   .size 	= 1 });
-	return(0);
+	return p;
 }
 
 void write_sigio_workaround(void)
 {
 	unsigned long stack;
+	struct pollfd *p;
 	int err;
+	int l_write_sigio_fds[2];
+	int l_sigio_private[2];
+	int l_write_sigio_pid;
 
+	/* We call this *tons* of times - and most ones we must just fail. */
 	sigio_lock();
-	if(write_sigio_pid != -1)
-		goto out;
+	l_write_sigio_pid = write_sigio_pid;
+	sigio_unlock();
 
-	err = os_pipe(write_sigio_fds, 1, 1);
+	if (l_write_sigio_pid != -1)
+		return;
+
+	err = os_pipe(l_write_sigio_fds, 1, 1);
 	if(err < 0){
 		printk("write_sigio_workaround - os_pipe 1 failed, "
 		       "err = %d\n", -err);
-		goto out;
+		return;
 	}
-	err = os_pipe(sigio_private, 1, 1);
+	err = os_pipe(l_sigio_private, 1, 1);
 	if(err < 0){
-		printk("write_sigio_workaround - os_pipe 2 failed, "
+		printk("write_sigio_workaround - os_pipe 1 failed, "
 		       "err = %d\n", -err);
 		goto out_close1;
 	}
-	if(setup_initial_poll(sigio_private[1]))
+
+	p = setup_initial_poll(l_sigio_private[1]);
+	if(!p)
 		goto out_close2;
 
-	write_sigio_pid = run_helper_thread(write_sigio_thread, NULL, 
+	sigio_lock();
+
+	/* Did we race? Don't try to optimize this, please, it's not so likely
+	 * to happen, and no more than once at the boot. */
+	if(write_sigio_pid != -1)
+		goto out_unlock;
+
+	write_sigio_pid = run_helper_thread(write_sigio_thread, NULL,
 					    CLONE_FILES | CLONE_VM, &stack, 0);
 
-	if(write_sigio_pid < 0) goto out_close2;
+	if (write_sigio_pid < 0)
+		goto out_clear;
 
-	if(write_sigio_irq(write_sigio_fds[0])) 
+	if (write_sigio_irq(l_write_sigio_fds[0]))
 		goto out_kill;
 
- out:
+	/* Success, finally. */
+	memcpy(write_sigio_fds, l_write_sigio_fds, sizeof(l_write_sigio_fds));
+	memcpy(sigio_private, l_sigio_private, sizeof(l_sigio_private));
+
+	current_poll = ((struct pollfds) { .poll 	= p,
+					   .used 	= 1,
+					   .size 	= 1 });
+
 	sigio_unlock();
 	return;
 
  out_kill:
-	os_kill_process(write_sigio_pid, 1);
+	l_write_sigio_pid = write_sigio_pid;
 	write_sigio_pid = -1;
+	sigio_unlock();
+	/* Going to call waitpid, avoid holding the lock. */
+	os_kill_process(l_write_sigio_pid, 1);
+	goto out_free;
+
+ out_clear:
+	write_sigio_pid = -1;
+ out_unlock:
+	sigio_unlock();
+ out_free:
+	kfree(p);
  out_close2:
-	os_close_file(sigio_private[0]);
-	os_close_file(sigio_private[1]);
+	os_close_file(l_sigio_private[0]);
+	os_close_file(l_sigio_private[1]);
  out_close1:
-	os_close_file(write_sigio_fds[0]);
-	os_close_file(write_sigio_fds[1]);
-	sigio_unlock();
+	os_close_file(l_write_sigio_fds[0]);
+	os_close_file(l_write_sigio_fds[1]);
+	return;
 }
 
 int read_sigio_fd(int fd)
diff --git a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal_kern.c
index 7b0e0e8..da17b75 100644
--- a/arch/um/kernel/signal_kern.c
+++ b/arch/um/kernel/signal_kern.c
@@ -99,31 +99,46 @@ static int handle_signal(struct pt_regs 
 	return err;
 }
 
-static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset)
+static int kern_do_signal(struct pt_regs *regs)
 {
 	struct k_sigaction ka_copy;
 	siginfo_t info;
+	sigset_t *oldset;
 	int sig, handled_sig = 0;
 
+	if (test_thread_flag(TIF_RESTORE_SIGMASK))
+		oldset = &current->saved_sigmask;
+	else
+		oldset = &current->blocked;
+
 	while((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0){
 		handled_sig = 1;
 		/* Whee!  Actually deliver the signal.  */
-		if(!handle_signal(regs, sig, &ka_copy, &info, oldset))
+		if(!handle_signal(regs, sig, &ka_copy, &info, oldset)){
+			/* a signal was successfully delivered; the saved
+			 * sigmask will have been stored in the signal frame,
+			 * and will be restored by sigreturn, so we can simply
+			 * clear the TIF_RESTORE_SIGMASK flag */
+			if (test_thread_flag(TIF_RESTORE_SIGMASK))
+				clear_thread_flag(TIF_RESTORE_SIGMASK);
 			break;
+		}
 	}
 
 	/* Did we come from a system call? */
 	if(!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)){
 		/* Restart the system call - no handlers present */
-		if(PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOHAND ||
-		   PT_REGS_SYSCALL_RET(regs) == -ERESTARTSYS ||
-		   PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOINTR){
+		switch(PT_REGS_SYSCALL_RET(regs)){
+		case -ERESTARTNOHAND:
+		case -ERESTARTSYS:
+		case -ERESTARTNOINTR:
 			PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs);
 			PT_REGS_RESTART_SYSCALL(regs);
-		}
-		else if(PT_REGS_SYSCALL_RET(regs) == -ERESTART_RESTARTBLOCK){
+			break;
+		case -ERESTART_RESTARTBLOCK:
 			PT_REGS_SYSCALL_RET(regs) = __NR_restart_syscall;
 			PT_REGS_RESTART_SYSCALL(regs);
+			break;
  		}
 	}
 
@@ -137,12 +152,19 @@ static int kern_do_signal(struct pt_regs
 	if(current->ptrace & PT_DTRACE)
 		current->thread.singlestep_syscall =
 			is_syscall(PT_REGS_IP(&current->thread.regs));
+
+	/* if there's no signal to deliver, we just put the saved sigmask
+	 * back */
+	if (!handled_sig && test_thread_flag(TIF_RESTORE_SIGMASK)) {
+		clear_thread_flag(TIF_RESTORE_SIGMASK);
+		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+	}
 	return(handled_sig);
 }
 
 int do_signal(void)
 {
-	return(kern_do_signal(&current->thread.regs, &current->blocked));
+	return(kern_do_signal(&current->thread.regs));
 }
 
 /*
@@ -150,63 +172,20 @@ int do_signal(void)
  */
 long sys_sigsuspend(int history0, int history1, old_sigset_t mask)
 {
-	sigset_t saveset;
-
 	mask &= _BLOCKABLE;
 	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
+	current->saved_sigmask = current->blocked;
 	siginitset(&current->blocked, mask);
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
 
-	PT_REGS_SYSCALL_RET(&current->thread.regs) = -EINTR;
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		if(kern_do_signal(&current->thread.regs, &saveset))
-			return(-EINTR);
-	}
-}
-
-long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
-{
-	sigset_t saveset, newset;
-
-	/* XXX: Don't preclude handling different sized sigset_t's.  */
-	if (sigsetsize != sizeof(sigset_t))
-		return -EINVAL;
-
-	if (copy_from_user(&newset, unewset, sizeof(newset)))
-		return -EFAULT;
-	sigdelsetmask(&newset, ~_BLOCKABLE);
-
-	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
-	current->blocked = newset;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-
-	PT_REGS_SYSCALL_RET(&current->thread.regs) = -EINTR;
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		if (kern_do_signal(&current->thread.regs, &saveset))
-			return(-EINTR);
-	}
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	set_thread_flag(TIF_RESTORE_SIGMASK);
+	return -ERESTARTNOHAND;
 }
 
 long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
 {
 	return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
 }
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
index 7a9fc16..57181a9 100644
--- a/arch/um/kernel/skas/Makefile
+++ b/arch/um/kernel/skas/Makefile
@@ -1,12 +1,12 @@
-# 
+#
 # Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com)
 # Licensed under the GPL
 #
 
-obj-y := clone.o exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \
+obj-y := clone.o exec_kern.o mem.o mmu.o process_kern.o \
 	syscall.o tlb.o uaccess.o
 
-USER_OBJS := process.o clone.o
+USER_OBJS := clone.o
 
 include arch/um/scripts/Makefile.rules
 
diff --git a/arch/um/kernel/skas/include/mm_id.h b/arch/um/kernel/skas/include/mm_id.h
deleted file mode 100644
index 48dd098..0000000
--- a/arch/um/kernel/skas/include/mm_id.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (C) 2005 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __MM_ID_H
-#define __MM_ID_H
-
-struct mm_id {
-	union {
-		int mm_fd;
-		int pid;
-	} u;
-	unsigned long stack;
-};
-
-#endif
diff --git a/arch/um/kernel/skas/include/mmu-skas.h b/arch/um/kernel/skas/include/mmu-skas.h
deleted file mode 100644
index 44110c5..0000000
--- a/arch/um/kernel/skas/include/mmu-skas.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __SKAS_MMU_H
-#define __SKAS_MMU_H
-
-#include "linux/config.h"
-#include "mm_id.h"
-#include "asm/ldt.h"
-
-struct mmu_context_skas {
-	struct mm_id id;
-        unsigned long last_page_table;
-#ifdef CONFIG_3_LEVEL_PGTABLES
-        unsigned long last_pmd;
-#endif
-	uml_ldt_t ldt;
-};
-
-extern void switch_mm_skas(struct mm_id * mm_idp);
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/skas/include/mode-skas.h b/arch/um/kernel/skas/include/mode-skas.h
deleted file mode 100644
index bcd26a6..0000000
--- a/arch/um/kernel/skas/include/mode-skas.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __MODE_SKAS_H__
-#define __MODE_SKAS_H__
-
-#include <sysdep/ptrace.h>
-
-extern unsigned long exec_regs[];
-extern unsigned long exec_fp_regs[];
-extern unsigned long exec_fpx_regs[];
-extern int have_fpx_regs;
-
-extern void sig_handler_common_skas(int sig, void *sc_ptr);
-extern void halt_skas(void);
-extern void reboot_skas(void);
-extern void kill_off_processes_skas(void);
-extern int is_skas_winch(int pid, int fd, void *data);
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/skas/include/mode_kern-skas.h b/arch/um/kernel/skas/include/mode_kern-skas.h
deleted file mode 100644
index c97a80d..0000000
--- a/arch/um/kernel/skas/include/mode_kern-skas.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __SKAS_MODE_KERN_H__
-#define __SKAS_MODE_KERN_H__
-
-#include "linux/sched.h"
-#include "asm/page.h"
-#include "asm/ptrace.h"
-
-extern void flush_thread_skas(void);
-extern void switch_to_skas(void *prev, void *next);
-extern void start_thread_skas(struct pt_regs *regs, unsigned long eip,
-			      unsigned long esp);
-extern int copy_thread_skas(int nr, unsigned long clone_flags,
-			    unsigned long sp, unsigned long stack_top,
-			    struct task_struct *p, struct pt_regs *regs);
-extern void release_thread_skas(struct task_struct *task);
-extern void initial_thread_cb_skas(void (*proc)(void *), void *arg);
-extern void init_idle_skas(void);
-extern void flush_tlb_kernel_range_skas(unsigned long start,
-					unsigned long end);
-extern void flush_tlb_kernel_vm_skas(void);
-extern void __flush_tlb_one_skas(unsigned long addr);
-extern void flush_tlb_range_skas(struct vm_area_struct *vma,
-				 unsigned long start, unsigned long end);
-extern void flush_tlb_mm_skas(struct mm_struct *mm);
-extern void force_flush_all_skas(void);
-extern long execute_syscall_skas(void *r);
-extern void before_mem_skas(unsigned long unused);
-extern unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
-					 unsigned long *task_size_out);
-extern int start_uml_skas(void);
-extern int external_pid_skas(struct task_struct *task);
-extern int thread_pid_skas(struct task_struct *task);
-
-#define kmem_end_skas (host_task_size - 1024 * 1024)
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/skas/include/proc_mm.h b/arch/um/kernel/skas/include/proc_mm.h
deleted file mode 100644
index cce61a6..0000000
--- a/arch/um/kernel/skas/include/proc_mm.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __SKAS_PROC_MM_H
-#define __SKAS_PROC_MM_H
-
-#define MM_MMAP 54
-#define MM_MUNMAP 55
-#define MM_MPROTECT 56
-#define MM_COPY_SEGMENTS 57
-
-struct mm_mmap {
-	unsigned long addr;
-	unsigned long len;
-	unsigned long prot;
-	unsigned long flags;
-	unsigned long fd;
-	unsigned long offset;
-};
-
-struct mm_munmap {
-	unsigned long addr;
-	unsigned long len;	
-};
-
-struct mm_mprotect {
-	unsigned long addr;
-	unsigned long len;
-        unsigned int prot;
-};
-
-struct proc_mm_op {
-	int op;
-	union {
-		struct mm_mmap mmap;
-		struct mm_munmap munmap;
-	        struct mm_mprotect mprotect;
-		int copy_segments;
-	} u;
-};
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h
deleted file mode 100644
index 01d489d..0000000
--- a/arch/um/kernel/skas/include/skas.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __SKAS_H
-#define __SKAS_H
-
-#include "mm_id.h"
-#include "sysdep/ptrace.h"
-
-extern int userspace_pid[];
-extern int proc_mm, ptrace_faultinfo, ptrace_ldt;
-extern int skas_needs_stub;
-
-extern void switch_threads(void *me, void *next);
-extern void thread_wait(void *sw, void *fb);
-extern void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
-                       void (*handler)(int));
-extern int start_idle_thread(void *stack, void *switch_buf_ptr, 
-			     void **fork_buf_ptr);
-extern int user_thread(unsigned long stack, int flags);
-extern void userspace(union uml_pt_regs *regs);
-extern void new_thread_proc(void *stack, void (*handler)(int sig));
-extern void new_thread_handler(int sig);
-extern void handle_syscall(union uml_pt_regs *regs);
-extern int map(struct mm_id * mm_idp, unsigned long virt,
-	       unsigned long len, int r, int w, int x, int phys_fd,
-	       unsigned long long offset, int done, void **data);
-extern int unmap(struct mm_id * mm_idp, void *addr, unsigned long len,
-		 int done, void **data);
-extern int protect(struct mm_id * mm_idp, unsigned long addr,
-		   unsigned long len, int r, int w, int x, int done,
-		   void **data);
-extern void user_signal(int sig, union uml_pt_regs *regs, int pid);
-extern int new_mm(int from, unsigned long stack);
-extern int start_userspace(unsigned long stub_stack);
-extern int copy_context_skas0(unsigned long stack, int pid);
-extern void get_skas_faultinfo(int pid, struct faultinfo * fi);
-extern long execute_syscall_skas(void *r);
-extern unsigned long current_stub_stack(void);
-extern long run_syscall_stub(struct mm_id * mm_idp,
-                             int syscall, unsigned long *args, long expected,
-                             void **addr, int done);
-extern long syscall_stub_data(struct mm_id * mm_idp,
-                              unsigned long *data, int data_count,
-                              void **addr, void **stub_addr);
-
-#endif
diff --git a/arch/um/kernel/skas/include/stub-data.h b/arch/um/kernel/skas/include/stub-data.h
deleted file mode 100644
index f6ed92c..0000000
--- a/arch/um/kernel/skas/include/stub-data.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (C) 2005 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __STUB_DATA_H
-#define __STUB_DATA_H
-
-#include <sys/time.h>
-
-struct stub_data {
-	long offset;
-	int fd;
-	struct itimerval timer;
-	long err;
-};
-
-#endif
diff --git a/arch/um/kernel/skas/include/uaccess-skas.h b/arch/um/kernel/skas/include/uaccess-skas.h
deleted file mode 100644
index 64516c5..0000000
--- a/arch/um/kernel/skas/include/uaccess-skas.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __SKAS_UACCESS_H
-#define __SKAS_UACCESS_H
-
-#include "asm/errno.h"
-
-/* No SKAS-specific checking. */
-#define access_ok_skas(type, addr, size) 0
-
-extern int copy_from_user_skas(void *to, const void __user *from, int n);
-extern int copy_to_user_skas(void __user *to, const void *from, int n);
-extern int strncpy_from_user_skas(char *dst, const char __user *src, int count);
-extern int __clear_user_skas(void __user *mem, int len);
-extern int clear_user_skas(void __user *mem, int len);
-extern int strnlen_user_skas(const void __user *str, int len);
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/skas/mem_user.c b/arch/um/kernel/skas/mem_user.c
deleted file mode 100644
index 1d89640..0000000
--- a/arch/um/kernel/skas/mem_user.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <signal.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/wait.h>
-#include <asm/page.h>
-#include <asm/unistd.h>
-#include "mem_user.h"
-#include "mem.h"
-#include "skas.h"
-#include "user.h"
-#include "os.h"
-#include "proc_mm.h"
-#include "ptrace_user.h"
-#include "user_util.h"
-#include "kern_util.h"
-#include "task.h"
-#include "registers.h"
-#include "uml-config.h"
-#include "sysdep/ptrace.h"
-#include "sysdep/stub.h"
-
-extern unsigned long batch_syscall_stub, __syscall_stub_start;
-
-extern void wait_stub_done(int pid, int sig, char * fname);
-
-static inline unsigned long *check_init_stack(struct mm_id * mm_idp,
-					      unsigned long *stack)
-{
-	if(stack == NULL){
-		stack = (unsigned long *) mm_idp->stack + 2;
-		*stack = 0;
-	}
-	return stack;
-}
-
-extern int proc_mm;
-
-int single_count = 0;
-int multi_count = 0;
-int multi_op_count = 0;
-
-static long do_syscall_stub(struct mm_id *mm_idp, void **addr)
-{
-	unsigned long regs[MAX_REG_NR];
-	unsigned long *data;
-	unsigned long *syscall;
-	long ret, offset;
-        int n, pid = mm_idp->u.pid;
-
-	if(proc_mm)
-#warning Need to look up userspace_pid by cpu
-		pid = userspace_pid[0];
-
-	multi_count++;
-
-        get_safe_registers(regs);
-        regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
-		((unsigned long) &batch_syscall_stub -
-                 (unsigned long) &__syscall_stub_start);
-	n = ptrace_setregs(pid, regs);
-	if(n < 0)
-		panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n",
-		      n);
-
-	wait_stub_done(pid, 0, "do_syscall_stub");
-
-	/* When the stub stops, we find the following values on the
-	 * beginning of the stack:
-	 * (long )return_value
-	 * (long )offset to failed sycall-data (0, if no error)
-	 */
-	ret = *((unsigned long *) mm_idp->stack);
-	offset = *((unsigned long *) mm_idp->stack + 1);
-	if (offset) {
-		data = (unsigned long *)(mm_idp->stack +
-					 offset - UML_CONFIG_STUB_DATA);
-		syscall = (unsigned long *)((unsigned long)data + data[0]);
-		printk("do_syscall_stub: syscall %ld failed, return value = "
-		       "0x%lx, expected return value = 0x%lx\n",
-		       syscall[0], ret, syscall[7]);
-		printk("    syscall parameters: "
-		       "0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n",
-		       syscall[1], syscall[2], syscall[3],
-		       syscall[4], syscall[5], syscall[6]);
-		for(n = 1; n < data[0]/sizeof(long); n++) {
-			if(n == 1)
-				printk("    additional syscall data:");
-			if(n % 4 == 1)
-				printk("\n      ");
-			printk("  0x%lx", data[n]);
-		}
-		if(n > 1)
-			printk("\n");
-	}
-	else ret = 0;
-
-	*addr = check_init_stack(mm_idp, NULL);
-
-	return ret;
-}
-
-long run_syscall_stub(struct mm_id * mm_idp, int syscall,
-		      unsigned long *args, long expected, void **addr,
- 		      int done)
-{
- 	unsigned long *stack = check_init_stack(mm_idp, *addr);
-
-	if(done && *addr == NULL)
-		single_count++;
-
- 	*stack += sizeof(long);
-	stack += *stack / sizeof(long);
-
-        *stack++ = syscall;
-        *stack++ = args[0];
-        *stack++ = args[1];
-        *stack++ = args[2];
-        *stack++ = args[3];
-        *stack++ = args[4];
-        *stack++ = args[5];
-	*stack++ = expected;
-        *stack = 0;
-        multi_op_count++;
-
-        if(!done && ((((unsigned long) stack) & ~PAGE_MASK) <
-		     PAGE_SIZE - 10 * sizeof(long))){
-		*addr = stack;
-                return 0;
-        }
-
-	return do_syscall_stub(mm_idp, addr);
-}
-
-long syscall_stub_data(struct mm_id * mm_idp,
-		       unsigned long *data, int data_count,
-		       void **addr, void **stub_addr)
-{
-	unsigned long *stack;
-	int ret = 0;
-
-	/* If *addr still is uninitialized, it *must* contain NULL.
-	 * Thus in this case do_syscall_stub correctly won't be called.
-	 */
-	if((((unsigned long) *addr) & ~PAGE_MASK) >=
-	   PAGE_SIZE - (10 + data_count) * sizeof(long)) {
-		ret = do_syscall_stub(mm_idp, addr);
- 		/* in case of error, don't overwrite data on stack */
-		if(ret)
-			return ret;
-	}
-
-	stack = check_init_stack(mm_idp, *addr);
-	*addr = stack;
-
-	*stack = data_count * sizeof(long);
-
-	memcpy(stack + 1, data, data_count * sizeof(long));
-
-	*stub_addr = (void *)(((unsigned long)(stack + 1) & ~PAGE_MASK) +
-			      UML_CONFIG_STUB_DATA);
-
-	return 0;
-}
-
-int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len,
-	int r, int w, int x, int phys_fd, unsigned long long offset,
-	int done, void **data)
-{
-        int prot, ret;
-
-        prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
-                (x ? PROT_EXEC : 0);
-
-        if(proc_mm){
-                struct proc_mm_op map;
-                int fd = mm_idp->u.mm_fd;
-
-                map = ((struct proc_mm_op) { .op	= MM_MMAP,
-                                             .u		=
-                                             { .mmap	=
-                                               { .addr	= virt,
-                                                 .len	= len,
-                                                 .prot	= prot,
-                                                 .flags	= MAP_SHARED |
-                                                 MAP_FIXED,
-                                                 .fd	= phys_fd,
-                                                 .offset= offset
-                                               } } } );
-		ret = os_write_file(fd, &map, sizeof(map));
-		if(ret != sizeof(map))
-			printk("map : /proc/mm map failed, err = %d\n", -ret);
-		else ret = 0;
-        }
-        else {
-                unsigned long args[] = { virt, len, prot,
-                                         MAP_SHARED | MAP_FIXED, phys_fd,
-                                         MMAP_OFFSET(offset) };
-
-		ret = run_syscall_stub(mm_idp, STUB_MMAP_NR, args, virt,
-				       data, done);
-        }
-
-	return ret;
-}
-
-int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done,
-	  void **data)
-{
-        int ret;
-
-        if(proc_mm){
-                struct proc_mm_op unmap;
-                int fd = mm_idp->u.mm_fd;
-
-                unmap = ((struct proc_mm_op) { .op	= MM_MUNMAP,
-                                               .u	=
-                                               { .munmap	=
-                                                 { .addr	=
-                                                   (unsigned long) addr,
-                                                   .len		= len } } } );
-		ret = os_write_file(fd, &unmap, sizeof(unmap));
-		if(ret != sizeof(unmap))
-			printk("unmap - proc_mm write returned %d\n", ret);
-		else ret = 0;
-        }
-        else {
-                unsigned long args[] = { (unsigned long) addr, len, 0, 0, 0,
-                                         0 };
-
-		ret = run_syscall_stub(mm_idp, __NR_munmap, args, 0,
-				       data, done);
-                if(ret < 0)
-                        printk("munmap stub failed, errno = %d\n", ret);
-        }
-
-        return ret;
-}
-
-int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
-	    int r, int w, int x, int done, void **data)
-{
-        struct proc_mm_op protect;
-        int prot, ret;
-
-        prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
-                (x ? PROT_EXEC : 0);
-
-        if(proc_mm){
-                int fd = mm_idp->u.mm_fd;
-                protect = ((struct proc_mm_op) { .op	= MM_MPROTECT,
-                                                 .u	=
-                                                 { .mprotect	=
-                                                   { .addr	=
-                                                     (unsigned long) addr,
-                                                     .len	= len,
-                                                     .prot	= prot } } } );
-
-                ret = os_write_file(fd, &protect, sizeof(protect));
-                if(ret != sizeof(protect))
-                        printk("protect failed, err = %d", -ret);
-                else ret = 0;
-        }
-        else {
-                unsigned long args[] = { addr, len, prot, 0, 0, 0 };
-
-                ret = run_syscall_stub(mm_idp, __NR_mprotect, args, 0,
-                                       data, done);
-        }
-
-        return ret;
-}
-
-void before_mem_skas(unsigned long unused)
-{
-}
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index 677871f..c5c9885 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -78,7 +78,7 @@ int init_new_context_skas(struct task_st
  	struct mmu_context_skas *from_mm = NULL;
 	struct mmu_context_skas *to_mm = &mm->context.skas;
 	unsigned long stack = 0;
-	int from_fd, ret = -ENOMEM;
+	int ret = -ENOMEM;
 
 	if(skas_needs_stub){
 		stack = get_zeroed_page(GFP_KERNEL);
@@ -108,11 +108,7 @@ int init_new_context_skas(struct task_st
 		from_mm = &current->mm->context.skas;
 
 	if(proc_mm){
-		if(from_mm)
-			from_fd = from_mm->id.u.mm_fd;
-		else from_fd = -1;
-
-		ret = new_mm(from_fd, stack);
+		ret = new_mm(stack);
 		if(ret < 0){
 			printk("init_new_context_skas - new_mm failed, "
 			       "errno = %d\n", ret);
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index 3b3955d..eea1c9c 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -18,7 +18,6 @@
 #include <asm/types.h>
 #include "user.h"
 #include "ptrace_user.h"
-#include "time_user.h"
 #include "sysdep/ptrace.h"
 #include "user_util.h"
 #include "kern_util.h"
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index dc41c6d..3f70a2e 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
@@ -13,14 +13,12 @@
 #include "asm/uaccess.h"
 #include "asm/atomic.h"
 #include "kern_util.h"
-#include "time_user.h"
 #include "skas.h"
 #include "os.h"
 #include "user_util.h"
 #include "tlb.h"
 #include "kern.h"
 #include "mode.h"
-#include "proc_mm.h"
 #include "registers.h"
 
 void switch_to_skas(void *prev, void *next)
@@ -34,7 +32,7 @@ void switch_to_skas(void *prev, void *ne
 	if(current->pid == 0)
 		switch_timers(0);
 
-	switch_threads(&from->thread.mode.skas.switch_buf, 
+	switch_threads(&from->thread.mode.skas.switch_buf,
 		       to->thread.mode.skas.switch_buf);
 
 	if(current->pid == 0)
@@ -50,8 +48,8 @@ void new_thread_handler(int sig)
 
 	fn = current->thread.request.u.thread.proc;
 	arg = current->thread.request.u.thread.arg;
-	change_sig(SIGUSR1, 1);
-	thread_wait(&current->thread.mode.skas.switch_buf, 
+	os_usr1_signal(1);
+	thread_wait(&current->thread.mode.skas.switch_buf,
 		    current->thread.mode.skas.fork_buf);
 
 	if(current->thread.prev_sched != NULL)
@@ -82,8 +80,8 @@ void release_thread_skas(struct task_str
 
 void fork_handler(int sig)
 {
-        change_sig(SIGUSR1, 1);
- 	thread_wait(&current->thread.mode.skas.switch_buf, 
+	os_usr1_signal(1);
+	thread_wait(&current->thread.mode.skas.switch_buf,
 		    current->thread.mode.skas.fork_buf);
   	
 	force_flush_all();
@@ -93,13 +91,13 @@ void fork_handler(int sig)
 	schedule_tail(current->thread.prev_sched);
 	current->thread.prev_sched = NULL;
 
-	/* Handle any immediate reschedules or signals */
+/* Handle any immediate reschedules or signals */
 	interrupt_end();
 	userspace(&current->thread.regs.regs);
 }
 
 int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp,
-		     unsigned long stack_top, struct task_struct * p, 
+		     unsigned long stack_top, struct task_struct * p,
 		     struct pt_regs *regs)
 {
   	void (*handler)(int);
@@ -123,27 +121,14 @@ int copy_thread_skas(int nr, unsigned lo
 	return(0);
 }
 
-extern void map_stub_pages(int fd, unsigned long code,
-			   unsigned long data, unsigned long stack);
-int new_mm(int from, unsigned long stack)
+int new_mm(unsigned long stack)
 {
-	struct proc_mm_op copy;
-	int n, fd;
+	int fd;
 
 	fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0);
 	if(fd < 0)
 		return(fd);
 
-	if(from != -1){
-		copy = ((struct proc_mm_op) { .op 	= MM_COPY_SEGMENTS,
-					      .u 	=
-					      { .copy_segments	= from } } );
-		n = os_write_file(fd, &copy, sizeof(copy));
-		if(n != sizeof(copy))
-			printk("new_mm : /proc/mm copy_segments failed, "
-			       "err = %d\n", -n);
-	}
-
 	if(skas_needs_stub)
 		map_stub_pages(fd, CONFIG_STUB_CODE, CONFIG_STUB_DATA, stack);
 
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index a5a4752..5992c32 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -13,7 +13,7 @@
 #include "asm/pgtable.h"
 #include "asm/uaccess.h"
 #include "kern_util.h"
-#include "user_util.h"
+#include "os.h"
 
 extern void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
 			     pte_t *pte_out);
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c
index 1429c13..1731d90 100644
--- a/arch/um/kernel/syscall.c
+++ b/arch/um/kernel/syscall.c
@@ -25,12 +25,12 @@ int record_syscall_start(int syscall)
 	syscall_record[index].syscall = syscall;
 	syscall_record[index].pid = current_pid();
 	syscall_record[index].result = 0xdeadbeef;
-	syscall_record[index].start = os_usecs();
+	syscall_record[index].start = os_nsecs();
 	return(index);
 }
 
 void record_syscall_end(int index, long result)
 {
 	syscall_record[index].result = result;
-	syscall_record[index].end = os_usecs();
+	syscall_record[index].end = os_nsecs();
 }
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
index 020ca79..3c7626c 100644
--- a/arch/um/kernel/time_kern.c
+++ b/arch/um/kernel/time_kern.c
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
@@ -13,12 +13,12 @@
 #include "linux/interrupt.h"
 #include "linux/init.h"
 #include "linux/delay.h"
+#include "linux/hrtimer.h"
 #include "asm/irq.h"
 #include "asm/param.h"
 #include "asm/current.h"
 #include "kern_util.h"
 #include "user_util.h"
-#include "time_user.h"
 #include "mode.h"
 #include "os.h"
 
@@ -39,7 +39,7 @@ unsigned long long sched_clock(void)
 int timer_irq_inited = 0;
 
 static int first_tick;
-static unsigned long long prev_usecs;
+static unsigned long long prev_nsecs;
 #ifdef CONFIG_UML_REAL_TIME_CLOCK
 static long long delta;   		/* Deviation per interval */
 #endif
@@ -58,23 +58,23 @@ void timer_irq(union uml_pt_regs *regs)
 	if(first_tick){
 #ifdef CONFIG_UML_REAL_TIME_CLOCK
 		/* We've had 1 tick */
-		unsigned long long usecs = os_usecs();
+		unsigned long long nsecs = os_nsecs();
 
-		delta += usecs - prev_usecs;
-		prev_usecs = usecs;
+		delta += nsecs - prev_nsecs;
+		prev_nsecs = nsecs;
 
 		/* Protect against the host clock being set backwards */
 		if(delta < 0)
 			delta = 0;
 
-		ticks += (delta * HZ) / MILLION;
-		delta -= (ticks * MILLION) / HZ;
+		ticks += (delta * HZ) / BILLION;
+		delta -= (ticks * BILLION) / HZ;
 #else
 		ticks = 1;
 #endif
 	}
 	else {
-		prev_usecs = os_usecs();
+		prev_nsecs = os_nsecs();
 		first_tick = 1;
 	}
 
@@ -84,49 +84,102 @@ void timer_irq(union uml_pt_regs *regs)
 	}
 }
 
-void boot_timer_handler(int sig)
+void do_boot_timer_handler(struct sigcontext * sc)
 {
 	struct pt_regs regs;
 
-	CHOOSE_MODE((void) 
-		    (UPT_SC(&regs.regs) = (struct sigcontext *) (&sig + 1)),
+	CHOOSE_MODE((void) (UPT_SC(&regs.regs) = sc),
 		    (void) (regs.regs.skas.is_user = 0));
 	do_timer(&regs);
 }
 
+static DEFINE_SPINLOCK(timer_spinlock);
+
+static unsigned long long local_offset = 0;
+
+static inline unsigned long long get_time(void)
+{
+	unsigned long long nsecs;
+	unsigned long flags;
+
+	spin_lock_irqsave(&timer_spinlock, flags);
+	nsecs = os_nsecs();
+	nsecs += local_offset;
+	spin_unlock_irqrestore(&timer_spinlock, flags);
+
+	return nsecs;
+}
+
 irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
 {
+	unsigned long long nsecs;
 	unsigned long flags;
 
 	do_timer(regs);
+
 	write_seqlock_irqsave(&xtime_lock, flags);
-	timer();
+	nsecs = get_time() + local_offset;
+	xtime.tv_sec = nsecs / NSEC_PER_SEC;
+	xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC;
 	write_sequnlock_irqrestore(&xtime_lock, flags);
+
 	return(IRQ_HANDLED);
 }
 
 long um_time(int __user *tloc)
 {
-	struct timeval now;
+	long ret = get_time() / NSEC_PER_SEC;
 
-	do_gettimeofday(&now);
-	if (tloc) {
- 		if (put_user(now.tv_sec, tloc))
-			now.tv_sec = -EFAULT;
-	}
-	return now.tv_sec;
+	if((tloc != NULL) && put_user(ret, tloc))
+		return -EFAULT;
+
+	return ret;
+}
+
+void do_gettimeofday(struct timeval *tv)
+{
+	unsigned long long nsecs = get_time();
+
+	tv->tv_sec = nsecs / NSEC_PER_SEC;
+	/* Careful about calculations here - this was originally done as
+	 * (nsecs - tv->tv_sec * NSEC_PER_SEC) / NSEC_PER_USEC
+	 * which gave bogus (> 1000000) values.  Dunno why, suspect gcc
+	 * (4.0.0) miscompiled it, or there's a subtle 64/32-bit conversion
+	 * problem that I missed.
+	 */
+	nsecs -= tv->tv_sec * NSEC_PER_SEC;
+	tv->tv_usec = (unsigned long) nsecs / NSEC_PER_USEC;
+}
+
+static inline void set_time(unsigned long long nsecs)
+{
+	unsigned long long now;
+	unsigned long flags;
+
+	spin_lock_irqsave(&timer_spinlock, flags);
+	now = os_nsecs();
+	local_offset = nsecs - now;
+	spin_unlock_irqrestore(&timer_spinlock, flags);
+
+	clock_was_set();
 }
 
 long um_stime(int __user *tptr)
 {
 	int value;
-	struct timespec new;
 
 	if (get_user(value, tptr))
                 return -EFAULT;
-	new.tv_sec = value;
-	new.tv_nsec = 0;
-	do_settimeofday(&new);
+
+	set_time((unsigned long long) value * NSEC_PER_SEC);
+
+	return 0;
+}
+
+int do_settimeofday(struct timespec *tv)
+{
+	set_time((unsigned long long) tv->tv_sec * NSEC_PER_SEC + tv->tv_nsec);
+
 	return 0;
 }
 
@@ -134,29 +187,15 @@ void timer_handler(int sig, union uml_pt
 {
 	local_irq_disable();
 	irq_enter();
-	update_process_times(CHOOSE_MODE(user_context(UPT_SP(regs)),
-					 (regs)->skas.is_user));
+	update_process_times(CHOOSE_MODE(
+	                     (UPT_SC(regs) && user_context(UPT_SP(regs))),
+			     (regs)->skas.is_user));
 	irq_exit();
 	local_irq_enable();
 	if(current_thread->cpu == 0)
 		timer_irq(regs);
 }
 
-static DEFINE_SPINLOCK(timer_spinlock);
-
-unsigned long time_lock(void)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&timer_spinlock, flags);
-	return(flags);
-}
-
-void time_unlock(unsigned long flags)
-{
-	spin_unlock_irqrestore(&timer_spinlock, flags);
-}
-
 int __init timer_init(void)
 {
 	int err;
@@ -171,14 +210,3 @@ int __init timer_init(void)
 }
 
 __initcall(timer_init);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c
index 8f40e48..5c1e4cc 100644
--- a/arch/um/kernel/tt/exec_kern.c
+++ b/arch/um/kernel/tt/exec_kern.c
@@ -13,7 +13,6 @@
 #include "user_util.h"
 #include "kern_util.h"
 #include "irq_user.h"
-#include "time_user.h"
 #include "mem_user.h"
 #include "os.h"
 #include "tlb.h"
diff --git a/arch/um/kernel/tt/gdb.c b/arch/um/kernel/tt/gdb.c
index 37e22d7..786e4ed 100644
--- a/arch/um/kernel/tt/gdb.c
+++ b/arch/um/kernel/tt/gdb.c
@@ -20,6 +20,7 @@
 #include "user_util.h"
 #include "tt.h"
 #include "sysdep/thread.h"
+#include "os.h"
 
 extern int debugger_pid;
 extern int debugger_fd;
diff --git a/arch/um/kernel/tt/include/debug.h b/arch/um/kernel/tt/include/debug.h
deleted file mode 100644
index 7384354..0000000
--- a/arch/um/kernel/tt/include/debug.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* 
- * Copyright (C) 2000, 2001, 2002  Jeff Dike (jdike@karaya.com) and
- * Lars Brinkhoff.
- * Licensed under the GPL
- */
-
-#ifndef __UML_TT_DEBUG_H
-#define __UML_TT_DEBUG_H
-
-extern int debugger_proxy(int status, pid_t pid);
-extern void child_proxy(pid_t pid, int status);
-extern void init_proxy (pid_t pid, int waiting, int status);
-extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd);
-extern void fake_child_exit(void);
-extern int gdb_config(char *str);
-extern int gdb_remove(int unused);
-
-#endif
diff --git a/arch/um/kernel/tt/include/mmu-tt.h b/arch/um/kernel/tt/include/mmu-tt.h
deleted file mode 100644
index 0440510..0000000
--- a/arch/um/kernel/tt/include/mmu-tt.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __TT_MMU_H
-#define __TT_MMU_H
-
-struct mmu_context_tt {
-};
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/include/tt.h b/arch/um/kernel/tt/include/tt.h
deleted file mode 100644
index c667b67..0000000
--- a/arch/um/kernel/tt/include/tt.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __TT_H__
-#define __TT_H__
-
-#include "sysdep/ptrace.h"
-
-extern int gdb_pid;
-extern int debug;
-extern int debug_stop;
-extern int debug_trace;
-
-extern int honeypot;
-
-extern int fork_tramp(void *sig_stack);
-extern int do_proc_op(void *t, int proc_id);
-extern int tracer(int (*init_proc)(void *), void *sp);
-extern void attach_process(int pid);
-extern void tracer_panic(char *format, ...);
-extern void set_init_pid(int pid);
-extern int set_user_mode(void *task);
-extern void set_tracing(void *t, int tracing);
-extern int is_tracing(void *task);
-extern void syscall_handler(int sig, union uml_pt_regs *regs);
-extern void exit_kernel(int pid, void *task);
-extern void do_syscall(void *task, int pid, int local_using_sysemu);
-extern void do_sigtrap(void *task);
-extern int is_valid_pid(int pid);
-extern void remap_data(void *segment_start, void *segment_end, int w);
-extern long execute_syscall_tt(void *r);
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/include/uaccess-tt.h b/arch/um/kernel/tt/include/uaccess-tt.h
deleted file mode 100644
index b9bfe9c..0000000
--- a/arch/um/kernel/tt/include/uaccess-tt.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
- * Licensed under the GPL
- */
-
-#ifndef __TT_UACCESS_H
-#define __TT_UACCESS_H
-
-#include "linux/string.h"
-#include "linux/sched.h"
-#include "asm/processor.h"
-#include "asm/errno.h"
-#include "asm/current.h"
-#include "asm/a.out.h"
-#include "uml_uaccess.h"
-
-#define ABOVE_KMEM (16 * 1024 * 1024)
-
-extern unsigned long end_vm;
-extern unsigned long uml_physmem;
-
-#define is_stack(addr, size) \
-	(((unsigned long) (addr) < STACK_TOP) && \
-	 ((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \
-	 (((unsigned long) (addr) + (size)) <= STACK_TOP))
-
-#define access_ok_tt(type, addr, size) \
-	(is_stack(addr, size))
-
-extern unsigned long get_fault_addr(void);
-
-extern int __do_copy_from_user(void *to, const void *from, int n,
-			       void **fault_addr, void **fault_catcher);
-extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
-				  void **fault_addr, void **fault_catcher);
-extern int __do_clear_user(void *mem, size_t len, void **fault_addr,
-			   void **fault_catcher);
-extern int __do_strnlen_user(const char *str, unsigned long n,
-			     void **fault_addr, void **fault_catcher);
-
-extern int copy_from_user_tt(void *to, const void __user *from, int n);
-extern int copy_to_user_tt(void __user *to, const void *from, int n);
-extern int strncpy_from_user_tt(char *dst, const char __user *src, int count);
-extern int __clear_user_tt(void __user *mem, int len);
-extern int clear_user_tt(void __user *mem, int len);
-extern int strnlen_user_tt(const void __user *str, int len);
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
index 6253530..295c1ac 100644
--- a/arch/um/kernel/tt/process_kern.c
+++ b/arch/um/kernel/tt/process_kern.c
@@ -18,7 +18,6 @@
 #include "os.h"
 #include "kern.h"
 #include "sigcontext.h"
-#include "time_user.h"
 #include "mem_user.h"
 #include "tlb.h"
 #include "mode.h"
diff --git a/arch/um/kernel/tt/ptproxy/ptrace.c b/arch/um/kernel/tt/ptproxy/ptrace.c
index 528a5fc..0377442 100644
--- a/arch/um/kernel/tt/ptproxy/ptrace.c
+++ b/arch/um/kernel/tt/ptproxy/ptrace.c
@@ -20,6 +20,7 @@ Jeff Dike (jdike@karaya.com) : Modified 
 #include "kern_util.h"
 #include "ptrace_user.h"
 #include "tt.h"
+#include "os.h"
 
 long proxy_ptrace(struct debugger *debugger, int arg1, pid_t arg2,
 		  long arg3, long arg4, pid_t child, int *ret)
diff --git a/arch/um/kernel/tt/ptproxy/sysdep.c b/arch/um/kernel/tt/ptproxy/sysdep.c
index a5f0e01..99f1783 100644
--- a/arch/um/kernel/tt/ptproxy/sysdep.c
+++ b/arch/um/kernel/tt/ptproxy/sysdep.c
@@ -15,6 +15,7 @@ terms and conditions.
 #include "ptrace_user.h"
 #include "user_util.h"
 #include "user.h"
+#include "os.h"
 
 int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, long *arg4, 
 		long *arg5)
diff --git a/arch/um/kernel/tt/syscall_kern.c b/arch/um/kernel/tt/syscall_kern.c
index 3d29c90..3fda9a0 100644
--- a/arch/um/kernel/tt/syscall_kern.c
+++ b/arch/um/kernel/tt/syscall_kern.c
@@ -23,16 +23,20 @@ void syscall_handler_tt(int sig, struct 
 	int syscall;
 #ifdef CONFIG_SYSCALL_DEBUG
 	int index;
-  	index = record_syscall_start(syscall);
 #endif
 	sc = UPT_SC(&regs->regs);
 	SC_START_SYSCALL(sc);
 
+	syscall = UPT_SYSCALL_NR(&regs->regs);
+
+#ifdef CONFIG_SYSCALL_DEBUG
+	index = record_syscall_start(syscall);
+#endif
+
 	syscall_trace(&regs->regs, 0);
 
 	current->thread.nsyscalls++;
 	nsyscalls++;
-	syscall = UPT_SYSCALL_NR(&regs->regs);
 
 	if((syscall >= NR_syscalls) || (syscall < 0))
 		result = -ENOSYS;
diff --git a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c
index a414c52..b5d9d64 100644
--- a/arch/um/kernel/tt/trap_user.c
+++ b/arch/um/kernel/tt/trap_user.c
@@ -18,7 +18,7 @@ void sig_handler_common_tt(int sig, void
 {
 	struct sigcontext *sc = sc_ptr;
 	struct tt_regs save_regs, *r;
-	int save_errno = errno, is_user;
+	int save_errno = errno, is_user = 0;
 	void (*handler)(int, union uml_pt_regs *);
 
 	/* This is done because to allow SIGSEGV to be delivered inside a SEGV
@@ -35,7 +35,8 @@ void sig_handler_common_tt(int sig, void
                 GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
         }
 	save_regs = *r;
-	is_user = user_context(SC_SP(sc));
+	if (sc)
+		is_user = user_context(SC_SP(sc));
 	r->sc = sc;
 	if(sig != SIGUSR2) 
 		r->syscall = -1;
diff --git a/arch/um/kernel/user_util.c b/arch/um/kernel/user_util.c
deleted file mode 100644
index 4c23116..0000000
--- a/arch/um/kernel/user_util.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/* 
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <limits.h>
-#include <setjmp.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/utsname.h>
-#include <sys/param.h>
-#include <sys/time.h>
-#include "asm/types.h"
-#include <ctype.h>
-#include <signal.h>
-#include <wait.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <sched.h>
-#include <termios.h>
-#include <string.h>
-#include "user_util.h"
-#include "kern_util.h"
-#include "user.h"
-#include "mem_user.h"
-#include "init.h"
-#include "ptrace_user.h"
-#include "uml-config.h"
-
-void stop(void)
-{
-	while(1) sleep(1000000);
-}
-
-void stack_protections(unsigned long address)
-{
-	int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
-
-        if(mprotect((void *) address, page_size(), prot) < 0)
-		panic("protecting stack failed, errno = %d", errno);
-}
-
-void task_protections(unsigned long address)
-{
-	unsigned long guard = address + page_size();
-	unsigned long stack = guard + page_size();
-	int prot = 0, pages;
-
-#ifdef notdef
-	if(mprotect((void *) stack, page_size(), prot) < 0)
-		panic("protecting guard page failed, errno = %d", errno);
-#endif
-	pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
-	prot = PROT_READ | PROT_WRITE | PROT_EXEC;
-	if(mprotect((void *) stack, pages * page_size(), prot) < 0)
-		panic("protecting stack failed, errno = %d", errno);
-}
-
-int wait_for_stop(int pid, int sig, int cont_type, void *relay)
-{
-	sigset_t *relay_signals = relay;
-	int status, ret;
-
-	while(1){
-		CATCH_EINTR(ret = waitpid(pid, &status, WUNTRACED));
-		if((ret < 0) ||
-		   !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
-			if(ret < 0){
-				printk("wait failed, errno = %d\n",
-				       errno);
-			}
-			else if(WIFEXITED(status)) 
-				printk("process %d exited with status %d\n",
-				       pid, WEXITSTATUS(status));
-			else if(WIFSIGNALED(status))
-				printk("process %d exited with signal %d\n",
-				       pid, WTERMSIG(status));
-			else if((WSTOPSIG(status) == SIGVTALRM) ||
-				(WSTOPSIG(status) == SIGALRM) ||
-				(WSTOPSIG(status) == SIGIO) ||
-				(WSTOPSIG(status) == SIGPROF) ||
-				(WSTOPSIG(status) == SIGCHLD) ||
-				(WSTOPSIG(status) == SIGWINCH) ||
-				(WSTOPSIG(status) == SIGINT)){
-				ptrace(cont_type, pid, 0, WSTOPSIG(status));
-				continue;
-			}
-			else if((relay_signals != NULL) &&
-				sigismember(relay_signals, WSTOPSIG(status))){
-				ptrace(cont_type, pid, 0, WSTOPSIG(status));
-				continue;
-			}
-			else printk("process %d stopped with signal %d\n",
-				    pid, WSTOPSIG(status));
-			panic("wait_for_stop failed to wait for %d to stop "
-			      "with %d\n", pid, sig);
-		}
-		return(status);
-	}
-}
-
-int raw(int fd)
-{
-	struct termios tt;
-	int err;
-
-	CATCH_EINTR(err = tcgetattr(fd, &tt));
-	if(err < 0)
-		return -errno;
-
-	cfmakeraw(&tt);
-
- 	CATCH_EINTR(err = tcsetattr(fd, TCSADRAIN, &tt));
-	if(err < 0)
-		return -errno;
-
-	/* XXX tcsetattr could have applied only some changes
-	 * (and cfmakeraw() is a set of changes) */
-	return(0);
-}
-
-void setup_machinename(char *machine_out)
-{
-	struct utsname host;
-
-	uname(&host);
-#if defined(UML_CONFIG_UML_X86) && !defined(UML_CONFIG_64BIT)
-	if (!strcmp(host.machine, "x86_64")) {
-		strcpy(machine_out, "i686");
-		return;
-	}
-#endif
-	strcpy(machine_out, host.machine);
-}
-
-char host_info[(_UTSNAME_LENGTH + 1) * 4 + _UTSNAME_NODENAME_LENGTH + 1];
-
-void setup_hostinfo(void)
-{
-	struct utsname host;
-
-	uname(&host);
-	sprintf(host_info, "%s %s %s %s %s", host.sysname, host.nodename,
-		host.release, host.version, host.machine);
-}
-
-int setjmp_wrapper(void (*proc)(void *, void *), ...)
-{
-        va_list args;
-	sigjmp_buf buf;
-	int n;
-
-	n = sigsetjmp(buf, 1);
-	if(n == 0){
-		va_start(args, proc);
-		(*proc)(&buf, &args);
-	}
-	va_end(args);
-	return(n);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index 40c7d6b..08a4e62 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -5,12 +5,12 @@
 
 obj-y = aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
 	start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o user_syms.o \
-	drivers/ sys-$(SUBARCH)/
+	util.o drivers/ sys-$(SUBARCH)/
 
 obj-$(CONFIG_MODE_SKAS) += skas/
 
 USER_OBJS := aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
-	start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o
+	start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o util.o
 
 elf_aux.o: $(ARCH_DIR)/kernel-offsets.h
 CFLAGS_elf_aux.o += -I$(objtree)/arch/um
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index 36cc847..6490a4f 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -60,7 +60,7 @@ int run_helper(void (*pre_exec)(void *),
 
 	if((stack_out != NULL) && (*stack_out != 0))
 		stack = *stack_out;
-	else stack = alloc_stack(0, um_in_interrupt());
+	else stack = alloc_stack(0, __cant_sleep());
 	if(stack == 0)
 		return(-ENOMEM);
 
@@ -124,7 +124,7 @@ int run_helper_thread(int (*proc)(void *
 	unsigned long stack, sp;
 	int pid, status, err;
 
-	stack = alloc_stack(stack_order, um_in_interrupt());
+	stack = alloc_stack(stack_order, __cant_sleep());
 	if(stack == 0) return(-ENOMEM);
 
 	sp = stack + (page_size() << stack_order) - sizeof(void *);
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index 172c847..2878e89 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -16,7 +16,6 @@
 #include "user_util.h"
 #include "kern_util.h"
 #include "mem_user.h"
-#include "time_user.h"
 #include "irq_user.h"
 #include "user.h"
 #include "init.h"
@@ -82,20 +81,8 @@ extern void scan_elf_aux( char **envp);
 int main(int argc, char **argv, char **envp)
 {
 	char **new_argv;
-	sigset_t mask;
 	int ret, i, err;
 
-	/* Enable all signals except SIGIO - in some environments, we can
-	 * enter with some signals blocked
-	 */
-
-	sigemptyset(&mask);
-	sigaddset(&mask, SIGIO);
-	if(sigprocmask(SIG_SETMASK, &mask, NULL) < 0){
-		perror("sigprocmask");
-		exit(1);
-	}
-
 #ifdef UML_CONFIG_CMDLINE_ON_HOST
 	/* Allocate memory for thread command lines */
 	if(argc < 2 || strlen(argv[1]) < THREAD_NAME_LEN - 1){
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index 39815c6..7f5e2da 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -18,6 +18,7 @@
 #include "process.h"
 #include "irq_user.h"
 #include "kern_util.h"
+#include "longjmp.h"
 
 #define ARBITRARY_ADDR -1
 #define FAILURE_PID    -1
@@ -205,24 +206,13 @@ void init_new_thread_signals(int altstac
 
 int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
 {
-       sigjmp_buf buf;
-       int n;
+	sigjmp_buf buf;
+	int n, enable;
 
-       *jmp_ptr = &buf;
-       n = sigsetjmp(buf, 1);
-       if(n != 0)
-               return(n);
-       (*fn)(arg);
-       return(0);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+	*jmp_ptr = &buf;
+	n = UML_SIGSETJMP(&buf, enable);
+	if(n != 0)
+		return(n);
+	(*fn)(arg);
+	return(0);
+}
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index c1f46a0..f11b312 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -12,32 +12,66 @@
 #include <string.h>
 #include <sys/mman.h>
 #include "user_util.h"
-#include "kern_util.h"
 #include "user.h"
 #include "signal_kern.h"
 #include "sysdep/sigcontext.h"
 #include "sysdep/signal.h"
 #include "sigcontext.h"
-#include "time_user.h"
 #include "mode.h"
+#include "os.h"
+
+/* These are the asynchronous signals.  SIGVTALRM and SIGARLM are handled
+ * together under SIGVTALRM_BIT.  SIGPROF is excluded because we want to
+ * be able to profile all of UML, not just the non-critical sections.  If
+ * profiling is not thread-safe, then that is not my problem.  We can disable
+ * profiling when SMP is enabled in that case.
+ */
+#define SIGIO_BIT 0
+#define SIGIO_MASK (1 << SIGIO_BIT)
+
+#define SIGVTALRM_BIT 1
+#define SIGVTALRM_MASK (1 << SIGVTALRM_BIT)
+
+#define SIGALRM_BIT 2
+#define SIGALRM_MASK (1 << SIGALRM_BIT)
+
+static int signals_enabled = 1;
+static int pending = 0;
 
 void sig_handler(ARCH_SIGHDLR_PARAM)
 {
 	struct sigcontext *sc;
+	int enabled;
+
+	/* Must be the first thing that this handler does - x86_64 stores
+	 * the sigcontext in %rdx, and we need to save it before it has a
+	 * chance to get trashed.
+	 */
 
 	ARCH_GET_SIGCONTEXT(sc, sig);
+
+	enabled = signals_enabled;
+	if(!enabled && (sig == SIGIO)){
+		pending |= SIGIO_MASK;
+		return;
+	}
+
+	block_signals();
+
 	CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
 			 sig, sc);
+
+	set_signals(enabled);
 }
 
 extern int timer_irq_inited;
 
-void alarm_handler(ARCH_SIGHDLR_PARAM)
+static void real_alarm_handler(int sig, struct sigcontext *sc)
 {
-	struct sigcontext *sc;
-
-	ARCH_GET_SIGCONTEXT(sc, sig);
-	if(!timer_irq_inited) return;
+	if(!timer_irq_inited){
+		signals_enabled = 1;
+		return;
+	}
 
 	if(sig == SIGALRM)
 		switch_timers(0);
@@ -47,6 +81,52 @@ void alarm_handler(ARCH_SIGHDLR_PARAM)
 
 	if(sig == SIGALRM)
 		switch_timers(1);
+
+}
+
+void alarm_handler(ARCH_SIGHDLR_PARAM)
+{
+	struct sigcontext *sc;
+	int enabled;
+
+	ARCH_GET_SIGCONTEXT(sc, sig);
+
+	enabled = signals_enabled;
+	if(!signals_enabled){
+		if(sig == SIGVTALRM)
+			pending |= SIGVTALRM_MASK;
+		else pending |= SIGALRM_MASK;
+
+		return;
+	}
+
+	block_signals();
+
+	real_alarm_handler(sig, sc);
+	set_signals(enabled);
+}
+
+extern void do_boot_timer_handler(struct sigcontext * sc);
+
+void boot_timer_handler(ARCH_SIGHDLR_PARAM)
+{
+	struct sigcontext *sc;
+	int enabled;
+
+	ARCH_GET_SIGCONTEXT(sc, sig);
+
+	enabled = signals_enabled;
+	if(!enabled){
+		if(sig == SIGVTALRM)
+			pending |= SIGVTALRM_MASK;
+		else pending |= SIGALRM_MASK;
+		return;
+	}
+
+	block_signals();
+
+	do_boot_timer_handler(sc);
+	set_signals(enabled);
 }
 
 void set_sigstack(void *sig_stack, int size)
@@ -73,6 +153,7 @@ void set_handler(int sig, void (*handler
 {
 	struct sigaction action;
 	va_list ap;
+	sigset_t sig_mask;
 	int mask;
 
 	va_start(ap, flags);
@@ -85,7 +166,12 @@ void set_handler(int sig, void (*handler
 	action.sa_flags = flags;
 	action.sa_restorer = NULL;
 	if(sigaction(sig, &action, NULL) < 0)
-		panic("sigaction failed");
+		panic("sigaction failed - errno = %d\n", errno);
+
+	sigemptyset(&sig_mask);
+	sigaddset(&sig_mask, sig);
+	if(sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
+		panic("sigprocmask failed - errno = %d\n", errno);
 }
 
 int change_sig(int signal, int on)
@@ -98,89 +184,77 @@ int change_sig(int signal, int on)
 	return(!sigismember(&old, signal));
 }
 
-/* Both here and in set/get_signal we don't touch SIGPROF, because we must not
- * disable profiling; it's safe because the profiling code does not interact
- * with the kernel code at all.*/
-
-static void change_signals(int type)
-{
-	sigset_t mask;
-
-	sigemptyset(&mask);
-	sigaddset(&mask, SIGVTALRM);
-	sigaddset(&mask, SIGALRM);
-	sigaddset(&mask, SIGIO);
-	if(sigprocmask(type, &mask, NULL) < 0)
-		panic("Failed to change signal mask - errno = %d", errno);
-}
-
 void block_signals(void)
 {
-	change_signals(SIG_BLOCK);
+	signals_enabled = 0;
 }
 
 void unblock_signals(void)
 {
-	change_signals(SIG_UNBLOCK);
-}
+	int save_pending;
 
-/* These are the asynchronous signals.  SIGVTALRM and SIGARLM are handled
- * together under SIGVTALRM_BIT.  SIGPROF is excluded because we want to
- * be able to profile all of UML, not just the non-critical sections.  If
- * profiling is not thread-safe, then that is not my problem.  We can disable
- * profiling when SMP is enabled in that case.
- */
-#define SIGIO_BIT 0
-#define SIGVTALRM_BIT 1
+	if(signals_enabled == 1)
+		return;
 
-static int enable_mask(sigset_t *mask)
-{
-	int sigs;
+	/* We loop because the IRQ handler returns with interrupts off.  So,
+	 * interrupts may have arrived and we need to re-enable them and
+	 * recheck pending.
+	 */
+	while(1){
+		/* Save and reset save_pending after enabling signals.  This
+		 * way, pending won't be changed while we're reading it.
+		 */
+		signals_enabled = 1;
+
+		save_pending = pending;
+		if(save_pending == 0)
+			return;
+
+		pending = 0;
+
+		/* We have pending interrupts, so disable signals, as the
+		 * handlers expect them off when they are called.  They will
+		 * be enabled again above.
+		 */
+
+		signals_enabled = 0;
+
+		/* Deal with SIGIO first because the alarm handler might
+		 * schedule, leaving the pending SIGIO stranded until we come
+		 * back here.
+		 */
+		if(save_pending & SIGIO_MASK)
+			CHOOSE_MODE_PROC(sig_handler_common_tt,
+					 sig_handler_common_skas, SIGIO, NULL);
 
-	sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT;
-	sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT;
-	sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT;
-	return(sigs);
+		if(save_pending & SIGALRM_MASK)
+			real_alarm_handler(SIGALRM, NULL);
+
+		if(save_pending & SIGVTALRM_MASK)
+			real_alarm_handler(SIGVTALRM, NULL);
+	}
 }
 
 int get_signals(void)
 {
-	sigset_t mask;
-
-	if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0)
-		panic("Failed to get signal mask");
-	return(enable_mask(&mask));
+	return signals_enabled;
 }
 
 int set_signals(int enable)
 {
-	sigset_t mask;
 	int ret;
+	if(signals_enabled == enable)
+		return enable;
 
-	sigemptyset(&mask);
-	if(enable & (1 << SIGIO_BIT))
-		sigaddset(&mask, SIGIO);
-	if(enable & (1 << SIGVTALRM_BIT)){
-		sigaddset(&mask, SIGVTALRM);
-		sigaddset(&mask, SIGALRM);
-	}
+	ret = signals_enabled;
+	if(enable)
+		unblock_signals();
+	else block_signals();
 
-	/* This is safe - sigprocmask is guaranteed to copy locally the
-	 * value of new_set, do his work and then, at the end, write to
-	 * old_set.
-	 */
-	if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
-		panic("Failed to enable signals");
-	ret = enable_mask(&mask);
-	sigemptyset(&mask);
-	if((enable & (1 << SIGIO_BIT)) == 0)
-		sigaddset(&mask, SIGIO);
-	if((enable & (1 << SIGVTALRM_BIT)) == 0){
-		sigaddset(&mask, SIGVTALRM);
-		sigaddset(&mask, SIGALRM);
-	}
-	if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
-		panic("Failed to block signals");
+	return ret;
+}
 
-	return(ret);
+void os_usr1_signal(int on)
+{
+	change_sig(SIGUSR1, on);
 }
diff --git a/arch/um/os-Linux/skas/Makefile b/arch/um/os-Linux/skas/Makefile
index eab5386..5fd8d4d 100644
--- a/arch/um/os-Linux/skas/Makefile
+++ b/arch/um/os-Linux/skas/Makefile
@@ -3,8 +3,8 @@
 # Licensed under the GPL
 #
 
-obj-y := trap.o
+obj-y := mem.o process.o trap.o
 
-USER_OBJS := trap.o
+USER_OBJS := mem.o process.o trap.o
 
 include arch/um/scripts/Makefile.rules
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
new file mode 100644
index 0000000..9890e90
--- /dev/null
+++ b/arch/um/os-Linux/skas/mem.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#include <signal.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+#include <asm/page.h>
+#include <asm/unistd.h>
+#include "mem_user.h"
+#include "mem.h"
+#include "skas.h"
+#include "user.h"
+#include "os.h"
+#include "proc_mm.h"
+#include "ptrace_user.h"
+#include "user_util.h"
+#include "kern_util.h"
+#include "task.h"
+#include "registers.h"
+#include "uml-config.h"
+#include "sysdep/ptrace.h"
+#include "sysdep/stub.h"
+
+extern unsigned long batch_syscall_stub, __syscall_stub_start;
+
+extern void wait_stub_done(int pid, int sig, char * fname);
+
+static inline unsigned long *check_init_stack(struct mm_id * mm_idp,
+					      unsigned long *stack)
+{
+	if(stack == NULL) {
+		stack = (unsigned long *) mm_idp->stack + 2;
+		*stack = 0;
+	}
+	return stack;
+}
+
+extern int proc_mm;
+
+int single_count = 0;
+int multi_count = 0;
+int multi_op_count = 0;
+
+static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
+{
+	unsigned long regs[MAX_REG_NR];
+	int n;
+	long ret, offset;
+	unsigned long * data;
+	unsigned long * syscall;
+	int pid = mm_idp->u.pid;
+
+	if(proc_mm)
+#warning Need to look up userspace_pid by cpu
+		pid = userspace_pid[0];
+
+	multi_count++;
+
+	get_safe_registers(regs);
+	regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
+		((unsigned long) &batch_syscall_stub -
+		 (unsigned long) &__syscall_stub_start);
+
+	n = ptrace_setregs(pid, regs);
+	if(n < 0)
+		panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n",
+		      n);
+
+	wait_stub_done(pid, 0, "do_syscall_stub");
+
+	/* When the stub stops, we find the following values on the
+	 * beginning of the stack:
+	 * (long )return_value
+	 * (long )offset to failed sycall-data (0, if no error)
+	 */
+	ret = *((unsigned long *) mm_idp->stack);
+	offset = *((unsigned long *) mm_idp->stack + 1);
+	if (offset) {
+		data = (unsigned long *)(mm_idp->stack +
+					 offset - UML_CONFIG_STUB_DATA);
+		printk("do_syscall_stub : ret = %d, offset = %d, "
+		       "data = 0x%x\n", ret, offset, data);
+		syscall = (unsigned long *)((unsigned long)data + data[0]);
+		printk("do_syscall_stub: syscall %ld failed, return value = "
+		       "0x%lx, expected return value = 0x%lx\n",
+		       syscall[0], ret, syscall[7]);
+		printk("    syscall parameters: "
+		       "0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n",
+		       syscall[1], syscall[2], syscall[3],
+		       syscall[4], syscall[5], syscall[6]);
+		for(n = 1; n < data[0]/sizeof(long); n++) {
+			if(n == 1)
+				printk("    additional syscall data:");
+			if(n % 4 == 1)
+				printk("\n      ");
+			printk("  0x%lx", data[n]);
+		}
+		if(n > 1)
+			printk("\n");
+	}
+	else ret = 0;
+
+	*addr = check_init_stack(mm_idp, NULL);
+
+	return ret;
+}
+
+long run_syscall_stub(struct mm_id * mm_idp, int syscall,
+		      unsigned long *args, long expected, void **addr,
+		      int done)
+{
+	unsigned long *stack = check_init_stack(mm_idp, *addr);
+
+	if(done && *addr == NULL)
+		single_count++;
+
+	*stack += sizeof(long);
+	stack += *stack / sizeof(long);
+
+	*stack++ = syscall;
+	*stack++ = args[0];
+	*stack++ = args[1];
+	*stack++ = args[2];
+	*stack++ = args[3];
+	*stack++ = args[4];
+	*stack++ = args[5];
+	*stack++ = expected;
+	*stack = 0;
+	multi_op_count++;
+
+	if(!done && ((((unsigned long) stack) & ~PAGE_MASK) <
+		     PAGE_SIZE - 10 * sizeof(long))){
+		*addr = stack;
+		return 0;
+	}
+
+	return do_syscall_stub(mm_idp, addr);
+}
+
+long syscall_stub_data(struct mm_id * mm_idp,
+		       unsigned long *data, int data_count,
+		       void **addr, void **stub_addr)
+{
+	unsigned long *stack;
+	int ret = 0;
+
+	/* If *addr still is uninitialized, it *must* contain NULL.
+	 * Thus in this case do_syscall_stub correctly won't be called.
+	 */
+	if((((unsigned long) *addr) & ~PAGE_MASK) >=
+	   PAGE_SIZE - (10 + data_count) * sizeof(long)) {
+		ret = do_syscall_stub(mm_idp, addr);
+		/* in case of error, don't overwrite data on stack */
+		if(ret)
+			return ret;
+	}
+
+	stack = check_init_stack(mm_idp, *addr);
+	*addr = stack;
+
+	*stack = data_count * sizeof(long);
+
+	memcpy(stack + 1, data, data_count * sizeof(long));
+
+	*stub_addr = (void *)(((unsigned long)(stack + 1) & ~PAGE_MASK) +
+			      UML_CONFIG_STUB_DATA);
+
+	return 0;
+}
+
+int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len,
+	int r, int w, int x, int phys_fd, unsigned long long offset,
+	int done, void **data)
+{
+	int prot, ret;
+
+	prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
+		(x ? PROT_EXEC : 0);
+
+	if(proc_mm){
+		struct proc_mm_op map;
+		int fd = mm_idp->u.mm_fd;
+
+		map = ((struct proc_mm_op) { .op	= MM_MMAP,
+				       .u		=
+				       { .mmap	=
+					 { .addr	= virt,
+					   .len	= len,
+					   .prot	= prot,
+					   .flags	= MAP_SHARED |
+					   MAP_FIXED,
+					   .fd	= phys_fd,
+					   .offset= offset
+					 } } } );
+		ret = os_write_file(fd, &map, sizeof(map));
+		if(ret != sizeof(map))
+			printk("map : /proc/mm map failed, err = %d\n", -ret);
+		else ret = 0;
+	}
+	else {
+		unsigned long args[] = { virt, len, prot,
+					 MAP_SHARED | MAP_FIXED, phys_fd,
+					 MMAP_OFFSET(offset) };
+
+		ret = run_syscall_stub(mm_idp, STUB_MMAP_NR, args, virt,
+				       data, done);
+	}
+
+	return ret;
+}
+
+int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done,
+	  void **data)
+{
+	int ret;
+
+	if(proc_mm){
+		struct proc_mm_op unmap;
+		int fd = mm_idp->u.mm_fd;
+
+		unmap = ((struct proc_mm_op) { .op	= MM_MUNMAP,
+					 .u	=
+					 { .munmap	=
+					   { .addr	=
+					     (unsigned long) addr,
+					     .len		= len } } } );
+		ret = os_write_file(fd, &unmap, sizeof(unmap));
+		if(ret != sizeof(unmap))
+			printk("unmap - proc_mm write returned %d\n", ret);
+		else ret = 0;
+	}
+	else {
+		unsigned long args[] = { (unsigned long) addr, len, 0, 0, 0,
+					 0 };
+
+		ret = run_syscall_stub(mm_idp, __NR_munmap, args, 0,
+				       data, done);
+	}
+
+	return ret;
+}
+
+int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
+	    int r, int w, int x, int done, void **data)
+{
+	struct proc_mm_op protect;
+	int prot, ret;
+
+	prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
+		(x ? PROT_EXEC : 0);
+	if(proc_mm){
+		int fd = mm_idp->u.mm_fd;
+
+		protect = ((struct proc_mm_op) { .op	= MM_MPROTECT,
+					   .u	=
+					   { .mprotect	=
+					     { .addr	=
+					       (unsigned long) addr,
+					       .len	= len,
+					       .prot	= prot } } } );
+
+		ret = os_write_file(fd, &protect, sizeof(protect));
+		if(ret != sizeof(protect))
+			printk("protect failed, err = %d", -ret);
+		else ret = 0;
+	}
+	else {
+		unsigned long args[] = { addr, len, prot, 0, 0, 0 };
+
+		ret = run_syscall_stub(mm_idp, __NR_mprotect, args, 0,
+				       data, done);
+	}
+
+	return ret;
+}
+
+void before_mem_skas(unsigned long unused)
+{
+}
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
new file mode 100644
index 0000000..120a21c
--- /dev/null
+++ b/arch/um/os-Linux/skas/process.c
@@ -0,0 +1,566 @@
+/*
+ * Copyright (C) 2002- 2004 Jeff Dike (jdike@addtoit.com)
+ * Licensed under the GPL
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <sched.h>
+#include "ptrace_user.h"
+#include <sys/wait.h>
+#include <sys/mman.h>
+#include <sys/user.h>
+#include <sys/time.h>
+#include <asm/unistd.h>
+#include <asm/types.h>
+#include "user.h"
+#include "sysdep/ptrace.h"
+#include "user_util.h"
+#include "kern_util.h"
+#include "skas.h"
+#include "stub-data.h"
+#include "mm_id.h"
+#include "sysdep/sigcontext.h"
+#include "sysdep/stub.h"
+#include "os.h"
+#include "proc_mm.h"
+#include "skas_ptrace.h"
+#include "chan_user.h"
+#include "registers.h"
+#include "mem.h"
+#include "uml-config.h"
+#include "process.h"
+#include "longjmp.h"
+
+int is_skas_winch(int pid, int fd, void *data)
+{
+	if(pid != os_getpgrp())
+		return(0);
+
+	register_winch_irq(-1, fd, -1, data);
+	return(1);
+}
+
+void wait_stub_done(int pid, int sig, char * fname)
+{
+	int n, status, err;
+
+	do {
+		if ( sig != -1 ) {
+			err = ptrace(PTRACE_CONT, pid, 0, sig);
+			if(err)
+				panic("%s : continue failed, errno = %d\n",
+				      fname, errno);
+		}
+		sig = 0;
+
+		CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
+	} while((n >= 0) && WIFSTOPPED(status) &&
+	        ((WSTOPSIG(status) == SIGVTALRM) ||
+		 /* running UML inside a detached screen can cause
+		  * SIGWINCHes
+		  */
+		 (WSTOPSIG(status) == SIGWINCH)));
+
+	if((n < 0) || !WIFSTOPPED(status) ||
+	   (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){
+		unsigned long regs[HOST_FRAME_SIZE];
+
+		if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
+			printk("Failed to get registers from stub, "
+			       "errno = %d\n", errno);
+		else {
+			int i;
+
+			printk("Stub registers -\n");
+			for(i = 0; i < HOST_FRAME_SIZE; i++)
+				printk("\t%d - %lx\n", i, regs[i]);
+		}
+		panic("%s : failed to wait for SIGUSR1/SIGTRAP, "
+		      "pid = %d, n = %d, errno = %d, status = 0x%x\n",
+		      fname, pid, n, errno, status);
+	}
+}
+
+extern unsigned long current_stub_stack(void);
+
+void get_skas_faultinfo(int pid, struct faultinfo * fi)
+{
+	int err;
+
+	if(ptrace_faultinfo){
+		err = ptrace(PTRACE_FAULTINFO, pid, 0, fi);
+		if(err)
+			panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, "
+			      "errno = %d\n", errno);
+
+		/* Special handling for i386, which has different structs */
+		if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo))
+			memset((char *)fi + sizeof(struct ptrace_faultinfo), 0,
+			       sizeof(struct faultinfo) -
+			       sizeof(struct ptrace_faultinfo));
+	}
+	else {
+		wait_stub_done(pid, SIGSEGV, "get_skas_faultinfo");
+
+		/* faultinfo is prepared by the stub-segv-handler at start of
+		 * the stub stack page. We just have to copy it.
+		 */
+		memcpy(fi, (void *)current_stub_stack(), sizeof(*fi));
+	}
+}
+
+static void handle_segv(int pid, union uml_pt_regs * regs)
+{
+	get_skas_faultinfo(pid, &regs->skas.faultinfo);
+	segv(regs->skas.faultinfo, 0, 1, NULL);
+}
+
+/*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/
+static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu)
+{
+	int err, status;
+
+	/* Mark this as a syscall */
+	UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->skas.regs);
+
+	if (!local_using_sysemu)
+	{
+		err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET,
+			     __NR_getpid);
+		if(err < 0)
+			panic("handle_trap - nullifying syscall failed errno = %d\n",
+			      errno);
+
+		err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
+		if(err < 0)
+			panic("handle_trap - continuing to end of syscall failed, "
+			      "errno = %d\n", errno);
+
+		CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
+		if((err < 0) || !WIFSTOPPED(status) ||
+		   (WSTOPSIG(status) != SIGTRAP + 0x80))
+			panic("handle_trap - failed to wait at end of syscall, "
+			      "errno = %d, status = %d\n", errno, status);
+	}
+
+	handle_syscall(regs);
+}
+
+extern int __syscall_stub_start;
+
+static int userspace_tramp(void *stack)
+{
+	void *addr;
+
+	ptrace(PTRACE_TRACEME, 0, 0, 0);
+
+	init_new_thread_signals(1);
+	enable_timer();
+
+	if(!proc_mm){
+		/* This has a pte, but it can't be mapped in with the usual
+		 * tlb_flush mechanism because this is part of that mechanism
+		 */
+		int fd;
+		__u64 offset;
+		fd = phys_mapping(to_phys(&__syscall_stub_start), &offset);
+		addr = mmap64((void *) UML_CONFIG_STUB_CODE, page_size(),
+			      PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset);
+		if(addr == MAP_FAILED){
+			printk("mapping mmap stub failed, errno = %d\n",
+			       errno);
+			exit(1);
+		}
+
+		if(stack != NULL){
+			fd = phys_mapping(to_phys(stack), &offset);
+			addr = mmap((void *) UML_CONFIG_STUB_DATA, page_size(),
+				    PROT_READ | PROT_WRITE,
+				    MAP_FIXED | MAP_SHARED, fd, offset);
+			if(addr == MAP_FAILED){
+				printk("mapping segfault stack failed, "
+				       "errno = %d\n", errno);
+				exit(1);
+			}
+		}
+	}
+	if(!ptrace_faultinfo && (stack != NULL)){
+		unsigned long v = UML_CONFIG_STUB_CODE +
+				  (unsigned long) stub_segv_handler -
+				  (unsigned long) &__syscall_stub_start;
+
+		set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size());
+		set_handler(SIGSEGV, (void *) v, SA_ONSTACK,
+			    SIGIO, SIGWINCH, SIGALRM, SIGVTALRM,
+			    SIGUSR1, -1);
+	}
+
+	os_stop_process(os_getpid());
+	return(0);
+}
+
+/* Each element set once, and only accessed by a single processor anyway */
+#undef NR_CPUS
+#define NR_CPUS 1
+int userspace_pid[NR_CPUS];
+
+int start_userspace(unsigned long stub_stack)
+{
+	void *stack;
+	unsigned long sp;
+	int pid, status, n, flags;
+
+	stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
+		     MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+	if(stack == MAP_FAILED)
+		panic("start_userspace : mmap failed, errno = %d", errno);
+	sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
+
+	flags = CLONE_FILES | SIGCHLD;
+	if(proc_mm) flags |= CLONE_VM;
+	pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack);
+	if(pid < 0)
+		panic("start_userspace : clone failed, errno = %d", errno);
+
+	do {
+		CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
+		if(n < 0)
+			panic("start_userspace : wait failed, errno = %d",
+			      errno);
+	} while(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));
+
+	if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
+		panic("start_userspace : expected SIGSTOP, got status = %d",
+		      status);
+
+	if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, (void *)PTRACE_O_TRACESYSGOOD) < 0)
+		panic("start_userspace : PTRACE_OLDSETOPTIONS failed, errno=%d\n",
+		      errno);
+
+	if(munmap(stack, PAGE_SIZE) < 0)
+		panic("start_userspace : munmap failed, errno = %d\n", errno);
+
+	return(pid);
+}
+
+void userspace(union uml_pt_regs *regs)
+{
+	int err, status, op, pid = userspace_pid[0];
+	int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/
+
+	while(1){
+		restore_registers(pid, regs);
+
+		/* Now we set local_using_sysemu to be used for one loop */
+		local_using_sysemu = get_using_sysemu();
+
+		op = SELECT_PTRACE_OPERATION(local_using_sysemu, singlestepping(NULL));
+
+		err = ptrace(op, pid, 0, 0);
+		if(err)
+			panic("userspace - could not resume userspace process, "
+			      "pid=%d, ptrace operation = %d, errno = %d\n",
+			      op, errno);
+
+		CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
+		if(err < 0)
+			panic("userspace - waitpid failed, errno = %d\n",
+			      errno);
+
+		regs->skas.is_user = 1;
+		save_registers(pid, regs);
+		UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
+
+		if(WIFSTOPPED(status)){
+		  	switch(WSTOPSIG(status)){
+			case SIGSEGV:
+				if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo)
+					user_signal(SIGSEGV, regs, pid);
+				else handle_segv(pid, regs);
+				break;
+			case SIGTRAP + 0x80:
+			        handle_trap(pid, regs, local_using_sysemu);
+				break;
+			case SIGTRAP:
+				relay_signal(SIGTRAP, regs);
+				break;
+			case SIGIO:
+			case SIGVTALRM:
+			case SIGILL:
+			case SIGBUS:
+			case SIGFPE:
+			case SIGWINCH:
+				user_signal(WSTOPSIG(status), regs, pid);
+				break;
+			default:
+			        printk("userspace - child stopped with signal "
+				       "%d\n", WSTOPSIG(status));
+			}
+			pid = userspace_pid[0];
+			interrupt_end();
+
+			/* Avoid -ERESTARTSYS handling in host */
+			if(PT_SYSCALL_NR_OFFSET != PT_SYSCALL_RET_OFFSET)
+				PT_SYSCALL_NR(regs->skas.regs) = -1;
+		}
+	}
+}
+#define INIT_JMP_NEW_THREAD 0
+#define INIT_JMP_REMOVE_SIGSTACK 1
+#define INIT_JMP_CALLBACK 2
+#define INIT_JMP_HALT 3
+#define INIT_JMP_REBOOT 4
+
+int copy_context_skas0(unsigned long new_stack, int pid)
+{
+	int err;
+	unsigned long regs[MAX_REG_NR];
+	unsigned long current_stack = current_stub_stack();
+	struct stub_data *data = (struct stub_data *) current_stack;
+	struct stub_data *child_data = (struct stub_data *) new_stack;
+	__u64 new_offset;
+	int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset);
+
+	/* prepare offset and fd of child's stack as argument for parent's
+	 * and child's mmap2 calls
+	 */
+	*data = ((struct stub_data) { .offset	= MMAP_OFFSET(new_offset),
+				      .fd	= new_fd,
+				      .timer    = ((struct itimerval)
+					            { { 0, 1000000 / hz() },
+						      { 0, 1000000 / hz() }})});
+	get_safe_registers(regs);
+
+	/* Set parent's instruction pointer to start of clone-stub */
+	regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
+				(unsigned long) stub_clone_handler -
+				(unsigned long) &__syscall_stub_start;
+	regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE -
+		sizeof(void *);
+#ifdef __SIGNAL_FRAMESIZE
+	regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE;
+#endif
+	err = ptrace_setregs(pid, regs);
+	if(err < 0)
+		panic("copy_context_skas0 : PTRACE_SETREGS failed, "
+		      "pid = %d, errno = %d\n", pid, errno);
+
+	/* set a well known return code for detection of child write failure */
+	child_data->err = 12345678;
+
+	/* Wait, until parent has finished its work: read child's pid from
+	 * parent's stack, and check, if bad result.
+	 */
+	wait_stub_done(pid, 0, "copy_context_skas0");
+
+	pid = data->err;
+	if(pid < 0)
+		panic("copy_context_skas0 - stub-parent reports error %d\n",
+		      pid);
+
+	/* Wait, until child has finished too: read child's result from
+	 * child's stack and check it.
+	 */
+	wait_stub_done(pid, -1, "copy_context_skas0");
+	if (child_data->err != UML_CONFIG_STUB_DATA)
+		panic("copy_context_skas0 - stub-child reports error %d\n",
+		      child_data->err);
+
+	if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL,
+		   (void *)PTRACE_O_TRACESYSGOOD) < 0)
+		panic("copy_context_skas0 : PTRACE_OLDSETOPTIONS failed, "
+		      "errno = %d\n", errno);
+
+	return pid;
+}
+
+/*
+ * This is used only, if stub pages are needed, while proc_mm is
+ * availabl. Opening /proc/mm creates a new mm_context, which lacks
+ * the stub-pages. Thus, we map them using /proc/mm-fd
+ */
+void map_stub_pages(int fd, unsigned long code,
+		    unsigned long data, unsigned long stack)
+{
+	struct proc_mm_op mmop;
+	int n;
+	__u64 code_offset;
+	int code_fd = phys_mapping(to_phys((void *) &__syscall_stub_start),
+				   &code_offset);
+
+	mmop = ((struct proc_mm_op) { .op        = MM_MMAP,
+				      .u         =
+				      { .mmap    =
+					{ .addr    = code,
+					  .len     = PAGE_SIZE,
+					  .prot    = PROT_EXEC,
+					  .flags   = MAP_FIXED | MAP_PRIVATE,
+					  .fd      = code_fd,
+					  .offset  = code_offset
+	} } });
+	n = os_write_file(fd, &mmop, sizeof(mmop));
+	if(n != sizeof(mmop))
+		panic("map_stub_pages : /proc/mm map for code failed, "
+		      "err = %d\n", -n);
+
+	if ( stack ) {
+		__u64 map_offset;
+		int map_fd = phys_mapping(to_phys((void *)stack), &map_offset);
+		mmop = ((struct proc_mm_op)
+				{ .op        = MM_MMAP,
+				  .u         =
+				  { .mmap    =
+				    { .addr    = data,
+				      .len     = PAGE_SIZE,
+				      .prot    = PROT_READ | PROT_WRITE,
+				      .flags   = MAP_FIXED | MAP_SHARED,
+				      .fd      = map_fd,
+				      .offset  = map_offset
+		} } });
+		n = os_write_file(fd, &mmop, sizeof(mmop));
+		if(n != sizeof(mmop))
+			panic("map_stub_pages : /proc/mm map for data failed, "
+			      "err = %d\n", -n);
+	}
+}
+
+void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
+		void (*handler)(int))
+{
+	unsigned long flags;
+	sigjmp_buf switch_buf, fork_buf;
+	int enable;
+
+	*switch_buf_ptr = &switch_buf;
+	*fork_buf_ptr = &fork_buf;
+
+	/* Somewhat subtle - siglongjmp restores the signal mask before doing
+	 * the longjmp.  This means that when jumping from one stack to another
+	 * when the target stack has interrupts enabled, an interrupt may occur
+	 * on the source stack.  This is bad when starting up a process because
+	 * it's not supposed to get timer ticks until it has been scheduled.
+	 * So, we disable interrupts around the sigsetjmp to ensure that
+	 * they can't happen until we get back here where they are safe.
+	 */
+	flags = get_signals();
+	block_signals();
+	if(UML_SIGSETJMP(&fork_buf, enable) == 0)
+		new_thread_proc(stack, handler);
+
+	remove_sigstack();
+
+	set_signals(flags);
+}
+
+void thread_wait(void *sw, void *fb)
+{
+	sigjmp_buf buf, **switch_buf = sw, *fork_buf;
+	int enable;
+
+	*switch_buf = &buf;
+	fork_buf = fb;
+	if(UML_SIGSETJMP(&buf, enable) == 0)
+		siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK);
+}
+
+void switch_threads(void *me, void *next)
+{
+	sigjmp_buf my_buf, **me_ptr = me, *next_buf = next;
+	int enable;
+
+	*me_ptr = &my_buf;
+	if(UML_SIGSETJMP(&my_buf, enable) == 0)
+		UML_SIGLONGJMP(next_buf, 1);
+}
+
+static sigjmp_buf initial_jmpbuf;
+
+/* XXX Make these percpu */
+static void (*cb_proc)(void *arg);
+static void *cb_arg;
+static sigjmp_buf *cb_back;
+
+int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
+{
+	sigjmp_buf **switch_buf = switch_buf_ptr;
+	int n, enable;
+
+	set_handler(SIGWINCH, (__sighandler_t) sig_handler,
+		    SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM,
+		    SIGVTALRM, -1);
+
+	*fork_buf_ptr = &initial_jmpbuf;
+	n = UML_SIGSETJMP(&initial_jmpbuf, enable);
+	switch(n){
+	case INIT_JMP_NEW_THREAD:
+		new_thread_proc((void *) stack, new_thread_handler);
+		break;
+	case INIT_JMP_REMOVE_SIGSTACK:
+		remove_sigstack();
+		break;
+	case INIT_JMP_CALLBACK:
+		(*cb_proc)(cb_arg);
+		UML_SIGLONGJMP(cb_back, 1);
+		break;
+	case INIT_JMP_HALT:
+		kmalloc_ok = 0;
+		return(0);
+	case INIT_JMP_REBOOT:
+		kmalloc_ok = 0;
+		return(1);
+	default:
+		panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
+	}
+	UML_SIGLONGJMP(*switch_buf, 1);
+}
+
+void initial_thread_cb_skas(void (*proc)(void *), void *arg)
+{
+	sigjmp_buf here;
+	int enable;
+
+	cb_proc = proc;
+	cb_arg = arg;
+	cb_back = &here;
+
+	block_signals();
+	if(UML_SIGSETJMP(&here, enable) == 0)
+		UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK);
+	unblock_signals();
+
+	cb_proc = NULL;
+	cb_arg = NULL;
+	cb_back = NULL;
+}
+
+void halt_skas(void)
+{
+	block_signals();
+	UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_HALT);
+}
+
+void reboot_skas(void)
+{
+	block_signals();
+	UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT);
+}
+
+void switch_mm_skas(struct mm_id *mm_idp)
+{
+	int err;
+
+#warning need cpu pid in switch_mm_skas
+	if(proc_mm){
+		err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0,
+			     mm_idp->u.mm_fd);
+		if(err)
+			panic("switch_mm_skas - PTRACE_SWITCH_MM failed, "
+			      "errno = %d\n", errno);
+	}
+	else userspace_pid[0] = mm_idp->u.pid;
+}
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index b47e5e7..6c5b17e 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -29,7 +29,6 @@
 #include "irq_user.h"
 #include "ptrace_user.h"
 #include "mem_user.h"
-#include "time_user.h"
 #include "init.h"
 #include "os.h"
 #include "uml-config.h"
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index cf30a39..6f76267 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -1,21 +1,128 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
 #include <sys/time.h>
+#include <signal.h>
+#include <errno.h>
+#include "user_util.h"
+#include "kern_util.h"
+#include "user.h"
+#include "process.h"
+#include "kern_constants.h"
+#include "os.h"
+
+/* XXX This really needs to be declared and initialized in a kernel file since
+ * it's in <linux/time.h>
+ */
+extern struct timespec wall_to_monotonic;
+
+static void set_interval(int timer_type)
+{
+	int usec = 1000000/hz();
+	struct itimerval interval = ((struct itimerval) { { 0, usec },
+							  { 0, usec } });
+
+	if(setitimer(timer_type, &interval, NULL) == -1)
+		panic("setitimer failed - errno = %d\n", errno);
+}
+
+void enable_timer(void)
+{
+	set_interval(ITIMER_VIRTUAL);
+}
+
+void disable_timer(void)
+{
+	struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
+	if((setitimer(ITIMER_VIRTUAL, &disable, NULL) < 0) ||
+	   (setitimer(ITIMER_REAL, &disable, NULL) < 0))
+		printk("disnable_timer - setitimer failed, errno = %d\n",
+		       errno);
+	/* If there are signals already queued, after unblocking ignore them */
+	set_handler(SIGALRM, SIG_IGN, 0, -1);
+	set_handler(SIGVTALRM, SIG_IGN, 0, -1);
+}
+
+void switch_timers(int to_real)
+{
+	struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
+	struct itimerval enable = ((struct itimerval) { { 0, 1000000/hz() },
+							{ 0, 1000000/hz() }});
+	int old, new;
+
+	if(to_real){
+		old = ITIMER_VIRTUAL;
+		new = ITIMER_REAL;
+	}
+	else {
+		old = ITIMER_REAL;
+		new = ITIMER_VIRTUAL;
+	}
+
+	if((setitimer(old, &disable, NULL) < 0) ||
+	   (setitimer(new, &enable, NULL)))
+		printk("switch_timers - setitimer failed, errno = %d\n",
+		       errno);
+}
 
-unsigned long long os_usecs(void)
+void uml_idle_timer(void)
+{
+	if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
+		panic("Couldn't unset SIGVTALRM handler");
+
+	set_handler(SIGALRM, (__sighandler_t) alarm_handler,
+		    SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
+	set_interval(ITIMER_REAL);
+}
+
+extern void ktime_get_ts(struct timespec *ts);
+#define do_posix_clock_monotonic_gettime(ts) ktime_get_ts(ts)
+
+void time_init(void)
+{
+	struct timespec now;
+
+	if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR)
+		panic("Couldn't set SIGVTALRM handler");
+	set_interval(ITIMER_VIRTUAL);
+
+	do_posix_clock_monotonic_gettime(&now);
+	wall_to_monotonic.tv_sec = -now.tv_sec;
+	wall_to_monotonic.tv_nsec = -now.tv_nsec;
+}
+
+unsigned long long os_nsecs(void)
 {
 	struct timeval tv;
 
 	gettimeofday(&tv, NULL);
-	return((unsigned long long) tv.tv_sec * 1000000 + tv.tv_usec);
+	return((unsigned long long) tv.tv_sec * BILLION + tv.tv_usec * 1000);
 }
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+void idle_sleep(int secs)
+{
+	struct timespec ts;
+
+	ts.tv_sec = secs;
+	ts.tv_nsec = 0;
+	nanosleep(&ts, NULL);
+}
+
+/* XXX This partly duplicates init_irq_signals */
+
+void user_time_init(void)
+{
+	set_handler(SIGVTALRM, (__sighandler_t) alarm_handler,
+		    SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH,
+		    SIGALRM, SIGUSR2, -1);
+	set_handler(SIGALRM, (__sighandler_t) alarm_handler,
+		    SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH,
+		    SIGVTALRM, SIGUSR2, -1);
+	set_interval(ITIMER_VIRTUAL);
+}
diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c
index 321e1c8..a9f6b26 100644
--- a/arch/um/os-Linux/trap.c
+++ b/arch/um/os-Linux/trap.c
@@ -10,6 +10,7 @@
 #include "user_util.h"
 #include "os.h"
 #include "mode.h"
+#include "longjmp.h"
 
 void usr2_handler(int sig, union uml_pt_regs *regs)
 {
@@ -36,5 +37,5 @@ void do_longjmp(void *b, int val)
 {
 	sigjmp_buf *buf = b;
 
-	siglongjmp(*buf, val);
+	UML_SIGLONGJMP(buf, val);
 }
diff --git a/arch/um/os-Linux/tt.c b/arch/um/os-Linux/tt.c
index cb2648b..919d19f 100644
--- a/arch/um/os-Linux/tt.c
+++ b/arch/um/os-Linux/tt.c
@@ -27,7 +27,6 @@
 #include "sysdep/sigcontext.h"
 #include "irq_user.h"
 #include "ptrace_user.h"
-#include "time_user.h"
 #include "init.h"
 #include "os.h"
 #include "uml-config.h"
@@ -63,6 +62,54 @@ void kill_child_dead(int pid)
 	} while(1);
 }
 
+void stop(void)
+{
+	while(1) sleep(1000000);
+}
+
+int wait_for_stop(int pid, int sig, int cont_type, void *relay)
+{
+	sigset_t *relay_signals = relay;
+	int status, ret;
+
+	while(1){
+		CATCH_EINTR(ret = waitpid(pid, &status, WUNTRACED));
+		if((ret < 0) ||
+		   !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
+			if(ret < 0){
+				printk("wait failed, errno = %d\n",
+				       errno);
+			}
+			else if(WIFEXITED(status))
+				printk("process %d exited with status %d\n",
+				       pid, WEXITSTATUS(status));
+			else if(WIFSIGNALED(status))
+				printk("process %d exited with signal %d\n",
+				       pid, WTERMSIG(status));
+			else if((WSTOPSIG(status) == SIGVTALRM) ||
+				(WSTOPSIG(status) == SIGALRM) ||
+				(WSTOPSIG(status) == SIGIO) ||
+				(WSTOPSIG(status) == SIGPROF) ||
+				(WSTOPSIG(status) == SIGCHLD) ||
+				(WSTOPSIG(status) == SIGWINCH) ||
+				(WSTOPSIG(status) == SIGINT)){
+				ptrace(cont_type, pid, 0, WSTOPSIG(status));
+				continue;
+			}
+			else if((relay_signals != NULL) &&
+				sigismember(relay_signals, WSTOPSIG(status))){
+				ptrace(cont_type, pid, 0, WSTOPSIG(status));
+				continue;
+			}
+			else printk("process %d stopped with signal %d\n",
+				    pid, WSTOPSIG(status));
+			panic("wait_for_stop failed to wait for %d to stop "
+			      "with %d\n", pid, sig);
+		}
+		return(status);
+	}
+}
+
 /*
  *-------------------------
  * only for tt mode (will be deleted in future...)
diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c
index 38d7101..166fb66 100644
--- a/arch/um/os-Linux/uaccess.c
+++ b/arch/um/os-Linux/uaccess.c
@@ -6,6 +6,7 @@
 
 #include <setjmp.h>
 #include <string.h>
+#include "longjmp.h"
 
 unsigned long __do_user_copy(void *to, const void *from, int n,
 			     void **fault_addr, void **fault_catcher,
@@ -13,10 +14,11 @@ unsigned long __do_user_copy(void *to, c
 					int n), int *faulted_out)
 {
 	unsigned long *faddrp = (unsigned long *) fault_addr, ret;
+	int enable;
 
 	sigjmp_buf jbuf;
 	*fault_catcher = &jbuf;
-	if(sigsetjmp(jbuf, 1) == 0){
+	if(UML_SIGSETJMP(&jbuf, enable) == 0){
 		(*op)(to, from, n);
 		ret = 0;
 		*faulted_out = 0;
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c
new file mode 100644
index 0000000..e32065e
--- /dev/null
+++ b/arch/um/os-Linux/util.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include <setjmp.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/utsname.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include "asm/types.h"
+#include <ctype.h>
+#include <signal.h>
+#include <wait.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <sched.h>
+#include <termios.h>
+#include <string.h>
+#include "user_util.h"
+#include "kern_util.h"
+#include "user.h"
+#include "mem_user.h"
+#include "init.h"
+#include "ptrace_user.h"
+#include "uml-config.h"
+#include "os.h"
+#include "longjmp.h"
+
+void stack_protections(unsigned long address)
+{
+	int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
+
+	if(mprotect((void *) address, page_size(), prot) < 0)
+		panic("protecting stack failed, errno = %d", errno);
+}
+
+void task_protections(unsigned long address)
+{
+	unsigned long guard = address + page_size();
+	unsigned long stack = guard + page_size();
+	int prot = 0, pages;
+
+#ifdef notdef
+	if(mprotect((void *) stack, page_size(), prot) < 0)
+		panic("protecting guard page failed, errno = %d", errno);
+#endif
+	pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
+	prot = PROT_READ | PROT_WRITE | PROT_EXEC;
+	if(mprotect((void *) stack, pages * page_size(), prot) < 0)
+		panic("protecting stack failed, errno = %d", errno);
+}
+
+int raw(int fd)
+{
+	struct termios tt;
+	int err;
+
+	CATCH_EINTR(err = tcgetattr(fd, &tt));
+	if(err < 0)
+		return -errno;
+
+	cfmakeraw(&tt);
+
+	CATCH_EINTR(err = tcsetattr(fd, TCSADRAIN, &tt));
+	if(err < 0)
+		return -errno;
+
+	/* XXX tcsetattr could have applied only some changes
+	 * (and cfmakeraw() is a set of changes) */
+	return(0);
+}
+
+void setup_machinename(char *machine_out)
+{
+	struct utsname host;
+
+	uname(&host);
+#if defined(UML_CONFIG_UML_X86) && !defined(UML_CONFIG_64BIT)
+	if (!strcmp(host.machine, "x86_64")) {
+		strcpy(machine_out, "i686");
+		return;
+	}
+#endif
+	strcpy(machine_out, host.machine);
+}
+
+char host_info[(_UTSNAME_LENGTH + 1) * 4 + _UTSNAME_NODENAME_LENGTH + 1];
+
+void setup_hostinfo(void)
+{
+	struct utsname host;
+
+	uname(&host);
+	sprintf(host_info, "%s %s %s %s %s", host.sysname, host.nodename,
+		host.release, host.version, host.machine);
+}
+
+int setjmp_wrapper(void (*proc)(void *, void *), ...)
+{
+	va_list args;
+	sigjmp_buf buf;
+	int n;
+
+	n = sigsetjmp(buf, 1);
+	if(n == 0){
+		va_start(args, proc);
+		(*proc)(&buf, &args);
+	}
+	va_end(args);
+	return(n);
+}
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index 17746b4..1fa09a7 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -16,6 +16,7 @@
 #include "choose-mode.h"
 #include "kern.h"
 #include "mode_kern.h"
+#include "os.h"
 
 extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
 
@@ -88,6 +89,7 @@ out:
 #include "skas.h"
 #include "skas_ptrace.h"
 #include "asm/mmu_context.h"
+#include "proc_mm.h"
 
 long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
 		     void **addr, int done)
@@ -456,13 +458,14 @@ long init_new_ldt(struct mmu_context_ska
 	int i;
 	long page, err=0;
 	void *addr = NULL;
+	struct proc_mm_op copy;
 
-	memset(&desc, 0, sizeof(desc));
 
 	if(!ptrace_ldt)
 		init_MUTEX(&new_mm->ldt.semaphore);
 
 	if(!from_mm){
+		memset(&desc, 0, sizeof(desc));
 		/*
 		 * We have to initialize a clean ldt.
 		 */
@@ -494,8 +497,26 @@ long init_new_ldt(struct mmu_context_ska
 			}
 		}
 		new_mm->ldt.entry_count = 0;
+
+		goto out;
 	}
-	else if (!ptrace_ldt) {
+
+	if(proc_mm){
+		/* We have a valid from_mm, so we now have to copy the LDT of
+		 * from_mm to new_mm, because using proc_mm an new mm with
+		 * an empty/default LDT was created in new_mm()
+		 */
+		copy = ((struct proc_mm_op) { .op 	= MM_COPY_SEGMENTS,
+					      .u 	=
+					      { .copy_segments =
+							from_mm->id.u.mm_fd } } );
+		i = os_write_file(new_mm->id.u.mm_fd, &copy, sizeof(copy));
+		if(i != sizeof(copy))
+			printk("new_mm : /proc/mm copy_segments failed, "
+			       "err = %d\n", -i);
+	}
+
+	if(!ptrace_ldt) {
 		/* Our local LDT is used to supply the data for
 		 * modify_ldt(READLDT), if PTRACE_LDT isn't available,
 		 * i.e., we have to use the stub for modify_ldt, which
@@ -524,6 +545,7 @@ long init_new_ldt(struct mmu_context_ska
 		up(&from_mm->ldt.semaphore);
 	}
 
+    out:
 	return err;
 }
 
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig
index 5231fe8..09a3eb7 100644
--- a/arch/x86_64/defconfig
+++ b/arch/x86_64/defconfig
@@ -646,6 +646,7 @@ CONFIG_8139TOO=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
 # CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
index 58f5bfb..067c0f4 100644
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -672,6 +672,19 @@ ia32_sys_call_table:
 	.quad sys_inotify_add_watch
 	.quad sys_inotify_rm_watch
 	.quad sys_migrate_pages
+	.quad compat_sys_openat		/* 295 */
+	.quad sys_mkdirat
+	.quad sys_mknodat
+	.quad sys_fchownat
+	.quad compat_sys_futimesat
+	.quad compat_sys_newfstatat	/* 300 */
+	.quad sys_unlinkat
+	.quad sys_renameat
+	.quad sys_linkat
+	.quad sys_symlinkat
+	.quad sys_readlinkat		/* 305 */
+	.quad sys_fchmodat
+	.quad sys_faccessat
 ia32_syscall_end:		
 	.rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8
 		.quad ni_syscall
diff --git a/arch/x86_64/kernel/acpi/Makefile b/arch/x86_64/kernel/acpi/Makefile
index 7da9ace..4fe9707 100644
--- a/arch/x86_64/kernel/acpi/Makefile
+++ b/arch/x86_64/kernel/acpi/Makefile
@@ -1,3 +1,8 @@
 obj-y			:= boot.o
 boot-y			:= ../../../i386/kernel/acpi/boot.o
 obj-$(CONFIG_ACPI_SLEEP)	+= sleep.o wakeup.o
+
+ifneq ($(CONFIG_ACPI_PROCESSOR),)
+obj-y			+= processor.o
+endif
+
diff --git a/arch/x86_64/kernel/acpi/processor.c b/arch/x86_64/kernel/acpi/processor.c
new file mode 100644
index 0000000..3bdc2ba
--- /dev/null
+++ b/arch/x86_64/kernel/acpi/processor.c
@@ -0,0 +1,72 @@
+/*
+ * arch/x86_64/kernel/acpi/processor.c
+ *
+ * Copyright (C) 2005 Intel Corporation
+ * 	Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ * 	- Added _PDC for platforms with Intel CPUs
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/acpi.h>
+
+#include <acpi/processor.h>
+#include <asm/acpi.h>
+
+static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c)
+{
+	struct acpi_object_list *obj_list;
+	union acpi_object *obj;
+	u32 *buf;
+
+	/* allocate and initialize pdc. It will be used later. */
+	obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
+	if (!obj_list) {
+		printk(KERN_ERR "Memory allocation error\n");
+		return;
+	}
+
+	obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
+	if (!obj) {
+		printk(KERN_ERR "Memory allocation error\n");
+		kfree(obj_list);
+		return;
+	}
+
+	buf = kmalloc(12, GFP_KERNEL);
+	if (!buf) {
+		printk(KERN_ERR "Memory allocation error\n");
+		kfree(obj);
+		kfree(obj_list);
+		return;
+	}
+
+	buf[0] = ACPI_PDC_REVISION_ID;
+	buf[1] = 1;
+	buf[2] = ACPI_PDC_EST_CAPABILITY_SMP;
+
+	obj->type = ACPI_TYPE_BUFFER;
+	obj->buffer.length = 12;
+	obj->buffer.pointer = (u8 *) buf;
+	obj_list->count = 1;
+	obj_list->pointer = obj;
+	pr->pdc = obj_list;
+
+	return;
+}
+
+/* Initialize _PDC data based on the CPU vendor */
+void arch_acpi_processor_init_pdc(struct acpi_processor *pr)
+{
+	unsigned int cpu = pr->id;
+	struct cpuinfo_x86 *c = cpu_data + cpu;
+
+	pr->pdc = NULL;
+	if (c->x86_vendor == X86_VENDOR_INTEL && cpu_has(c, X86_FEATURE_EST))
+		init_intel_pdc(pr, c);
+
+	return;
+}
+
+EXPORT_SYMBOL(arch_acpi_processor_init_pdc);
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index e8cf44e..1a5060b 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -2027,7 +2027,7 @@ int __init io_apic_get_redir_entries (in
 }
 
 
-int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low)
+int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int polarity)
 {
 	struct IO_APIC_route_entry entry;
 	unsigned long flags;
@@ -2049,8 +2049,8 @@ int io_apic_set_pci_routing (int ioapic,
 	entry.delivery_mode = INT_DELIVERY_MODE;
 	entry.dest_mode = INT_DEST_MODE;
 	entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
-	entry.trigger = edge_level;
-	entry.polarity = active_high_low;
+	entry.trigger = triggering;
+	entry.polarity = polarity;
 	entry.mask = 1;					 /* Disabled (masked) */
 
 	irq = gsi_irq_sharing(irq);
@@ -2065,9 +2065,9 @@ int io_apic_set_pci_routing (int ioapic,
 	apic_printk(APIC_VERBOSE,KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry (%d-%d -> 0x%x -> "
 		"IRQ %d Mode:%i Active:%i)\n", ioapic, 
 	       mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq,
-	       edge_level, active_high_low);
+	       triggering, polarity);
 
-	ioapic_register_intr(irq, entry.vector, edge_level);
+	ioapic_register_intr(irq, entry.vector, triggering);
 
 	if (!ioapic && (irq < 16))
 		disable_8259A_irq(irq);
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
index 1105250..dc49bfb 100644
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -915,7 +915,7 @@ void __init mp_config_acpi_legacy_irqs (
 
 #define MAX_GSI_NUM	4096
 
-int mp_register_gsi(u32 gsi, int edge_level, int active_high_low)
+int mp_register_gsi(u32 gsi, int triggering, int polarity)
 {
 	int			ioapic = -1;
 	int			ioapic_pin = 0;
@@ -964,7 +964,7 @@ int mp_register_gsi(u32 gsi, int edge_le
 
 	mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
 
-	if (edge_level) {
+	if (triggering == ACPI_LEVEL_SENSITIVE) {
 		/*
 		 * For PCI devices assign IRQs in order, avoiding gaps
 		 * due to unused I/O APIC pins.
@@ -986,8 +986,8 @@ int mp_register_gsi(u32 gsi, int edge_le
 	}
 
 	io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
-		edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1,
-		active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1);
+		triggering == ACPI_EDGE_SENSITIVE ? 0 : 1,
+		polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
 	return gsi;
 }
 
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
index 8ac4db0..70f1bb8 100644
--- a/arch/x86_64/kernel/setup64.c
+++ b/arch/x86_64/kernel/setup64.c
@@ -146,7 +146,7 @@ void pda_init(int cpu)
 	pda->irqstackptr += IRQSTACKSIZE-64;
 } 
 
-char boot_exception_stacks[(N_EXCEPTION_STACKS - 2) * EXCEPTION_STKSZ + DEBUG_STKSZ]
+char boot_exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]
 __attribute__((section(".bss.page_aligned")));
 
 /* May not be marked __init: used by software suspend */
diff --git a/arch/x86_64/lib/Makefile b/arch/x86_64/lib/Makefile
index bba5db6..ccef6ae 100644
--- a/arch/x86_64/lib/Makefile
+++ b/arch/x86_64/lib/Makefile
@@ -4,7 +4,7 @@
 
 CFLAGS_csum-partial.o := -funroll-loops
 
-obj-y := io.o
+obj-y := io.o iomap_copy.o
 
 lib-y := csum-partial.o csum-copy.o csum-wrappers.o delay.o \
 	usercopy.o getuser.o putuser.o  \
diff --git a/arch/x86_64/lib/iomap_copy.S b/arch/x86_64/lib/iomap_copy.S
new file mode 100644
index 0000000..8bbade5
--- /dev/null
+++ b/arch/x86_64/lib/iomap_copy.S
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2006 PathScale, Inc.  All Rights Reserved.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * override generic version in lib/iomap_copy.c
+ */
+ 	.globl __iowrite32_copy
+	.p2align 4
+__iowrite32_copy:
+	movl %edx,%ecx
+	rep movsd
+	ret
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c
index f16c0d5..00d4ddb 100644
--- a/arch/x86_64/pci/mmconfig.c
+++ b/arch/x86_64/pci/mmconfig.c
@@ -29,11 +29,8 @@ static char __iomem *get_virt(unsigned i
 
 	while (1) {
 		++cfg_num;
-		if (cfg_num >= pci_mmcfg_config_num) {
-			/* Not found - fall back to type 1. This happens
-			   e.g. on the internal devices of a K8 northbridge. */
-			return NULL;
-		}
+		if (cfg_num >= pci_mmcfg_config_num)
+			break;
 		cfg = pci_mmcfg_virt[cfg_num].cfg;
 		if (cfg->pci_segment_group_number != seg)
 			continue;
@@ -41,6 +38,18 @@ static char __iomem *get_virt(unsigned i
 		    (cfg->end_bus_number >= bus))
 			return pci_mmcfg_virt[cfg_num].virt;
 	}
+
+	/* Handle more broken MCFG tables on Asus etc.
+	   They only contain a single entry for bus 0-0. Assume
+ 	   this applies to all busses. */
+	cfg = &pci_mmcfg_config[0];
+	if (pci_mmcfg_config_num == 1 &&
+		cfg->pci_segment_group_number == 0 &&
+		(cfg->start_bus_number | cfg->end_bus_number) == 0)
+		return cfg->base_address;
+
+	/* Fall back to type 0 */
+	return 0;
 }
 
 static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
diff --git a/block/elevator.c b/block/elevator.c
index c9f424d..96a61e0 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -139,35 +139,16 @@ static int elevator_attach(request_queue
 
 static char chosen_elevator[16];
 
-static void elevator_setup_default(void)
+static int __init elevator_setup(char *str)
 {
-	struct elevator_type *e;
-
-	/*
-	 * If default has not been set, use the compiled-in selection.
-	 */
-	if (!chosen_elevator[0])
-		strcpy(chosen_elevator, CONFIG_DEFAULT_IOSCHED);
-
 	/*
 	 * Be backwards-compatible with previous kernels, so users
 	 * won't get the wrong elevator.
 	 */
-	if (!strcmp(chosen_elevator, "as"))
+	if (!strcmp(str, "as"))
 		strcpy(chosen_elevator, "anticipatory");
-
- 	/*
- 	 * If the given scheduler is not available, fall back to the default
- 	 */
- 	if ((e = elevator_find(chosen_elevator)))
-		elevator_put(e);
 	else
- 		strcpy(chosen_elevator, CONFIG_DEFAULT_IOSCHED);
-}
-
-static int __init elevator_setup(char *str)
-{
-	strncpy(chosen_elevator, str, sizeof(chosen_elevator) - 1);
+		strncpy(chosen_elevator, str, sizeof(chosen_elevator) - 1);
 	return 0;
 }
 
@@ -184,14 +165,16 @@ int elevator_init(request_queue_t *q, ch
 	q->end_sector = 0;
 	q->boundary_rq = NULL;
 
-	elevator_setup_default();
+	if (name && !(e = elevator_get(name)))
+		return -EINVAL;
 
-	if (!name)
-		name = chosen_elevator;
+	if (!e && *chosen_elevator && !(e = elevator_get(chosen_elevator)))
+		printk("I/O scheduler %s not found\n", chosen_elevator);
 
-	e = elevator_get(name);
-	if (!e)
-		return -EINVAL;
+	if (!e && !(e = elevator_get(CONFIG_DEFAULT_IOSCHED))) {
+		printk("Default I/O scheduler not found, using no-op\n");
+		e = elevator_get("noop");
+	}
 
 	eq = kmalloc(sizeof(struct elevator_queue), GFP_KERNEL);
 	if (!eq) {
@@ -669,8 +652,10 @@ int elv_register(struct elevator_type *e
 	spin_unlock_irq(&elv_list_lock);
 
 	printk(KERN_INFO "io scheduler %s registered", e->elevator_name);
-	if (!strcmp(e->elevator_name, chosen_elevator))
-		printk(" (default)");
+	if (!strcmp(e->elevator_name, chosen_elevator) ||
+			(!*chosen_elevator &&
+			 !strcmp(e->elevator_name, CONFIG_DEFAULT_IOSCHED)))
+				printk(" (default)");
 	printk("\n");
 	return 0;
 }
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 8e27d0a..f9fc07e 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -304,6 +304,7 @@ static inline void rq_init(request_queue
  * blk_queue_ordered - does this queue support ordered writes
  * @q:        the request queue
  * @ordered:  one of QUEUE_ORDERED_*
+ * @prepare_flush_fn: rq setup helper for cache flush ordered writes
  *
  * Description:
  *   For journalled file systems, doing ordered writes on a commit
@@ -332,6 +333,7 @@ int blk_queue_ordered(request_queue_t *q
 		return -EINVAL;
 	}
 
+	q->ordered = ordered;
 	q->next_ordered = ordered;
 	q->prepare_flush_fn = prepare_flush_fn;
 
@@ -662,7 +664,7 @@ EXPORT_SYMBOL(blk_queue_bounce_limit);
  *    Enables a low level driver to set an upper limit on the size of
  *    received requests.
  **/
-void blk_queue_max_sectors(request_queue_t *q, unsigned short max_sectors)
+void blk_queue_max_sectors(request_queue_t *q, unsigned int max_sectors)
 {
 	if ((max_sectors << 9) < PAGE_CACHE_SIZE) {
 		max_sectors = 1 << (PAGE_CACHE_SHIFT - 9);
@@ -2577,6 +2579,8 @@ void disk_round_stats(struct gendisk *di
 	disk->stamp = now;
 }
 
+EXPORT_SYMBOL_GPL(disk_round_stats);
+
 /*
  * queue lock must be held
  */
@@ -2632,6 +2636,7 @@ EXPORT_SYMBOL(blk_put_request);
 /**
  * blk_end_sync_rq - executes a completion event on a request
  * @rq: request to complete
+ * @error: end io status of the request
  */
 void blk_end_sync_rq(struct request *rq, int error)
 {
@@ -3153,7 +3158,7 @@ static int __end_that_request_first(stru
 	if (blk_fs_request(req) && req->rq_disk) {
 		const int rw = rq_data_dir(req);
 
-		__disk_stat_add(req->rq_disk, sectors[rw], nr_bytes >> 9);
+		disk_stat_add(req->rq_disk, sectors[rw], nr_bytes >> 9);
 	}
 
 	total_bytes = bio_nbytes = 0;
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 283c089..bddf431 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -68,4 +68,6 @@ source "drivers/infiniband/Kconfig"
 
 source "drivers/sn/Kconfig"
 
+source "drivers/edac/Kconfig"
+
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 7c45050..619dd96 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -63,6 +63,7 @@ obj-$(CONFIG_PHONE)		+= telephony/
 obj-$(CONFIG_MD)		+= md/
 obj-$(CONFIG_BT)		+= bluetooth/
 obj-$(CONFIG_ISDN)		+= isdn/
+obj-$(CONFIG_EDAC)		+= edac/
 obj-$(CONFIG_MCA)		+= mca/
 obj-$(CONFIG_EISA)		+= eisa/
 obj-$(CONFIG_CPU_FREQ)		+= cpufreq/
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 6d61945..0cce28c 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -267,7 +267,6 @@ config ACPI_DEBUG
 
 config ACPI_EC
 	bool
-	depends on X86
 	default y
 	help
 	  This driver is required on some systems for the proper operation of
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index 2143609..d882bf8 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -71,8 +71,8 @@ static struct acpi_driver acpi_memory_de
 struct acpi_memory_device {
 	acpi_handle handle;
 	unsigned int state;	/* State of the memory device */
-	unsigned short cache_attribute;	/* memory cache attribute */
-	unsigned short read_write_attribute;	/* memory read/write attribute */
+	unsigned short caching;	/* memory cache attribute */
+	unsigned short write_protect;	/* memory read/write attribute */
 	u64 start_addr;		/* Memory Range start physical addr */
 	u64 end_addr;		/* Memory Range end physical addr */
 };
@@ -97,12 +97,12 @@ acpi_memory_get_device_resources(struct 
 	if (ACPI_SUCCESS(status)) {
 		if (address64.resource_type == ACPI_MEMORY_RANGE) {
 			/* Populate the structure */
-			mem_device->cache_attribute =
-			    address64.attribute.memory.cache_attribute;
-			mem_device->read_write_attribute =
-			    address64.attribute.memory.read_write_attribute;
-			mem_device->start_addr = address64.min_address_range;
-			mem_device->end_addr = address64.max_address_range;
+			mem_device->caching =
+			    address64.info.mem.caching;
+			mem_device->write_protect =
+			    address64.info.mem.write_protect;
+			mem_device->start_addr = address64.minimum;
+			mem_device->end_addr = address64.maximum;
 		}
 	}
 
@@ -250,7 +250,6 @@ static int acpi_memory_disable_device(st
 	int result;
 	u64 start = mem_device->start_addr;
 	u64 len = mem_device->end_addr - start + 1;
-	unsigned long attr = mem_device->read_write_attribute;
 
 	ACPI_FUNCTION_TRACE("acpi_memory_disable_device");
 
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index fec895a..f4c8775 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -78,9 +78,9 @@ MODULE_LICENSE("GPL");
 static uid_t asus_uid;
 static gid_t asus_gid;
 module_param(asus_uid, uint, 0);
-MODULE_PARM_DESC(uid, "UID for entries in /proc/acpi/asus.\n");
+MODULE_PARM_DESC(asus_uid, "UID for entries in /proc/acpi/asus.\n");
 module_param(asus_gid, uint, 0);
-MODULE_PARM_DESC(gid, "GID for entries in /proc/acpi/asus.\n");
+MODULE_PARM_DESC(asus_gid, "GID for entries in /proc/acpi/asus.\n");
 
 /* For each model, all features implemented, 
  * those marked with R are relative to HOTK, A for absolute */
@@ -302,7 +302,7 @@ static struct model_data model_conf[END_
 	 .brightness_set = "SPLV",
 	 .brightness_get = "GPLV",
 	 .display_set = "SDSP",
-	 .display_get = "\\SSTE"},
+	 .display_get = "\\_SB.PCI0.P0P1.VGA.GETD"},
 	{
 	 .name = "M6R",
 	 .mt_mled = "MLED",
@@ -851,6 +851,8 @@ static int __init asus_hotk_add_fs(struc
 		mode = S_IFREG | S_IRUGO | S_IWUGO;
 	} else {
 		mode = S_IFREG | S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP;
+		printk(KERN_WARNING "  asus_uid and asus_gid parameters are "
+		       "deprecated, use chown and chmod instead!\n");
 	}
 
 	acpi_device_dir(device) = asus_proc_dir;
@@ -987,9 +989,21 @@ static int __init asus_hotk_get_info(voi
 		printk(KERN_NOTICE "  BSTS called, 0x%02x returned\n",
 		       bsts_result);
 
-	/* Samsung P30 has a device with a valid _HID whose INIT does not 
-	 * return anything. Catch this one and any similar here */
-	if (buffer.pointer == NULL) {
+	/* This is unlikely with implicit return */
+	if (buffer.pointer == NULL)
+		return -EINVAL;
+
+	model = (union acpi_object *) buffer.pointer;
+	/*
+	 * Samsung P30 has a device with a valid _HID whose INIT does not 
+	 * return anything. It used to be possible to catch this exception,
+	 * but the implicit return code will now happily confuse the 
+	 * driver. We assume that every ACPI_TYPE_STRING is a valid model
+	 * identifier but it's still possible to get completely bogus data.
+	 */
+	if (model->type == ACPI_TYPE_STRING) {
+		printk(KERN_NOTICE "  %s model detected, ", model->string.pointer);
+	} else {
 		if (asus_info &&	/* Samsung P30 */
 		    strncmp(asus_info->oem_table_id, "ODEM", 4) == 0) {
 			hotk->model = P30;
@@ -1002,13 +1016,10 @@ static int __init asus_hotk_get_info(voi
 			       "the developers with your DSDT\n");
 		}
 		hotk->methods = &model_conf[hotk->model];
-		return AE_OK;
-	}
+		
+		acpi_os_free(model);
 
-	model = (union acpi_object *)buffer.pointer;
-	if (model->type == ACPI_TYPE_STRING) {
-		printk(KERN_NOTICE "  %s model detected, ",
-		       model->string.pointer);
+		return AE_OK;
 	}
 
 	hotk->model = END_MODEL;
diff --git a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c
index 2022aea..76bc046 100644
--- a/drivers/acpi/dispatcher/dsfield.c
+++ b/drivers/acpi/dispatcher/dsfield.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -128,7 +128,7 @@ acpi_ds_create_buffer_field(union acpi_p
 				   ACPI_IMODE_LOAD_PASS1, flags, walk_state,
 				   &(node));
 		if (ACPI_FAILURE(status)) {
-			ACPI_REPORT_NSERROR(arg->common.value.string, status);
+			ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
 			return_ACPI_STATUS(status);
 		}
 	}
@@ -232,7 +232,8 @@ acpi_ds_get_field_names(struct acpi_crea
 			    + (acpi_integer) arg->common.value.size;
 
 			if (position > ACPI_UINT32_MAX) {
-				ACPI_REPORT_ERROR(("Bit offset within field too large (> 0xFFFFFFFF)\n"));
+				ACPI_ERROR((AE_INFO,
+					    "Bit offset within field too large (> 0xFFFFFFFF)"));
 				return_ACPI_STATUS(AE_SUPPORT);
 			}
 
@@ -268,8 +269,8 @@ acpi_ds_get_field_names(struct acpi_crea
 						ACPI_NS_DONT_OPEN_SCOPE,
 						walk_state, &info->field_node);
 			if (ACPI_FAILURE(status)) {
-				ACPI_REPORT_NSERROR((char *)&arg->named.name,
-						    status);
+				ACPI_ERROR_NAMESPACE((char *)&arg->named.name,
+						     status);
 				if (status != AE_ALREADY_EXISTS) {
 					return_ACPI_STATUS(status);
 				}
@@ -293,7 +294,11 @@ acpi_ds_get_field_names(struct acpi_crea
 			    + (acpi_integer) arg->common.value.size;
 
 			if (position > ACPI_UINT32_MAX) {
-				ACPI_REPORT_ERROR(("Field [%4.4s] bit offset too large (> 0xFFFFFFFF)\n", (char *)&info->field_node->name));
+				ACPI_ERROR((AE_INFO,
+					    "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
+					    ACPI_CAST_PTR(char,
+							  &info->field_node->
+							  name)));
 				return_ACPI_STATUS(AE_SUPPORT);
 			}
 
@@ -302,9 +307,9 @@ acpi_ds_get_field_names(struct acpi_crea
 
 		default:
 
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Invalid opcode in field list: %X\n",
-					  arg->common.aml_opcode));
+			ACPI_ERROR((AE_INFO,
+				    "Invalid opcode in field list: %X",
+				    arg->common.aml_opcode));
 			return_ACPI_STATUS(AE_AML_BAD_OPCODE);
 		}
 
@@ -349,7 +354,7 @@ acpi_ds_create_field(union acpi_parse_ob
 				   ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
 				   walk_state, &region_node);
 		if (ACPI_FAILURE(status)) {
-			ACPI_REPORT_NSERROR(arg->common.value.name, status);
+			ACPI_ERROR_NAMESPACE(arg->common.value.name, status);
 			return_ACPI_STATUS(status);
 		}
 	}
@@ -431,8 +436,8 @@ acpi_ds_init_field_objects(union acpi_pa
 						ACPI_NS_ERROR_IF_FOUND,
 						walk_state, &node);
 			if (ACPI_FAILURE(status)) {
-				ACPI_REPORT_NSERROR((char *)&arg->named.name,
-						    status);
+				ACPI_ERROR_NAMESPACE((char *)&arg->named.name,
+						     status);
 				if (status != AE_ALREADY_EXISTS) {
 					return_ACPI_STATUS(status);
 				}
@@ -488,7 +493,7 @@ acpi_ds_create_bank_field(union acpi_par
 				   ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
 				   walk_state, &region_node);
 		if (ACPI_FAILURE(status)) {
-			ACPI_REPORT_NSERROR(arg->common.value.name, status);
+			ACPI_ERROR_NAMESPACE(arg->common.value.name, status);
 			return_ACPI_STATUS(status);
 		}
 	}
@@ -502,7 +507,7 @@ acpi_ds_create_bank_field(union acpi_par
 			   ACPI_NS_SEARCH_PARENT, walk_state,
 			   &info.register_node);
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_NSERROR(arg->common.value.string, status);
+		ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
 		return_ACPI_STATUS(status);
 	}
 
@@ -560,7 +565,7 @@ acpi_ds_create_index_field(union acpi_pa
 			   ACPI_NS_SEARCH_PARENT, walk_state,
 			   &info.register_node);
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_NSERROR(arg->common.value.string, status);
+		ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
 		return_ACPI_STATUS(status);
 	}
 
@@ -573,7 +578,7 @@ acpi_ds_create_index_field(union acpi_pa
 			   ACPI_NS_SEARCH_PARENT, walk_state,
 			   &info.data_register_node);
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_NSERROR(arg->common.value.string, status);
+		ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
 		return_ACPI_STATUS(status);
 	}
 
diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c
index 8693c70..e65a07a 100644
--- a/drivers/acpi/dispatcher/dsinit.c
+++ b/drivers/acpi/dispatcher/dsinit.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -84,7 +84,7 @@ acpi_ds_init_one_object(acpi_handle obj_
 	acpi_object_type type;
 	acpi_status status;
 
-	ACPI_FUNCTION_NAME("ds_init_one_object");
+	ACPI_FUNCTION_ENTRY();
 
 	/*
 	 * We are only interested in NS nodes owned by the table that
@@ -105,11 +105,10 @@ acpi_ds_init_one_object(acpi_handle obj_
 
 		status = acpi_ds_initialize_region(obj_handle);
 		if (ACPI_FAILURE(status)) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Region %p [%4.4s] - Init failure, %s\n",
-					  obj_handle,
-					  acpi_ut_get_node_name(obj_handle),
-					  acpi_format_exception(status)));
+			ACPI_EXCEPTION((AE_INFO, status,
+					"During Region initialization %p [%4.4s]",
+					obj_handle,
+					acpi_ut_get_node_name(obj_handle)));
 		}
 
 		info->op_region_count++;
@@ -118,14 +117,6 @@ acpi_ds_init_one_object(acpi_handle obj_
 	case ACPI_TYPE_METHOD:
 
 		/*
-		 * Print a dot for each method unless we are going to print
-		 * the entire pathname
-		 */
-		if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
-			ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "."));
-		}
-
-		/*
 		 * Set the execution data width (32 or 64) based upon the
 		 * revision number of the parent ACPI table.
 		 * TBD: This is really for possible future support of integer width
@@ -134,6 +125,21 @@ acpi_ds_init_one_object(acpi_handle obj_
 		if (info->table_desc->pointer->revision == 1) {
 			node->flags |= ANOBJ_DATA_WIDTH_32;
 		}
+#ifdef ACPI_INIT_PARSE_METHODS
+		/*
+		 * Note 11/2005: Removed this code to parse all methods during table
+		 * load because it causes problems if there are any errors during the
+		 * parse. Also, it seems like overkill and we probably don't want to
+		 * abort a table load because of an issue with a single method.
+		 */
+
+		/*
+		 * Print a dot for each method unless we are going to print
+		 * the entire pathname
+		 */
+		if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
+			ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "."));
+		}
 
 		/*
 		 * Always parse methods to detect errors, we will delete
@@ -141,15 +147,15 @@ acpi_ds_init_one_object(acpi_handle obj_
 		 */
 		status = acpi_ds_parse_method(obj_handle);
 		if (ACPI_FAILURE(status)) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "\n+Method %p [%4.4s] - parse failure, %s\n",
-					  obj_handle,
-					  acpi_ut_get_node_name(obj_handle),
-					  acpi_format_exception(status)));
+			ACPI_ERROR((AE_INFO,
+				    "Method %p [%4.4s] - parse failure, %s",
+				    obj_handle,
+				    acpi_ut_get_node_name(obj_handle),
+				    acpi_format_exception(status)));
 
 			/* This parse failed, but we will continue parsing more methods */
 		}
-
+#endif
 		info->method_count++;
 		break;
 
@@ -207,8 +213,7 @@ acpi_ds_initialize_objects(struct acpi_t
 	status = acpi_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
 				     acpi_ds_init_one_object, &info, NULL);
 	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "walk_namespace failed, %s\n",
-				  acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status, "During walk_namespace"));
 	}
 
 	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
index 36c1ca0..c475546 100644
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -47,135 +47,66 @@
 #include <acpi/acdispat.h>
 #include <acpi/acinterp.h>
 #include <acpi/acnamesp.h>
+#include <acpi/acdisasm.h>
 
 #define _COMPONENT          ACPI_DISPATCHER
 ACPI_MODULE_NAME("dsmethod")
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ds_parse_method
+ * FUNCTION:    acpi_ds_method_error
  *
- * PARAMETERS:  Node        - Method node
+ * PARAMETERS:  Status          - Execution status
+ *              walk_state      - Current state
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Parse the AML that is associated with the method.
+ * DESCRIPTION: Called on method error. Invoke the global exception handler if
+ *              present, dump the method data if the disassembler is configured
  *
- * MUTEX:       Assumes parser is locked
+ *              Note: Allows the exception handler to change the status code
  *
  ******************************************************************************/
-acpi_status acpi_ds_parse_method(struct acpi_namespace_node *node)
+acpi_status
+acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state)
 {
-	acpi_status status;
-	union acpi_operand_object *obj_desc;
-	union acpi_parse_object *op;
-	struct acpi_walk_state *walk_state;
-
-	ACPI_FUNCTION_TRACE_PTR("ds_parse_method", node);
+	ACPI_FUNCTION_ENTRY();
 
-	/* Parameter Validation */
+	/* Ignore AE_OK and control exception codes */
 
-	if (!node) {
-		return_ACPI_STATUS(AE_NULL_ENTRY);
+	if (ACPI_SUCCESS(status) || (status & AE_CODE_CONTROL)) {
+		return (status);
 	}
 
-	ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
-			  "**** Parsing [%4.4s] **** named_obj=%p\n",
-			  acpi_ut_get_node_name(node), node));
-
-	/* Extract the method object from the method Node */
+	/* Invoke the global exception handler */
 
-	obj_desc = acpi_ns_get_attached_object(node);
-	if (!obj_desc) {
-		return_ACPI_STATUS(AE_NULL_OBJECT);
-	}
+	if (acpi_gbl_exception_handler) {
+		/* Exit the interpreter, allow handler to execute methods */
 
-	/* Create a mutex for the method if there is a concurrency limit */
+		acpi_ex_exit_interpreter();
 
-	if ((obj_desc->method.concurrency != ACPI_INFINITE_CONCURRENCY) &&
-	    (!obj_desc->method.semaphore)) {
-		status = acpi_os_create_semaphore(obj_desc->method.concurrency,
-						  obj_desc->method.concurrency,
-						  &obj_desc->method.semaphore);
-		if (ACPI_FAILURE(status)) {
-			return_ACPI_STATUS(status);
-		}
-	}
-
-	/*
-	 * Allocate a new parser op to be the root of the parsed
-	 * method tree
-	 */
-	op = acpi_ps_alloc_op(AML_METHOD_OP);
-	if (!op) {
-		return_ACPI_STATUS(AE_NO_MEMORY);
-	}
-
-	/* Init new op with the method name and pointer back to the Node */
-
-	acpi_ps_set_name(op, node->name.integer);
-	op->common.node = node;
-
-	/*
-	 * Get a new owner_id for objects created by this method. Namespace
-	 * objects (such as Operation Regions) can be created during the
-	 * first pass parse.
-	 */
-	status = acpi_ut_allocate_owner_id(&obj_desc->method.owner_id);
-	if (ACPI_FAILURE(status)) {
-		goto cleanup;
-	}
-
-	/* Create and initialize a new walk state */
-
-	walk_state =
-	    acpi_ds_create_walk_state(obj_desc->method.owner_id, NULL, NULL,
-				      NULL);
-	if (!walk_state) {
-		status = AE_NO_MEMORY;
-		goto cleanup2;
+		/*
+		 * Handler can map the exception code to anything it wants, including
+		 * AE_OK, in which case the executing method will not be aborted.
+		 */
+		status = acpi_gbl_exception_handler(status,
+						    walk_state->method_node ?
+						    walk_state->method_node->
+						    name.integer : 0,
+						    walk_state->opcode,
+						    walk_state->aml_offset,
+						    NULL);
+		(void)acpi_ex_enter_interpreter();
 	}
-
-	status = acpi_ds_init_aml_walk(walk_state, op, node,
-				       obj_desc->method.aml_start,
-				       obj_desc->method.aml_length, NULL, 1);
+#ifdef ACPI_DISASSEMBLER
 	if (ACPI_FAILURE(status)) {
-		acpi_ds_delete_walk_state(walk_state);
-		goto cleanup2;
-	}
+		/* Display method locals/args if disassembler is present */
 
-	/*
-	 * Parse the method, first pass
-	 *
-	 * The first pass load is where newly declared named objects are added into
-	 * the namespace.  Actual evaluation of the named objects (what would be
-	 * called a "second pass") happens during the actual execution of the
-	 * method so that operands to the named objects can take on dynamic
-	 * run-time values.
-	 */
-	status = acpi_ps_parse_aml(walk_state);
-	if (ACPI_FAILURE(status)) {
-		goto cleanup2;
+		acpi_dm_dump_method_info(status, walk_state, walk_state->op);
 	}
+#endif
 
-	ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
-			  "**** [%4.4s] Parsed **** named_obj=%p Op=%p\n",
-			  acpi_ut_get_node_name(node), node, op));
-
-	/*
-	 * Delete the parse tree. We simply re-parse the method for every
-	 * execution since there isn't much overhead (compared to keeping lots
-	 * of parse trees around)
-	 */
-	acpi_ns_delete_namespace_subtree(node);
-	acpi_ns_delete_namespace_by_owner(obj_desc->method.owner_id);
-
-      cleanup2:
-	acpi_ut_release_owner_id(&obj_desc->method.owner_id);
-
-      cleanup:
-	acpi_ps_delete_parse_tree(op);
-	return_ACPI_STATUS(status);
+	return (status);
 }
 
 /*******************************************************************************
@@ -195,9 +126,9 @@ acpi_status acpi_ds_parse_method(struct 
  ******************************************************************************/
 
 acpi_status
-acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
-			       union acpi_operand_object *obj_desc,
-			       struct acpi_namespace_node *calling_method_node)
+acpi_ds_begin_method_execution(struct acpi_namespace_node * method_node,
+			       union acpi_operand_object * obj_desc,
+			       struct acpi_namespace_node * calling_method_node)
 {
 	acpi_status status = AE_OK;
 
@@ -210,7 +141,8 @@ acpi_ds_begin_method_execution(struct ac
 	/* Prevent wraparound of thread count */
 
 	if (obj_desc->method.thread_count == ACPI_UINT8_MAX) {
-		ACPI_REPORT_ERROR(("Method reached maximum reentrancy limit (255)\n"));
+		ACPI_ERROR((AE_INFO,
+			    "Method reached maximum reentrancy limit (255)"));
 		return_ACPI_STATUS(AE_AML_METHOD_LIMIT);
 	}
 
@@ -539,22 +471,61 @@ void acpi_ds_terminate_control_method(st
 		    acpi_os_signal_semaphore(walk_state->method_desc->method.
 					     semaphore, 1);
 		if (ACPI_FAILURE(status)) {
-			ACPI_REPORT_ERROR(("Could not signal method semaphore\n"));
+			ACPI_ERROR((AE_INFO,
+				    "Could not signal method semaphore"));
 
 			/* Ignore error and continue cleanup */
 		}
 	}
 
+	/*
+	 * There are no more threads executing this method.  Perform
+	 * additional cleanup.
+	 *
+	 * The method Node is stored in the walk state
+	 */
+	method_node = walk_state->method_node;
+
+	/* Lock namespace for possible update */
+
+	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE(status)) {
+		goto exit;
+	}
+
+	/*
+	 * Delete any namespace entries created immediately underneath
+	 * the method
+	 */
+	if (method_node->child) {
+		acpi_ns_delete_namespace_subtree(method_node);
+	}
+
+	/*
+	 * Delete any namespace entries created anywhere else within
+	 * the namespace by the execution of this method
+	 */
+	acpi_ns_delete_namespace_by_owner(walk_state->method_desc->method.
+					  owner_id);
+	status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+
+	/* Are there any other threads currently executing this method? */
+
 	if (walk_state->method_desc->method.thread_count) {
+		/*
+		 * Additional threads. Do not release the owner_id in this case,
+		 * we immediately reuse it for the next thread executing this method
+		 */
 		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
-				  "*** Not deleting method namespace, there are still %d threads\n",
+				  "*** Completed execution of one thread, %d threads remaining\n",
 				  walk_state->method_desc->method.
 				  thread_count));
-	} else {		/* This is the last executing thread */
+	} else {
+		/* This is the only executing thread for this method */
 
 		/*
 		 * Support to dynamically change a method from not_serialized to
-		 * Serialized if it appears that the method is written foolishly and
+		 * Serialized if it appears that the method is incorrectly written and
 		 * does not support multiple thread execution.  The best example of this
 		 * is if such a method creates namespace objects and blocks.  A second
 		 * thread will fail with an AE_ALREADY_EXISTS exception
@@ -570,34 +541,8 @@ void acpi_ds_terminate_control_method(st
 							  semaphore);
 		}
 
-		/*
-		 * There are no more threads executing this method.  Perform
-		 * additional cleanup.
-		 *
-		 * The method Node is stored in the walk state
-		 */
-		method_node = walk_state->method_node;
-
-		/*
-		 * Delete any namespace entries created immediately underneath
-		 * the method
-		 */
-		status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
-		if (ACPI_FAILURE(status)) {
-			goto exit;
-		}
-
-		if (method_node->child) {
-			acpi_ns_delete_namespace_subtree(method_node);
-		}
+		/* No more threads, we can free the owner_id */
 
-		/*
-		 * Delete any namespace entries created anywhere else within
-		 * the namespace
-		 */
-		acpi_ns_delete_namespace_by_owner(walk_state->method_desc->
-						  method.owner_id);
-		status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 		acpi_ut_release_owner_id(&walk_state->method_desc->method.
 					 owner_id);
 	}
@@ -606,3 +551,140 @@ void acpi_ds_terminate_control_method(st
 	(void)acpi_ut_release_mutex(ACPI_MTX_PARSER);
 	return_VOID;
 }
+
+#ifdef ACPI_INIT_PARSE_METHODS
+	/*
+	 * Note 11/2005: Removed this code to parse all methods during table
+	 * load because it causes problems if there are any errors during the
+	 * parse. Also, it seems like overkill and we probably don't want to
+	 * abort a table load because of an issue with a single method.
+	 */
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_parse_method
+ *
+ * PARAMETERS:  Node        - Method node
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Parse the AML that is associated with the method.
+ *
+ * MUTEX:       Assumes parser is locked
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ds_parse_method(struct acpi_namespace_node *node)
+{
+	acpi_status status;
+	union acpi_operand_object *obj_desc;
+	union acpi_parse_object *op;
+	struct acpi_walk_state *walk_state;
+
+	ACPI_FUNCTION_TRACE_PTR("ds_parse_method", node);
+
+	/* Parameter Validation */
+
+	if (!node) {
+		return_ACPI_STATUS(AE_NULL_ENTRY);
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
+			  "**** Parsing [%4.4s] **** named_obj=%p\n",
+			  acpi_ut_get_node_name(node), node));
+
+	/* Extract the method object from the method Node */
+
+	obj_desc = acpi_ns_get_attached_object(node);
+	if (!obj_desc) {
+		return_ACPI_STATUS(AE_NULL_OBJECT);
+	}
+
+	/* Create a mutex for the method if there is a concurrency limit */
+
+	if ((obj_desc->method.concurrency != ACPI_INFINITE_CONCURRENCY) &&
+	    (!obj_desc->method.semaphore)) {
+		status = acpi_os_create_semaphore(obj_desc->method.concurrency,
+						  obj_desc->method.concurrency,
+						  &obj_desc->method.semaphore);
+		if (ACPI_FAILURE(status)) {
+			return_ACPI_STATUS(status);
+		}
+	}
+
+	/*
+	 * Allocate a new parser op to be the root of the parsed
+	 * method tree
+	 */
+	op = acpi_ps_alloc_op(AML_METHOD_OP);
+	if (!op) {
+		return_ACPI_STATUS(AE_NO_MEMORY);
+	}
+
+	/* Init new op with the method name and pointer back to the Node */
+
+	acpi_ps_set_name(op, node->name.integer);
+	op->common.node = node;
+
+	/*
+	 * Get a new owner_id for objects created by this method. Namespace
+	 * objects (such as Operation Regions) can be created during the
+	 * first pass parse.
+	 */
+	status = acpi_ut_allocate_owner_id(&obj_desc->method.owner_id);
+	if (ACPI_FAILURE(status)) {
+		goto cleanup;
+	}
+
+	/* Create and initialize a new walk state */
+
+	walk_state =
+	    acpi_ds_create_walk_state(obj_desc->method.owner_id, NULL, NULL,
+				      NULL);
+	if (!walk_state) {
+		status = AE_NO_MEMORY;
+		goto cleanup2;
+	}
+
+	status = acpi_ds_init_aml_walk(walk_state, op, node,
+				       obj_desc->method.aml_start,
+				       obj_desc->method.aml_length, NULL, 1);
+	if (ACPI_FAILURE(status)) {
+		acpi_ds_delete_walk_state(walk_state);
+		goto cleanup2;
+	}
+
+	/*
+	 * Parse the method, first pass
+	 *
+	 * The first pass load is where newly declared named objects are added into
+	 * the namespace.  Actual evaluation of the named objects (what would be
+	 * called a "second pass") happens during the actual execution of the
+	 * method so that operands to the named objects can take on dynamic
+	 * run-time values.
+	 */
+	status = acpi_ps_parse_aml(walk_state);
+	if (ACPI_FAILURE(status)) {
+		goto cleanup2;
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
+			  "**** [%4.4s] Parsed **** named_obj=%p Op=%p\n",
+			  acpi_ut_get_node_name(node), node, op));
+
+	/*
+	 * Delete the parse tree. We simply re-parse the method for every
+	 * execution since there isn't much overhead (compared to keeping lots
+	 * of parse trees around)
+	 */
+	acpi_ns_delete_namespace_subtree(node);
+	acpi_ns_delete_namespace_by_owner(obj_desc->method.owner_id);
+
+      cleanup2:
+	acpi_ut_release_owner_id(&obj_desc->method.owner_id);
+
+      cleanup:
+	acpi_ps_delete_parse_tree(op);
+	return_ACPI_STATUS(status);
+}
+#endif
diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c
index 4095ce7..c025674 100644
--- a/drivers/acpi/dispatcher/dsmthdat.c
+++ b/drivers/acpi/dispatcher/dsmthdat.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -260,9 +260,9 @@ acpi_ds_method_data_get_node(u16 opcode,
 	case AML_LOCAL_OP:
 
 		if (index > ACPI_METHOD_MAX_LOCAL) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Local index %d is invalid (max %d)\n",
-					  index, ACPI_METHOD_MAX_LOCAL));
+			ACPI_ERROR((AE_INFO,
+				    "Local index %d is invalid (max %d)",
+				    index, ACPI_METHOD_MAX_LOCAL));
 			return_ACPI_STATUS(AE_AML_INVALID_INDEX);
 		}
 
@@ -274,9 +274,9 @@ acpi_ds_method_data_get_node(u16 opcode,
 	case AML_ARG_OP:
 
 		if (index > ACPI_METHOD_MAX_ARG) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Arg index %d is invalid (max %d)\n",
-					  index, ACPI_METHOD_MAX_ARG));
+			ACPI_ERROR((AE_INFO,
+				    "Arg index %d is invalid (max %d)",
+				    index, ACPI_METHOD_MAX_ARG));
 			return_ACPI_STATUS(AE_AML_INVALID_INDEX);
 		}
 
@@ -286,8 +286,7 @@ acpi_ds_method_data_get_node(u16 opcode,
 		break;
 
 	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Opcode %d is invalid\n",
-				  opcode));
+		ACPI_ERROR((AE_INFO, "Opcode %d is invalid", opcode));
 		return_ACPI_STATUS(AE_AML_BAD_OPCODE);
 	}
 
@@ -378,8 +377,7 @@ acpi_ds_method_data_get_value(u16 opcode
 	/* Validate the object descriptor */
 
 	if (!dest_desc) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Null object descriptor pointer\n"));
+		ACPI_ERROR((AE_INFO, "Null object descriptor pointer"));
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
@@ -424,23 +422,24 @@ acpi_ds_method_data_get_value(u16 opcode
 			switch (opcode) {
 			case AML_ARG_OP:
 
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "Uninitialized Arg[%d] at node %p\n",
-						  index, node));
+				ACPI_ERROR((AE_INFO,
+					    "Uninitialized Arg[%d] at node %p",
+					    index, node));
 
 				return_ACPI_STATUS(AE_AML_UNINITIALIZED_ARG);
 
 			case AML_LOCAL_OP:
 
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "Uninitialized Local[%d] at node %p\n",
-						  index, node));
+				ACPI_ERROR((AE_INFO,
+					    "Uninitialized Local[%d] at node %p",
+					    index, node));
 
 				return_ACPI_STATUS(AE_AML_UNINITIALIZED_LOCAL);
 
 			default:
-				ACPI_REPORT_ERROR(("Not Arg/Local opcode: %X\n",
-						   opcode));
+				ACPI_ERROR((AE_INFO,
+					    "Not a Arg/Local opcode: %X",
+					    opcode));
 				return_ACPI_STATUS(AE_AML_INTERNAL);
 			}
 	}
diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c
index 8ac0cd9..8b21f0f 100644
--- a/drivers/acpi/dispatcher/dsobject.c
+++ b/drivers/acpi/dispatcher/dsobject.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -51,6 +51,7 @@
 #define _COMPONENT          ACPI_DISPATCHER
 ACPI_MODULE_NAME("dsobject")
 
+/* Local prototypes */
 static acpi_status
 acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
 			      union acpi_parse_object *op,
@@ -85,7 +86,7 @@ acpi_ds_build_internal_object(struct acp
 	*obj_desc_ptr = NULL;
 	if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
 		/*
-		 * This is an named object reference.  If this name was
+		 * This is a named object reference. If this name was
 		 * previously looked up in the namespace, it was stored in this op.
 		 * Otherwise, go ahead and look it up now
 		 */
@@ -96,18 +97,48 @@ acpi_ds_build_internal_object(struct acp
 						ACPI_IMODE_EXECUTE,
 						ACPI_NS_SEARCH_PARENT |
 						ACPI_NS_DONT_OPEN_SCOPE, NULL,
-						(struct acpi_namespace_node **)
-						&(op->common.node));
-
+						ACPI_CAST_INDIRECT_PTR(struct
+								       acpi_namespace_node,
+								       &(op->
+									 common.
+									 node)));
 			if (ACPI_FAILURE(status)) {
-				ACPI_REPORT_NSERROR(op->common.value.string,
-						    status);
+				/* Check if we are resolving a named reference within a package */
+
+				if ((status == AE_NOT_FOUND)
+				    && (acpi_gbl_enable_interpreter_slack)
+				    &&
+				    ((op->common.parent->common.aml_opcode ==
+				      AML_PACKAGE_OP)
+				     || (op->common.parent->common.aml_opcode ==
+					 AML_VAR_PACKAGE_OP))) {
+					/*
+					 * We didn't find the target and we are populating elements
+					 * of a package - ignore if slack enabled. Some ASL code
+					 * contains dangling invalid references in packages and
+					 * expects that no exception will be issued. Leave the
+					 * element as a null element. It cannot be used, but it
+					 * can be overwritten by subsequent ASL code - this is
+					 * typically the case.
+					 */
+					ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+							  "Ignoring unresolved reference in package [%4.4s]\n",
+							  walk_state->
+							  scope_info->scope.
+							  node->name.ascii));
+
+					return_ACPI_STATUS(AE_OK);
+				} else {
+					ACPI_ERROR_NAMESPACE(op->common.value.
+							     string, status);
+				}
+
 				return_ACPI_STATUS(status);
 			}
 		}
 	}
 
-	/* Create and init the internal ACPI object */
+	/* Create and init a new internal ACPI object */
 
 	obj_desc = acpi_ut_create_internal_object((acpi_ps_get_opcode_info
 						   (op->common.aml_opcode))->
@@ -157,13 +188,13 @@ acpi_ds_build_internal_buffer_obj(struct
 
 	ACPI_FUNCTION_TRACE("ds_build_internal_buffer_obj");
 
+	/*
+	 * If we are evaluating a Named buffer object "Name (xxxx, Buffer)".
+	 * The buffer object already exists (from the NS node), otherwise it must
+	 * be created.
+	 */
 	obj_desc = *obj_desc_ptr;
-	if (obj_desc) {
-		/*
-		 * We are evaluating a Named buffer object "Name (xxxx, Buffer)".
-		 * The buffer object already exists (from the NS node)
-		 */
-	} else {
+	if (!obj_desc) {
 		/* Create a new buffer object */
 
 		obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
@@ -183,10 +214,9 @@ acpi_ds_build_internal_buffer_obj(struct
 	byte_list = arg->named.next;
 	if (byte_list) {
 		if (byte_list->common.aml_opcode != AML_INT_BYTELIST_OP) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Expecting bytelist, got AML opcode %X in op %p\n",
-					  byte_list->common.aml_opcode,
-					  byte_list));
+			ACPI_ERROR((AE_INFO,
+				    "Expecting bytelist, got AML opcode %X in op %p",
+				    byte_list->common.aml_opcode, byte_list));
 
 			acpi_ut_remove_reference(obj_desc);
 			return (AE_TYPE);
@@ -259,7 +289,7 @@ acpi_ds_build_internal_package_obj(struc
 	union acpi_operand_object *obj_desc = NULL;
 	u32 package_list_length;
 	acpi_status status = AE_OK;
-	u32 i;
+	acpi_native_uint i;
 
 	ACPI_FUNCTION_TRACE("ds_build_internal_package_obj");
 
@@ -271,13 +301,12 @@ acpi_ds_build_internal_package_obj(struc
 		parent = parent->common.parent;
 	}
 
+	/*
+	 * If we are evaluating a Named package object "Name (xxxx, Package)",
+	 * the package object already exists, otherwise it must be created.
+	 */
 	obj_desc = *obj_desc_ptr;
-	if (obj_desc) {
-		/*
-		 * We are evaluating a Named package object "Name (xxxx, Package)".
-		 * Get the existing package object from the NS node
-		 */
-	} else {
+	if (!obj_desc) {
 		obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_PACKAGE);
 		*obj_desc_ptr = obj_desc;
 		if (!obj_desc) {
@@ -291,11 +320,9 @@ acpi_ds_build_internal_package_obj(struc
 
 	/* Count the number of items in the package list */
 
-	package_list_length = 0;
 	arg = op->common.value.arg;
 	arg = arg->common.next;
-	while (arg) {
-		package_list_length++;
+	for (package_list_length = 0; arg; package_list_length++) {
 		arg = arg->common.next;
 	}
 
@@ -322,12 +349,11 @@ acpi_ds_build_internal_package_obj(struc
 	}
 
 	/*
-	 * Now init the elements of the package
+	 * Initialize all elements of the package
 	 */
-	i = 0;
 	arg = op->common.value.arg;
 	arg = arg->common.next;
-	while (arg) {
+	for (i = 0; arg; i++) {
 		if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) {
 			/* Object (package or buffer) is already built */
 
@@ -340,8 +366,6 @@ acpi_ds_build_internal_package_obj(struc
 							       package.
 							       elements[i]);
 		}
-
-		i++;
 		arg = arg->common.next;
 	}
 
@@ -518,9 +542,9 @@ acpi_ds_init_object_from_op(struct acpi_
 
 			default:
 
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "Unknown constant opcode %X\n",
-						  opcode));
+				ACPI_ERROR((AE_INFO,
+					    "Unknown constant opcode %X",
+					    opcode));
 				status = AE_AML_OPERAND_TYPE;
 				break;
 			}
@@ -535,9 +559,8 @@ acpi_ds_init_object_from_op(struct acpi_
 			break;
 
 		default:
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Unknown Integer type %X\n",
-					  op_info->type));
+			ACPI_ERROR((AE_INFO, "Unknown Integer type %X",
+				    op_info->type));
 			status = AE_AML_OPERAND_TYPE;
 			break;
 		}
@@ -615,9 +638,8 @@ acpi_ds_init_object_from_op(struct acpi_
 
 	default:
 
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Unimplemented data type: %X\n",
-				  ACPI_GET_OBJECT_TYPE(obj_desc)));
+		ACPI_ERROR((AE_INFO, "Unimplemented data type: %X",
+			    ACPI_GET_OBJECT_TYPE(obj_desc)));
 
 		status = AE_AML_OPERAND_TYPE;
 		break;
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
index 939d167..6229c10 100644
--- a/drivers/acpi/dispatcher/dsopcode.c
+++ b/drivers/acpi/dispatcher/dsopcode.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -245,7 +245,9 @@ acpi_status acpi_ds_get_buffer_arguments
 
 	node = obj_desc->buffer.node;
 	if (!node) {
-		ACPI_REPORT_ERROR(("No pointer back to NS node in buffer obj %p\n", obj_desc));
+		ACPI_ERROR((AE_INFO,
+			    "No pointer back to NS node in buffer obj %p",
+			    obj_desc));
 		return_ACPI_STATUS(AE_AML_INTERNAL);
 	}
 
@@ -287,8 +289,9 @@ acpi_status acpi_ds_get_package_argument
 
 	node = obj_desc->package.node;
 	if (!node) {
-		ACPI_REPORT_ERROR(("No pointer back to NS node in package %p\n",
-				   obj_desc));
+		ACPI_ERROR((AE_INFO,
+			    "No pointer back to NS node in package %p",
+			    obj_desc));
 		return_ACPI_STATUS(AE_AML_INTERNAL);
 	}
 
@@ -413,9 +416,9 @@ acpi_ds_init_buffer_field(u16 aml_opcode
 	/* Host object must be a Buffer */
 
 	if (ACPI_GET_OBJECT_TYPE(buffer_desc) != ACPI_TYPE_BUFFER) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Target of Create Field is not a Buffer object - %s\n",
-				  acpi_ut_get_object_type_name(buffer_desc)));
+		ACPI_ERROR((AE_INFO,
+			    "Target of Create Field is not a Buffer object - %s",
+			    acpi_ut_get_object_type_name(buffer_desc)));
 
 		status = AE_AML_OPERAND_TYPE;
 		goto cleanup;
@@ -427,10 +430,10 @@ acpi_ds_init_buffer_field(u16 aml_opcode
 	 * after resolution in acpi_ex_resolve_operands().
 	 */
 	if (ACPI_GET_DESCRIPTOR_TYPE(result_desc) != ACPI_DESC_TYPE_NAMED) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "(%s) destination not a NS Node [%s]\n",
-				  acpi_ps_get_opcode_name(aml_opcode),
-				  acpi_ut_get_descriptor_name(result_desc)));
+		ACPI_ERROR((AE_INFO,
+			    "(%s) destination not a NS Node [%s]",
+			    acpi_ps_get_opcode_name(aml_opcode),
+			    acpi_ut_get_descriptor_name(result_desc)));
 
 		status = AE_AML_OPERAND_TYPE;
 		goto cleanup;
@@ -453,8 +456,8 @@ acpi_ds_init_buffer_field(u16 aml_opcode
 		/* Must have a valid (>0) bit count */
 
 		if (bit_count == 0) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Attempt to create_field of length 0\n"));
+			ACPI_ERROR((AE_INFO,
+				    "Attempt to create_field of length zero"));
 			status = AE_AML_OPERAND_VALUE;
 			goto cleanup;
 		}
@@ -507,9 +510,8 @@ acpi_ds_init_buffer_field(u16 aml_opcode
 
 	default:
 
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Unknown field creation opcode %02x\n",
-				  aml_opcode));
+		ACPI_ERROR((AE_INFO,
+			    "Unknown field creation opcode %02x", aml_opcode));
 		status = AE_AML_BAD_OPCODE;
 		goto cleanup;
 	}
@@ -517,13 +519,12 @@ acpi_ds_init_buffer_field(u16 aml_opcode
 	/* Entire field must fit within the current length of the buffer */
 
 	if ((bit_offset + bit_count) > (8 * (u32) buffer_desc->buffer.length)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Field [%4.4s] size %d exceeds Buffer [%4.4s] size %d (bits)\n",
-				  acpi_ut_get_node_name(result_desc),
-				  bit_offset + bit_count,
-				  acpi_ut_get_node_name(buffer_desc->buffer.
-							node),
-				  8 * (u32) buffer_desc->buffer.length));
+		ACPI_ERROR((AE_INFO,
+			    "Field [%4.4s] at %d exceeds Buffer [%4.4s] size %d (bits)",
+			    acpi_ut_get_node_name(result_desc),
+			    bit_offset + bit_count,
+			    acpi_ut_get_node_name(buffer_desc->buffer.node),
+			    8 * (u32) buffer_desc->buffer.length));
 		status = AE_AML_BUFFER_LIMIT;
 		goto cleanup;
 	}
@@ -629,9 +630,9 @@ acpi_ds_eval_buffer_field_operands(struc
 			   "after acpi_ex_resolve_operands");
 
 	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "(%s) bad operand(s) (%X)\n",
-				  acpi_ps_get_opcode_name(op->common.
-							  aml_opcode), status));
+		ACPI_ERROR((AE_INFO, "(%s) bad operand(s) (%X)",
+			    acpi_ps_get_opcode_name(op->common.aml_opcode),
+			    status));
 
 		return_ACPI_STATUS(status);
 	}
@@ -1155,9 +1156,8 @@ acpi_ds_exec_end_control_op(struct acpi_
 
 	default:
 
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Unknown control opcode=%X Op=%p\n",
-				  op->common.aml_opcode, op));
+		ACPI_ERROR((AE_INFO, "Unknown control opcode=%X Op=%p",
+			    op->common.aml_opcode, op));
 
 		status = AE_AML_BAD_OPCODE;
 		break;
diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c
index 83ae1c1..53356a5 100644
--- a/drivers/acpi/dispatcher/dsutils.c
+++ b/drivers/acpi/dispatcher/dsutils.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -176,8 +176,8 @@ acpi_ds_is_result_used(union acpi_parse_
 	/* Must have both an Op and a Result Object */
 
 	if (!op) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Null Op\n"));
-		return_VALUE(TRUE);
+		ACPI_ERROR((AE_INFO, "Null Op"));
+		return_UINT8(TRUE);
 	}
 
 	/*
@@ -208,7 +208,7 @@ acpi_ds_is_result_used(union acpi_parse_
 				  "At Method level, result of [%s] not used\n",
 				  acpi_ps_get_opcode_name(op->common.
 							  aml_opcode)));
-		return_VALUE(FALSE);
+		return_UINT8(FALSE);
 	}
 
 	/* Get info on the parent. The root_op is AML_SCOPE */
@@ -216,9 +216,8 @@ acpi_ds_is_result_used(union acpi_parse_
 	parent_info =
 	    acpi_ps_get_opcode_info(op->common.parent->common.aml_opcode);
 	if (parent_info->class == AML_CLASS_UNKNOWN) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Unknown parent opcode. Op=%p\n", op));
-		return_VALUE(FALSE);
+		ACPI_ERROR((AE_INFO, "Unknown parent opcode Op=%p", op));
+		return_UINT8(FALSE);
 	}
 
 	/*
@@ -304,7 +303,7 @@ acpi_ds_is_result_used(union acpi_parse_
 			  acpi_ps_get_opcode_name(op->common.parent->common.
 						  aml_opcode), op));
 
-	return_VALUE(TRUE);
+	return_UINT8(TRUE);
 
       result_not_used:
 	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
@@ -313,7 +312,7 @@ acpi_ds_is_result_used(union acpi_parse_
 			  acpi_ps_get_opcode_name(op->common.parent->common.
 						  aml_opcode), op));
 
-	return_VALUE(FALSE);
+	return_UINT8(FALSE);
 }
 
 /*******************************************************************************
@@ -344,7 +343,7 @@ acpi_ds_delete_result_if_not_used(union 
 	ACPI_FUNCTION_TRACE_PTR("ds_delete_result_if_not_used", result_obj);
 
 	if (!op) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Null Op\n"));
+		ACPI_ERROR((AE_INFO, "Null Op"));
 		return_VOID;
 	}
 
@@ -567,7 +566,7 @@ acpi_ds_create_operand(struct acpi_walk_
 			}
 
 			if (ACPI_FAILURE(status)) {
-				ACPI_REPORT_NSERROR(name_string, status);
+				ACPI_ERROR_NAMESPACE(name_string, status);
 			}
 		}
 
@@ -616,7 +615,7 @@ acpi_ds_create_operand(struct acpi_walk_
 
 		if (op_info->flags & AML_HAS_RETVAL) {
 			ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
-					  "Argument previously created, already stacked \n"));
+					  "Argument previously created, already stacked\n"));
 
 			ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object
 					   (walk_state->
@@ -635,10 +634,8 @@ acpi_ds_create_operand(struct acpi_walk_
 				 * Only error is underflow, and this indicates
 				 * a missing or null operand!
 				 */
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "Missing or null operand, %s\n",
-						  acpi_format_exception
-						  (status)));
+				ACPI_EXCEPTION((AE_INFO, status,
+						"Missing or null operand"));
 				return_ACPI_STATUS(status);
 			}
 		} else {
@@ -730,7 +727,7 @@ acpi_ds_create_operands(struct acpi_walk
 	 */
 	(void)acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state);
 
-	ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "While creating Arg %d - %s\n",
-			  (arg_count + 1), acpi_format_exception(status)));
+	ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d",
+			(arg_count + 1)));
 	return_ACPI_STATUS(status);
 }
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
index e522763..f1af655 100644
--- a/drivers/acpi/dispatcher/dswexec.c
+++ b/drivers/acpi/dispatcher/dswexec.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -100,9 +100,8 @@ acpi_ds_get_predicate_value(struct acpi_
 	if (result_obj) {
 		status = acpi_ds_result_pop(&obj_desc, walk_state);
 		if (ACPI_FAILURE(status)) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Could not get result from predicate evaluation, %s\n",
-					  acpi_format_exception(status)));
+			ACPI_EXCEPTION((AE_INFO, status,
+					"Could not get result from predicate evaluation"));
 
 			return_ACPI_STATUS(status);
 		}
@@ -123,9 +122,9 @@ acpi_ds_get_predicate_value(struct acpi_
 	}
 
 	if (!obj_desc) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "No predicate obj_desc=%p State=%p\n",
-				  obj_desc, walk_state));
+		ACPI_ERROR((AE_INFO,
+			    "No predicate obj_desc=%p State=%p",
+			    obj_desc, walk_state));
 
 		return_ACPI_STATUS(AE_AML_NO_OPERAND);
 	}
@@ -140,10 +139,10 @@ acpi_ds_get_predicate_value(struct acpi_
 	}
 
 	if (ACPI_GET_OBJECT_TYPE(local_obj_desc) != ACPI_TYPE_INTEGER) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Bad predicate (not an integer) obj_desc=%p State=%p Type=%X\n",
-				  obj_desc, walk_state,
-				  ACPI_GET_OBJECT_TYPE(obj_desc)));
+		ACPI_ERROR((AE_INFO,
+			    "Bad predicate (not an integer) obj_desc=%p State=%p Type=%X",
+			    obj_desc, walk_state,
+			    ACPI_GET_OBJECT_TYPE(obj_desc)));
 
 		status = AE_AML_OPERAND_TYPE;
 		goto cleanup;
@@ -314,12 +313,13 @@ acpi_ds_exec_begin_op(struct acpi_walk_s
 
 	case AML_CLASS_EXECUTE:
 	case AML_CLASS_CREATE:
-
 		/*
 		 * Most operators with arguments.
 		 * Start a new result/operand state
 		 */
-		status = acpi_ds_result_stack_push(walk_state);
+		if (walk_state->opcode != AML_CREATE_FIELD_OP) {
+			status = acpi_ds_result_stack_push(walk_state);
+		}
 		break;
 
 	default:
@@ -361,8 +361,8 @@ acpi_status acpi_ds_exec_end_op(struct a
 	op_class = walk_state->op_info->class;
 
 	if (op_class == AML_CLASS_UNKNOWN) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown opcode %X\n",
-				  op->common.aml_opcode));
+		ACPI_ERROR((AE_INFO, "Unknown opcode %X",
+			    op->common.aml_opcode));
 		return_ACPI_STATUS(AE_NOT_IMPLEMENTED);
 	}
 
@@ -452,12 +452,10 @@ acpi_status acpi_ds_exec_end_op(struct a
 				walk_state->operands[1]->reference.offset)) {
 				status = AE_OK;
 			} else {
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "[%s]: Could not resolve operands, %s\n",
-						  acpi_ps_get_opcode_name
-						  (walk_state->opcode),
-						  acpi_format_exception
-						  (status)));
+				ACPI_EXCEPTION((AE_INFO, status,
+						"While resolving operands for [%s]",
+						acpi_ps_get_opcode_name
+						(walk_state->opcode)));
 			}
 		}
 
@@ -676,8 +674,8 @@ acpi_status acpi_ds_exec_end_op(struct a
 
 		case AML_TYPE_UNDEFINED:
 
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Undefined opcode type Op=%p\n", op));
+			ACPI_ERROR((AE_INFO,
+				    "Undefined opcode type Op=%p", op));
 			return_ACPI_STATUS(AE_NOT_IMPLEMENTED);
 
 		case AML_TYPE_BOGUS:
@@ -689,10 +687,10 @@ acpi_status acpi_ds_exec_end_op(struct a
 
 		default:
 
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Unimplemented opcode, class=%X type=%X Opcode=%X Op=%p\n",
-					  op_class, op_type,
-					  op->common.aml_opcode, op));
+			ACPI_ERROR((AE_INFO,
+				    "Unimplemented opcode, class=%X type=%X Opcode=%X Op=%p",
+				    op_class, op_type, op->common.aml_opcode,
+				    op));
 
 			status = AE_NOT_IMPLEMENTED;
 			break;
@@ -723,20 +721,6 @@ acpi_status acpi_ds_exec_end_op(struct a
 
       cleanup:
 
-	/* Invoke exception handler on error */
-
-	if (ACPI_FAILURE(status) &&
-	    acpi_gbl_exception_handler && !(status & AE_CODE_CONTROL)) {
-		acpi_ex_exit_interpreter();
-		status = acpi_gbl_exception_handler(status,
-						    walk_state->method_node->
-						    name.integer,
-						    walk_state->opcode,
-						    walk_state->aml_offset,
-						    NULL);
-		(void)acpi_ex_enter_interpreter();
-	}
-
 	if (walk_state->result_obj) {
 		/* Break to debugger to display result */
 
@@ -758,18 +742,14 @@ acpi_status acpi_ds_exec_end_op(struct a
 	}
 #endif
 
-	/* Always clear the object stack */
-
-	walk_state->num_operands = 0;
-
-#ifdef ACPI_DISASSEMBLER
-
-	/* On error, display method locals/args */
+	/* Invoke exception handler on error */
 
 	if (ACPI_FAILURE(status)) {
-		acpi_dm_dump_method_info(status, walk_state, op);
+		status = acpi_ds_method_error(status, walk_state);
 	}
-#endif
 
+	/* Always clear the object stack */
+
+	walk_state->num_operands = 0;
 	return_ACPI_STATUS(status);
 }
diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c
index 4117312..d3d24da 100644
--- a/drivers/acpi/dispatcher/dswload.c
+++ b/drivers/acpi/dispatcher/dswload.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -127,7 +127,7 @@ acpi_ds_load1_begin_op(struct acpi_walk_
 	char *path;
 	u32 flags;
 
-	ACPI_FUNCTION_NAME("ds_load1_begin_op");
+	ACPI_FUNCTION_TRACE("ds_load1_begin_op");
 
 	op = walk_state->op;
 	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
@@ -138,14 +138,14 @@ acpi_ds_load1_begin_op(struct acpi_walk_
 	if (op) {
 		if (!(walk_state->op_info->flags & AML_NAMED)) {
 			*out_op = op;
-			return (AE_OK);
+			return_ACPI_STATUS(AE_OK);
 		}
 
 		/* Check if this object has already been installed in the namespace */
 
 		if (op->common.node) {
 			*out_op = op;
-			return (AE_OK);
+			return_ACPI_STATUS(AE_OK);
 		}
 	}
 
@@ -187,8 +187,8 @@ acpi_ds_load1_begin_op(struct acpi_walk_
 		}
 #endif
 		if (ACPI_FAILURE(status)) {
-			ACPI_REPORT_NSERROR(path, status);
-			return (status);
+			ACPI_ERROR_NAMESPACE(path, status);
+			return_ACPI_STATUS(status);
 		}
 
 		/*
@@ -233,9 +233,11 @@ acpi_ds_load1_begin_op(struct acpi_walk_
 
 			/* All other types are an error */
 
-			ACPI_REPORT_ERROR(("Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)\n", acpi_ut_get_type_name(node->type), path));
+			ACPI_ERROR((AE_INFO,
+				    "Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)",
+				    acpi_ut_get_type_name(node->type), path));
 
-			return (AE_AML_OPERAND_TYPE);
+			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 		}
 		break;
 
@@ -257,6 +259,7 @@ acpi_ds_load1_begin_op(struct acpi_walk_
 		 *       buffer_field, or Package), the name of the object is already
 		 *       in the namespace.
 		 */
+
 		if (walk_state->deferred_node) {
 			/* This name is already in the namespace, get the node */
 
@@ -265,6 +268,16 @@ acpi_ds_load1_begin_op(struct acpi_walk_
 			break;
 		}
 
+		/*
+		 * If we are executing a method, do not create any namespace objects
+		 * during the load phase, only during execution.
+		 */
+		if (walk_state->method_node) {
+			node = NULL;
+			status = AE_OK;
+			break;
+		}
+
 		flags = ACPI_NS_NO_UPSEARCH;
 		if ((walk_state->opcode != AML_SCOPE_OP) &&
 		    (!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) {
@@ -289,8 +302,8 @@ acpi_ds_load1_begin_op(struct acpi_walk_
 				   ACPI_IMODE_LOAD_PASS1, flags, walk_state,
 				   &(node));
 		if (ACPI_FAILURE(status)) {
-			ACPI_REPORT_NSERROR(path, status);
-			return (status);
+			ACPI_ERROR_NAMESPACE(path, status);
+			return_ACPI_STATUS(status);
 		}
 		break;
 	}
@@ -302,28 +315,29 @@ acpi_ds_load1_begin_op(struct acpi_walk_
 
 		op = acpi_ps_alloc_op(walk_state->opcode);
 		if (!op) {
-			return (AE_NO_MEMORY);
+			return_ACPI_STATUS(AE_NO_MEMORY);
 		}
 	}
 
-	/* Initialize */
-
-	op->named.name = node->name.integer;
+	/* Initialize the op */
 
 #if (defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY))
-	op->named.path = (u8 *) path;
+	op->named.path = ACPI_CAST_PTR(u8, path);
 #endif
 
-	/*
-	 * Put the Node in the "op" object that the parser uses, so we
-	 * can get it again quickly when this scope is closed
-	 */
-	op->common.node = node;
+	if (node) {
+		/*
+		 * Put the Node in the "op" object that the parser uses, so we
+		 * can get it again quickly when this scope is closed
+		 */
+		op->common.node = node;
+		op->named.name = node->name.integer;
+	}
+
 	acpi_ps_append_arg(acpi_ps_get_parent_scope(&walk_state->parser_state),
 			   op);
-
 	*out_op = op;
-	return (status);
+	return_ACPI_STATUS(status);
 }
 
 /*******************************************************************************
@@ -339,13 +353,13 @@ acpi_ds_load1_begin_op(struct acpi_walk_
  *
  ******************************************************************************/
 
-acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state)
+acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state)
 {
 	union acpi_parse_object *op;
 	acpi_object_type object_type;
 	acpi_status status = AE_OK;
 
-	ACPI_FUNCTION_NAME("ds_load1_end_op");
+	ACPI_FUNCTION_TRACE("ds_load1_end_op");
 
 	op = walk_state->op;
 	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
@@ -354,7 +368,7 @@ acpi_status acpi_ds_load1_end_op(struct 
 	/* We are only interested in opcodes that have an associated name */
 
 	if (!(walk_state->op_info->flags & (AML_NAMED | AML_FIELD))) {
-		return (AE_OK);
+		return_ACPI_STATUS(AE_OK);
 	}
 
 	/* Get the object type to determine if we should pop the scope */
@@ -363,21 +377,37 @@ acpi_status acpi_ds_load1_end_op(struct 
 
 #ifndef ACPI_NO_METHOD_EXECUTION
 	if (walk_state->op_info->flags & AML_FIELD) {
-		if (walk_state->opcode == AML_FIELD_OP ||
-		    walk_state->opcode == AML_BANK_FIELD_OP ||
-		    walk_state->opcode == AML_INDEX_FIELD_OP) {
-			status = acpi_ds_init_field_objects(op, walk_state);
+		/*
+		 * If we are executing a method, do not create any namespace objects
+		 * during the load phase, only during execution.
+		 */
+		if (!walk_state->method_node) {
+			if (walk_state->opcode == AML_FIELD_OP ||
+			    walk_state->opcode == AML_BANK_FIELD_OP ||
+			    walk_state->opcode == AML_INDEX_FIELD_OP) {
+				status =
+				    acpi_ds_init_field_objects(op, walk_state);
+			}
 		}
-		return (status);
+		return_ACPI_STATUS(status);
 	}
 
-	if (op->common.aml_opcode == AML_REGION_OP) {
-		status = acpi_ex_create_region(op->named.data, op->named.length,
-					       (acpi_adr_space_type)
-					       ((op->common.value.arg)->common.
-						value.integer), walk_state);
-		if (ACPI_FAILURE(status)) {
-			return (status);
+	/*
+	 * If we are executing a method, do not create any namespace objects
+	 * during the load phase, only during execution.
+	 */
+	if (!walk_state->method_node) {
+		if (op->common.aml_opcode == AML_REGION_OP) {
+			status =
+			    acpi_ex_create_region(op->named.data,
+						  op->named.length,
+						  (acpi_adr_space_type)
+						  ((op->common.value.arg)->
+						   common.value.integer),
+						  walk_state);
+			if (ACPI_FAILURE(status)) {
+				return_ACPI_STATUS(status);
+			}
 		}
 	}
 #endif
@@ -391,47 +421,63 @@ acpi_status acpi_ds_load1_end_op(struct 
 							       common.
 							       aml_opcode))->
 			    object_type;
-			op->common.node->type = (u8) object_type;
+
+			/* Set node type if we have a namespace node */
+
+			if (op->common.node) {
+				op->common.node->type = (u8) object_type;
+			}
 		}
 	}
 
-	if (op->common.aml_opcode == AML_METHOD_OP) {
-		/*
-		 * method_op pkg_length name_string method_flags term_list
-		 *
-		 * Note: We must create the method node/object pair as soon as we
-		 * see the method declaration.  This allows later pass1 parsing
-		 * of invocations of the method (need to know the number of
-		 * arguments.)
-		 */
-		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
-				  "LOADING-Method: State=%p Op=%p named_obj=%p\n",
-				  walk_state, op, op->named.node));
+	/*
+	 * If we are executing a method, do not create any namespace objects
+	 * during the load phase, only during execution.
+	 */
+	if (!walk_state->method_node) {
+		if (op->common.aml_opcode == AML_METHOD_OP) {
+			/*
+			 * method_op pkg_length name_string method_flags term_list
+			 *
+			 * Note: We must create the method node/object pair as soon as we
+			 * see the method declaration.  This allows later pass1 parsing
+			 * of invocations of the method (need to know the number of
+			 * arguments.)
+			 */
+			ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+					  "LOADING-Method: State=%p Op=%p named_obj=%p\n",
+					  walk_state, op, op->named.node));
 
-		if (!acpi_ns_get_attached_object(op->named.node)) {
-			walk_state->operands[0] = (void *)op->named.node;
-			walk_state->num_operands = 1;
+			if (!acpi_ns_get_attached_object(op->named.node)) {
+				walk_state->operands[0] =
+				    ACPI_CAST_PTR(void, op->named.node);
+				walk_state->num_operands = 1;
 
-			status =
-			    acpi_ds_create_operands(walk_state,
-						    op->common.value.arg);
-			if (ACPI_SUCCESS(status)) {
-				status = acpi_ex_create_method(op->named.data,
-							       op->named.length,
-							       walk_state);
-			}
-			walk_state->operands[0] = NULL;
-			walk_state->num_operands = 0;
+				status =
+				    acpi_ds_create_operands(walk_state,
+							    op->common.value.
+							    arg);
+				if (ACPI_SUCCESS(status)) {
+					status =
+					    acpi_ex_create_method(op->named.
+								  data,
+								  op->named.
+								  length,
+								  walk_state);
+				}
+				walk_state->operands[0] = NULL;
+				walk_state->num_operands = 0;
 
-			if (ACPI_FAILURE(status)) {
-				return (status);
+				if (ACPI_FAILURE(status)) {
+					return_ACPI_STATUS(status);
+				}
 			}
 		}
 	}
 
-	/* Pop the scope stack */
+	/* Pop the scope stack (only if loading a table) */
 
-	if (acpi_ns_opens_scope(object_type)) {
+	if (!walk_state->method_node && acpi_ns_opens_scope(object_type)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
 				  "(%s): Popping scope for Op %p\n",
 				  acpi_ut_get_type_name(object_type), op));
@@ -439,7 +485,7 @@ acpi_status acpi_ds_load1_end_op(struct 
 		status = acpi_ds_scope_stack_pop(walk_state);
 	}
 
-	return (status);
+	return_ACPI_STATUS(status);
 }
 
 /*******************************************************************************
@@ -456,8 +502,8 @@ acpi_status acpi_ds_load1_end_op(struct 
  ******************************************************************************/
 
 acpi_status
-acpi_ds_load2_begin_op(struct acpi_walk_state * walk_state,
-		       union acpi_parse_object ** out_op)
+acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
+		       union acpi_parse_object **out_op)
 {
 	union acpi_parse_object *op;
 	struct acpi_namespace_node *node;
@@ -574,10 +620,10 @@ acpi_ds_load2_begin_op(struct acpi_walk_
 			if (status == AE_NOT_FOUND) {
 				status = AE_OK;
 			} else {
-				ACPI_REPORT_NSERROR(buffer_ptr, status);
+				ACPI_ERROR_NAMESPACE(buffer_ptr, status);
 			}
 #else
-			ACPI_REPORT_NSERROR(buffer_ptr, status);
+			ACPI_ERROR_NAMESPACE(buffer_ptr, status);
 #endif
 			return_ACPI_STATUS(status);
 		}
@@ -607,7 +653,10 @@ acpi_ds_load2_begin_op(struct acpi_walk_
 			 *  Scope (DEB) { ... }
 			 */
 
-			ACPI_REPORT_WARNING(("Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n", buffer_ptr, acpi_ut_get_type_name(node->type)));
+			ACPI_WARNING((AE_INFO,
+				      "Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)",
+				      buffer_ptr,
+				      acpi_ut_get_type_name(node->type)));
 
 			node->type = ACPI_TYPE_ANY;
 			walk_state->scope_info->common.value = ACPI_TYPE_ANY;
@@ -617,7 +666,10 @@ acpi_ds_load2_begin_op(struct acpi_walk_
 
 			/* All other types are an error */
 
-			ACPI_REPORT_ERROR(("Invalid type (%s) for target of Scope operator [%4.4s]\n", acpi_ut_get_type_name(node->type), buffer_ptr));
+			ACPI_ERROR((AE_INFO,
+				    "Invalid type (%s) for target of Scope operator [%4.4s]",
+				    acpi_ut_get_type_name(node->type),
+				    buffer_ptr));
 
 			return (AE_AML_OPERAND_TYPE);
 		}
@@ -670,7 +722,7 @@ acpi_ds_load2_begin_op(struct acpi_walk_
 	}
 
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_NSERROR(buffer_ptr, status);
+		ACPI_ERROR_NAMESPACE(buffer_ptr, status);
 		return_ACPI_STATUS(status);
 	}
 
@@ -840,6 +892,13 @@ acpi_status acpi_ds_load2_end_op(struct 
 
 	case AML_TYPE_NAMED_FIELD:
 
+		/*
+		 * If we are executing a method, initialize the field
+		 */
+		if (walk_state->method_node) {
+			status = acpi_ds_init_field_objects(op, walk_state);
+		}
+
 		switch (op->common.aml_opcode) {
 		case AML_INDEX_FIELD_OP:
 
@@ -929,6 +988,24 @@ acpi_status acpi_ds_load2_end_op(struct 
 		switch (op->common.aml_opcode) {
 #ifndef ACPI_NO_METHOD_EXECUTION
 		case AML_REGION_OP:
+
+			/*
+			 * If we are executing a method, initialize the region
+			 */
+			if (walk_state->method_node) {
+				status =
+				    acpi_ex_create_region(op->named.data,
+							  op->named.length,
+							  (acpi_adr_space_type)
+							  ((op->common.value.
+							    arg)->common.value.
+							   integer),
+							  walk_state);
+				if (ACPI_FAILURE(status)) {
+					return (status);
+				}
+			}
+
 			/*
 			 * The op_region is not fully parsed at this time. Only valid
 			 * argument is the space_id. (We must save the address of the
@@ -957,11 +1034,50 @@ acpi_status acpi_ds_load2_end_op(struct 
 
 			status = acpi_ds_create_node(walk_state, node, op);
 			break;
+
+		case AML_METHOD_OP:
+			/*
+			 * method_op pkg_length name_string method_flags term_list
+			 *
+			 * Note: We must create the method node/object pair as soon as we
+			 * see the method declaration.  This allows later pass1 parsing
+			 * of invocations of the method (need to know the number of
+			 * arguments.)
+			 */
+			ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+					  "LOADING-Method: State=%p Op=%p named_obj=%p\n",
+					  walk_state, op, op->named.node));
+
+			if (!acpi_ns_get_attached_object(op->named.node)) {
+				walk_state->operands[0] =
+				    ACPI_CAST_PTR(void, op->named.node);
+				walk_state->num_operands = 1;
+
+				status =
+				    acpi_ds_create_operands(walk_state,
+							    op->common.value.
+							    arg);
+				if (ACPI_SUCCESS(status)) {
+					status =
+					    acpi_ex_create_method(op->named.
+								  data,
+								  op->named.
+								  length,
+								  walk_state);
+				}
+				walk_state->operands[0] = NULL;
+				walk_state->num_operands = 0;
+
+				if (ACPI_FAILURE(status)) {
+					return_ACPI_STATUS(status);
+				}
+			}
+			break;
+
 #endif				/* ACPI_NO_METHOD_EXECUTION */
 
 		default:
 			/* All NAMED_COMPLEX opcodes must be handled above */
-			/* Note: Method objects were already created in Pass 1 */
 			break;
 		}
 		break;
@@ -1004,7 +1120,7 @@ acpi_status acpi_ds_load2_end_op(struct 
 			 */
 			op->common.node = new_node;
 		} else {
-			ACPI_REPORT_NSERROR(arg->common.value.string, status);
+			ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
 		}
 		break;
 
diff --git a/drivers/acpi/dispatcher/dswscope.c b/drivers/acpi/dispatcher/dswscope.c
index defe956..ada21ef 100644
--- a/drivers/acpi/dispatcher/dswscope.c
+++ b/drivers/acpi/dispatcher/dswscope.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -107,14 +107,14 @@ acpi_ds_scope_stack_push(struct acpi_nam
 	if (!node) {
 		/* Invalid scope   */
 
-		ACPI_REPORT_ERROR(("ds_scope_stack_push: null scope passed\n"));
+		ACPI_ERROR((AE_INFO, "Null scope parameter"));
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
 	/* Make sure object type is valid */
 
 	if (!acpi_ut_valid_object_type(type)) {
-		ACPI_REPORT_WARNING(("ds_scope_stack_push: Invalid object type: 0x%X\n", type));
+		ACPI_WARNING((AE_INFO, "Invalid object type: 0x%X", type));
 	}
 
 	/* Allocate a new scope object */
diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c
index 7d68a5a..fa78cb7 100644
--- a/drivers/acpi/dispatcher/dswstate.c
+++ b/drivers/acpi/dispatcher/dswstate.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -92,26 +92,23 @@ acpi_ds_result_remove(union acpi_operand
 
 	state = walk_state->results;
 	if (!state) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "No result object pushed! State=%p\n",
-				  walk_state));
+		ACPI_ERROR((AE_INFO, "No result object pushed! State=%p",
+			    walk_state));
 		return (AE_NOT_EXIST);
 	}
 
 	if (index >= ACPI_OBJ_MAX_OPERAND) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Index out of range: %X State=%p Num=%X\n",
-				  index, walk_state,
-				  state->results.num_results));
+		ACPI_ERROR((AE_INFO,
+			    "Index out of range: %X State=%p Num=%X",
+			    index, walk_state, state->results.num_results));
 	}
 
 	/* Check for a valid result object */
 
 	if (!state->results.obj_desc[index]) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Null operand! State=%p #Ops=%X, Index=%X\n",
-				  walk_state, state->results.num_results,
-				  index));
+		ACPI_ERROR((AE_INFO,
+			    "Null operand! State=%p #Ops=%X, Index=%X",
+			    walk_state, state->results.num_results, index));
 		return (AE_AML_NO_RETURN_VALUE);
 	}
 
@@ -163,9 +160,8 @@ acpi_ds_result_pop(union acpi_operand_ob
 	}
 
 	if (!state->results.num_results) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Result stack is empty! State=%p\n",
-				  walk_state));
+		ACPI_ERROR((AE_INFO, "Result stack is empty! State=%p",
+			    walk_state));
 		return (AE_AML_NO_RETURN_VALUE);
 	}
 
@@ -192,8 +188,7 @@ acpi_ds_result_pop(union acpi_operand_ob
 		}
 	}
 
-	ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-			  "No result objects! State=%p\n", walk_state));
+	ACPI_ERROR((AE_INFO, "No result objects! State=%p", walk_state));
 	return (AE_AML_NO_RETURN_VALUE);
 }
 
@@ -222,15 +217,14 @@ acpi_ds_result_pop_from_bottom(union acp
 
 	state = walk_state->results;
 	if (!state) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Warning: No result object pushed! State=%p\n",
-				  walk_state));
+		ACPI_ERROR((AE_INFO,
+			    "No result object pushed! State=%p", walk_state));
 		return (AE_NOT_EXIST);
 	}
 
 	if (!state->results.num_results) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "No result objects! State=%p\n", walk_state));
+		ACPI_ERROR((AE_INFO, "No result objects! State=%p",
+			    walk_state));
 		return (AE_AML_NO_RETURN_VALUE);
 	}
 
@@ -250,10 +244,10 @@ acpi_ds_result_pop_from_bottom(union acp
 	/* Check for a valid result object */
 
 	if (!*object) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Null operand! State=%p #Ops=%X Index=%X\n",
-				  walk_state, state->results.num_results,
-				  (u32) index));
+		ACPI_ERROR((AE_INFO,
+			    "Null operand! State=%p #Ops=%X Index=%X",
+			    walk_state, state->results.num_results,
+			    (u32) index));
 		return (AE_AML_NO_RETURN_VALUE);
 	}
 
@@ -288,23 +282,21 @@ acpi_ds_result_push(union acpi_operand_o
 
 	state = walk_state->results;
 	if (!state) {
-		ACPI_REPORT_ERROR(("No result stack frame during push\n"));
+		ACPI_ERROR((AE_INFO, "No result stack frame during push"));
 		return (AE_AML_INTERNAL);
 	}
 
 	if (state->results.num_results == ACPI_OBJ_NUM_OPERANDS) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Result stack overflow: Obj=%p State=%p Num=%X\n",
-				  object, walk_state,
-				  state->results.num_results));
+		ACPI_ERROR((AE_INFO,
+			    "Result stack overflow: Obj=%p State=%p Num=%X",
+			    object, walk_state, state->results.num_results));
 		return (AE_STACK_OVERFLOW);
 	}
 
 	if (!object) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Null Object! Obj=%p State=%p Num=%X\n",
-				  object, walk_state,
-				  state->results.num_results));
+		ACPI_ERROR((AE_INFO,
+			    "Null Object! Obj=%p State=%p Num=%X",
+			    object, walk_state, state->results.num_results));
 		return (AE_BAD_PARAMETER);
 	}
 
@@ -413,10 +405,9 @@ acpi_ds_obj_stack_push(void *object, str
 	/* Check for stack overflow */
 
 	if (walk_state->num_operands >= ACPI_OBJ_NUM_OPERANDS) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "overflow! Obj=%p State=%p #Ops=%X\n",
-				  object, walk_state,
-				  walk_state->num_operands));
+		ACPI_ERROR((AE_INFO,
+			    "Object stack overflow! Obj=%p State=%p #Ops=%X",
+			    object, walk_state, walk_state->num_operands));
 		return (AE_STACK_OVERFLOW);
 	}
 
@@ -460,10 +451,10 @@ acpi_ds_obj_stack_pop(u32 pop_count, str
 		/* Check for stack underflow */
 
 		if (walk_state->num_operands == 0) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Underflow! Count=%X State=%p #Ops=%X\n",
-					  pop_count, walk_state,
-					  walk_state->num_operands));
+			ACPI_ERROR((AE_INFO,
+				    "Object stack underflow! Count=%X State=%p #Ops=%X",
+				    pop_count, walk_state,
+				    walk_state->num_operands));
 			return (AE_STACK_UNDERFLOW);
 		}
 
@@ -506,10 +497,10 @@ acpi_ds_obj_stack_pop_and_delete(u32 pop
 		/* Check for stack underflow */
 
 		if (walk_state->num_operands == 0) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Underflow! Count=%X State=%p #Ops=%X\n",
-					  pop_count, walk_state,
-					  walk_state->num_operands));
+			ACPI_ERROR((AE_INFO,
+				    "Object stack underflow! Count=%X State=%p #Ops=%X",
+				    pop_count, walk_state,
+				    walk_state->num_operands));
 			return (AE_STACK_UNDERFLOW);
 		}
 
@@ -826,16 +817,14 @@ void acpi_ds_delete_walk_state(struct ac
 	}
 
 	if (walk_state->data_type != ACPI_DESC_TYPE_WALK) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "%p is not a valid walk state\n",
-				  walk_state));
+		ACPI_ERROR((AE_INFO, "%p is not a valid walk state",
+			    walk_state));
 		return;
 	}
 
 	if (walk_state->parser_state.scope) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "%p walk still has a scope list\n",
-				  walk_state));
+		ACPI_ERROR((AE_INFO, "%p walk still has a scope list",
+			    walk_state));
 	}
 
 	/* Always must free any linked control states */
@@ -894,25 +883,24 @@ acpi_ds_result_insert(void *object,
 
 	state = walk_state->results;
 	if (!state) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "No result object pushed! State=%p\n",
-				  walk_state));
+		ACPI_ERROR((AE_INFO, "No result object pushed! State=%p",
+			    walk_state));
 		return (AE_NOT_EXIST);
 	}
 
 	if (index >= ACPI_OBJ_NUM_OPERANDS) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Index out of range: %X Obj=%p State=%p Num=%X\n",
-				  index, object, walk_state,
-				  state->results.num_results));
+		ACPI_ERROR((AE_INFO,
+			    "Index out of range: %X Obj=%p State=%p Num=%X",
+			    index, object, walk_state,
+			    state->results.num_results));
 		return (AE_BAD_PARAMETER);
 	}
 
 	if (!object) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Null Object! Index=%X Obj=%p State=%p Num=%X\n",
-				  index, object, walk_state,
-				  state->results.num_results));
+		ACPI_ERROR((AE_INFO,
+			    "Null Object! Index=%X Obj=%p State=%p Num=%X",
+			    index, object, walk_state,
+			    state->results.num_results));
 		return (AE_BAD_PARAMETER);
 	}
 
@@ -986,9 +974,9 @@ acpi_ds_obj_stack_pop_object(union acpi_
 	/* Check for stack underflow */
 
 	if (walk_state->num_operands == 0) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Missing operand/stack empty! State=%p #Ops=%X\n",
-				  walk_state, walk_state->num_operands));
+		ACPI_ERROR((AE_INFO,
+			    "Missing operand/stack empty! State=%p #Ops=%X",
+			    walk_state, walk_state->num_operands));
 		*object = NULL;
 		return (AE_AML_NO_OPERAND);
 	}
@@ -1000,9 +988,9 @@ acpi_ds_obj_stack_pop_object(union acpi_
 	/* Check for a valid operand */
 
 	if (!walk_state->operands[walk_state->num_operands]) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Null operand! State=%p #Ops=%X\n",
-				  walk_state, walk_state->num_operands));
+		ACPI_ERROR((AE_INFO,
+			    "Null operand! State=%p #Ops=%X",
+			    walk_state, walk_state->num_operands));
 		*object = NULL;
 		return (AE_AML_NO_OPERAND);
 	}
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 3758b55..79b09d7 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -60,20 +60,20 @@ ACPI_MODULE_NAME("acpi_ec")
 #define ACPI_EC_BURST_ENABLE	0x82
 #define ACPI_EC_BURST_DISABLE	0x83
 #define ACPI_EC_COMMAND_QUERY	0x84
-#define EC_POLLING		0xFF
-#define EC_BURST		0x00
+#define EC_POLL			0xFF
+#define EC_INTR			0x00
 static int acpi_ec_remove(struct acpi_device *device, int type);
 static int acpi_ec_start(struct acpi_device *device);
 static int acpi_ec_stop(struct acpi_device *device, int type);
-static int acpi_ec_burst_add(struct acpi_device *device);
-static int acpi_ec_polling_add(struct acpi_device *device);
+static int acpi_ec_intr_add(struct acpi_device *device);
+static int acpi_ec_poll_add(struct acpi_device *device);
 
 static struct acpi_driver acpi_ec_driver = {
 	.name = ACPI_EC_DRIVER_NAME,
 	.class = ACPI_EC_CLASS,
 	.ids = ACPI_EC_HID,
 	.ops = {
-		.add = acpi_ec_polling_add,
+		.add = acpi_ec_intr_add,
 		.remove = acpi_ec_remove,
 		.start = acpi_ec_start,
 		.stop = acpi_ec_stop,
@@ -105,7 +105,7 @@ union acpi_ec {
 		atomic_t pending_gpe;
 		struct semaphore sem;
 		wait_queue_head_t wait;
-	} burst;
+	} intr;
 
 	struct {
 		u32 mode;
@@ -117,37 +117,37 @@ union acpi_ec {
 		struct acpi_generic_address data_addr;
 		unsigned long global_lock;
 		spinlock_t lock;
-	} polling;
+	} poll;
 };
 
-static int acpi_ec_polling_wait(union acpi_ec *ec, u8 event);
-static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event);
-static int acpi_ec_polling_read(union acpi_ec *ec, u8 address, u32 * data);
-static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data);
-static int acpi_ec_polling_write(union acpi_ec *ec, u8 address, u8 data);
-static int acpi_ec_burst_write(union acpi_ec *ec, u8 address, u8 data);
-static int acpi_ec_polling_query(union acpi_ec *ec, u32 * data);
-static int acpi_ec_burst_query(union acpi_ec *ec, u32 * data);
-static void acpi_ec_gpe_polling_query(void *ec_cxt);
-static void acpi_ec_gpe_burst_query(void *ec_cxt);
-static u32 acpi_ec_gpe_polling_handler(void *data);
-static u32 acpi_ec_gpe_burst_handler(void *data);
+static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event);
+static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event);
+static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data);
+static int acpi_ec_intr_read(union acpi_ec *ec, u8 address, u32 * data);
+static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data);
+static int acpi_ec_intr_write(union acpi_ec *ec, u8 address, u8 data);
+static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data);
+static int acpi_ec_intr_query(union acpi_ec *ec, u32 * data);
+static void acpi_ec_gpe_poll_query(void *ec_cxt);
+static void acpi_ec_gpe_intr_query(void *ec_cxt);
+static u32 acpi_ec_gpe_poll_handler(void *data);
+static u32 acpi_ec_gpe_intr_handler(void *data);
 static acpi_status __init
-acpi_fake_ecdt_polling_callback(acpi_handle handle,
+acpi_fake_ecdt_poll_callback(acpi_handle handle,
 				u32 Level, void *context, void **retval);
 
 static acpi_status __init
-acpi_fake_ecdt_burst_callback(acpi_handle handle,
+acpi_fake_ecdt_intr_callback(acpi_handle handle,
 			      u32 Level, void *context, void **retval);
 
-static int __init acpi_ec_polling_get_real_ecdt(void);
-static int __init acpi_ec_burst_get_real_ecdt(void);
+static int __init acpi_ec_poll_get_real_ecdt(void);
+static int __init acpi_ec_intr_get_real_ecdt(void);
 /* If we find an EC via the ECDT, we need to keep a ptr to its context */
 static union acpi_ec *ec_ecdt;
 
 /* External interfaces use first EC only, so remember */
 static struct acpi_device *first_ec;
-static int acpi_ec_polling_mode = EC_POLLING;
+static int acpi_ec_poll_mode = EC_INTR;
 
 /* --------------------------------------------------------------------------
                              Transaction Management
@@ -163,13 +163,13 @@ static u32 acpi_ec_read_status(union acp
 
 static int acpi_ec_wait(union acpi_ec *ec, u8 event)
 {
-	if (acpi_ec_polling_mode)
-		return acpi_ec_polling_wait(ec, event);
+	if (acpi_ec_poll_mode)
+		return acpi_ec_poll_wait(ec, event);
 	else
-		return acpi_ec_burst_wait(ec, event);
+		return acpi_ec_intr_wait(ec, event);
 }
 
-static int acpi_ec_polling_wait(union acpi_ec *ec, u8 event)
+static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event)
 {
 	u32 acpi_ec_status = 0;
 	u32 i = ACPI_EC_UDELAY_COUNT;
@@ -203,36 +203,31 @@ static int acpi_ec_polling_wait(union ac
 
 	return -ETIME;
 }
-static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event)
+static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event)
 {
 	int result = 0;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_wait");
 
-	ec->burst.expect_event = event;
+	ec->intr.expect_event = event;
 	smp_mb();
 
 	switch (event) {
-	case ACPI_EC_EVENT_OBF:
-		if (acpi_ec_read_status(ec) & event) {
-			ec->burst.expect_event = 0;
-			return_VALUE(0);
-		}
-		break;
-
 	case ACPI_EC_EVENT_IBE:
 		if (~acpi_ec_read_status(ec) & event) {
-			ec->burst.expect_event = 0;
+			ec->intr.expect_event = 0;
 			return_VALUE(0);
 		}
 		break;
+	default:
+		break;
 	}
 
-	result = wait_event_timeout(ec->burst.wait,
-				    !ec->burst.expect_event,
+	result = wait_event_timeout(ec->intr.wait,
+				    !ec->intr.expect_event,
 				    msecs_to_jiffies(ACPI_EC_DELAY));
 
-	ec->burst.expect_event = 0;
+	ec->intr.expect_event = 0;
 	smp_mb();
 
 	/*
@@ -255,7 +250,12 @@ static int acpi_ec_burst_wait(union acpi
 	return_VALUE(-ETIME);
 }
 
-static int acpi_ec_enter_burst_mode(union acpi_ec *ec)
+#ifdef ACPI_FUTURE_USAGE
+/*
+ * Note: samsung nv5000 doesn't work with ec burst mode.
+ * http://bugzilla.kernel.org/show_bug.cgi?id=4980
+ */
+int acpi_ec_enter_burst_mode(union acpi_ec *ec)
 {
 	u32 tmp = 0;
 	int status = 0;
@@ -270,45 +270,56 @@ static int acpi_ec_enter_burst_mode(unio
 		acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE,
 					&ec->common.command_addr);
 		status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
-		if (status)
-			return_VALUE(-EINVAL);
 		acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
 		if (tmp != 0x90) {	/* Burst ACK byte */
 			return_VALUE(-EINVAL);
 		}
 	}
 
-	atomic_set(&ec->burst.leaving_burst, 0);
+	atomic_set(&ec->intr.leaving_burst, 0);
 	return_VALUE(0);
       end:
-	printk("Error in acpi_ec_wait\n");
+	printk(KERN_WARNING PREFIX "Error in acpi_ec_wait\n");
 	return_VALUE(-1);
 }
 
-static int acpi_ec_leave_burst_mode(union acpi_ec *ec)
+int acpi_ec_leave_burst_mode(union acpi_ec *ec)
 {
+	int status = 0;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode");
 
-	atomic_set(&ec->burst.leaving_burst, 1);
+	status = acpi_ec_read_status(ec);
+	if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)){
+		status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
+		if(status)
+			goto end;
+		acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr);
+		acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
+	} 
+	atomic_set(&ec->intr.leaving_burst, 1);
 	return_VALUE(0);
+end:
+	printk(KERN_WARNING PREFIX "leave burst_mode:error\n");
+	return_VALUE(-1);
 }
+#endif /* ACPI_FUTURE_USAGE */
 
 static int acpi_ec_read(union acpi_ec *ec, u8 address, u32 * data)
 {
-	if (acpi_ec_polling_mode)
-		return acpi_ec_polling_read(ec, address, data);
+	if (acpi_ec_poll_mode)
+		return acpi_ec_poll_read(ec, address, data);
 	else
-		return acpi_ec_burst_read(ec, address, data);
+		return acpi_ec_intr_read(ec, address, data);
 }
 static int acpi_ec_write(union acpi_ec *ec, u8 address, u8 data)
 {
-	if (acpi_ec_polling_mode)
-		return acpi_ec_polling_write(ec, address, data);
+	if (acpi_ec_poll_mode)
+		return acpi_ec_poll_write(ec, address, data);
 	else
-		return acpi_ec_burst_write(ec, address, data);
+		return acpi_ec_intr_write(ec, address, data);
 }
-static int acpi_ec_polling_read(union acpi_ec *ec, u8 address, u32 * data)
+static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data)
 {
 	acpi_status status = AE_OK;
 	int result = 0;
@@ -328,7 +339,7 @@ static int acpi_ec_polling_read(union ac
 			return_VALUE(-ENODEV);
 	}
 
-	spin_lock_irqsave(&ec->polling.lock, flags);
+	spin_lock_irqsave(&ec->poll.lock, flags);
 
 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ,
 				&ec->common.command_addr);
@@ -347,7 +358,7 @@ static int acpi_ec_polling_read(union ac
 			  *data, address));
 
       end:
-	spin_unlock_irqrestore(&ec->polling.lock, flags);
+	spin_unlock_irqrestore(&ec->poll.lock, flags);
 
 	if (ec->common.global_lock)
 		acpi_release_global_lock(glk);
@@ -355,7 +366,7 @@ static int acpi_ec_polling_read(union ac
 	return_VALUE(result);
 }
 
-static int acpi_ec_polling_write(union acpi_ec *ec, u8 address, u8 data)
+static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data)
 {
 	int result = 0;
 	acpi_status status = AE_OK;
@@ -373,7 +384,7 @@ static int acpi_ec_polling_write(union a
 			return_VALUE(-ENODEV);
 	}
 
-	spin_lock_irqsave(&ec->polling.lock, flags);
+	spin_lock_irqsave(&ec->poll.lock, flags);
 
 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE,
 				&ec->common.command_addr);
@@ -395,7 +406,7 @@ static int acpi_ec_polling_write(union a
 			  data, address));
 
       end:
-	spin_unlock_irqrestore(&ec->polling.lock, flags);
+	spin_unlock_irqrestore(&ec->poll.lock, flags);
 
 	if (ec->common.global_lock)
 		acpi_release_global_lock(glk);
@@ -403,7 +414,7 @@ static int acpi_ec_polling_write(union a
 	return_VALUE(result);
 }
 
-static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data)
+static int acpi_ec_intr_read(union acpi_ec *ec, u8 address, u32 * data)
 {
 	int status = 0;
 	u32 glk;
@@ -422,25 +433,24 @@ static int acpi_ec_burst_read(union acpi
 	}
 
 	WARN_ON(in_interrupt());
-	down(&ec->burst.sem);
+	down(&ec->intr.sem);
 
-	acpi_ec_enter_burst_mode(ec);
 	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
 	if (status) {
-		printk("read EC, IB not empty\n");
+		printk(KERN_DEBUG PREFIX "read EC, IB not empty\n");
 		goto end;
 	}
 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ,
 				&ec->common.command_addr);
 	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
 	if (status) {
-		printk("read EC, IB not empty\n");
+		printk(KERN_DEBUG PREFIX "read EC, IB not empty\n");
 	}
 
 	acpi_hw_low_level_write(8, address, &ec->common.data_addr);
 	status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
 	if (status) {
-		printk("read EC, OB not full\n");
+		printk(KERN_DEBUG PREFIX "read EC, OB not full\n");
 		goto end;
 	}
 	acpi_hw_low_level_read(8, data, &ec->common.data_addr);
@@ -448,8 +458,7 @@ static int acpi_ec_burst_read(union acpi
 			  *data, address));
 
       end:
-	acpi_ec_leave_burst_mode(ec);
-	up(&ec->burst.sem);
+	up(&ec->intr.sem);
 
 	if (ec->common.global_lock)
 		acpi_release_global_lock(glk);
@@ -457,7 +466,7 @@ static int acpi_ec_burst_read(union acpi
 	return_VALUE(status);
 }
 
-static int acpi_ec_burst_write(union acpi_ec *ec, u8 address, u8 data)
+static int acpi_ec_intr_write(union acpi_ec *ec, u8 address, u8 data)
 {
 	int status = 0;
 	u32 glk;
@@ -474,25 +483,23 @@ static int acpi_ec_burst_write(union acp
 	}
 
 	WARN_ON(in_interrupt());
-	down(&ec->burst.sem);
-
-	acpi_ec_enter_burst_mode(ec);
+	down(&ec->intr.sem);
 
 	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
 	if (status) {
-		printk("write EC, IB not empty\n");
+		printk(KERN_DEBUG PREFIX "write EC, IB not empty\n");
 	}
 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE,
 				&ec->common.command_addr);
 	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
 	if (status) {
-		printk("write EC, IB not empty\n");
+		printk(KERN_DEBUG PREFIX "write EC, IB not empty\n");
 	}
 
 	acpi_hw_low_level_write(8, address, &ec->common.data_addr);
 	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
 	if (status) {
-		printk("write EC, IB not empty\n");
+		printk(KERN_DEBUG PREFIX "write EC, IB not empty\n");
 	}
 
 	acpi_hw_low_level_write(8, data, &ec->common.data_addr);
@@ -500,8 +507,7 @@ static int acpi_ec_burst_write(union acp
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
 			  data, address));
 
-	acpi_ec_leave_burst_mode(ec);
-	up(&ec->burst.sem);
+	up(&ec->intr.sem);
 
 	if (ec->common.global_lock)
 		acpi_release_global_lock(glk);
@@ -553,12 +559,12 @@ EXPORT_SYMBOL(ec_write);
 
 static int acpi_ec_query(union acpi_ec *ec, u32 * data)
 {
-	if (acpi_ec_polling_mode)
-		return acpi_ec_polling_query(ec, data);
+	if (acpi_ec_poll_mode)
+		return acpi_ec_poll_query(ec, data);
 	else
-		return acpi_ec_burst_query(ec, data);
+		return acpi_ec_intr_query(ec, data);
 }
-static int acpi_ec_polling_query(union acpi_ec *ec, u32 * data)
+static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data)
 {
 	int result = 0;
 	acpi_status status = AE_OK;
@@ -583,7 +589,7 @@ static int acpi_ec_polling_query(union a
 	 * Note that successful completion of the query causes the ACPI_EC_SCI
 	 * bit to be cleared (and thus clearing the interrupt source).
 	 */
-	spin_lock_irqsave(&ec->polling.lock, flags);
+	spin_lock_irqsave(&ec->poll.lock, flags);
 
 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY,
 				&ec->common.command_addr);
@@ -596,14 +602,14 @@ static int acpi_ec_polling_query(union a
 		result = -ENODATA;
 
       end:
-	spin_unlock_irqrestore(&ec->polling.lock, flags);
+	spin_unlock_irqrestore(&ec->poll.lock, flags);
 
 	if (ec->common.global_lock)
 		acpi_release_global_lock(glk);
 
 	return_VALUE(result);
 }
-static int acpi_ec_burst_query(union acpi_ec *ec, u32 * data)
+static int acpi_ec_intr_query(union acpi_ec *ec, u32 * data)
 {
 	int status = 0;
 	u32 glk;
@@ -620,11 +626,11 @@ static int acpi_ec_burst_query(union acp
 			return_VALUE(-ENODEV);
 	}
 
-	down(&ec->burst.sem);
+	down(&ec->intr.sem);
 
 	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
 	if (status) {
-		printk("query EC, IB not empty\n");
+		printk(KERN_DEBUG PREFIX "query EC, IB not empty\n");
 		goto end;
 	}
 	/*
@@ -636,7 +642,7 @@ static int acpi_ec_burst_query(union acp
 				&ec->common.command_addr);
 	status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
 	if (status) {
-		printk("query EC, OB not full\n");
+		printk(KERN_DEBUG PREFIX "query EC, OB not full\n");
 		goto end;
 	}
 
@@ -645,7 +651,7 @@ static int acpi_ec_burst_query(union acp
 		status = -ENODATA;
 
       end:
-	up(&ec->burst.sem);
+	up(&ec->intr.sem);
 
 	if (ec->common.global_lock)
 		acpi_release_global_lock(glk);
@@ -664,13 +670,13 @@ union acpi_ec_query_data {
 
 static void acpi_ec_gpe_query(void *ec_cxt)
 {
-	if (acpi_ec_polling_mode)
-		acpi_ec_gpe_polling_query(ec_cxt);
+	if (acpi_ec_poll_mode)
+		acpi_ec_gpe_poll_query(ec_cxt);
 	else
-		acpi_ec_gpe_burst_query(ec_cxt);
+		acpi_ec_gpe_intr_query(ec_cxt);
 }
 
-static void acpi_ec_gpe_polling_query(void *ec_cxt)
+static void acpi_ec_gpe_poll_query(void *ec_cxt)
 {
 	union acpi_ec *ec = (union acpi_ec *)ec_cxt;
 	u32 value = 0;
@@ -685,9 +691,9 @@ static void acpi_ec_gpe_polling_query(vo
 	if (!ec_cxt)
 		goto end;
 
-	spin_lock_irqsave(&ec->polling.lock, flags);
+	spin_lock_irqsave(&ec->poll.lock, flags);
 	acpi_hw_low_level_read(8, &value, &ec->common.command_addr);
-	spin_unlock_irqrestore(&ec->polling.lock, flags);
+	spin_unlock_irqrestore(&ec->poll.lock, flags);
 
 	/* TBD: Implement asynch events!
 	 * NOTE: All we care about are EC-SCI's.  Other EC events are
@@ -711,7 +717,7 @@ static void acpi_ec_gpe_polling_query(vo
       end:
 	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
 }
-static void acpi_ec_gpe_burst_query(void *ec_cxt)
+static void acpi_ec_gpe_intr_query(void *ec_cxt)
 {
 	union acpi_ec *ec = (union acpi_ec *)ec_cxt;
 	u32 value;
@@ -736,18 +742,18 @@ static void acpi_ec_gpe_burst_query(void
 
 	acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL);
       end:
-	atomic_dec(&ec->burst.pending_gpe);
+	atomic_dec(&ec->intr.pending_gpe);
 	return;
 }
 
 static u32 acpi_ec_gpe_handler(void *data)
 {
-	if (acpi_ec_polling_mode)
-		return acpi_ec_gpe_polling_handler(data);
+	if (acpi_ec_poll_mode)
+		return acpi_ec_gpe_poll_handler(data);
 	else
-		return acpi_ec_gpe_burst_handler(data);
+		return acpi_ec_gpe_intr_handler(data);
 }
-static u32 acpi_ec_gpe_polling_handler(void *data)
+static u32 acpi_ec_gpe_poll_handler(void *data)
 {
 	acpi_status status = AE_OK;
 	union acpi_ec *ec = (union acpi_ec *)data;
@@ -765,7 +771,7 @@ static u32 acpi_ec_gpe_polling_handler(v
 	else
 		return ACPI_INTERRUPT_NOT_HANDLED;
 }
-static u32 acpi_ec_gpe_burst_handler(void *data)
+static u32 acpi_ec_gpe_intr_handler(void *data)
 {
 	acpi_status status = AE_OK;
 	u32 value;
@@ -777,22 +783,22 @@ static u32 acpi_ec_gpe_burst_handler(voi
 	acpi_clear_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
 	value = acpi_ec_read_status(ec);
 
-	switch (ec->burst.expect_event) {
+	switch (ec->intr.expect_event) {
 	case ACPI_EC_EVENT_OBF:
 		if (!(value & ACPI_EC_FLAG_OBF))
 			break;
 	case ACPI_EC_EVENT_IBE:
 		if ((value & ACPI_EC_FLAG_IBF))
 			break;
-		ec->burst.expect_event = 0;
-		wake_up(&ec->burst.wait);
+		ec->intr.expect_event = 0;
+		wake_up(&ec->intr.wait);
 		return ACPI_INTERRUPT_HANDLED;
 	default:
 		break;
 	}
 
 	if (value & ACPI_EC_FLAG_SCI) {
-		atomic_add(1, &ec->burst.pending_gpe);
+		atomic_add(1, &ec->intr.pending_gpe);
 		status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
 						     acpi_ec_gpe_query, ec);
 		return status == AE_OK ?
@@ -980,7 +986,7 @@ static int acpi_ec_remove_fs(struct acpi
                                Driver Interface
    -------------------------------------------------------------------------- */
 
-static int acpi_ec_polling_add(struct acpi_device *device)
+static int acpi_ec_poll_add(struct acpi_device *device)
 {
 	int result = 0;
 	acpi_status status = AE_OK;
@@ -999,7 +1005,7 @@ static int acpi_ec_polling_add(struct ac
 
 	ec->common.handle = device->handle;
 	ec->common.uid = -1;
-	spin_lock_init(&ec->polling.lock);
+	spin_lock_init(&ec->poll.lock);
 	strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_EC_CLASS);
 	acpi_driver_data(device) = ec;
@@ -1038,7 +1044,7 @@ static int acpi_ec_polling_add(struct ac
 	if (result)
 		goto end;
 
-	printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n",
+	printk(KERN_INFO PREFIX "%s [%s] (gpe %d) polling mode.\n",
 	       acpi_device_name(device), acpi_device_bid(device),
 	       (u32) ec->common.gpe_bit);
 
@@ -1051,7 +1057,7 @@ static int acpi_ec_polling_add(struct ac
 
 	return_VALUE(result);
 }
-static int acpi_ec_burst_add(struct acpi_device *device)
+static int acpi_ec_intr_add(struct acpi_device *device)
 {
 	int result = 0;
 	acpi_status status = AE_OK;
@@ -1070,10 +1076,10 @@ static int acpi_ec_burst_add(struct acpi
 
 	ec->common.handle = device->handle;
 	ec->common.uid = -1;
-	atomic_set(&ec->burst.pending_gpe, 0);
-	atomic_set(&ec->burst.leaving_burst, 1);
-	init_MUTEX(&ec->burst.sem);
-	init_waitqueue_head(&ec->burst.wait);
+	atomic_set(&ec->intr.pending_gpe, 0);
+	atomic_set(&ec->intr.leaving_burst, 1);
+	init_MUTEX(&ec->intr.sem);
+	init_waitqueue_head(&ec->intr.wait);
 	strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_EC_CLASS);
 	acpi_driver_data(device) = ec;
@@ -1112,8 +1118,7 @@ static int acpi_ec_burst_add(struct acpi
 	if (result)
 		goto end;
 
-	printk("burst-mode-ec-10-Aug\n");
-	printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n",
+	printk(KERN_INFO PREFIX "%s [%s] (gpe %d) interrupt mode.\n",
 	       acpi_device_name(device), acpi_device_bid(device),
 	       (u32) ec->common.gpe_bit);
 
@@ -1151,7 +1156,7 @@ acpi_ec_io_ports(struct acpi_resource *r
 	union acpi_ec *ec = (union acpi_ec *)context;
 	struct acpi_generic_address *addr;
 
-	if (resource->id != ACPI_RSTYPE_IO) {
+	if (resource->type != ACPI_RESOURCE_TYPE_IO) {
 		return AE_OK;
 	}
 
@@ -1171,7 +1176,7 @@ acpi_ec_io_ports(struct acpi_resource *r
 	addr->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
 	addr->register_bit_width = 8;
 	addr->register_bit_offset = 0;
-	addr->address = resource->data.io.min_base_address;
+	addr->address = resource->data.io.minimum;
 
 	return AE_OK;
 }
@@ -1267,16 +1272,16 @@ acpi_fake_ecdt_callback(acpi_handle hand
 			u32 Level, void *context, void **retval)
 {
 
-	if (acpi_ec_polling_mode)
-		return acpi_fake_ecdt_polling_callback(handle,
+	if (acpi_ec_poll_mode)
+		return acpi_fake_ecdt_poll_callback(handle,
 						       Level, context, retval);
 	else
-		return acpi_fake_ecdt_burst_callback(handle,
+		return acpi_fake_ecdt_intr_callback(handle,
 						     Level, context, retval);
 }
 
 static acpi_status __init
-acpi_fake_ecdt_polling_callback(acpi_handle handle,
+acpi_fake_ecdt_poll_callback(acpi_handle handle,
 				u32 Level, void *context, void **retval)
 {
 	acpi_status status;
@@ -1295,7 +1300,7 @@ acpi_fake_ecdt_polling_callback(acpi_han
 				  &ec_ecdt->common.gpe_bit);
 	if (ACPI_FAILURE(status))
 		return status;
-	spin_lock_init(&ec_ecdt->polling.lock);
+	spin_lock_init(&ec_ecdt->poll.lock);
 	ec_ecdt->common.global_lock = TRUE;
 	ec_ecdt->common.handle = handle;
 
@@ -1308,13 +1313,13 @@ acpi_fake_ecdt_polling_callback(acpi_han
 }
 
 static acpi_status __init
-acpi_fake_ecdt_burst_callback(acpi_handle handle,
+acpi_fake_ecdt_intr_callback(acpi_handle handle,
 			      u32 Level, void *context, void **retval)
 {
 	acpi_status status;
 
-	init_MUTEX(&ec_ecdt->burst.sem);
-	init_waitqueue_head(&ec_ecdt->burst.wait);
+	init_MUTEX(&ec_ecdt->intr.sem);
+	init_waitqueue_head(&ec_ecdt->intr.wait);
 	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
 				     acpi_ec_io_ports, ec_ecdt);
 	if (ACPI_FAILURE(status))
@@ -1380,13 +1385,13 @@ static int __init acpi_ec_fake_ecdt(void
 
 static int __init acpi_ec_get_real_ecdt(void)
 {
-	if (acpi_ec_polling_mode)
-		return acpi_ec_polling_get_real_ecdt();
+	if (acpi_ec_poll_mode)
+		return acpi_ec_poll_get_real_ecdt();
 	else
-		return acpi_ec_burst_get_real_ecdt();
+		return acpi_ec_intr_get_real_ecdt();
 }
 
-static int __init acpi_ec_polling_get_real_ecdt(void)
+static int __init acpi_ec_poll_get_real_ecdt(void)
 {
 	acpi_status status;
 	struct acpi_table_ecdt *ecdt_ptr;
@@ -1411,7 +1416,7 @@ static int __init acpi_ec_polling_get_re
 	ec_ecdt->common.status_addr = ecdt_ptr->ec_control;
 	ec_ecdt->common.data_addr = ecdt_ptr->ec_data;
 	ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit;
-	spin_lock_init(&ec_ecdt->polling.lock);
+	spin_lock_init(&ec_ecdt->poll.lock);
 	/* use the GL just to be safe */
 	ec_ecdt->common.global_lock = TRUE;
 	ec_ecdt->common.uid = ecdt_ptr->uid;
@@ -1431,7 +1436,7 @@ static int __init acpi_ec_polling_get_re
 	return -ENODEV;
 }
 
-static int __init acpi_ec_burst_get_real_ecdt(void)
+static int __init acpi_ec_intr_get_real_ecdt(void)
 {
 	acpi_status status;
 	struct acpi_table_ecdt *ecdt_ptr;
@@ -1452,8 +1457,8 @@ static int __init acpi_ec_burst_get_real
 		return -ENOMEM;
 	memset(ec_ecdt, 0, sizeof(union acpi_ec));
 
-	init_MUTEX(&ec_ecdt->burst.sem);
-	init_waitqueue_head(&ec_ecdt->burst.wait);
+	init_MUTEX(&ec_ecdt->intr.sem);
+	init_waitqueue_head(&ec_ecdt->intr.wait);
 	ec_ecdt->common.command_addr = ecdt_ptr->ec_control;
 	ec_ecdt->common.status_addr = ecdt_ptr->ec_control;
 	ec_ecdt->common.data_addr = ecdt_ptr->ec_data;
@@ -1571,22 +1576,22 @@ static int __init acpi_fake_ecdt_setup(c
 }
 
 __setup("acpi_fake_ecdt", acpi_fake_ecdt_setup);
-static int __init acpi_ec_set_polling_mode(char *str)
+static int __init acpi_ec_set_intr_mode(char *str)
 {
-	int burst;
+	int intr;
 
-	if (!get_option(&str, &burst))
+	if (!get_option(&str, &intr))
 		return 0;
 
-	if (burst) {
-		acpi_ec_polling_mode = EC_BURST;
-		acpi_ec_driver.ops.add = acpi_ec_burst_add;
+	if (intr) {
+		acpi_ec_poll_mode = EC_INTR;
+		acpi_ec_driver.ops.add = acpi_ec_intr_add;
 	} else {
-		acpi_ec_polling_mode = EC_POLLING;
-		acpi_ec_driver.ops.add = acpi_ec_polling_add;
+		acpi_ec_poll_mode = EC_POLL;
+		acpi_ec_driver.ops.add = acpi_ec_poll_add;
 	}
-	printk(KERN_INFO PREFIX "EC %s mode.\n", burst ? "burst" : "polling");
+	printk(KERN_INFO PREFIX "EC %s mode.\n", intr ? "interrupt" : "polling");
 	return 0;
 }
 
-__setup("ec_burst=", acpi_ec_set_polling_mode);
+__setup("ec_intr=", acpi_ec_set_intr_mode);
diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c
index 842d1e3..c9ac05c 100644
--- a/drivers/acpi/events/evevent.c
+++ b/drivers/acpi/events/evevent.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -73,7 +73,7 @@ acpi_status acpi_ev_initialize_events(vo
 	/* Make sure we have ACPI tables */
 
 	if (!acpi_gbl_DSDT) {
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "No ACPI tables present!\n"));
+		ACPI_WARNING((AE_INFO, "No ACPI tables present!"));
 		return_ACPI_STATUS(AE_NO_ACPI_TABLES);
 	}
 
@@ -84,14 +84,15 @@ acpi_status acpi_ev_initialize_events(vo
 	 */
 	status = acpi_ev_fixed_event_initialize();
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("Unable to initialize fixed events, %s\n",
-				   acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status,
+				"Unable to initialize fixed events"));
 		return_ACPI_STATUS(status);
 	}
 
 	status = acpi_ev_gpe_initialize();
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("Unable to initialize general purpose events, %s\n", acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status,
+				"Unable to initialize general purpose events"));
 		return_ACPI_STATUS(status);
 	}
 
@@ -100,6 +101,48 @@ acpi_status acpi_ev_initialize_events(vo
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_ev_install_fadt_gpes
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Completes initialization of the FADT-defined GPE blocks
+ *              (0 and 1). This causes the _PRW methods to be run, so the HW
+ *              must be fully initialized at this point, including global lock
+ *              support.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ev_install_fadt_gpes(void)
+{
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE("ev_install_fadt_gpes");
+
+	/* Namespace must be locked */
+
+	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	/* FADT GPE Block 0 */
+
+	(void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device,
+					   acpi_gbl_gpe_fadt_blocks[0]);
+
+	/* FADT GPE Block 1 */
+
+	(void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device,
+					   acpi_gbl_gpe_fadt_blocks[1]);
+
+	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+	return_ACPI_STATUS(AE_OK);
+}
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_ev_install_xrupt_handlers
  *
  * PARAMETERS:  None
@@ -120,7 +163,8 @@ acpi_status acpi_ev_install_xrupt_handle
 
 	status = acpi_ev_install_sci_handler();
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("Unable to install System Control Interrupt Handler, %s\n", acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status,
+				"Unable to install System Control Interrupt handler"));
 		return_ACPI_STATUS(status);
 	}
 
@@ -128,7 +172,8 @@ acpi_status acpi_ev_install_xrupt_handle
 
 	status = acpi_ev_init_global_lock_handler();
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("Unable to initialize Global Lock handler, %s\n", acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status,
+				"Unable to initialize Global Lock handler"));
 		return_ACPI_STATUS(status);
 	}
 
@@ -262,7 +307,9 @@ static u32 acpi_ev_fixed_event_dispatch(
 					enable_register_id, 0,
 					ACPI_MTX_DO_NOT_LOCK);
 
-		ACPI_REPORT_ERROR(("No installed handler for fixed event [%08X]\n", event));
+		ACPI_ERROR((AE_INFO,
+			    "No installed handler for fixed event [%08X]",
+			    event));
 
 		return (ACPI_INTERRUPT_NOT_HANDLED);
 	}
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
index b2f232d..f64f977 100644
--- a/drivers/acpi/events/evgpe.c
+++ b/drivers/acpi/events/evgpe.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -372,14 +372,14 @@ struct acpi_gpe_event_info *acpi_ev_get_
 
 u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
 {
+	acpi_status status;
+	struct acpi_gpe_block_info *gpe_block;
+	struct acpi_gpe_register_info *gpe_register_info;
 	u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;
 	u8 enabled_status_byte;
-	struct acpi_gpe_register_info *gpe_register_info;
 	u32 status_reg;
 	u32 enable_reg;
-	u32 flags;
-	acpi_status status;
-	struct acpi_gpe_block_info *gpe_block;
+	acpi_cpu_flags flags;
 	acpi_native_uint i;
 	acpi_native_uint j;
 
@@ -546,7 +546,11 @@ static void ACPI_SYSTEM_XFACE acpi_ev_as
 
 		status = acpi_ns_evaluate_by_handle(&info);
 		if (ACPI_FAILURE(status)) {
-			ACPI_REPORT_ERROR(("%s while evaluating method [%4.4s] for GPE[%2X]\n", acpi_format_exception(status), acpi_ut_get_node_name(local_gpe_event_info.dispatch.method_node), gpe_number));
+			ACPI_EXCEPTION((AE_INFO, status,
+					"While evaluating method [%4.4s] for GPE[%2X]",
+					acpi_ut_get_node_name
+					(local_gpe_event_info.dispatch.
+					 method_node), gpe_number));
 		}
 	}
 
@@ -599,8 +603,10 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_eve
 	    ACPI_GPE_EDGE_TRIGGERED) {
 		status = acpi_hw_clear_gpe(gpe_event_info);
 		if (ACPI_FAILURE(status)) {
-			ACPI_REPORT_ERROR(("acpi_ev_gpe_dispatch: %s, Unable to clear GPE[%2X]\n", acpi_format_exception(status), gpe_number));
-			return_VALUE(ACPI_INTERRUPT_NOT_HANDLED);
+			ACPI_EXCEPTION((AE_INFO, status,
+					"Unable to clear GPE[%2X]",
+					gpe_number));
+			return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
 		}
 	}
 
@@ -637,8 +643,10 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_eve
 		    ACPI_GPE_LEVEL_TRIGGERED) {
 			status = acpi_hw_clear_gpe(gpe_event_info);
 			if (ACPI_FAILURE(status)) {
-				ACPI_REPORT_ERROR(("acpi_ev_gpe_dispatch: %s, Unable to clear GPE[%2X]\n", acpi_format_exception(status), gpe_number));
-				return_VALUE(ACPI_INTERRUPT_NOT_HANDLED);
+				ACPI_EXCEPTION((AE_INFO, status,
+						"Unable to clear GPE[%2X]",
+						gpe_number));
+				return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
 			}
 		}
 		break;
@@ -651,8 +659,10 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_eve
 		 */
 		status = acpi_ev_disable_gpe(gpe_event_info);
 		if (ACPI_FAILURE(status)) {
-			ACPI_REPORT_ERROR(("acpi_ev_gpe_dispatch: %s, Unable to disable GPE[%2X]\n", acpi_format_exception(status), gpe_number));
-			return_VALUE(ACPI_INTERRUPT_NOT_HANDLED);
+			ACPI_EXCEPTION((AE_INFO, status,
+					"Unable to disable GPE[%2X]",
+					gpe_number));
+			return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
 		}
 
 		/*
@@ -663,7 +673,9 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_eve
 						     acpi_ev_asynch_execute_gpe_method,
 						     gpe_event_info);
 		if (ACPI_FAILURE(status)) {
-			ACPI_REPORT_ERROR(("acpi_ev_gpe_dispatch: %s, Unable to queue handler for GPE[%2X] - event disabled\n", acpi_format_exception(status), gpe_number));
+			ACPI_EXCEPTION((AE_INFO, status,
+					"Unable to queue handler for GPE[%2X] - event disabled",
+					gpe_number));
 		}
 		break;
 
@@ -671,7 +683,9 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_eve
 
 		/* No handler or method to run! */
 
-		ACPI_REPORT_ERROR(("acpi_ev_gpe_dispatch: No handler or method for GPE[%2X], disabling event\n", gpe_number));
+		ACPI_ERROR((AE_INFO,
+			    "No handler or method for GPE[%2X], disabling event",
+			    gpe_number));
 
 		/*
 		 * Disable the GPE.  The GPE will remain disabled until the ACPI
@@ -679,13 +693,15 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_eve
 		 */
 		status = acpi_ev_disable_gpe(gpe_event_info);
 		if (ACPI_FAILURE(status)) {
-			ACPI_REPORT_ERROR(("acpi_ev_gpe_dispatch: %s, Unable to disable GPE[%2X]\n", acpi_format_exception(status), gpe_number));
-			return_VALUE(ACPI_INTERRUPT_NOT_HANDLED);
+			ACPI_EXCEPTION((AE_INFO, status,
+					"Unable to disable GPE[%2X]",
+					gpe_number));
+			return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
 		}
 		break;
 	}
 
-	return_VALUE(ACPI_INTERRUPT_HANDLED);
+	return_UINT32(ACPI_INTERRUPT_HANDLED);
 }
 
 #ifdef ACPI_GPE_NOTIFY_CHECK
@@ -722,7 +738,9 @@ acpi_ev_check_for_wake_only_gpe(struct a
 
 		acpi_ev_set_gpe_type(gpe_event_info, ACPI_GPE_TYPE_WAKE);
 
-		ACPI_REPORT_INFO(("GPE %p was updated from wake/run to wake-only\n", gpe_event_info));
+		ACPI_INFO((AE_INFO,
+			   "GPE %p was updated from wake/run to wake-only",
+			   gpe_event_info));
 
 		/* This was a wake-only GPE */
 
diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c
index b312eb3..0fd00b5 100644
--- a/drivers/acpi/events/evgpeblk.c
+++ b/drivers/acpi/events/evgpeblk.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -78,7 +78,7 @@ acpi_ev_create_gpe_info_blocks(struct ac
  *
  * RETURN:      TRUE if the gpe_event is valid
  *
- * DESCRIPTION: Validate a GPE event.  DO NOT CALL FROM INTERRUPT LEVEL.
+ * DESCRIPTION: Validate a GPE event. DO NOT CALL FROM INTERRUPT LEVEL.
  *              Should be called only when the GPE lists are semaphore locked
  *              and not subject to change.
  *
@@ -136,7 +136,7 @@ acpi_status acpi_ev_walk_gpe_list(ACPI_G
 	struct acpi_gpe_block_info *gpe_block;
 	struct acpi_gpe_xrupt_info *gpe_xrupt_info;
 	acpi_status status = AE_OK;
-	u32 flags;
+	acpi_cpu_flags flags;
 
 	ACPI_FUNCTION_TRACE("ev_walk_gpe_list");
 
@@ -264,7 +264,7 @@ acpi_ev_save_method_info(acpi_handle obj
 	 * 2) Edge/Level determination is based on the 2nd character
 	 *    of the method name
 	 *
-	 * NOTE: Default GPE type is RUNTIME.  May be changed later to WAKE
+	 * NOTE: Default GPE type is RUNTIME. May be changed later to WAKE
 	 * if a _PRW object is found that points to this GPE.
 	 */
 	switch (name[1]) {
@@ -279,9 +279,9 @@ acpi_ev_save_method_info(acpi_handle obj
 	default:
 		/* Unknown method type, just ignore it! */
 
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Unknown GPE method type: %s (name not of form _Lxx or _Exx)\n",
-				  name));
+		ACPI_ERROR((AE_INFO,
+			    "Unknown GPE method type: %s (name not of form _Lxx or _Exx)",
+			    name));
 		return_ACPI_STATUS(AE_OK);
 	}
 
@@ -291,9 +291,9 @@ acpi_ev_save_method_info(acpi_handle obj
 	if (gpe_number == ACPI_UINT32_MAX) {
 		/* Conversion failed; invalid method, just ignore it */
 
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Could not extract GPE number from name: %s (name is not of form _Lxx or _Exx)\n",
-				  name));
+		ACPI_ERROR((AE_INFO,
+			    "Could not extract GPE number from name: %s (name is not of form _Lxx or _Exx)",
+			    name));
 		return_ACPI_STATUS(AE_OK);
 	}
 
@@ -313,14 +313,14 @@ acpi_ev_save_method_info(acpi_handle obj
 
 	/*
 	 * Now we can add this information to the gpe_event_info block
-	 * for use during dispatch of this GPE.  Default type is RUNTIME, although
+	 * for use during dispatch of this GPE. Default type is RUNTIME, although
 	 * this may change when the _PRW methods are executed later.
 	 */
 	gpe_event_info =
 	    &gpe_block->event_info[gpe_number - gpe_block->block_base_number];
 
-	gpe_event_info->flags = (u8) (type | ACPI_GPE_DISPATCH_METHOD |
-				      ACPI_GPE_TYPE_RUNTIME);
+	gpe_event_info->flags = (u8)
+	    (type | ACPI_GPE_DISPATCH_METHOD | ACPI_GPE_TYPE_RUNTIME);
 
 	gpe_event_info->dispatch.method_node =
 	    (struct acpi_namespace_node *)obj_handle;
@@ -341,11 +341,11 @@ acpi_ev_save_method_info(acpi_handle obj
  *
  * PARAMETERS:  Callback from walk_namespace
  *
- * RETURN:      Status.  NOTE: We ignore errors so that the _PRW walk is
+ * RETURN:      Status. NOTE: We ignore errors so that the _PRW walk is
  *              not aborted on a single _PRW failure.
  *
  * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a
- *              Device.  Run the _PRW method.  If present, extract the GPE
+ *              Device. Run the _PRW method. If present, extract the GPE
  *              number and mark the GPE as a WAKE GPE.
  *
  ******************************************************************************/
@@ -443,6 +443,7 @@ acpi_ev_match_prw_and_gpe(acpi_handle ob
 
 		gpe_event_info->flags &=
 		    ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED);
+
 		status =
 		    acpi_ev_set_gpe_type(gpe_event_info, ACPI_GPE_TYPE_WAKE);
 		if (ACPI_FAILURE(status)) {
@@ -466,7 +467,7 @@ acpi_ev_match_prw_and_gpe(acpi_handle ob
  *
  * RETURN:      A GPE interrupt block
  *
- * DESCRIPTION: Get or Create a GPE interrupt block.  There is one interrupt
+ * DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt
  *              block per unique interrupt level used for GPEs.
  *              Should be called only when the GPE lists are semaphore locked
  *              and not subject to change.
@@ -479,7 +480,7 @@ static struct acpi_gpe_xrupt_info *acpi_
 	struct acpi_gpe_xrupt_info *next_gpe_xrupt;
 	struct acpi_gpe_xrupt_info *gpe_xrupt;
 	acpi_status status;
-	u32 flags;
+	acpi_cpu_flags flags;
 
 	ACPI_FUNCTION_TRACE("ev_get_gpe_xrupt_block");
 
@@ -526,9 +527,9 @@ static struct acpi_gpe_xrupt_info *acpi_
 							   acpi_ev_gpe_xrupt_handler,
 							   gpe_xrupt);
 		if (ACPI_FAILURE(status)) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Could not install GPE interrupt handler at level 0x%X\n",
-					  interrupt_number));
+			ACPI_ERROR((AE_INFO,
+				    "Could not install GPE interrupt handler at level 0x%X",
+				    interrupt_number));
 			return_PTR(NULL);
 		}
 	}
@@ -553,7 +554,7 @@ static acpi_status
 acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt)
 {
 	acpi_status status;
-	u32 flags;
+	acpi_cpu_flags flags;
 
 	ACPI_FUNCTION_TRACE("ev_delete_gpe_xrupt");
 
@@ -566,8 +567,9 @@ acpi_ev_delete_gpe_xrupt(struct acpi_gpe
 
 	/* Disable this interrupt */
 
-	status = acpi_os_remove_interrupt_handler(gpe_xrupt->interrupt_number,
-						  acpi_ev_gpe_xrupt_handler);
+	status =
+	    acpi_os_remove_interrupt_handler(gpe_xrupt->interrupt_number,
+					     acpi_ev_gpe_xrupt_handler);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -610,7 +612,7 @@ acpi_ev_install_gpe_block(struct acpi_gp
 	struct acpi_gpe_block_info *next_gpe_block;
 	struct acpi_gpe_xrupt_info *gpe_xrupt_block;
 	acpi_status status;
-	u32 flags;
+	acpi_cpu_flags flags;
 
 	ACPI_FUNCTION_TRACE("ev_install_gpe_block");
 
@@ -663,7 +665,7 @@ acpi_ev_install_gpe_block(struct acpi_gp
 acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block)
 {
 	acpi_status status;
-	u32 flags;
+	acpi_cpu_flags flags;
 
 	ACPI_FUNCTION_TRACE("ev_install_gpe_block");
 
@@ -743,22 +745,22 @@ acpi_ev_create_gpe_info_blocks(struct ac
 					       sizeof(struct
 						      acpi_gpe_register_info));
 	if (!gpe_register_info) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Could not allocate the gpe_register_info table\n"));
+		ACPI_ERROR((AE_INFO,
+			    "Could not allocate the gpe_register_info table"));
 		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
 
 	/*
 	 * Allocate the GPE event_info block. There are eight distinct GPEs
-	 * per register.  Initialization to zeros is sufficient.
+	 * per register. Initialization to zeros is sufficient.
 	 */
 	gpe_event_info = ACPI_MEM_CALLOCATE(((acpi_size) gpe_block->
 					     register_count *
 					     ACPI_GPE_REGISTER_WIDTH) *
 					    sizeof(struct acpi_gpe_event_info));
 	if (!gpe_event_info) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Could not allocate the gpe_event_info table\n"));
+		ACPI_ERROR((AE_INFO,
+			    "Could not allocate the gpe_event_info table"));
 		status = AE_NO_MEMORY;
 		goto error_exit;
 	}
@@ -769,9 +771,9 @@ acpi_ev_create_gpe_info_blocks(struct ac
 	gpe_block->event_info = gpe_event_info;
 
 	/*
-	 * Initialize the GPE Register and Event structures.  A goal of these
+	 * Initialize the GPE Register and Event structures. A goal of these
 	 * tables is to hide the fact that there are two separate GPE register sets
-	 * in a given gpe hardware block, the status registers occupy the first half,
+	 * in a given GPE hardware block, the status registers occupy the first half,
 	 * and the enable registers occupy the second half.
 	 */
 	this_register = gpe_register_info;
@@ -812,11 +814,8 @@ acpi_ev_create_gpe_info_blocks(struct ac
 			this_event++;
 		}
 
-		/*
-		 * Clear the status/enable registers.  Note that status registers
-		 * are cleared by writing a '1', while enable registers are cleared
-		 * by writing a '0'.
-		 */
+		/* Disable all GPEs within this register */
+
 		status = acpi_hw_low_level_write(ACPI_GPE_REGISTER_WIDTH, 0x00,
 						 &this_register->
 						 enable_address);
@@ -824,6 +823,8 @@ acpi_ev_create_gpe_info_blocks(struct ac
 			goto error_exit;
 		}
 
+		/* Clear any pending GPE events within this register */
+
 		status = acpi_hw_low_level_write(ACPI_GPE_REGISTER_WIDTH, 0xFF,
 						 &this_register->
 						 status_address);
@@ -860,7 +861,9 @@ acpi_ev_create_gpe_info_blocks(struct ac
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Create and Install a block of GPE registers
+ * DESCRIPTION: Create and Install a block of GPE registers. All GPEs within
+ *              the block are disabled at exit.
+ *              Note: Assumes namespace is locked.
  *
  ******************************************************************************/
 
@@ -872,14 +875,8 @@ acpi_ev_create_gpe_block(struct acpi_nam
 			 u32 interrupt_number,
 			 struct acpi_gpe_block_info **return_gpe_block)
 {
-	struct acpi_gpe_block_info *gpe_block;
-	struct acpi_gpe_event_info *gpe_event_info;
-	acpi_native_uint i;
-	acpi_native_uint j;
-	u32 wake_gpe_count;
-	u32 gpe_enabled_count;
 	acpi_status status;
-	struct acpi_gpe_walk_info gpe_info;
+	struct acpi_gpe_block_info *gpe_block;
 
 	ACPI_FUNCTION_TRACE("ev_create_gpe_block");
 
@@ -896,22 +893,24 @@ acpi_ev_create_gpe_block(struct acpi_nam
 
 	/* Initialize the new GPE block */
 
+	gpe_block->node = gpe_device;
 	gpe_block->register_count = register_count;
 	gpe_block->block_base_number = gpe_block_base_number;
-	gpe_block->node = gpe_device;
 
 	ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address,
 		    sizeof(struct acpi_generic_address));
 
-	/* Create the register_info and event_info sub-structures */
-
+	/*
+	 * Create the register_info and event_info sub-structures
+	 * Note: disables and clears all GPEs in the block
+	 */
 	status = acpi_ev_create_gpe_info_blocks(gpe_block);
 	if (ACPI_FAILURE(status)) {
 		ACPI_MEM_FREE(gpe_block);
 		return_ACPI_STATUS(status);
 	}
 
-	/* Install the new block in the global list(s) */
+	/* Install the new block in the global lists */
 
 	status = acpi_ev_install_gpe_block(gpe_block, interrupt_number);
 	if (ACPI_FAILURE(status)) {
@@ -926,16 +925,70 @@ acpi_ev_create_gpe_block(struct acpi_nam
 					acpi_ev_save_method_info, gpe_block,
 					NULL);
 
+	/* Return the new block */
+
+	if (return_gpe_block) {
+		(*return_gpe_block) = gpe_block;
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INIT,
+			  "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",
+			  (u32) gpe_block->block_base_number,
+			  (u32) (gpe_block->block_base_number +
+				 ((gpe_block->register_count *
+				   ACPI_GPE_REGISTER_WIDTH) - 1)),
+			  gpe_device->name.ascii, gpe_block->register_count,
+			  interrupt_number));
+
+	return_ACPI_STATUS(AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_initialize_gpe_block
+ *
+ * PARAMETERS:  gpe_device          - Handle to the parent GPE block
+ *              gpe_block           - Gpe Block info
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initialize and enable a GPE block. First find and run any
+ *              _PRT methods associated with the block, then enable the
+ *              appropriate GPEs.
+ *              Note: Assumes namespace is locked.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
+			     struct acpi_gpe_block_info *gpe_block)
+{
+	acpi_status status;
+	struct acpi_gpe_event_info *gpe_event_info;
+	struct acpi_gpe_walk_info gpe_info;
+	u32 wake_gpe_count;
+	u32 gpe_enabled_count;
+	acpi_native_uint i;
+	acpi_native_uint j;
+
+	ACPI_FUNCTION_TRACE("ev_initialize_gpe_block");
+
+	/* Ignore a null GPE block (e.g., if no GPE block 1 exists) */
+
+	if (!gpe_block) {
+		return_ACPI_STATUS(AE_OK);
+	}
+
 	/*
-	 * Runtime option: Should Wake GPEs be enabled at runtime?  The default
-	 * is No, they should only be enabled just as the machine goes to sleep.
+	 * Runtime option: Should wake GPEs be enabled at runtime?  The default
+	 * is no, they should only be enabled just as the machine goes to sleep.
 	 */
 	if (acpi_gbl_leave_wake_gpes_disabled) {
 		/*
-		 * Differentiate RUNTIME vs WAKE GPEs, via the _PRW control methods.
-		 * (Each GPE that has one or more _PRWs that reference it is by
-		 * definition a WAKE GPE and will not be enabled while the machine
-		 * is running.)
+		 * Differentiate runtime vs wake GPEs, via the _PRW control methods.
+		 * Each GPE that has one or more _PRWs that reference it is by
+		 * definition a wake GPE and will not be enabled while the machine
+		 * is running.
 		 */
 		gpe_info.gpe_block = gpe_block;
 		gpe_info.gpe_device = gpe_device;
@@ -948,9 +1001,12 @@ acpi_ev_create_gpe_block(struct acpi_nam
 	}
 
 	/*
-	 * Enable all GPEs in this block that are 1) "runtime" or "run/wake" GPEs,
-	 * and 2) have a corresponding _Lxx or _Exx method.  All other GPEs must
-	 * be enabled via the acpi_enable_gpe() external interface.
+	 * Enable all GPEs in this block that have these attributes:
+	 * 1) are "runtime" or "run/wake" GPEs, and
+	 * 2) have a corresponding _Lxx or _Exx method
+	 *
+	 * Any other GPEs within this block must be enabled via the acpi_enable_gpe()
+	 * external interface.
 	 */
 	wake_gpe_count = 0;
 	gpe_enabled_count = 0;
@@ -976,32 +1032,19 @@ acpi_ev_create_gpe_block(struct acpi_nam
 		}
 	}
 
-	/* Dump info about this GPE block */
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INIT,
-			  "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",
-			  (u32) gpe_block->block_base_number,
-			  (u32) (gpe_block->block_base_number +
-				 ((gpe_block->register_count *
-				   ACPI_GPE_REGISTER_WIDTH) - 1)),
-			  gpe_device->name.ascii, gpe_block->register_count,
-			  interrupt_number));
-
-	/* Enable all valid GPEs found above */
-
-	status = acpi_hw_enable_runtime_gpe_block(NULL, gpe_block);
-
 	ACPI_DEBUG_PRINT((ACPI_DB_INIT,
 			  "Found %u Wake, Enabled %u Runtime GPEs in this block\n",
 			  wake_gpe_count, gpe_enabled_count));
 
-	/* Return the new block */
+	/* Enable all valid runtime GPEs found above */
 
-	if (return_gpe_block) {
-		(*return_gpe_block) = gpe_block;
+	status = acpi_hw_enable_runtime_gpe_block(NULL, gpe_block);
+	if (ACPI_FAILURE(status)) {
+		ACPI_ERROR((AE_INFO, "Could not enable GPEs in gpe_block %p",
+			    gpe_block));
 	}
 
-	return_ACPI_STATUS(AE_OK);
+	return_ACPI_STATUS(status);
 }
 
 /*******************************************************************************
@@ -1072,8 +1115,8 @@ acpi_status acpi_ev_gpe_initialize(void)
 						  &acpi_gbl_gpe_fadt_blocks[0]);
 
 		if (ACPI_FAILURE(status)) {
-			ACPI_REPORT_ERROR(("Could not create GPE Block 0, %s\n",
-					   acpi_format_exception(status)));
+			ACPI_EXCEPTION((AE_INFO, status,
+					"Could not create GPE Block 0"));
 		}
 	}
 
@@ -1086,7 +1129,12 @@ acpi_status acpi_ev_gpe_initialize(void)
 
 		if ((register_count0) &&
 		    (gpe_number_max >= acpi_gbl_FADT->gpe1_base)) {
-			ACPI_REPORT_ERROR(("GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1\n", gpe_number_max, acpi_gbl_FADT->gpe1_base, acpi_gbl_FADT->gpe1_base + ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1)));
+			ACPI_ERROR((AE_INFO,
+				    "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1",
+				    gpe_number_max, acpi_gbl_FADT->gpe1_base,
+				    acpi_gbl_FADT->gpe1_base +
+				    ((register_count1 *
+				      ACPI_GPE_REGISTER_WIDTH) - 1)));
 
 			/* Ignore GPE1 block by setting the register count to zero */
 
@@ -1104,7 +1152,8 @@ acpi_status acpi_ev_gpe_initialize(void)
 						     [1]);
 
 			if (ACPI_FAILURE(status)) {
-				ACPI_REPORT_ERROR(("Could not create GPE Block 1, %s\n", acpi_format_exception(status)));
+				ACPI_EXCEPTION((AE_INFO, status,
+						"Could not create GPE Block 1"));
 			}
 
 			/*
@@ -1130,7 +1179,9 @@ acpi_status acpi_ev_gpe_initialize(void)
 	/* Check for Max GPE number out-of-range */
 
 	if (gpe_number_max > ACPI_GPE_MAX) {
-		ACPI_REPORT_ERROR(("Maximum GPE number from FADT is too large: 0x%X\n", gpe_number_max));
+		ACPI_ERROR((AE_INFO,
+			    "Maximum GPE number from FADT is too large: 0x%X",
+			    gpe_number_max));
 		status = AE_BAD_VALUE;
 		goto cleanup;
 	}
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index 7e57b84..0909ba6 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -303,7 +303,8 @@ static void ACPI_SYSTEM_XFACE acpi_ev_gl
 		    acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore,
 					     acpi_gbl_global_lock_thread_count);
 		if (ACPI_FAILURE(status)) {
-			ACPI_REPORT_ERROR(("Could not signal Global Lock semaphore\n"));
+			ACPI_ERROR((AE_INFO,
+				    "Could not signal Global Lock semaphore"));
 		}
 	}
 }
@@ -344,7 +345,8 @@ static u32 acpi_ev_global_lock_handler(v
 						     acpi_ev_global_lock_thread,
 						     context);
 		if (ACPI_FAILURE(status)) {
-			ACPI_REPORT_ERROR(("Could not queue Global Lock thread, %s\n", acpi_format_exception(status)));
+			ACPI_EXCEPTION((AE_INFO, status,
+					"Could not queue Global Lock thread"));
 
 			return (ACPI_INTERRUPT_NOT_HANDLED);
 		}
@@ -384,7 +386,8 @@ acpi_status acpi_ev_init_global_lock_han
 	 * with an error.
 	 */
 	if (status == AE_NO_HARDWARE_RESPONSE) {
-		ACPI_REPORT_ERROR(("No response from Global Lock hardware, disabling lock\n"));
+		ACPI_ERROR((AE_INFO,
+			    "No response from Global Lock hardware, disabling lock"));
 
 		acpi_gbl_global_lock_present = FALSE;
 		status = AE_OK;
@@ -480,7 +483,8 @@ acpi_status acpi_ev_release_global_lock(
 	ACPI_FUNCTION_TRACE("ev_release_global_lock");
 
 	if (!acpi_gbl_global_lock_thread_count) {
-		ACPI_REPORT_WARNING(("Cannot release HW Global Lock, it has not been acquired\n"));
+		ACPI_WARNING((AE_INFO,
+			      "Cannot release HW Global Lock, it has not been acquired"));
 		return_ACPI_STATUS(AE_NOT_ACQUIRED);
 	}
 
@@ -542,9 +546,9 @@ void acpi_ev_terminate(void)
 		for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
 			status = acpi_disable_event((u32) i, 0);
 			if (ACPI_FAILURE(status)) {
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "Could not disable fixed event %d\n",
-						  (u32) i));
+				ACPI_ERROR((AE_INFO,
+					    "Could not disable fixed event %d",
+					    (u32) i));
 			}
 		}
 
@@ -556,8 +560,7 @@ void acpi_ev_terminate(void)
 
 		status = acpi_ev_remove_sci_handler();
 		if (ACPI_FAILURE(status)) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Could not remove SCI handler\n"));
+			ACPI_ERROR((AE_INFO, "Could not remove SCI handler"));
 		}
 	}
 
@@ -570,8 +573,7 @@ void acpi_ev_terminate(void)
 	if (acpi_gbl_original_mode == ACPI_SYS_MODE_LEGACY) {
 		status = acpi_disable();
 		if (ACPI_FAILURE(status)) {
-			ACPI_DEBUG_PRINT((ACPI_DB_WARN,
-					  "acpi_disable failed\n"));
+			ACPI_WARNING((AE_INFO, "acpi_disable failed"));
 		}
 	}
 	return_VOID;
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
index 84fad08..6da58e7 100644
--- a/drivers/acpi/events/evregion.c
+++ b/drivers/acpi/events/evregion.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -295,12 +295,12 @@ acpi_ev_address_space_dispatch(union acp
 
 	handler_desc = region_obj->region.handler;
 	if (!handler_desc) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "No handler for Region [%4.4s] (%p) [%s]\n",
-				  acpi_ut_get_node_name(region_obj->region.
-							node), region_obj,
-				  acpi_ut_get_region_name(region_obj->region.
-							  space_id)));
+		ACPI_ERROR((AE_INFO,
+			    "No handler for Region [%4.4s] (%p) [%s]",
+			    acpi_ut_get_node_name(region_obj->region.node),
+			    region_obj,
+			    acpi_ut_get_region_name(region_obj->region.
+						    space_id)));
 
 		return_ACPI_STATUS(AE_NOT_EXIST);
 	}
@@ -317,12 +317,11 @@ acpi_ev_address_space_dispatch(union acp
 		if (!region_setup) {
 			/* No initialization routine, exit with error */
 
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "No init routine for region(%p) [%s]\n",
-					  region_obj,
-					  acpi_ut_get_region_name(region_obj->
-								  region.
-								  space_id)));
+			ACPI_ERROR((AE_INFO,
+				    "No init routine for region(%p) [%s]",
+				    region_obj,
+				    acpi_ut_get_region_name(region_obj->region.
+							    space_id)));
 			return_ACPI_STATUS(AE_NOT_EXIST);
 		}
 
@@ -347,12 +346,11 @@ acpi_ev_address_space_dispatch(union acp
 		/* Check for failure of the Region Setup */
 
 		if (ACPI_FAILURE(status)) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Region Init: %s [%s]\n",
-					  acpi_format_exception(status),
-					  acpi_ut_get_region_name(region_obj->
-								  region.
-								  space_id)));
+			ACPI_EXCEPTION((AE_INFO, status,
+					"During region initialization: [%s]",
+					acpi_ut_get_region_name(region_obj->
+								region.
+								space_id)));
 			return_ACPI_STATUS(status);
 		}
 
@@ -406,10 +404,9 @@ acpi_ev_address_space_dispatch(union acp
 			 region_obj2->extra.region_context);
 
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("Handler for [%s] returned %s\n",
-				   acpi_ut_get_region_name(region_obj->region.
-							   space_id),
-				   acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status, "Returned by Handler for [%s]",
+				acpi_ut_get_region_name(region_obj->region.
+							space_id)));
 	}
 
 	if (!
@@ -501,12 +498,10 @@ acpi_ev_detach_region(union acpi_operand
 
 			status = acpi_ev_execute_reg_method(region_obj, 0);
 			if (ACPI_FAILURE(status)) {
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "%s from region _REG, [%s]\n",
-						  acpi_format_exception(status),
-						  acpi_ut_get_region_name
-						  (region_obj->region.
-						   space_id)));
+				ACPI_EXCEPTION((AE_INFO, status,
+						"from region _REG, [%s]",
+						acpi_ut_get_region_name
+						(region_obj->region.space_id)));
 			}
 
 			if (acpi_ns_is_locked) {
@@ -528,12 +523,10 @@ acpi_ev_detach_region(union acpi_operand
 			/* Init routine may fail, Just ignore errors */
 
 			if (ACPI_FAILURE(status)) {
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "%s from region init, [%s]\n",
-						  acpi_format_exception(status),
-						  acpi_ut_get_region_name
-						  (region_obj->region.
-						   space_id)));
+				ACPI_EXCEPTION((AE_INFO, status,
+						"from region init, [%s]",
+						acpi_ut_get_region_name
+						(region_obj->region.space_id)));
 			}
 
 			region_obj->region.flags &= ~(AOPOBJ_SETUP_COMPLETE);
diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c
index a1bd2da..baed8c1 100644
--- a/drivers/acpi/events/evrgnini.c
+++ b/drivers/acpi/events/evrgnini.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -233,7 +233,11 @@ acpi_ev_pci_config_region_setup(acpi_han
 							 */
 							status = AE_OK;
 						} else {
-							ACPI_REPORT_ERROR(("Could not install pci_config handler for Root Bridge %4.4s, %s\n", acpi_ut_get_node_name(pci_root_node), acpi_format_exception(status)));
+							ACPI_EXCEPTION((AE_INFO,
+									status,
+									"Could not install pci_config handler for Root Bridge %4.4s",
+									acpi_ut_get_node_name
+									(pci_root_node)));
 						}
 					}
 					break;
diff --git a/drivers/acpi/events/evsci.c b/drivers/acpi/events/evsci.c
index 1418359..9a62216 100644
--- a/drivers/acpi/events/evsci.c
+++ b/drivers/acpi/events/evsci.c
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -88,7 +88,7 @@ static u32 ACPI_SYSTEM_XFACE acpi_ev_sci
 	 */
 	interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list);
 
-	return_VALUE(interrupt_handled);
+	return_UINT32(interrupt_handled);
 }
 
 /*******************************************************************************
@@ -121,7 +121,7 @@ u32 ACPI_SYSTEM_XFACE acpi_ev_gpe_xrupt_
 	 */
 	interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list);
 
-	return_VALUE(interrupt_handled);
+	return_UINT32(interrupt_handled);
 }
 
 /******************************************************************************
diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
index 43b33d1..b38b39d 100644
--- a/drivers/acpi/events/evxface.c
+++ b/drivers/acpi/events/evxface.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -143,8 +143,8 @@ acpi_install_fixed_event_handler(u32 eve
 	if (ACPI_SUCCESS(status))
 		status = acpi_enable_event(event, 0);
 	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN,
-				  "Could not enable fixed event.\n"));
+		ACPI_WARNING((AE_INFO, "Could not enable fixed event %X",
+			      event));
 
 		/* Remove the handler */
 
@@ -204,10 +204,11 @@ acpi_remove_fixed_event_handler(u32 even
 	acpi_gbl_fixed_event_handlers[event].context = NULL;
 
 	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN,
-				  "Could not write to fixed event enable register.\n"));
+		ACPI_WARNING((AE_INFO,
+			      "Could not write to fixed event enable register %X",
+			      event));
 	} else {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabled fixed event %X.\n",
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabled fixed event %X\n",
 				  event));
 	}
 
@@ -434,7 +435,7 @@ acpi_remove_notify_handler(acpi_handle d
 
 	if (device == ACPI_ROOT_OBJECT) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Removing notify handler for ROOT object.\n"));
+				  "Removing notify handler for namespace root object\n"));
 
 		if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
 		     !acpi_gbl_system_notify.handler) ||
@@ -562,7 +563,7 @@ acpi_install_gpe_handler(acpi_handle gpe
 	struct acpi_gpe_event_info *gpe_event_info;
 	struct acpi_handler_info *handler;
 	acpi_status status;
-	u32 flags;
+	acpi_cpu_flags flags;
 
 	ACPI_FUNCTION_TRACE("acpi_install_gpe_handler");
 
@@ -653,7 +654,7 @@ acpi_remove_gpe_handler(acpi_handle gpe_
 	struct acpi_gpe_event_info *gpe_event_info;
 	struct acpi_handler_info *handler;
 	acpi_status status;
-	u32 flags;
+	acpi_cpu_flags flags;
 
 	ACPI_FUNCTION_TRACE("acpi_remove_gpe_handler");
 
diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c
index 887ff9f..ec9ce84 100644
--- a/drivers/acpi/events/evxfevnt.c
+++ b/drivers/acpi/events/evxfevnt.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -70,8 +70,7 @@ acpi_status acpi_enable(void)
 	/* Make sure we have the FADT */
 
 	if (!acpi_gbl_FADT) {
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN,
-				  "No FADT information present!\n"));
+		ACPI_WARNING((AE_INFO, "No FADT information present!"));
 		return_ACPI_STATUS(AE_NO_ACPI_TABLES);
 	}
 
@@ -83,7 +82,8 @@ acpi_status acpi_enable(void)
 
 		status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI);
 		if (ACPI_FAILURE(status)) {
-			ACPI_REPORT_ERROR(("Could not transition to ACPI mode.\n"));
+			ACPI_ERROR((AE_INFO,
+				    "Could not transition to ACPI mode"));
 			return_ACPI_STATUS(status);
 		}
 
@@ -113,8 +113,7 @@ acpi_status acpi_disable(void)
 	ACPI_FUNCTION_TRACE("acpi_disable");
 
 	if (!acpi_gbl_FADT) {
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN,
-				  "No FADT information present!\n"));
+		ACPI_WARNING((AE_INFO, "No FADT information present!"));
 		return_ACPI_STATUS(AE_NO_ACPI_TABLES);
 	}
 
@@ -127,8 +126,8 @@ acpi_status acpi_disable(void)
 		status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY);
 
 		if (ACPI_FAILURE(status)) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Could not exit ACPI mode to legacy mode"));
+			ACPI_ERROR((AE_INFO,
+				    "Could not exit ACPI mode to legacy mode"));
 			return_ACPI_STATUS(status);
 		}
 
@@ -185,9 +184,9 @@ acpi_status acpi_enable_event(u32 event,
 	}
 
 	if (value != 1) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Could not enable %s event\n",
-				  acpi_ut_get_event_name(event)));
+		ACPI_ERROR((AE_INFO,
+			    "Could not enable %s event",
+			    acpi_ut_get_event_name(event)));
 		return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
 	}
 
@@ -384,9 +383,9 @@ acpi_status acpi_disable_event(u32 event
 	}
 
 	if (value != 0) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Could not disable %s events\n",
-				  acpi_ut_get_event_name(event)));
+		ACPI_ERROR((AE_INFO,
+			    "Could not disable %s events",
+			    acpi_ut_get_event_name(event)));
 		return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
 	}
 
@@ -626,6 +625,13 @@ acpi_install_gpe_block(acpi_handle gpe_d
 		goto unlock_and_exit;
 	}
 
+	/* Run the _PRW methods and enable the GPEs */
+
+	status = acpi_ev_initialize_gpe_block(node, gpe_block);
+	if (ACPI_FAILURE(status)) {
+		goto unlock_and_exit;
+	}
+
 	/* Get the device_object attached to the node */
 
 	obj_desc = acpi_ns_get_attached_object(node);
diff --git a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c
index 6f28ea2..abf5cac 100644
--- a/drivers/acpi/events/evxfregn.c
+++ b/drivers/acpi/events/evxfregn.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
index 1ce365d..a29782f 100644
--- a/drivers/acpi/executer/exconfig.c
+++ b/drivers/acpi/executer/exconfig.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -413,9 +413,9 @@ acpi_ex_load_op(union acpi_operand_objec
 	    (!ACPI_STRNCMP(table_ptr->signature,
 			   acpi_gbl_table_data[ACPI_TABLE_SSDT].signature,
 			   acpi_gbl_table_data[ACPI_TABLE_SSDT].sig_length))) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Table has invalid signature [%4.4s], must be SSDT or PSDT\n",
-				  table_ptr->signature));
+		ACPI_ERROR((AE_INFO,
+			    "Table has invalid signature [%4.4s], must be SSDT or PSDT",
+			    table_ptr->signature));
 		status = AE_BAD_SIGNATURE;
 		goto cleanup;
 	}
diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c
index 04e5194..e6d52e1 100644
--- a/drivers/acpi/executer/exconvrt.c
+++ b/drivers/acpi/executer/exconvrt.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -504,18 +504,12 @@ acpi_ex_convert_to_string(union acpi_ope
 		}
 
 		/*
-		 * Perform the conversion.
+		 * Create a new string object and string buffer
 		 * (-1 because of extra separator included in string_length from above)
 		 */
-		string_length--;
-		if (string_length > ACPI_MAX_STRING_CONVERSION) {	/* ACPI limit */
-			return_ACPI_STATUS(AE_AML_STRING_LIMIT);
-		}
-
-		/* Create a new string object and string buffer */
-
 		return_desc =
-		    acpi_ut_create_string_object((acpi_size) string_length);
+		    acpi_ut_create_string_object((acpi_size)
+						 (string_length - 1));
 		if (!return_desc) {
 			return_ACPI_STATUS(AE_NO_MEMORY);
 		}
@@ -647,7 +641,9 @@ acpi_ex_convert_to_target_type(acpi_obje
 			break;
 
 		default:
-			ACPI_REPORT_ERROR(("Bad destination type during conversion: %X\n", destination_type));
+			ACPI_ERROR((AE_INFO,
+				    "Bad destination type during conversion: %X",
+				    destination_type));
 			status = AE_AML_INTERNAL;
 			break;
 		}
@@ -660,17 +656,13 @@ acpi_ex_convert_to_target_type(acpi_obje
 		break;
 
 	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Unknown Target type ID 0x%X Op %s dest_type %s\n",
-				  GET_CURRENT_ARG_TYPE(walk_state->op_info->
-						       runtime_args),
-				  walk_state->op_info->name,
-				  acpi_ut_get_type_name(destination_type)));
-
-		ACPI_REPORT_ERROR(("Bad Target Type (ARGI): %X\n",
-				   GET_CURRENT_ARG_TYPE(walk_state->op_info->
-							runtime_args)))
-		    status = AE_AML_INTERNAL;
+		ACPI_ERROR((AE_INFO,
+			    "Unknown Target type ID 0x%X aml_opcode %X dest_type %s",
+			    GET_CURRENT_ARG_TYPE(walk_state->op_info->
+						 runtime_args),
+			    walk_state->opcode,
+			    acpi_ut_get_type_name(destination_type)));
+		status = AE_AML_INTERNAL;
 	}
 
 	/*
diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c
index 91c4918..6805754 100644
--- a/drivers/acpi/executer/excreate.c
+++ b/drivers/acpi/executer/excreate.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -300,8 +300,8 @@ acpi_ex_create_region(u8 * aml_start,
 	 */
 	if ((region_space >= ACPI_NUM_PREDEFINED_REGIONS) &&
 	    (region_space < ACPI_USER_REGION_BEGIN)) {
-		ACPI_REPORT_ERROR(("Invalid address_space type %X\n",
-				   region_space));
+		ACPI_ERROR((AE_INFO, "Invalid address_space type %X",
+			    region_space));
 		return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID);
 	}
 
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c
index bc2fa99..a7cca8d 100644
--- a/drivers/acpi/executer/exdump.c
+++ b/drivers/acpi/executer/exdump.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -55,20 +55,386 @@ ACPI_MODULE_NAME("exdump")
  */
 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
 /* Local prototypes */
-#ifdef ACPI_FUTURE_USAGE
 static void acpi_ex_out_string(char *title, char *value);
 
 static void acpi_ex_out_pointer(char *title, void *value);
 
-static void acpi_ex_out_integer(char *title, u32 value);
-
 static void acpi_ex_out_address(char *title, acpi_physical_address value);
 
-static void acpi_ex_dump_reference(union acpi_operand_object *obj_desc);
+static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc);
 
 static void
-acpi_ex_dump_package(union acpi_operand_object *obj_desc, u32 level, u32 index);
-#endif				/* ACPI_FUTURE_USAGE */
+acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc,
+			 u32 level, u32 index);
+
+/*******************************************************************************
+ *
+ * Object Descriptor info tables
+ *
+ * Note: The first table entry must be an INIT opcode and must contain
+ * the table length (number of table entries)
+ *
+ ******************************************************************************/
+
+static struct acpi_exdump_info acpi_ex_dump_integer[2] = {
+	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_integer), NULL},
+	{ACPI_EXD_UINT64, ACPI_EXD_OFFSET(integer.value), "Value"}
+};
+
+static struct acpi_exdump_info acpi_ex_dump_string[4] = {
+	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_string), NULL},
+	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(string.length), "Length"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(string.pointer), "Pointer"},
+	{ACPI_EXD_STRING, 0, NULL}
+};
+
+static struct acpi_exdump_info acpi_ex_dump_buffer[4] = {
+	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_buffer), NULL},
+	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(buffer.length), "Length"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer.pointer), "Pointer"},
+	{ACPI_EXD_BUFFER, 0, NULL}
+};
+
+static struct acpi_exdump_info acpi_ex_dump_package[5] = {
+	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_package), NULL},
+	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(package.flags), "Flags"},
+	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(package.count), "Elements"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(package.elements), "Element List"},
+	{ACPI_EXD_PACKAGE, 0, NULL}
+};
+
+static struct acpi_exdump_info acpi_ex_dump_device[4] = {
+	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_device), NULL},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.handler), "Handler"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.system_notify),
+	 "System Notify"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.device_notify),
+	 "Device Notify"}
+};
+
+static struct acpi_exdump_info acpi_ex_dump_event[2] = {
+	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_event), NULL},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(event.semaphore), "Semaphore"}
+};
+
+static struct acpi_exdump_info acpi_ex_dump_method[8] = {
+	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_method), NULL},
+	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count), "param_count"},
+	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.concurrency), "Concurrency"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.semaphore), "Semaphore"},
+	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.owner_id), "Owner Id"},
+	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.thread_count), "Thread Count"},
+	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(method.aml_length), "Aml Length"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.aml_start), "Aml Start"}
+};
+
+static struct acpi_exdump_info acpi_ex_dump_mutex[5] = {
+	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL},
+	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread), "Owner Thread"},
+	{ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth),
+	 "Acquire Depth"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.semaphore), "Semaphore"}
+};
+
+static struct acpi_exdump_info acpi_ex_dump_region[7] = {
+	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_region), NULL},
+	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(region.space_id), "Space Id"},
+	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(region.flags), "Flags"},
+	{ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET(region.address), "Address"},
+	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(region.length), "Length"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(region.handler), "Handler"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(region.next), "Next"}
+};
+
+static struct acpi_exdump_info acpi_ex_dump_power[5] = {
+	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_power), NULL},
+	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(power_resource.system_level),
+	 "System Level"},
+	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(power_resource.resource_order),
+	 "Resource Order"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(power_resource.system_notify),
+	 "System Notify"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(power_resource.device_notify),
+	 "Device Notify"}
+};
+
+static struct acpi_exdump_info acpi_ex_dump_processor[7] = {
+	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_processor), NULL},
+	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(processor.proc_id), "Processor ID"},
+	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(processor.length), "Length"},
+	{ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET(processor.address), "Address"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.system_notify),
+	 "System Notify"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.device_notify),
+	 "Device Notify"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.handler), "Handler"}
+};
+
+static struct acpi_exdump_info acpi_ex_dump_thermal[4] = {
+	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_thermal), NULL},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(thermal_zone.system_notify),
+	 "System Notify"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(thermal_zone.device_notify),
+	 "Device Notify"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(thermal_zone.handler), "Handler"}
+};
+
+static struct acpi_exdump_info acpi_ex_dump_buffer_field[3] = {
+	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_buffer_field), NULL},
+	{ACPI_EXD_FIELD, 0, NULL},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer_field.buffer_obj),
+	 "Buffer Object"}
+};
+
+static struct acpi_exdump_info acpi_ex_dump_region_field[3] = {
+	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_region_field), NULL},
+	{ACPI_EXD_FIELD, 0, NULL},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(field.region_obj), "Region Object"}
+};
+
+static struct acpi_exdump_info acpi_ex_dump_bank_field[5] = {
+	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_bank_field), NULL},
+	{ACPI_EXD_FIELD, 0, NULL},
+	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(bank_field.value), "Value"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(bank_field.region_obj),
+	 "Region Object"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(bank_field.bank_obj), "Bank Object"}
+};
+
+static struct acpi_exdump_info acpi_ex_dump_index_field[5] = {
+	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_bank_field), NULL},
+	{ACPI_EXD_FIELD, 0, NULL},
+	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(index_field.value), "Value"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(index_field.index_obj),
+	 "Index Object"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(index_field.data_obj), "Data Object"}
+};
+
+static struct acpi_exdump_info acpi_ex_dump_reference[7] = {
+	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_reference), NULL},
+	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(reference.target_type), "Target Type"},
+	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(reference.offset), "Offset"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.object), "Object Desc"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.node), "Node"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.where), "Where"},
+	{ACPI_EXD_REFERENCE, 0, NULL}
+};
+
+static struct acpi_exdump_info acpi_ex_dump_address_handler[6] = {
+	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_address_handler),
+	 NULL},
+	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(address_space.space_id), "Space Id"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.next), "Next"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.region_list),
+	 "Region List"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.node), "Node"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.context), "Context"}
+};
+
+static struct acpi_exdump_info acpi_ex_dump_notify[3] = {
+	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_notify), NULL},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.node), "Node"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.context), "Context"}
+};
+
+/* Miscellaneous tables */
+
+static struct acpi_exdump_info acpi_ex_dump_common[4] = {
+	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_common), NULL},
+	{ACPI_EXD_TYPE, 0, NULL},
+	{ACPI_EXD_UINT16, ACPI_EXD_OFFSET(common.reference_count),
+	 "Reference Count"},
+	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(common.flags), "Flags"}
+};
+
+static struct acpi_exdump_info acpi_ex_dump_field_common[7] = {
+	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_field_common), NULL},
+	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(common_field.field_flags),
+	 "Field Flags"},
+	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(common_field.access_byte_width),
+	 "Access Byte Width"},
+	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(common_field.bit_length),
+	 "Bit Length"},
+	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(common_field.start_field_bit_offset),
+	 "Field Bit Offset"},
+	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(common_field.base_byte_offset),
+	 "Base Byte Offset"},
+	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(common_field.node), "Parent Node"}
+};
+
+static struct acpi_exdump_info acpi_ex_dump_node[6] = {
+	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_node), NULL},
+	{ACPI_EXD_UINT8, ACPI_EXD_NSOFFSET(flags), "Flags"},
+	{ACPI_EXD_UINT8, ACPI_EXD_NSOFFSET(owner_id), "Owner Id"},
+	{ACPI_EXD_UINT16, ACPI_EXD_NSOFFSET(reference_count),
+	 "Reference Count"},
+	{ACPI_EXD_POINTER, ACPI_EXD_NSOFFSET(child), "Child List"},
+	{ACPI_EXD_POINTER, ACPI_EXD_NSOFFSET(peer), "Next Peer"}
+};
+
+/* Dispatch table, indexed by object type */
+
+static struct acpi_exdump_info *acpi_ex_dump_info[] = {
+	NULL,
+	acpi_ex_dump_integer,
+	acpi_ex_dump_string,
+	acpi_ex_dump_buffer,
+	acpi_ex_dump_package,
+	NULL,
+	acpi_ex_dump_device,
+	acpi_ex_dump_event,
+	acpi_ex_dump_method,
+	acpi_ex_dump_mutex,
+	acpi_ex_dump_region,
+	acpi_ex_dump_power,
+	acpi_ex_dump_processor,
+	acpi_ex_dump_thermal,
+	acpi_ex_dump_buffer_field,
+	NULL,
+	NULL,
+	acpi_ex_dump_region_field,
+	acpi_ex_dump_bank_field,
+	acpi_ex_dump_index_field,
+	acpi_ex_dump_reference,
+	NULL,
+	NULL,
+	acpi_ex_dump_notify,
+	acpi_ex_dump_address_handler,
+	NULL,
+	NULL,
+	NULL
+};
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_dump_object
+ *
+ * PARAMETERS:  obj_desc            - Descriptor to dump
+ *              Info                - Info table corresponding to this object
+ *                                    type
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Walk the info table for this object
+ *
+ ******************************************************************************/
+
+static void
+acpi_ex_dump_object(union acpi_operand_object *obj_desc,
+		    struct acpi_exdump_info *info)
+{
+	u8 *target;
+	char *name;
+	u8 count;
+
+	if (!info) {
+		acpi_os_printf
+		    ("ex_dump_object: Display not implemented for object type %s\n",
+		     acpi_ut_get_object_type_name(obj_desc));
+		return;
+	}
+
+	/* First table entry must contain the table length (# of table entries) */
+
+	count = info->offset;
+
+	while (count) {
+		target = ACPI_ADD_PTR(u8, obj_desc, info->offset);
+		name = info->name;
+
+		switch (info->opcode) {
+		case ACPI_EXD_INIT:
+			break;
+
+		case ACPI_EXD_TYPE:
+			acpi_ex_out_string("Type",
+					   acpi_ut_get_object_type_name
+					   (obj_desc));
+			break;
+
+		case ACPI_EXD_UINT8:
+
+			acpi_os_printf("%20s : %2.2X\n", name, *target);
+			break;
+
+		case ACPI_EXD_UINT16:
+
+			acpi_os_printf("%20s : %4.4X\n", name,
+				       ACPI_GET16(target));
+			break;
+
+		case ACPI_EXD_UINT32:
+
+			acpi_os_printf("%20s : %8.8X\n", name,
+				       ACPI_GET32(target));
+			break;
+
+		case ACPI_EXD_UINT64:
+
+			acpi_os_printf("%20s : %8.8X%8.8X\n", "Value",
+				       ACPI_FORMAT_UINT64(ACPI_GET64(target)));
+			break;
+
+		case ACPI_EXD_POINTER:
+
+			acpi_ex_out_pointer(name,
+					    *ACPI_CAST_PTR(void *, target));
+			break;
+
+		case ACPI_EXD_ADDRESS:
+
+			acpi_ex_out_address(name,
+					    *ACPI_CAST_PTR
+					    (acpi_physical_address, target));
+			break;
+
+		case ACPI_EXD_STRING:
+
+			acpi_ut_print_string(obj_desc->string.pointer,
+					     ACPI_UINT8_MAX);
+			acpi_os_printf("\n");
+			break;
+
+		case ACPI_EXD_BUFFER:
+
+			ACPI_DUMP_BUFFER(obj_desc->buffer.pointer,
+					 obj_desc->buffer.length);
+			break;
+
+		case ACPI_EXD_PACKAGE:
+
+			/* Dump the package contents */
+
+			acpi_os_printf("\nPackage Contents:\n");
+			acpi_ex_dump_package_obj(obj_desc, 0, 0);
+			break;
+
+		case ACPI_EXD_FIELD:
+
+			acpi_ex_dump_object(obj_desc,
+					    acpi_ex_dump_field_common);
+			break;
+
+		case ACPI_EXD_REFERENCE:
+
+			acpi_ex_out_string("Opcode",
+					   (acpi_ps_get_opcode_info
+					    (obj_desc->reference.opcode))->
+					   name);
+			acpi_ex_dump_reference_obj(obj_desc);
+			break;
+
+		default:
+			acpi_os_printf("**** Invalid table opcode [%X] ****\n",
+				       info->opcode);
+			return;
+		}
+
+		info++;
+		count--;
+	}
+}
 
 /*******************************************************************************
  *
@@ -214,7 +580,7 @@ void acpi_ex_dump_operand(union acpi_ope
 
 	case ACPI_TYPE_BUFFER:
 
-		acpi_os_printf("Buffer len %X @ %p \n",
+		acpi_os_printf("Buffer len %X @ %p\n",
 			       obj_desc->buffer.length,
 			       obj_desc->buffer.pointer);
 
@@ -320,17 +686,17 @@ void acpi_ex_dump_operand(union acpi_ope
 
 	case ACPI_TYPE_BUFFER_FIELD:
 
-		acpi_os_printf("buffer_field: %X bits at byte %X bit %X of \n",
+		acpi_os_printf("buffer_field: %X bits at byte %X bit %X of\n",
 			       obj_desc->buffer_field.bit_length,
 			       obj_desc->buffer_field.base_byte_offset,
 			       obj_desc->buffer_field.start_field_bit_offset);
 
 		if (!obj_desc->buffer_field.buffer_obj) {
-			ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "*NULL* \n"));
+			ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "*NULL*\n"));
 		} else
 		    if (ACPI_GET_OBJECT_TYPE(obj_desc->buffer_field.buffer_obj)
 			!= ACPI_TYPE_BUFFER) {
-			acpi_os_printf("*not a Buffer* \n");
+			acpi_os_printf("*not a Buffer*\n");
 		} else {
 			acpi_ex_dump_operand(obj_desc->buffer_field.buffer_obj,
 					     depth + 1);
@@ -441,7 +807,6 @@ acpi_ex_dump_operands(union acpi_operand
 	return;
 }
 
-#ifdef ACPI_FUTURE_USAGE
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ex_out* functions
@@ -465,11 +830,6 @@ static void acpi_ex_out_pointer(char *ti
 	acpi_os_printf("%20s : %p\n", title, value);
 }
 
-static void acpi_ex_out_integer(char *title, u32 value)
-{
-	acpi_os_printf("%20s : %.2X\n", title, value);
-}
-
 static void acpi_ex_out_address(char *title, acpi_physical_address value)
 {
 
@@ -482,16 +842,16 @@ static void acpi_ex_out_address(char *ti
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ex_dump_node
+ * FUNCTION:    acpi_ex_dump_namespace_node
  *
- * PARAMETERS:  *Node               - Descriptor to dump
+ * PARAMETERS:  Node                - Descriptor to dump
  *              Flags               - Force display if TRUE
  *
  * DESCRIPTION: Dumps the members of the given.Node
  *
  ******************************************************************************/
 
-void acpi_ex_dump_node(struct acpi_namespace_node *node, u32 flags)
+void acpi_ex_dump_namespace_node(struct acpi_namespace_node *node, u32 flags)
 {
 
 	ACPI_FUNCTION_ENTRY();
@@ -506,19 +866,17 @@ void acpi_ex_dump_node(struct acpi_names
 
 	acpi_os_printf("%20s : %4.4s\n", "Name", acpi_ut_get_node_name(node));
 	acpi_ex_out_string("Type", acpi_ut_get_type_name(node->type));
-	acpi_ex_out_integer("Flags", node->flags);
-	acpi_ex_out_integer("Owner Id", node->owner_id);
-	acpi_ex_out_integer("Reference Count", node->reference_count);
 	acpi_ex_out_pointer("Attached Object",
 			    acpi_ns_get_attached_object(node));
-	acpi_ex_out_pointer("child_list", node->child);
-	acpi_ex_out_pointer("next_peer", node->peer);
 	acpi_ex_out_pointer("Parent", acpi_ns_get_parent_node(node));
+
+	acpi_ex_dump_object(ACPI_CAST_PTR(union acpi_operand_object, node),
+			    acpi_ex_dump_node);
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ex_dump_reference
+ * FUNCTION:    acpi_ex_dump_reference_obj
  *
  * PARAMETERS:  Object              - Descriptor to dump
  *
@@ -526,14 +884,16 @@ void acpi_ex_dump_node(struct acpi_names
  *
  ******************************************************************************/
 
-static void acpi_ex_dump_reference(union acpi_operand_object *obj_desc)
+static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc)
 {
 	struct acpi_buffer ret_buf;
 	acpi_status status;
 
+	ret_buf.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+
 	if (obj_desc->reference.opcode == AML_INT_NAMEPATH_OP) {
 		acpi_os_printf("Named Object %p ", obj_desc->reference.node);
-		ret_buf.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+
 		status =
 		    acpi_ns_handle_to_pathname(obj_desc->reference.node,
 					       &ret_buf);
@@ -551,9 +911,9 @@ static void acpi_ex_dump_reference(union
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ex_dump_package
+ * FUNCTION:    acpi_ex_dump_package_obj
  *
- * PARAMETERS:  Object              - Descriptor to dump
+ * PARAMETERS:  obj_desc            - Descriptor to dump
  *              Level               - Indentation Level
  *              Index               - Package index for this object
  *
@@ -562,7 +922,8 @@ static void acpi_ex_dump_reference(union
  ******************************************************************************/
 
 static void
-acpi_ex_dump_package(union acpi_operand_object *obj_desc, u32 level, u32 index)
+acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc,
+			 u32 level, u32 index)
 {
 	u32 i;
 
@@ -608,7 +969,8 @@ acpi_ex_dump_package(union acpi_operand_
 		acpi_os_printf("[Buffer] Length %.2X = ",
 			       obj_desc->buffer.length);
 		if (obj_desc->buffer.length) {
-			acpi_ut_dump_buffer((u8 *) obj_desc->buffer.pointer,
+			acpi_ut_dump_buffer(ACPI_CAST_PTR
+					    (u8, obj_desc->buffer.pointer),
 					    obj_desc->buffer.length,
 					    DB_DWORD_DISPLAY, _COMPONENT);
 		} else {
@@ -618,19 +980,19 @@ acpi_ex_dump_package(union acpi_operand_
 
 	case ACPI_TYPE_PACKAGE:
 
-		acpi_os_printf("[Package] Contains %d Elements: \n",
+		acpi_os_printf("[Package] Contains %d Elements:\n",
 			       obj_desc->package.count);
 
 		for (i = 0; i < obj_desc->package.count; i++) {
-			acpi_ex_dump_package(obj_desc->package.elements[i],
-					     level + 1, i);
+			acpi_ex_dump_package_obj(obj_desc->package.elements[i],
+						 level + 1, i);
 		}
 		break;
 
 	case ACPI_TYPE_LOCAL_REFERENCE:
 
 		acpi_os_printf("[Object Reference] ");
-		acpi_ex_dump_reference(obj_desc);
+		acpi_ex_dump_reference_obj(obj_desc);
 		break;
 
 	default:
@@ -645,7 +1007,7 @@ acpi_ex_dump_package(union acpi_operand_
  *
  * FUNCTION:    acpi_ex_dump_object_descriptor
  *
- * PARAMETERS:  Object              - Descriptor to dump
+ * PARAMETERS:  obj_desc            - Descriptor to dump
  *              Flags               - Force display if TRUE
  *
  * DESCRIPTION: Dumps the members of the object descriptor given.
@@ -670,11 +1032,13 @@ acpi_ex_dump_object_descriptor(union acp
 	}
 
 	if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_NAMED) {
-		acpi_ex_dump_node((struct acpi_namespace_node *)obj_desc,
-				  flags);
+		acpi_ex_dump_namespace_node((struct acpi_namespace_node *)
+					    obj_desc, flags);
+
 		acpi_os_printf("\nAttached Object (%p):\n",
 			       ((struct acpi_namespace_node *)obj_desc)->
 			       object);
+
 		acpi_ex_dump_object_descriptor(((struct acpi_namespace_node *)
 						obj_desc)->object, flags);
 		return_VOID;
@@ -687,233 +1051,18 @@ acpi_ex_dump_object_descriptor(union acp
 		return_VOID;
 	}
 
-	/* Common Fields */
-
-	acpi_ex_out_string("Type", acpi_ut_get_object_type_name(obj_desc));
-	acpi_ex_out_integer("Reference Count",
-			    obj_desc->common.reference_count);
-	acpi_ex_out_integer("Flags", obj_desc->common.flags);
-
-	/* Object-specific Fields */
-
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
-	case ACPI_TYPE_INTEGER:
-
-		acpi_os_printf("%20s : %8.8X%8.8X\n", "Value",
-			       ACPI_FORMAT_UINT64(obj_desc->integer.value));
-		break;
-
-	case ACPI_TYPE_STRING:
-
-		acpi_ex_out_integer("Length", obj_desc->string.length);
-
-		acpi_os_printf("%20s : %p ", "Pointer",
-			       obj_desc->string.pointer);
-		acpi_ut_print_string(obj_desc->string.pointer, ACPI_UINT8_MAX);
-		acpi_os_printf("\n");
-		break;
-
-	case ACPI_TYPE_BUFFER:
-
-		acpi_ex_out_integer("Length", obj_desc->buffer.length);
-		acpi_ex_out_pointer("Pointer", obj_desc->buffer.pointer);
-		ACPI_DUMP_BUFFER(obj_desc->buffer.pointer,
-				 obj_desc->buffer.length);
-		break;
-
-	case ACPI_TYPE_PACKAGE:
-
-		acpi_ex_out_integer("Flags", obj_desc->package.flags);
-		acpi_ex_out_integer("Elements", obj_desc->package.count);
-		acpi_ex_out_pointer("Element List", obj_desc->package.elements);
-
-		/* Dump the package contents */
-
-		acpi_os_printf("\nPackage Contents:\n");
-		acpi_ex_dump_package(obj_desc, 0, 0);
-		break;
-
-	case ACPI_TYPE_DEVICE:
-
-		acpi_ex_out_pointer("Handler", obj_desc->device.handler);
-		acpi_ex_out_pointer("system_notify",
-				    obj_desc->device.system_notify);
-		acpi_ex_out_pointer("device_notify",
-				    obj_desc->device.device_notify);
-		break;
-
-	case ACPI_TYPE_EVENT:
-
-		acpi_ex_out_pointer("Semaphore", obj_desc->event.semaphore);
-		break;
-
-	case ACPI_TYPE_METHOD:
-
-		acpi_ex_out_integer("param_count",
-				    obj_desc->method.param_count);
-		acpi_ex_out_integer("Concurrency",
-				    obj_desc->method.concurrency);
-		acpi_ex_out_pointer("Semaphore", obj_desc->method.semaphore);
-		acpi_ex_out_integer("owner_id", obj_desc->method.owner_id);
-		acpi_ex_out_integer("aml_length", obj_desc->method.aml_length);
-		acpi_ex_out_pointer("aml_start", obj_desc->method.aml_start);
-		break;
-
-	case ACPI_TYPE_MUTEX:
-
-		acpi_ex_out_integer("sync_level", obj_desc->mutex.sync_level);
-		acpi_ex_out_pointer("owner_thread",
-				    obj_desc->mutex.owner_thread);
-		acpi_ex_out_integer("acquire_depth",
-				    obj_desc->mutex.acquisition_depth);
-		acpi_ex_out_pointer("Semaphore", obj_desc->mutex.semaphore);
-		break;
-
-	case ACPI_TYPE_REGION:
-
-		acpi_ex_out_integer("space_id", obj_desc->region.space_id);
-		acpi_ex_out_integer("Flags", obj_desc->region.flags);
-		acpi_ex_out_address("Address", obj_desc->region.address);
-		acpi_ex_out_integer("Length", obj_desc->region.length);
-		acpi_ex_out_pointer("Handler", obj_desc->region.handler);
-		acpi_ex_out_pointer("Next", obj_desc->region.next);
-		break;
-
-	case ACPI_TYPE_POWER:
-
-		acpi_ex_out_integer("system_level",
-				    obj_desc->power_resource.system_level);
-		acpi_ex_out_integer("resource_order",
-				    obj_desc->power_resource.resource_order);
-		acpi_ex_out_pointer("system_notify",
-				    obj_desc->power_resource.system_notify);
-		acpi_ex_out_pointer("device_notify",
-				    obj_desc->power_resource.device_notify);
-		break;
-
-	case ACPI_TYPE_PROCESSOR:
-
-		acpi_ex_out_integer("Processor ID",
-				    obj_desc->processor.proc_id);
-		acpi_ex_out_integer("Length", obj_desc->processor.length);
-		acpi_ex_out_address("Address",
-				    (acpi_physical_address) obj_desc->processor.
-				    address);
-		acpi_ex_out_pointer("system_notify",
-				    obj_desc->processor.system_notify);
-		acpi_ex_out_pointer("device_notify",
-				    obj_desc->processor.device_notify);
-		acpi_ex_out_pointer("Handler", obj_desc->processor.handler);
-		break;
-
-	case ACPI_TYPE_THERMAL:
-
-		acpi_ex_out_pointer("system_notify",
-				    obj_desc->thermal_zone.system_notify);
-		acpi_ex_out_pointer("device_notify",
-				    obj_desc->thermal_zone.device_notify);
-		acpi_ex_out_pointer("Handler", obj_desc->thermal_zone.handler);
-		break;
-
-	case ACPI_TYPE_BUFFER_FIELD:
-	case ACPI_TYPE_LOCAL_REGION_FIELD:
-	case ACPI_TYPE_LOCAL_BANK_FIELD:
-	case ACPI_TYPE_LOCAL_INDEX_FIELD:
-
-		acpi_ex_out_integer("field_flags",
-				    obj_desc->common_field.field_flags);
-		acpi_ex_out_integer("access_byte_width",
-				    obj_desc->common_field.access_byte_width);
-		acpi_ex_out_integer("bit_length",
-				    obj_desc->common_field.bit_length);
-		acpi_ex_out_integer("fld_bit_offset",
-				    obj_desc->common_field.
-				    start_field_bit_offset);
-		acpi_ex_out_integer("base_byte_offset",
-				    obj_desc->common_field.base_byte_offset);
-		acpi_ex_out_pointer("parent_node", obj_desc->common_field.node);
-
-		switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
-		case ACPI_TYPE_BUFFER_FIELD:
-			acpi_ex_out_pointer("buffer_obj",
-					    obj_desc->buffer_field.buffer_obj);
-			break;
-
-		case ACPI_TYPE_LOCAL_REGION_FIELD:
-			acpi_ex_out_pointer("region_obj",
-					    obj_desc->field.region_obj);
-			break;
-
-		case ACPI_TYPE_LOCAL_BANK_FIELD:
-			acpi_ex_out_integer("Value",
-					    obj_desc->bank_field.value);
-			acpi_ex_out_pointer("region_obj",
-					    obj_desc->bank_field.region_obj);
-			acpi_ex_out_pointer("bank_obj",
-					    obj_desc->bank_field.bank_obj);
-			break;
-
-		case ACPI_TYPE_LOCAL_INDEX_FIELD:
-			acpi_ex_out_integer("Value",
-					    obj_desc->index_field.value);
-			acpi_ex_out_pointer("Index",
-					    obj_desc->index_field.index_obj);
-			acpi_ex_out_pointer("Data",
-					    obj_desc->index_field.data_obj);
-			break;
-
-		default:
-			/* All object types covered above */
-			break;
-		}
-		break;
-
-	case ACPI_TYPE_LOCAL_REFERENCE:
-
-		acpi_ex_out_integer("target_type",
-				    obj_desc->reference.target_type);
-		acpi_ex_out_string("Opcode",
-				   (acpi_ps_get_opcode_info
-				    (obj_desc->reference.opcode))->name);
-		acpi_ex_out_integer("Offset", obj_desc->reference.offset);
-		acpi_ex_out_pointer("obj_desc", obj_desc->reference.object);
-		acpi_ex_out_pointer("Node", obj_desc->reference.node);
-		acpi_ex_out_pointer("Where", obj_desc->reference.where);
-
-		acpi_ex_dump_reference(obj_desc);
-		break;
-
-	case ACPI_TYPE_LOCAL_ADDRESS_HANDLER:
-
-		acpi_ex_out_integer("space_id",
-				    obj_desc->address_space.space_id);
-		acpi_ex_out_pointer("Next", obj_desc->address_space.next);
-		acpi_ex_out_pointer("region_list",
-				    obj_desc->address_space.region_list);
-		acpi_ex_out_pointer("Node", obj_desc->address_space.node);
-		acpi_ex_out_pointer("Context", obj_desc->address_space.context);
-		break;
-
-	case ACPI_TYPE_LOCAL_NOTIFY:
+	if (obj_desc->common.type > ACPI_TYPE_NS_NODE_MAX) {
+		return_VOID;
+	}
 
-		acpi_ex_out_pointer("Node", obj_desc->notify.node);
-		acpi_ex_out_pointer("Context", obj_desc->notify.context);
-		break;
+	/* Common Fields */
 
-	case ACPI_TYPE_LOCAL_ALIAS:
-	case ACPI_TYPE_LOCAL_METHOD_ALIAS:
-	case ACPI_TYPE_LOCAL_EXTRA:
-	case ACPI_TYPE_LOCAL_DATA:
-	default:
+	acpi_ex_dump_object(obj_desc, acpi_ex_dump_common);
 
-		acpi_os_printf
-		    ("ex_dump_object_descriptor: Display not implemented for object type %s\n",
-		     acpi_ut_get_object_type_name(obj_desc));
-		break;
-	}
+	/* Object-specific fields */
 
+	acpi_ex_dump_object(obj_desc, acpi_ex_dump_info[obj_desc->common.type]);
 	return_VOID;
 }
 
-#endif				/*  ACPI_FUTURE_USAGE  */
 #endif
diff --git a/drivers/acpi/executer/exfield.c b/drivers/acpi/executer/exfield.c
index ab1ba39..e259201 100644
--- a/drivers/acpi/executer/exfield.c
+++ b/drivers/acpi/executer/exfield.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -249,13 +249,18 @@ acpi_ex_write_data_to_field(union acpi_o
 		 * Source must be a buffer of sufficient size (ACPI_SMBUS_BUFFER_SIZE).
 		 */
 		if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) {
-			ACPI_REPORT_ERROR(("SMBus write requires Buffer, found type %s\n", acpi_ut_get_object_type_name(source_desc)));
+			ACPI_ERROR((AE_INFO,
+				    "SMBus write requires Buffer, found type %s",
+				    acpi_ut_get_object_type_name(source_desc)));
 
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 		}
 
 		if (source_desc->buffer.length < ACPI_SMBUS_BUFFER_SIZE) {
-			ACPI_REPORT_ERROR(("SMBus write requires Buffer of length %X, found length %X\n", ACPI_SMBUS_BUFFER_SIZE, source_desc->buffer.length));
+			ACPI_ERROR((AE_INFO,
+				    "SMBus write requires Buffer of length %X, found length %X",
+				    ACPI_SMBUS_BUFFER_SIZE,
+				    source_desc->buffer.length));
 
 			return_ACPI_STATUS(AE_AML_BUFFER_LIMIT);
 		}
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c
index ba6e088..bd1af35 100644
--- a/drivers/acpi/executer/exfldio.c
+++ b/drivers/acpi/executer/exfldio.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -94,10 +94,9 @@ acpi_ex_setup_region(union acpi_operand_
 	/* We must have a valid region */
 
 	if (ACPI_GET_OBJECT_TYPE(rgn_desc) != ACPI_TYPE_REGION) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Needed Region, found type %X (%s)\n",
-				  ACPI_GET_OBJECT_TYPE(rgn_desc),
-				  acpi_ut_get_object_type_name(rgn_desc)));
+		ACPI_ERROR((AE_INFO, "Needed Region, found type %X (%s)",
+			    ACPI_GET_OBJECT_TYPE(rgn_desc),
+			    acpi_ut_get_object_type_name(rgn_desc)));
 
 		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 	}
@@ -162,31 +161,28 @@ acpi_ex_setup_region(union acpi_operand_
 			 * than the region itself.  For example, a region of length one
 			 * byte, and a field with Dword access specified.
 			 */
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)\n",
-					  acpi_ut_get_node_name(obj_desc->
-								common_field.
-								node),
-					  obj_desc->common_field.
-					  access_byte_width,
-					  acpi_ut_get_node_name(rgn_desc->
-								region.node),
-					  rgn_desc->region.length));
+			ACPI_ERROR((AE_INFO,
+				    "Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)",
+				    acpi_ut_get_node_name(obj_desc->
+							  common_field.node),
+				    obj_desc->common_field.access_byte_width,
+				    acpi_ut_get_node_name(rgn_desc->region.
+							  node),
+				    rgn_desc->region.length));
 		}
 
 		/*
 		 * Offset rounded up to next multiple of field width
 		 * exceeds region length, indicate an error
 		 */
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Field [%4.4s] Base+Offset+Width %X+%X+%X is beyond end of region [%4.4s] (length %X)\n",
-				  acpi_ut_get_node_name(obj_desc->common_field.
-							node),
-				  obj_desc->common_field.base_byte_offset,
-				  field_datum_byte_offset,
-				  obj_desc->common_field.access_byte_width,
-				  acpi_ut_get_node_name(rgn_desc->region.node),
-				  rgn_desc->region.length));
+		ACPI_ERROR((AE_INFO,
+			    "Field [%4.4s] Base+Offset+Width %X+%X+%X is beyond end of region [%4.4s] (length %X)",
+			    acpi_ut_get_node_name(obj_desc->common_field.node),
+			    obj_desc->common_field.base_byte_offset,
+			    field_datum_byte_offset,
+			    obj_desc->common_field.access_byte_width,
+			    acpi_ut_get_node_name(rgn_desc->region.node),
+			    rgn_desc->region.length));
 
 		return_ACPI_STATUS(AE_AML_REGION_LIMIT);
 	}
@@ -270,18 +266,17 @@ acpi_ex_access_region(union acpi_operand
 
 	if (ACPI_FAILURE(status)) {
 		if (status == AE_NOT_IMPLEMENTED) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Region %s(%X) not implemented\n",
-					  acpi_ut_get_region_name(rgn_desc->
-								  region.
-								  space_id),
-					  rgn_desc->region.space_id));
+			ACPI_ERROR((AE_INFO,
+				    "Region %s(%X) not implemented",
+				    acpi_ut_get_region_name(rgn_desc->region.
+							    space_id),
+				    rgn_desc->region.space_id));
 		} else if (status == AE_NOT_EXIST) {
-			ACPI_REPORT_ERROR(("Region %s(%X) has no handler\n",
-					   acpi_ut_get_region_name(rgn_desc->
-								   region.
-								   space_id),
-					   rgn_desc->region.space_id));
+			ACPI_ERROR((AE_INFO,
+				    "Region %s(%X) has no handler",
+				    acpi_ut_get_region_name(rgn_desc->region.
+							    space_id),
+				    rgn_desc->region.space_id));
 		}
 	}
 
@@ -514,8 +509,8 @@ acpi_ex_field_datum_io(union acpi_operan
 
 	default:
 
-		ACPI_REPORT_ERROR(("Wrong object type in field I/O %X\n",
-				   ACPI_GET_OBJECT_TYPE(obj_desc)));
+		ACPI_ERROR((AE_INFO, "Wrong object type in field I/O %X",
+			    ACPI_GET_OBJECT_TYPE(obj_desc)));
 		status = AE_AML_INTERNAL;
 		break;
 	}
@@ -618,11 +613,11 @@ acpi_ex_write_with_update_rule(union acp
 
 		default:
 
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "write_with_update_rule: Unknown update_rule setting: %X\n",
-					  (obj_desc->common_field.
-					   field_flags &
-					   AML_FIELD_UPDATE_RULE_MASK)));
+			ACPI_ERROR((AE_INFO,
+				    "Unknown update_rule value: %X",
+				    (obj_desc->common_field.
+				     field_flags &
+				     AML_FIELD_UPDATE_RULE_MASK)));
 			return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
 		}
 	}
@@ -677,10 +672,9 @@ acpi_ex_extract_from_field(union acpi_op
 
 	if (buffer_length <
 	    ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Field size %X (bits) is too large for buffer (%X)\n",
-				  obj_desc->common_field.bit_length,
-				  buffer_length));
+		ACPI_ERROR((AE_INFO,
+			    "Field size %X (bits) is too large for buffer (%X)",
+			    obj_desc->common_field.bit_length, buffer_length));
 
 		return_ACPI_STATUS(AE_BUFFER_OVERFLOW);
 	}
@@ -792,10 +786,9 @@ acpi_ex_insert_into_field(union acpi_ope
 
 	if (buffer_length <
 	    ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Field size %X (bits) is too large for buffer (%X)\n",
-				  obj_desc->common_field.bit_length,
-				  buffer_length));
+		ACPI_ERROR((AE_INFO,
+			    "Field size %X (bits) is too large for buffer (%X)",
+			    obj_desc->common_field.bit_length, buffer_length));
 
 		return_ACPI_STATUS(AE_BUFFER_OVERFLOW);
 	}
diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c
index a3f4d72..48c18d2 100644
--- a/drivers/acpi/executer/exmisc.c
+++ b/drivers/acpi/executer/exmisc.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -45,6 +45,7 @@
 #include <acpi/acpi.h>
 #include <acpi/acinterp.h>
 #include <acpi/amlcode.h>
+#include <acpi/amlresrc.h>
 
 #define _COMPONENT          ACPI_EXECUTER
 ACPI_MODULE_NAME("exmisc")
@@ -97,7 +98,8 @@ acpi_ex_get_object_reference(union acpi_
 
 		default:
 
-			ACPI_REPORT_ERROR(("Unknown Reference opcode in get_reference %X\n", obj_desc->reference.opcode));
+			ACPI_ERROR((AE_INFO, "Unknown Reference opcode %X",
+				    obj_desc->reference.opcode));
 			return_ACPI_STATUS(AE_AML_INTERNAL);
 		}
 		break;
@@ -112,7 +114,8 @@ acpi_ex_get_object_reference(union acpi_
 
 	default:
 
-		ACPI_REPORT_ERROR(("Invalid descriptor type in get_reference: %X\n", ACPI_GET_DESCRIPTOR_TYPE(obj_desc)));
+		ACPI_ERROR((AE_INFO, "Invalid descriptor type %X",
+			    ACPI_GET_DESCRIPTOR_TYPE(obj_desc)));
 		return_ACPI_STATUS(AE_TYPE);
 	}
 
@@ -157,48 +160,65 @@ acpi_ex_concat_template(union acpi_opera
 			union acpi_operand_object **actual_return_desc,
 			struct acpi_walk_state *walk_state)
 {
+	acpi_status status;
 	union acpi_operand_object *return_desc;
 	u8 *new_buf;
-	u8 *end_tag1;
-	u8 *end_tag2;
+	u8 *end_tag;
+	acpi_size length0;
 	acpi_size length1;
-	acpi_size length2;
+	acpi_size new_length;
 
 	ACPI_FUNCTION_TRACE("ex_concat_template");
 
-	/* Find the end_tags in each resource template */
+	/*
+	 * Find the end_tag descriptor in each resource template.
+	 * Note1: returned pointers point TO the end_tag, not past it.
+	 * Note2: zero-length buffers are allowed; treated like one end_tag
+	 */
+
+	/* Get the length of the first resource template */
 
-	end_tag1 = acpi_ut_get_resource_end_tag(operand0);
-	end_tag2 = acpi_ut_get_resource_end_tag(operand1);
-	if (!end_tag1 || !end_tag2) {
-		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
+	status = acpi_ut_get_resource_end_tag(operand0, &end_tag);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
 	}
 
-	/* Compute the length of each part */
+	length0 = ACPI_PTR_DIFF(end_tag, operand0->buffer.pointer);
+
+	/* Get the length of the second resource template */
+
+	status = acpi_ut_get_resource_end_tag(operand1, &end_tag);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
 
-	length1 = ACPI_PTR_DIFF(end_tag1, operand0->buffer.pointer);
-	length2 = ACPI_PTR_DIFF(end_tag2, operand1->buffer.pointer) + 2;	/* Size of END_TAG */
+	length1 = ACPI_PTR_DIFF(end_tag, operand1->buffer.pointer);
 
-	/* Create a new buffer object for the result */
+	/* Combine both lengths, minimum size will be 2 for end_tag */
 
-	return_desc = acpi_ut_create_buffer_object(length1 + length2);
+	new_length = length0 + length1 + sizeof(struct aml_resource_end_tag);
+
+	/* Create a new buffer object for the result (with one end_tag) */
+
+	return_desc = acpi_ut_create_buffer_object(new_length);
 	if (!return_desc) {
 		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
 
-	/* Copy the templates to the new descriptor */
-
+	/*
+	 * Copy the templates to the new buffer, 0 first, then 1 follows. One
+	 * end_tag descriptor is copied from Operand1.
+	 */
 	new_buf = return_desc->buffer.pointer;
-	ACPI_MEMCPY(new_buf, operand0->buffer.pointer, length1);
-	ACPI_MEMCPY(new_buf + length1, operand1->buffer.pointer, length2);
+	ACPI_MEMCPY(new_buf, operand0->buffer.pointer, length0);
+	ACPI_MEMCPY(new_buf + length0, operand1->buffer.pointer, length1);
 
-	/* Compute the new checksum */
+	/* Insert end_tag and set the checksum to zero, means "ignore checksum" */
 
-	new_buf[return_desc->buffer.length - 1] =
-	    acpi_ut_generate_checksum(return_desc->buffer.pointer,
-				      (return_desc->buffer.length - 1));
+	new_buf[new_length - 1] = 0;
+	new_buf[new_length - 2] = ACPI_RESOURCE_NAME_END_TAG | 1;
 
-	/* Return the completed template descriptor */
+	/* Return the completed resource template */
 
 	*actual_return_desc = return_desc;
 	return_ACPI_STATUS(AE_OK);
@@ -229,7 +249,6 @@ acpi_ex_do_concatenate(union acpi_operan
 	union acpi_operand_object *return_desc;
 	char *new_buf;
 	acpi_status status;
-	acpi_size new_length;
 
 	ACPI_FUNCTION_TRACE("ex_do_concatenate");
 
@@ -256,8 +275,8 @@ acpi_ex_do_concatenate(union acpi_operan
 		break;
 
 	default:
-		ACPI_REPORT_ERROR(("Concat - invalid obj type: %X\n",
-				   ACPI_GET_OBJECT_TYPE(operand0)));
+		ACPI_ERROR((AE_INFO, "Invalid object type: %X",
+			    ACPI_GET_OBJECT_TYPE(operand0)));
 		status = AE_AML_INTERNAL;
 	}
 
@@ -296,8 +315,7 @@ acpi_ex_do_concatenate(union acpi_operan
 
 		/* Copy the first integer, LSB first */
 
-		ACPI_MEMCPY(new_buf,
-			    &operand0->integer.value,
+		ACPI_MEMCPY(new_buf, &operand0->integer.value,
 			    acpi_gbl_integer_byte_width);
 
 		/* Copy the second integer (LSB first) after the first */
@@ -311,14 +329,11 @@ acpi_ex_do_concatenate(union acpi_operan
 
 		/* Result of two Strings is a String */
 
-		new_length = (acpi_size) operand0->string.length +
-		    (acpi_size) local_operand1->string.length;
-		if (new_length > ACPI_MAX_STRING_CONVERSION) {
-			status = AE_AML_STRING_LIMIT;
-			goto cleanup;
-		}
-
-		return_desc = acpi_ut_create_string_object(new_length);
+		return_desc = acpi_ut_create_string_object((acpi_size)
+							   (operand0->string.
+							    length +
+							    local_operand1->
+							    string.length));
 		if (!return_desc) {
 			status = AE_NO_MEMORY;
 			goto cleanup;
@@ -338,11 +353,10 @@ acpi_ex_do_concatenate(union acpi_operan
 		/* Result of two Buffers is a Buffer */
 
 		return_desc = acpi_ut_create_buffer_object((acpi_size)
-							   operand0->buffer.
-							   length +
-							   (acpi_size)
-							   local_operand1->
-							   buffer.length);
+							   (operand0->buffer.
+							    length +
+							    local_operand1->
+							    buffer.length));
 		if (!return_desc) {
 			status = AE_NO_MEMORY;
 			goto cleanup;
@@ -352,8 +366,8 @@ acpi_ex_do_concatenate(union acpi_operan
 
 		/* Concatenate the buffers */
 
-		ACPI_MEMCPY(new_buf,
-			    operand0->buffer.pointer, operand0->buffer.length);
+		ACPI_MEMCPY(new_buf, operand0->buffer.pointer,
+			    operand0->buffer.length);
 		ACPI_MEMCPY(new_buf + operand0->buffer.length,
 			    local_operand1->buffer.pointer,
 			    local_operand1->buffer.length);
@@ -363,8 +377,8 @@ acpi_ex_do_concatenate(union acpi_operan
 
 		/* Invalid object type, should not happen here */
 
-		ACPI_REPORT_ERROR(("Concatenate - Invalid object type: %X\n",
-				   ACPI_GET_OBJECT_TYPE(operand0)));
+		ACPI_ERROR((AE_INFO, "Invalid object type: %X",
+			    ACPI_GET_OBJECT_TYPE(operand0)));
 		status = AE_AML_INTERNAL;
 		goto cleanup;
 	}
@@ -625,9 +639,8 @@ acpi_ex_do_logical_op(u16 opcode,
 
 		/* Lexicographic compare: compare the data bytes */
 
-		compare = ACPI_MEMCMP((const char *)operand0->buffer.pointer,
-				      (const char *)local_operand1->buffer.
-				      pointer,
+		compare = ACPI_MEMCMP(operand0->buffer.pointer,
+				      local_operand1->buffer.pointer,
 				      (length0 > length1) ? length1 : length0);
 
 		switch (opcode) {
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
index ab47f6d..f843b22 100644
--- a/drivers/acpi/executer/exmutex.c
+++ b/drivers/acpi/executer/exmutex.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -153,7 +153,9 @@ acpi_ex_acquire_mutex(union acpi_operand
 	/* Sanity check -- we must have a valid thread ID */
 
 	if (!walk_state->thread) {
-		ACPI_REPORT_ERROR(("Cannot acquire Mutex [%4.4s], null thread info\n", acpi_ut_get_node_name(obj_desc->mutex.node)));
+		ACPI_ERROR((AE_INFO,
+			    "Cannot acquire Mutex [%4.4s], null thread info",
+			    acpi_ut_get_node_name(obj_desc->mutex.node)));
 		return_ACPI_STATUS(AE_AML_INTERNAL);
 	}
 
@@ -162,7 +164,9 @@ acpi_ex_acquire_mutex(union acpi_operand
 	 * mutex.  This mechanism provides some deadlock prevention
 	 */
 	if (walk_state->thread->current_sync_level > obj_desc->mutex.sync_level) {
-		ACPI_REPORT_ERROR(("Cannot acquire Mutex [%4.4s], incorrect sync_level\n", acpi_ut_get_node_name(obj_desc->mutex.node)));
+		ACPI_ERROR((AE_INFO,
+			    "Cannot acquire Mutex [%4.4s], incorrect sync_level",
+			    acpi_ut_get_node_name(obj_desc->mutex.node)));
 		return_ACPI_STATUS(AE_AML_MUTEX_ORDER);
 	}
 
@@ -237,14 +241,18 @@ acpi_ex_release_mutex(union acpi_operand
 	/* The mutex must have been previously acquired in order to release it */
 
 	if (!obj_desc->mutex.owner_thread) {
-		ACPI_REPORT_ERROR(("Cannot release Mutex [%4.4s], not acquired\n", acpi_ut_get_node_name(obj_desc->mutex.node)));
+		ACPI_ERROR((AE_INFO,
+			    "Cannot release Mutex [%4.4s], not acquired",
+			    acpi_ut_get_node_name(obj_desc->mutex.node)));
 		return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED);
 	}
 
 	/* Sanity check -- we must have a valid thread ID */
 
 	if (!walk_state->thread) {
-		ACPI_REPORT_ERROR(("Cannot release Mutex [%4.4s], null thread info\n", acpi_ut_get_node_name(obj_desc->mutex.node)));
+		ACPI_ERROR((AE_INFO,
+			    "Cannot release Mutex [%4.4s], null thread info",
+			    acpi_ut_get_node_name(obj_desc->mutex.node)));
 		return_ACPI_STATUS(AE_AML_INTERNAL);
 	}
 
@@ -255,7 +263,11 @@ acpi_ex_release_mutex(union acpi_operand
 	if ((obj_desc->mutex.owner_thread->thread_id !=
 	     walk_state->thread->thread_id)
 	    && (obj_desc->mutex.semaphore != acpi_gbl_global_lock_semaphore)) {
-		ACPI_REPORT_ERROR(("Thread %X cannot release Mutex [%4.4s] acquired by thread %X\n", walk_state->thread->thread_id, acpi_ut_get_node_name(obj_desc->mutex.node), obj_desc->mutex.owner_thread->thread_id));
+		ACPI_ERROR((AE_INFO,
+			    "Thread %X cannot release Mutex [%4.4s] acquired by thread %X",
+			    walk_state->thread->thread_id,
+			    acpi_ut_get_node_name(obj_desc->mutex.node),
+			    obj_desc->mutex.owner_thread->thread_id));
 		return_ACPI_STATUS(AE_AML_NOT_OWNER);
 	}
 
@@ -264,7 +276,9 @@ acpi_ex_release_mutex(union acpi_operand
 	 * equal to the current sync level
 	 */
 	if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) {
-		ACPI_REPORT_ERROR(("Cannot release Mutex [%4.4s], incorrect sync_level\n", acpi_ut_get_node_name(obj_desc->mutex.node)));
+		ACPI_ERROR((AE_INFO,
+			    "Cannot release Mutex [%4.4s], incorrect sync_level",
+			    acpi_ut_get_node_name(obj_desc->mutex.node)));
 		return_ACPI_STATUS(AE_AML_MUTEX_ORDER);
 	}
 
diff --git a/drivers/acpi/executer/exnames.c b/drivers/acpi/executer/exnames.c
index 239d847..054fe5e 100644
--- a/drivers/acpi/executer/exnames.c
+++ b/drivers/acpi/executer/exnames.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -99,7 +99,8 @@ static char *acpi_ex_allocate_name_strin
 	 */
 	name_string = ACPI_MEM_ALLOCATE(size_needed);
 	if (!name_string) {
-		ACPI_REPORT_ERROR(("ex_allocate_name_string: Could not allocate size %d\n", size_needed));
+		ACPI_ERROR((AE_INFO,
+			    "Could not allocate size %d", size_needed));
 		return_PTR(NULL);
 	}
 
@@ -167,8 +168,7 @@ static acpi_status acpi_ex_name_segment(
 	char_buf[0] = *aml_address;
 
 	if ('0' <= char_buf[0] && char_buf[0] <= '9') {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "leading digit: %c\n",
-				  char_buf[0]));
+		ACPI_ERROR((AE_INFO, "Invalid leading digit: %c", char_buf[0]));
 		return_ACPI_STATUS(AE_CTRL_PENDING);
 	}
 
@@ -191,10 +191,10 @@ static acpi_status acpi_ex_name_segment(
 		if (name_string) {
 			ACPI_STRCAT(name_string, char_buf);
 			ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
-					  "Appended to - %s \n", name_string));
+					  "Appended to - %s\n", name_string));
 		} else {
 			ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
-					  "No Name string - %s \n", char_buf));
+					  "No Name string - %s\n", char_buf));
 		}
 	} else if (index == 0) {
 		/*
@@ -211,12 +211,12 @@ static acpi_status acpi_ex_name_segment(
 		 * the required 4
 		 */
 		status = AE_AML_BAD_NAME;
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Bad character %02x in name, at %p\n",
-				  *aml_address, aml_address));
+		ACPI_ERROR((AE_INFO,
+			    "Bad character %02x in name, at %p",
+			    *aml_address, aml_address));
 	}
 
-	*in_aml_address = (u8 *) aml_address;
+	*in_aml_address = ACPI_CAST_PTR(u8, aml_address);
 	return_ACPI_STATUS(status);
 }
 
@@ -412,8 +412,7 @@ acpi_ex_get_name_string(acpi_object_type
 	if (AE_CTRL_PENDING == status && has_prefix) {
 		/* Ran out of segments after processing a prefix */
 
-		ACPI_REPORT_ERROR(("ex_do_name: Malformed Name at %p\n",
-				   name_string));
+		ACPI_ERROR((AE_INFO, "Malformed Name at %p", name_string));
 		status = AE_AML_BAD_NAME;
 	}
 
diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c
index 97e3454..23d0823 100644
--- a/drivers/acpi/executer/exoparg1.c
+++ b/drivers/acpi/executer/exoparg1.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -111,7 +111,8 @@ acpi_status acpi_ex_opcode_0A_0T_1R(stru
 
 	default:		/*  Unknown opcode  */
 
-		ACPI_REPORT_ERROR(("acpi_ex_opcode_0A_0T_1R: Unknown opcode %X\n", walk_state->opcode));
+		ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
+			    walk_state->opcode));
 		status = AE_AML_BAD_OPCODE;
 		break;
 	}
@@ -188,7 +189,8 @@ acpi_status acpi_ex_opcode_1A_0T_0R(stru
 
 	default:		/*  Unknown opcode  */
 
-		ACPI_REPORT_ERROR(("acpi_ex_opcode_1A_0T_0R: Unknown opcode %X\n", walk_state->opcode));
+		ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
+			    walk_state->opcode));
 		status = AE_AML_BAD_OPCODE;
 		break;
 	}
@@ -227,7 +229,8 @@ acpi_status acpi_ex_opcode_1A_1T_0R(stru
 
 	default:		/* Unknown opcode */
 
-		ACPI_REPORT_ERROR(("acpi_ex_opcode_1A_1T_0R: Unknown opcode %X\n", walk_state->opcode));
+		ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
+			    walk_state->opcode));
 		status = AE_AML_BAD_OPCODE;
 		goto cleanup;
 	}
@@ -346,9 +349,9 @@ acpi_status acpi_ex_opcode_1A_1T_1R(stru
 				/* Check the range of the digit */
 
 				if (temp32 > 9) {
-					ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-							  "BCD digit too large (not decimal): 0x%X\n",
-							  temp32));
+					ACPI_ERROR((AE_INFO,
+						    "BCD digit too large (not decimal): 0x%X",
+						    temp32));
 
 					status = AE_AML_NUMERIC_OVERFLOW;
 					goto cleanup;
@@ -393,12 +396,10 @@ acpi_status acpi_ex_opcode_1A_1T_1R(stru
 			/* Overflow if there is any data left in Digit */
 
 			if (digit > 0) {
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "Integer too large to convert to BCD: %8.8X%8.8X\n",
-						  ACPI_FORMAT_UINT64(operand
-								     [0]->
-								     integer.
-								     value)));
+				ACPI_ERROR((AE_INFO,
+					    "Integer too large to convert to BCD: %8.8X%8.8X",
+					    ACPI_FORMAT_UINT64(operand[0]->
+							       integer.value)));
 				status = AE_AML_NUMERIC_OVERFLOW;
 				goto cleanup;
 			}
@@ -525,15 +526,16 @@ acpi_status acpi_ex_opcode_1A_1T_1R(stru
 
 		/* These are two obsolete opcodes */
 
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "%s is obsolete and not implemented\n",
-				  acpi_ps_get_opcode_name(walk_state->opcode)));
+		ACPI_ERROR((AE_INFO,
+			    "%s is obsolete and not implemented",
+			    acpi_ps_get_opcode_name(walk_state->opcode)));
 		status = AE_SUPPORT;
 		goto cleanup;
 
 	default:		/* Unknown opcode */
 
-		ACPI_REPORT_ERROR(("acpi_ex_opcode_1A_1T_1R: Unknown opcode %X\n", walk_state->opcode));
+		ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
+			    walk_state->opcode));
 		status = AE_AML_BAD_OPCODE;
 		goto cleanup;
 	}
@@ -639,11 +641,10 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 		    acpi_ex_resolve_operands(AML_LNOT_OP, &temp_desc,
 					     walk_state);
 		if (ACPI_FAILURE(status)) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "%s: bad operand(s) %s\n",
-					  acpi_ps_get_opcode_name(walk_state->
-								  opcode),
-					  acpi_format_exception(status)));
+			ACPI_EXCEPTION((AE_INFO, status,
+					"While resolving operands for [%s]",
+					acpi_ps_get_opcode_name(walk_state->
+								opcode)));
 
 			goto cleanup;
 		}
@@ -742,9 +743,9 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 			break;
 
 		default:
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "size_of - Operand is not Buf/Int/Str/Pkg - found type %s\n",
-					  acpi_ut_get_type_name(type)));
+			ACPI_ERROR((AE_INFO,
+				    "Operand is not Buf/Int/Str/Pkg - found type %s",
+				    acpi_ut_get_type_name(type)));
 			status = AE_AML_OPERAND_TYPE;
 			goto cleanup;
 		}
@@ -941,11 +942,10 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 
 				default:
 
-					ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-							  "Unknown Index target_type %X in obj %p\n",
-							  operand[0]->reference.
-							  target_type,
-							  operand[0]));
+					ACPI_ERROR((AE_INFO,
+						    "Unknown Index target_type %X in obj %p",
+						    operand[0]->reference.
+						    target_type, operand[0]));
 					status = AE_AML_OPERAND_TYPE;
 					goto cleanup;
 				}
@@ -971,11 +971,10 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 				break;
 
 			default:
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "Unknown opcode in ref(%p) - %X\n",
-						  operand[0],
-						  operand[0]->reference.
-						  opcode));
+				ACPI_ERROR((AE_INFO,
+					    "Unknown opcode in ref(%p) - %X",
+					    operand[0],
+					    operand[0]->reference.opcode));
 
 				status = AE_TYPE;
 				goto cleanup;
@@ -985,7 +984,8 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 
 	default:
 
-		ACPI_REPORT_ERROR(("acpi_ex_opcode_1A_0T_1R: Unknown opcode %X\n", walk_state->opcode));
+		ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
+			    walk_state->opcode));
 		status = AE_AML_BAD_OPCODE;
 		goto cleanup;
 	}
diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c
index 8d70c6b..e263a5d 100644
--- a/drivers/acpi/executer/exoparg2.c
+++ b/drivers/acpi/executer/exoparg2.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -111,9 +111,9 @@ acpi_status acpi_ex_opcode_2A_0T_0R(stru
 		/* Are notifies allowed on this object? */
 
 		if (!acpi_ev_is_notify_object(node)) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Unexpected notify object type [%s]\n",
-					  acpi_ut_get_type_name(node->type)));
+			ACPI_ERROR((AE_INFO,
+				    "Unexpected notify object type [%s]",
+				    acpi_ut_get_type_name(node->type)));
 
 			status = AE_AML_OPERAND_TYPE;
 			break;
@@ -157,7 +157,8 @@ acpi_status acpi_ex_opcode_2A_0T_0R(stru
 
 	default:
 
-		ACPI_REPORT_ERROR(("acpi_ex_opcode_2A_0T_0R: Unknown opcode %X\n", walk_state->opcode));
+		ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
+			    walk_state->opcode));
 		status = AE_AML_BAD_OPCODE;
 	}
 
@@ -221,7 +222,8 @@ acpi_status acpi_ex_opcode_2A_2T_1R(stru
 
 	default:
 
-		ACPI_REPORT_ERROR(("acpi_ex_opcode_2A_2T_1R: Unknown opcode %X\n", walk_state->opcode));
+		ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
+			    walk_state->opcode));
 		status = AE_AML_BAD_OPCODE;
 		goto cleanup;
 	}
@@ -344,10 +346,6 @@ acpi_status acpi_ex_opcode_2A_1T_1R(stru
 		       (length < operand[1]->integer.value) &&
 		       (operand[0]->buffer.pointer[length])) {
 			length++;
-			if (length > ACPI_MAX_STRING_CONVERSION) {
-				status = AE_AML_STRING_LIMIT;
-				goto cleanup;
-			}
 		}
 
 		/* Allocate a new string object */
@@ -358,8 +356,10 @@ acpi_status acpi_ex_opcode_2A_1T_1R(stru
 			goto cleanup;
 		}
 
-		/* Copy the raw buffer data with no transform. NULL terminated already */
-
+		/*
+		 * Copy the raw buffer data with no transform.
+		 * (NULL terminated already)
+		 */
 		ACPI_MEMCPY(return_desc->string.pointer,
 			    operand[0]->buffer.pointer, length);
 		break;
@@ -391,10 +391,10 @@ acpi_status acpi_ex_opcode_2A_1T_1R(stru
 			/* Object to be indexed is a Package */
 
 			if (index >= operand[0]->package.count) {
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "Index value (%X%8.8X) beyond package end (%X)\n",
-						  ACPI_FORMAT_UINT64(index),
-						  operand[0]->package.count));
+				ACPI_ERROR((AE_INFO,
+					    "Index value (%X%8.8X) beyond package end (%X)",
+					    ACPI_FORMAT_UINT64(index),
+					    operand[0]->package.count));
 				status = AE_AML_PACKAGE_LIMIT;
 				goto cleanup;
 			}
@@ -407,10 +407,10 @@ acpi_status acpi_ex_opcode_2A_1T_1R(stru
 			/* Object to be indexed is a Buffer/String */
 
 			if (index >= operand[0]->buffer.length) {
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "Index value (%X%8.8X) beyond end of buffer (%X)\n",
-						  ACPI_FORMAT_UINT64(index),
-						  operand[0]->buffer.length));
+				ACPI_ERROR((AE_INFO,
+					    "Index value (%X%8.8X) beyond end of buffer (%X)",
+					    ACPI_FORMAT_UINT64(index),
+					    operand[0]->buffer.length));
 				status = AE_AML_BUFFER_LIMIT;
 				goto cleanup;
 			}
@@ -442,7 +442,8 @@ acpi_status acpi_ex_opcode_2A_1T_1R(stru
 
 	default:
 
-		ACPI_REPORT_ERROR(("acpi_ex_opcode_2A_1T_1R: Unknown opcode %X\n", walk_state->opcode));
+		ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
+			    walk_state->opcode));
 		status = AE_AML_BAD_OPCODE;
 		break;
 	}
@@ -546,7 +547,8 @@ acpi_status acpi_ex_opcode_2A_0T_1R(stru
 
 	default:
 
-		ACPI_REPORT_ERROR(("acpi_ex_opcode_2A_0T_1R: Unknown opcode %X\n", walk_state->opcode));
+		ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
+			    walk_state->opcode));
 		status = AE_AML_BAD_OPCODE;
 		goto cleanup;
 	}
diff --git a/drivers/acpi/executer/exoparg3.c b/drivers/acpi/executer/exoparg3.c
index 4833657..6a3a883 100644
--- a/drivers/acpi/executer/exoparg3.c
+++ b/drivers/acpi/executer/exoparg3.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -119,7 +119,8 @@ acpi_status acpi_ex_opcode_3A_0T_0R(stru
 
 	default:
 
-		ACPI_REPORT_ERROR(("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n", walk_state->opcode));
+		ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
+			    walk_state->opcode));
 		status = AE_AML_BAD_OPCODE;
 		goto cleanup;
 	}
@@ -223,8 +224,8 @@ acpi_status acpi_ex_opcode_3A_1T_1R(stru
 			goto cleanup;
 		}
 
-		if (length > 0) {
-			/* Copy the portion requested */
+		if (buffer) {
+			/* We have a buffer, copy the portion requested */
 
 			ACPI_MEMCPY(buffer, operand[0]->string.pointer + index,
 				    length);
@@ -242,7 +243,8 @@ acpi_status acpi_ex_opcode_3A_1T_1R(stru
 
 	default:
 
-		ACPI_REPORT_ERROR(("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n", walk_state->opcode));
+		ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
+			    walk_state->opcode));
 		status = AE_AML_BAD_OPCODE;
 		goto cleanup;
 	}
diff --git a/drivers/acpi/executer/exoparg6.c b/drivers/acpi/executer/exoparg6.c
index 5dee771..e043d92 100644
--- a/drivers/acpi/executer/exoparg6.c
+++ b/drivers/acpi/executer/exoparg6.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -234,8 +234,7 @@ acpi_status acpi_ex_opcode_6A_0T_1R(stru
 
 		if ((operand[1]->integer.value > MAX_MATCH_OPERATOR) ||
 		    (operand[3]->integer.value > MAX_MATCH_OPERATOR)) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Match operator out of range\n"));
+			ACPI_ERROR((AE_INFO, "Match operator out of range"));
 			status = AE_AML_OPERAND_VALUE;
 			goto cleanup;
 		}
@@ -244,10 +243,10 @@ acpi_status acpi_ex_opcode_6A_0T_1R(stru
 
 		index = operand[5]->integer.value;
 		if (index >= operand[0]->package.count) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Index (%X%8.8X) beyond package end (%X)\n",
-					  ACPI_FORMAT_UINT64(index),
-					  operand[0]->package.count));
+			ACPI_ERROR((AE_INFO,
+				    "Index (%X%8.8X) beyond package end (%X)",
+				    ACPI_FORMAT_UINT64(index),
+				    operand[0]->package.count));
 			status = AE_AML_PACKAGE_LIMIT;
 			goto cleanup;
 		}
@@ -316,7 +315,8 @@ acpi_status acpi_ex_opcode_6A_0T_1R(stru
 
 	default:
 
-		ACPI_REPORT_ERROR(("acpi_ex_opcode_6A_0T_1R: Unknown opcode %X\n", walk_state->opcode));
+		ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
+			    walk_state->opcode));
 		status = AE_AML_BAD_OPCODE;
 		goto cleanup;
 	}
diff --git a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c
index 7476c36..7719ae5 100644
--- a/drivers/acpi/executer/exprep.c
+++ b/drivers/acpi/executer/exprep.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -274,9 +274,8 @@ acpi_ex_decode_field_access(union acpi_o
 	default:
 		/* Invalid field access type */
 
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Unknown field access type %X\n", access));
-		return_VALUE(0);
+		ACPI_ERROR((AE_INFO, "Unknown field access type %X", access));
+		return_UINT32(0);
 	}
 
 	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
@@ -289,7 +288,7 @@ acpi_ex_decode_field_access(union acpi_o
 	}
 
 	*return_byte_alignment = byte_alignment;
-	return_VALUE(bit_length);
+	return_UINT32(bit_length);
 }
 
 /*******************************************************************************
@@ -422,15 +421,15 @@ acpi_status acpi_ex_prep_field_value(str
 
 	if (info->field_type != ACPI_TYPE_LOCAL_INDEX_FIELD) {
 		if (!info->region_node) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Null region_node\n"));
+			ACPI_ERROR((AE_INFO, "Null region_node"));
 			return_ACPI_STATUS(AE_AML_NO_OPERAND);
 		}
 
 		type = acpi_ns_get_type(info->region_node);
 		if (type != ACPI_TYPE_REGION) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Needed Region, found type %X (%s)\n",
-					  type, acpi_ut_get_type_name(type)));
+			ACPI_ERROR((AE_INFO,
+				    "Needed Region, found type %X (%s)",
+				    type, acpi_ut_get_type_name(type)));
 
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 		}
@@ -499,17 +498,17 @@ acpi_status acpi_ex_prep_field_value(str
 
 	case ACPI_TYPE_LOCAL_INDEX_FIELD:
 
+		/* Get the Index and Data registers */
+
 		obj_desc->index_field.index_obj =
 		    acpi_ns_get_attached_object(info->register_node);
 		obj_desc->index_field.data_obj =
 		    acpi_ns_get_attached_object(info->data_register_node);
-		obj_desc->index_field.value = (u32)
-		    (info->field_bit_position /
-		     ACPI_MUL_8(obj_desc->field.access_byte_width));
 
 		if (!obj_desc->index_field.data_obj
 		    || !obj_desc->index_field.index_obj) {
-			ACPI_REPORT_ERROR(("Null Index Object during field prep\n"));
+			ACPI_ERROR((AE_INFO,
+				    "Null Index Object during field prep"));
 			acpi_ut_delete_object_desc(obj_desc);
 			return_ACPI_STATUS(AE_AML_INTERNAL);
 		}
@@ -519,6 +518,15 @@ acpi_status acpi_ex_prep_field_value(str
 		acpi_ut_add_reference(obj_desc->index_field.data_obj);
 		acpi_ut_add_reference(obj_desc->index_field.index_obj);
 
+		/*
+		 * The value written to the Index register is the byte offset of the
+		 * target field
+		 * Note: may change code to: ACPI_DIV_8 (Info->field_bit_position)
+		 */
+		obj_desc->index_field.value = (u32)
+		    (info->field_bit_position /
+		     ACPI_MUL_8(obj_desc->field.access_byte_width));
+
 		ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
 				  "index_field: bit_off %X, Off %X, Value %X, Gran %X, Index %p, Data %p\n",
 				  obj_desc->index_field.start_field_bit_offset,
diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c
index 9a2f5be..6a4cfdf 100644
--- a/drivers/acpi/executer/exregion.c
+++ b/drivers/acpi/executer/exregion.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -77,7 +77,7 @@ acpi_ex_system_memory_space_handler(u32 
 	struct acpi_mem_space_context *mem_info = region_context;
 	u32 length;
 	acpi_size window_size;
-#ifndef ACPI_MISALIGNED_TRANSFERS
+#ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
 	u32 remainder;
 #endif
 
@@ -103,13 +103,12 @@ acpi_ex_system_memory_space_handler(u32 
 		break;
 
 	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Invalid system_memory width %d\n",
-				  bit_width));
+		ACPI_ERROR((AE_INFO, "Invalid system_memory width %d",
+			    bit_width));
 		return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
 	}
 
-#ifndef ACPI_MISALIGNED_TRANSFERS
+#ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
 	/*
 	 * Hardware does not support non-aligned data transfers, we must verify
 	 * the request.
@@ -159,10 +158,10 @@ acpi_ex_system_memory_space_handler(u32 
 					    (void **)&mem_info->
 					    mapped_logical_address);
 		if (ACPI_FAILURE(status)) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Could not map memory at %8.8X%8.8X, size %X\n",
-					  ACPI_FORMAT_UINT64(address),
-					  (u32) window_size));
+			ACPI_ERROR((AE_INFO,
+				    "Could not map memory at %8.8X%8.8X, size %X",
+				    ACPI_FORMAT_UINT64(address),
+				    (u32) window_size));
 			mem_info->mapped_length = 0;
 			return_ACPI_STATUS(status);
 		}
@@ -199,20 +198,20 @@ acpi_ex_system_memory_space_handler(u32 
 		*value = 0;
 		switch (bit_width) {
 		case 8:
-			*value = (acpi_integer) * ((u8 *) logical_addr_ptr);
+			*value = (acpi_integer) ACPI_GET8(logical_addr_ptr);
 			break;
 
 		case 16:
-			*value = (acpi_integer) * ((u16 *) logical_addr_ptr);
+			*value = (acpi_integer) ACPI_GET16(logical_addr_ptr);
 			break;
 
 		case 32:
-			*value = (acpi_integer) * ((u32 *) logical_addr_ptr);
+			*value = (acpi_integer) ACPI_GET32(logical_addr_ptr);
 			break;
 
 #if ACPI_MACHINE_WIDTH != 16
 		case 64:
-			*value = (acpi_integer) * ((u64 *) logical_addr_ptr);
+			*value = (acpi_integer) ACPI_GET64(logical_addr_ptr);
 			break;
 #endif
 		default:
@@ -225,20 +224,20 @@ acpi_ex_system_memory_space_handler(u32 
 
 		switch (bit_width) {
 		case 8:
-			*(u8 *) logical_addr_ptr = (u8) * value;
+			ACPI_SET8(logical_addr_ptr) = (u8) * value;
 			break;
 
 		case 16:
-			*(u16 *) logical_addr_ptr = (u16) * value;
+			ACPI_SET16(logical_addr_ptr) = (u16) * value;
 			break;
 
 		case 32:
-			*(u32 *) logical_addr_ptr = (u32) * value;
+			ACPI_SET32(logical_addr_ptr) = (u32) * value;
 			break;
 
 #if ACPI_MACHINE_WIDTH != 16
 		case 64:
-			*(u64 *) logical_addr_ptr = (u64) * value;
+			ACPI_SET64(logical_addr_ptr) = (u64) * value;
 			break;
 #endif
 
diff --git a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c
index ff5d8f9..01b26c8 100644
--- a/drivers/acpi/executer/exresnte.c
+++ b/drivers/acpi/executer/exresnte.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -122,8 +122,7 @@ acpi_ex_resolve_node_to_value(struct acp
 	}
 
 	if (!source_desc) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "No object attached to node %p\n", node));
+		ACPI_ERROR((AE_INFO, "No object attached to node %p", node));
 		return_ACPI_STATUS(AE_AML_NO_OPERAND);
 	}
 
@@ -135,10 +134,8 @@ acpi_ex_resolve_node_to_value(struct acp
 	case ACPI_TYPE_PACKAGE:
 
 		if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_PACKAGE) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Object not a Package, type %s\n",
-					  acpi_ut_get_object_type_name
-					  (source_desc)));
+			ACPI_ERROR((AE_INFO, "Object not a Package, type %s",
+				    acpi_ut_get_object_type_name(source_desc)));
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 		}
 
@@ -154,10 +151,8 @@ acpi_ex_resolve_node_to_value(struct acp
 	case ACPI_TYPE_BUFFER:
 
 		if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Object not a Buffer, type %s\n",
-					  acpi_ut_get_object_type_name
-					  (source_desc)));
+			ACPI_ERROR((AE_INFO, "Object not a Buffer, type %s",
+				    acpi_ut_get_object_type_name(source_desc)));
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 		}
 
@@ -173,10 +168,8 @@ acpi_ex_resolve_node_to_value(struct acp
 	case ACPI_TYPE_STRING:
 
 		if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Object not a String, type %s\n",
-					  acpi_ut_get_object_type_name
-					  (source_desc)));
+			ACPI_ERROR((AE_INFO, "Object not a String, type %s",
+				    acpi_ut_get_object_type_name(source_desc)));
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 		}
 
@@ -189,10 +182,8 @@ acpi_ex_resolve_node_to_value(struct acp
 	case ACPI_TYPE_INTEGER:
 
 		if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_INTEGER) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Object not a Integer, type %s\n",
-					  acpi_ut_get_object_type_name
-					  (source_desc)));
+			ACPI_ERROR((AE_INFO, "Object not a Integer, type %s",
+				    acpi_ut_get_object_type_name(source_desc)));
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 		}
 
@@ -236,9 +227,8 @@ acpi_ex_resolve_node_to_value(struct acp
 
 	case ACPI_TYPE_ANY:
 
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Untyped entry %p, no attached object!\n",
-				  node));
+		ACPI_ERROR((AE_INFO,
+			    "Untyped entry %p, no attached object!", node));
 
 		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);	/* Cannot be AE_TYPE */
 
@@ -257,12 +247,11 @@ acpi_ex_resolve_node_to_value(struct acp
 		default:
 			/* No named references are allowed here */
 
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Unsupported Reference opcode %X (%s)\n",
-					  source_desc->reference.opcode,
-					  acpi_ps_get_opcode_name(source_desc->
-								  reference.
-								  opcode)));
+			ACPI_ERROR((AE_INFO,
+				    "Unsupported Reference opcode %X (%s)",
+				    source_desc->reference.opcode,
+				    acpi_ps_get_opcode_name(source_desc->
+							    reference.opcode)));
 
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 		}
@@ -272,9 +261,9 @@ acpi_ex_resolve_node_to_value(struct acp
 
 		/* Default case is for unknown types */
 
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Node %p - Unknown object type %X\n",
-				  node, entry_type));
+		ACPI_ERROR((AE_INFO,
+			    "Node %p - Unknown object type %X",
+			    node, entry_type));
 
 		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 
diff --git a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c
index 97eecbd..1deed49 100644
--- a/drivers/acpi/executer/exresolv.c
+++ b/drivers/acpi/executer/exresolv.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -81,7 +81,7 @@ acpi_ex_resolve_to_value(union acpi_oper
 	ACPI_FUNCTION_TRACE_PTR("ex_resolve_to_value", stack_ptr);
 
 	if (!stack_ptr || !*stack_ptr) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Internal - null pointer\n"));
+		ACPI_ERROR((AE_INFO, "Internal - null pointer"));
 		return_ACPI_STATUS(AE_AML_NO_OPERAND);
 	}
 
@@ -97,8 +97,7 @@ acpi_ex_resolve_to_value(union acpi_oper
 		}
 
 		if (!*stack_ptr) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Internal - null pointer\n"));
+			ACPI_ERROR((AE_INFO, "Internal - null pointer"));
 			return_ACPI_STATUS(AE_AML_NO_OPERAND);
 		}
 	}
@@ -228,9 +227,9 @@ acpi_ex_resolve_object_to_value(union ac
 					 * A NULL object descriptor means an unitialized element of
 					 * the package, can't dereference it
 					 */
-					ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-							  "Attempt to deref an Index to NULL pkg element Idx=%p\n",
-							  stack_desc));
+					ACPI_ERROR((AE_INFO,
+						    "Attempt to deref an Index to NULL pkg element Idx=%p",
+						    stack_desc));
 					status = AE_AML_UNINITIALIZED_ELEMENT;
 				}
 				break;
@@ -239,7 +238,10 @@ acpi_ex_resolve_object_to_value(union ac
 
 				/* Invalid reference object */
 
-				ACPI_REPORT_ERROR(("During resolve, Unknown target_type %X in Index/Reference obj %p\n", stack_desc->reference.target_type, stack_desc));
+				ACPI_ERROR((AE_INFO,
+					    "Unknown target_type %X in Index/Reference obj %p",
+					    stack_desc->reference.target_type,
+					    stack_desc));
 				status = AE_AML_INTERNAL;
 				break;
 			}
@@ -264,7 +266,10 @@ acpi_ex_resolve_object_to_value(union ac
 
 		default:
 
-			ACPI_REPORT_ERROR(("During resolve, Unknown Reference opcode %X (%s) in %p\n", opcode, acpi_ps_get_opcode_name(opcode), stack_desc));
+			ACPI_ERROR((AE_INFO,
+				    "Unknown Reference opcode %X (%s) in %p",
+				    opcode, acpi_ps_get_opcode_name(opcode),
+				    stack_desc));
 			status = AE_AML_INTERNAL;
 			break;
 		}
@@ -386,7 +391,9 @@ acpi_ex_resolve_multiple(struct acpi_wal
 
 			if (ACPI_GET_DESCRIPTOR_TYPE(node) !=
 			    ACPI_DESC_TYPE_NAMED) {
-				ACPI_REPORT_ERROR(("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n", node, acpi_ut_get_descriptor_name(node)));
+				ACPI_ERROR((AE_INFO, "Not a NS node %p [%s]",
+					    node,
+					    acpi_ut_get_descriptor_name(node)));
 				return_ACPI_STATUS(AE_AML_INTERNAL);
 			}
 
@@ -442,7 +449,9 @@ acpi_ex_resolve_multiple(struct acpi_wal
 
 			if (ACPI_GET_DESCRIPTOR_TYPE(node) !=
 			    ACPI_DESC_TYPE_NAMED) {
-				ACPI_REPORT_ERROR(("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n", node, acpi_ut_get_descriptor_name(node)));
+				ACPI_ERROR((AE_INFO, "Not a NS node %p [%s]",
+					    node,
+					    acpi_ut_get_descriptor_name(node)));
 				return_ACPI_STATUS(AE_AML_INTERNAL);
 			}
 
@@ -511,7 +520,9 @@ acpi_ex_resolve_multiple(struct acpi_wal
 
 		default:
 
-			ACPI_REPORT_ERROR(("acpi_ex_resolve_multiple: Unknown Reference subtype %X\n", obj_desc->reference.opcode));
+			ACPI_ERROR((AE_INFO,
+				    "Unknown Reference subtype %X",
+				    obj_desc->reference.opcode));
 			return_ACPI_STATUS(AE_AML_INTERNAL);
 		}
 	}
diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c
index ff064e7..a1c000f 100644
--- a/drivers/acpi/executer/exresop.c
+++ b/drivers/acpi/executer/exresop.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -46,6 +46,7 @@
 #include <acpi/amlcode.h>
 #include <acpi/acparser.h>
 #include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
 
 #define _COMPONENT          ACPI_EXECUTER
 ACPI_MODULE_NAME("exresop")
@@ -73,7 +74,7 @@ static acpi_status
 acpi_ex_check_object_type(acpi_object_type type_needed,
 			  acpi_object_type this_type, void *object)
 {
-	ACPI_FUNCTION_NAME("ex_check_object_type");
+	ACPI_FUNCTION_ENTRY();
 
 	if (type_needed == ACPI_TYPE_ANY) {
 		/* All types OK, so we don't perform any typechecks */
@@ -95,10 +96,10 @@ acpi_ex_check_object_type(acpi_object_ty
 	}
 
 	if (type_needed != this_type) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Needed [%s], found [%s] %p\n",
-				  acpi_ut_get_type_name(type_needed),
-				  acpi_ut_get_type_name(this_type), object));
+		ACPI_ERROR((AE_INFO,
+			    "Needed type [%s], found [%s] %p",
+			    acpi_ut_get_type_name(type_needed),
+			    acpi_ut_get_type_name(this_type), object));
 
 		return (AE_AML_OPERAND_TYPE);
 	}
@@ -151,13 +152,13 @@ acpi_ex_resolve_operands(u16 opcode,
 
 	arg_types = op_info->runtime_args;
 	if (arg_types == ARGI_INVALID_OPCODE) {
-		ACPI_REPORT_ERROR(("resolve_operands: %X is not a valid AML opcode\n", opcode));
+		ACPI_ERROR((AE_INFO, "Unknown AML opcode %X", opcode));
 
 		return_ACPI_STATUS(AE_AML_INTERNAL);
 	}
 
 	ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-			  "Opcode %X [%s] required_operand_types=%8.8X \n",
+			  "Opcode %X [%s] required_operand_types=%8.8X\n",
 			  opcode, op_info->name, arg_types));
 
 	/*
@@ -169,7 +170,8 @@ acpi_ex_resolve_operands(u16 opcode,
 	 */
 	while (GET_CURRENT_ARG_TYPE(arg_types)) {
 		if (!stack_ptr || !*stack_ptr) {
-			ACPI_REPORT_ERROR(("resolve_operands: Null stack entry at %p\n", stack_ptr));
+			ACPI_ERROR((AE_INFO, "Null stack entry at %p",
+				    stack_ptr));
 
 			return_ACPI_STATUS(AE_AML_INTERNAL);
 		}
@@ -187,6 +189,22 @@ acpi_ex_resolve_operands(u16 opcode,
 
 			object_type =
 			    ((struct acpi_namespace_node *)obj_desc)->type;
+
+			/*
+			 * Resolve an alias object. The construction of these objects
+			 * guarantees that there is only one level of alias indirection;
+			 * thus, the attached object is always the aliased namespace node
+			 */
+			if (object_type == ACPI_TYPE_LOCAL_ALIAS) {
+				obj_desc =
+				    acpi_ns_get_attached_object((struct
+								 acpi_namespace_node
+								 *)obj_desc);
+				*stack_ptr = obj_desc;
+				object_type =
+				    ((struct acpi_namespace_node *)obj_desc)->
+				    type;
+			}
 			break;
 
 		case ACPI_DESC_TYPE_OPERAND:
@@ -198,9 +216,9 @@ acpi_ex_resolve_operands(u16 opcode,
 			/* Check for bad acpi_object_type */
 
 			if (!acpi_ut_valid_object_type(object_type)) {
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "Bad operand object type [%X]\n",
-						  object_type));
+				ACPI_ERROR((AE_INFO,
+					    "Bad operand object type [%X]",
+					    object_type));
 
 				return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 			}
@@ -238,13 +256,10 @@ acpi_ex_resolve_operands(u16 opcode,
 					break;
 
 				default:
-					ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-							  "Operand is a Reference, Unknown Reference Opcode %X [%s]\n",
-							  obj_desc->reference.
-							  opcode,
-							  (acpi_ps_get_opcode_info
-							   (obj_desc->reference.
-							    opcode))->name));
+					ACPI_ERROR((AE_INFO,
+						    "Operand is a Reference, Unknown Reference Opcode: %X",
+						    obj_desc->reference.
+						    opcode));
 
 					return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 				}
@@ -255,11 +270,10 @@ acpi_ex_resolve_operands(u16 opcode,
 
 			/* Invalid descriptor */
 
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Invalid descriptor %p [%s]\n",
-					  obj_desc,
-					  acpi_ut_get_descriptor_name
-					  (obj_desc)));
+			ACPI_ERROR((AE_INFO,
+				    "Invalid descriptor %p [%s]",
+				    obj_desc,
+				    acpi_ut_get_descriptor_name(obj_desc)));
 
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 		}
@@ -417,11 +431,10 @@ acpi_ex_resolve_operands(u16 opcode,
 			    acpi_ex_convert_to_integer(obj_desc, stack_ptr, 16);
 			if (ACPI_FAILURE(status)) {
 				if (status == AE_TYPE) {
-					ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-							  "Needed [Integer/String/Buffer], found [%s] %p\n",
-							  acpi_ut_get_object_type_name
-							  (obj_desc),
-							  obj_desc));
+					ACPI_ERROR((AE_INFO,
+						    "Needed [Integer/String/Buffer], found [%s] %p",
+						    acpi_ut_get_object_type_name
+						    (obj_desc), obj_desc));
 
 					return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 				}
@@ -444,11 +457,10 @@ acpi_ex_resolve_operands(u16 opcode,
 			status = acpi_ex_convert_to_buffer(obj_desc, stack_ptr);
 			if (ACPI_FAILURE(status)) {
 				if (status == AE_TYPE) {
-					ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-							  "Needed [Integer/String/Buffer], found [%s] %p\n",
-							  acpi_ut_get_object_type_name
-							  (obj_desc),
-							  obj_desc));
+					ACPI_ERROR((AE_INFO,
+						    "Needed [Integer/String/Buffer], found [%s] %p",
+						    acpi_ut_get_object_type_name
+						    (obj_desc), obj_desc));
 
 					return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 				}
@@ -472,11 +484,10 @@ acpi_ex_resolve_operands(u16 opcode,
 							   ACPI_IMPLICIT_CONVERT_HEX);
 			if (ACPI_FAILURE(status)) {
 				if (status == AE_TYPE) {
-					ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-							  "Needed [Integer/String/Buffer], found [%s] %p\n",
-							  acpi_ut_get_object_type_name
-							  (obj_desc),
-							  obj_desc));
+					ACPI_ERROR((AE_INFO,
+						    "Needed [Integer/String/Buffer], found [%s] %p",
+						    acpi_ut_get_object_type_name
+						    (obj_desc), obj_desc));
 
 					return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 				}
@@ -502,10 +513,10 @@ acpi_ex_resolve_operands(u16 opcode,
 				break;
 
 			default:
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "Needed [Integer/String/Buffer], found [%s] %p\n",
-						  acpi_ut_get_object_type_name
-						  (obj_desc), obj_desc));
+				ACPI_ERROR((AE_INFO,
+					    "Needed [Integer/String/Buffer], found [%s] %p",
+					    acpi_ut_get_object_type_name
+					    (obj_desc), obj_desc));
 
 				return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 			}
@@ -539,10 +550,10 @@ acpi_ex_resolve_operands(u16 opcode,
 				break;
 
 			default:
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "Needed [Integer/String/Buffer], found [%s] %p\n",
-						  acpi_ut_get_object_type_name
-						  (obj_desc), obj_desc));
+				ACPI_ERROR((AE_INFO,
+					    "Needed [Integer/String/Buffer], found [%s] %p",
+					    acpi_ut_get_object_type_name
+					    (obj_desc), obj_desc));
 
 				return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 			}
@@ -566,10 +577,10 @@ acpi_ex_resolve_operands(u16 opcode,
 				break;
 
 			default:
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "Needed [Buffer/String/Package/Reference], found [%s] %p\n",
-						  acpi_ut_get_object_type_name
-						  (obj_desc), obj_desc));
+				ACPI_ERROR((AE_INFO,
+					    "Needed [Buffer/String/Package/Reference], found [%s] %p",
+					    acpi_ut_get_object_type_name
+					    (obj_desc), obj_desc));
 
 				return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 			}
@@ -588,10 +599,10 @@ acpi_ex_resolve_operands(u16 opcode,
 				break;
 
 			default:
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "Needed [Buffer/String/Package], found [%s] %p\n",
-						  acpi_ut_get_object_type_name
-						  (obj_desc), obj_desc));
+				ACPI_ERROR((AE_INFO,
+					    "Needed [Buffer/String/Package], found [%s] %p",
+					    acpi_ut_get_object_type_name
+					    (obj_desc), obj_desc));
 
 				return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 			}
@@ -611,10 +622,10 @@ acpi_ex_resolve_operands(u16 opcode,
 				break;
 
 			default:
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "Needed [Region/region_field], found [%s] %p\n",
-						  acpi_ut_get_object_type_name
-						  (obj_desc), obj_desc));
+				ACPI_ERROR((AE_INFO,
+					    "Needed [Region/region_field], found [%s] %p",
+					    acpi_ut_get_object_type_name
+					    (obj_desc), obj_desc));
 
 				return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 			}
@@ -656,10 +667,10 @@ acpi_ex_resolve_operands(u16 opcode,
 					break;
 				}
 
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "Needed Integer/Buffer/String/Package/Ref/Ddb], found [%s] %p\n",
-						  acpi_ut_get_object_type_name
-						  (obj_desc), obj_desc));
+				ACPI_ERROR((AE_INFO,
+					    "Needed Integer/Buffer/String/Package/Ref/Ddb], found [%s] %p",
+					    acpi_ut_get_object_type_name
+					    (obj_desc), obj_desc));
 
 				return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 			}
@@ -669,9 +680,9 @@ acpi_ex_resolve_operands(u16 opcode,
 
 			/* Unknown type */
 
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Internal - Unknown ARGI (required operand) type %X\n",
-					  this_arg_type));
+			ACPI_ERROR((AE_INFO,
+				    "Internal - Unknown ARGI (required operand) type %X",
+				    this_arg_type));
 
 			return_ACPI_STATUS(AE_BAD_PARAMETER);
 		}
diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c
index a7d8eea..3f020c0 100644
--- a/drivers/acpi/executer/exstore.c
+++ b/drivers/acpi/executer/exstore.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -250,7 +250,7 @@ acpi_ex_store(union acpi_operand_object 
 	/* Validate parameters */
 
 	if (!source_desc || !dest_desc) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Null parameter\n"));
+		ACPI_ERROR((AE_INFO, "Null parameter"));
 		return_ACPI_STATUS(AE_AML_NO_OPERAND);
 	}
 
@@ -290,10 +290,10 @@ acpi_ex_store(union acpi_operand_object 
 
 		/* Destination is not a Reference object */
 
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Target is not a Reference or Constant object - %s [%p]\n",
-				  acpi_ut_get_object_type_name(dest_desc),
-				  dest_desc));
+		ACPI_ERROR((AE_INFO,
+			    "Target is not a Reference or Constant object - %s [%p]",
+			    acpi_ut_get_object_type_name(dest_desc),
+			    dest_desc));
 
 		ACPI_DUMP_STACK_ENTRY(source_desc);
 		ACPI_DUMP_STACK_ENTRY(dest_desc);
@@ -360,8 +360,8 @@ acpi_ex_store(union acpi_operand_object 
 
 	default:
 
-		ACPI_REPORT_ERROR(("ex_store: Unknown Reference opcode %X\n",
-				   ref_desc->reference.opcode));
+		ACPI_ERROR((AE_INFO, "Unknown Reference opcode %X",
+			    ref_desc->reference.opcode));
 		ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_ERROR);
 
 		status = AE_AML_INTERNAL;
@@ -490,10 +490,9 @@ acpi_ex_store_object_to_index(union acpi
 
 			/* All other types are invalid */
 
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Source must be Integer/Buffer/String type, not %s\n",
-					  acpi_ut_get_object_type_name
-					  (source_desc)));
+			ACPI_ERROR((AE_INFO,
+				    "Source must be Integer/Buffer/String type, not %s",
+				    acpi_ut_get_object_type_name(source_desc)));
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 		}
 
@@ -503,8 +502,8 @@ acpi_ex_store_object_to_index(union acpi
 		break;
 
 	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Target is not a Package or buffer_field\n"));
+		ACPI_ERROR((AE_INFO,
+			    "Target is not a Package or buffer_field"));
 		status = AE_AML_OPERAND_TYPE;
 		break;
 	}
diff --git a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c
index 382f63c..42967ba 100644
--- a/drivers/acpi/executer/exstoren.c
+++ b/drivers/acpi/executer/exstoren.c
@@ -7,7 +7,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -123,11 +123,10 @@ acpi_ex_resolve_object(union acpi_operan
 		      && (source_desc->reference.opcode == AML_LOAD_OP))) {
 			/* Conversion successful but still not a valid type */
 
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Cannot assign type %s to %s (must be type Int/Str/Buf)\n",
-					  acpi_ut_get_object_type_name
-					  (source_desc),
-					  acpi_ut_get_type_name(target_type)));
+			ACPI_ERROR((AE_INFO,
+				    "Cannot assign type %s to %s (must be type Int/Str/Buf)",
+				    acpi_ut_get_object_type_name(source_desc),
+				    acpi_ut_get_type_name(target_type)));
 			status = AE_AML_OPERAND_TYPE;
 		}
 		break;
@@ -135,9 +134,11 @@ acpi_ex_resolve_object(union acpi_operan
 	case ACPI_TYPE_LOCAL_ALIAS:
 	case ACPI_TYPE_LOCAL_METHOD_ALIAS:
 
-		/* Aliases are resolved by acpi_ex_prep_operands */
-
-		ACPI_REPORT_ERROR(("Store into Alias - should never happen\n"));
+		/*
+		 * All aliases should have been resolved earlier, during the
+		 * operand resolution phase.
+		 */
+		ACPI_ERROR((AE_INFO, "Store into an unresolved Alias object"));
 		status = AE_AML_INTERNAL;
 		break;
 
@@ -280,9 +281,8 @@ acpi_ex_store_object_to_object(union acp
 		/*
 		 * All other types come here.
 		 */
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN,
-				  "Store into type %s not implemented\n",
-				  acpi_ut_get_object_type_name(dest_desc)));
+		ACPI_WARNING((AE_INFO, "Store into type %s not implemented",
+			      acpi_ut_get_object_type_name(dest_desc)));
 
 		status = AE_NOT_IMPLEMENTED;
 		break;
diff --git a/drivers/acpi/executer/exstorob.c b/drivers/acpi/executer/exstorob.c
index c4ff654..6ab7070 100644
--- a/drivers/acpi/executer/exstorob.c
+++ b/drivers/acpi/executer/exstorob.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -71,7 +71,7 @@ acpi_ex_store_buffer_to_buffer(union acp
 
 	/* We know that source_desc is a buffer by now */
 
-	buffer = (u8 *) source_desc->buffer.pointer;
+	buffer = ACPI_CAST_PTR(u8, source_desc->buffer.pointer);
 	length = source_desc->buffer.length;
 
 	/*
@@ -160,7 +160,7 @@ acpi_ex_store_string_to_string(union acp
 
 	/* We know that source_desc is a string by now */
 
-	buffer = (u8 *) source_desc->string.pointer;
+	buffer = ACPI_CAST_PTR(u8, source_desc->string.pointer);
 	length = source_desc->string.length;
 
 	/*
diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c
index 8a88b84..ea9144f 100644
--- a/drivers/acpi/executer/exsystem.c
+++ b/drivers/acpi/executer/exsystem.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -129,8 +129,8 @@ acpi_status acpi_ex_system_do_stall(u32 
 		 * (ACPI specifies 100 usec as max, but this gives some slack in
 		 * order to support existing BIOSs)
 		 */
-		ACPI_REPORT_ERROR(("Stall: Time parameter is too large (%d)\n",
-				   how_long));
+		ACPI_ERROR((AE_INFO, "Time parameter is too large (%d)",
+			    how_long));
 		status = AE_AML_OPERAND_VALUE;
 	} else {
 		acpi_os_stall(how_long);
diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c
index 1ee79d8..f73a61a 100644
--- a/drivers/acpi/executer/exutils.c
+++ b/drivers/acpi/executer/exutils.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -91,7 +91,7 @@ acpi_status acpi_ex_enter_interpreter(vo
 
 	status = acpi_ut_acquire_mutex(ACPI_MTX_EXECUTE);
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("Could not acquire interpreter mutex\n"));
+		ACPI_ERROR((AE_INFO, "Could not acquire interpreter mutex"));
 	}
 
 	return_ACPI_STATUS(status);
@@ -127,7 +127,7 @@ void acpi_ex_exit_interpreter(void)
 
 	status = acpi_ut_release_mutex(ACPI_MTX_EXECUTE);
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("Could not release interpreter mutex\n"));
+		ACPI_ERROR((AE_INFO, "Could not release interpreter mutex"));
 	}
 
 	return_VOID;
@@ -200,13 +200,12 @@ u8 acpi_ex_acquire_global_lock(u32 field
 		if (ACPI_SUCCESS(status)) {
 			locked = TRUE;
 		} else {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Could not acquire Global Lock, %s\n",
-					  acpi_format_exception(status)));
+			ACPI_EXCEPTION((AE_INFO, status,
+					"Could not acquire Global Lock"));
 		}
 	}
 
-	return_VALUE(locked);
+	return_UINT8(locked);
 }
 
 /*******************************************************************************
@@ -237,7 +236,8 @@ void acpi_ex_release_global_lock(u8 lock
 		if (ACPI_FAILURE(status)) {
 			/* Report the error, but there isn't much else we can do */
 
-			ACPI_REPORT_ERROR(("Could not release ACPI Global Lock, %s\n", acpi_format_exception(status)));
+			ACPI_EXCEPTION((AE_INFO, status,
+					"Could not release ACPI Global Lock"));
 		}
 	}
 
@@ -268,7 +268,7 @@ static u32 acpi_ex_digits_needed(acpi_in
 	/* acpi_integer is unsigned, so we don't worry about a '-' prefix */
 
 	if (value == 0) {
-		return_VALUE(1);
+		return_UINT32(1);
 	}
 
 	current_value = value;
@@ -282,7 +282,7 @@ static u32 acpi_ex_digits_needed(acpi_in
 		num_digits++;
 	}
 
-	return_VALUE(num_digits);
+	return_UINT32(num_digits);
 }
 
 /*******************************************************************************
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index aa99371..8daef57 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -99,15 +99,15 @@ do_root_bridge_busnr_callback(struct acp
 	unsigned long *busnr = (unsigned long *)data;
 	struct acpi_resource_address64 address;
 
-	if (resource->id != ACPI_RSTYPE_ADDRESS16 &&
-	    resource->id != ACPI_RSTYPE_ADDRESS32 &&
-	    resource->id != ACPI_RSTYPE_ADDRESS64)
+	if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
+	    resource->type != ACPI_RESOURCE_TYPE_ADDRESS32 &&
+	    resource->type != ACPI_RESOURCE_TYPE_ADDRESS64)
 		return AE_OK;
 
 	acpi_resource_to_address64(resource, &address);
 	if ((address.address_length > 0) &&
 	    (address.resource_type == ACPI_BUS_NUMBER_RANGE))
-		*busnr = address.min_address_range;
+		*busnr = address.minimum;
 
 	return AE_OK;
 }
diff --git a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/hardware/hwacpi.c
index 1bb3463..ea2f132 100644
--- a/drivers/acpi/hardware/hwacpi.c
+++ b/drivers/acpi/hardware/hwacpi.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -68,8 +68,7 @@ acpi_status acpi_hw_initialize(void)
 	/* We must have the ACPI tables by the time we get here */
 
 	if (!acpi_gbl_FADT) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No FADT is present\n"));
-
+		ACPI_ERROR((AE_INFO, "No FADT is present"));
 		return_ACPI_STATUS(AE_NO_ACPI_TABLES);
 	}
 
@@ -108,7 +107,8 @@ acpi_status acpi_hw_set_mode(u32 mode)
 	 * system does not support mode transition.
 	 */
 	if (!acpi_gbl_FADT->smi_cmd) {
-		ACPI_REPORT_ERROR(("No SMI_CMD in FADT, mode transition failed.\n"));
+		ACPI_ERROR((AE_INFO,
+			    "No SMI_CMD in FADT, mode transition failed"));
 		return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
 	}
 
@@ -120,7 +120,8 @@ acpi_status acpi_hw_set_mode(u32 mode)
 	 * transitions are not supported.
 	 */
 	if (!acpi_gbl_FADT->acpi_enable && !acpi_gbl_FADT->acpi_disable) {
-		ACPI_REPORT_ERROR(("No ACPI mode transition supported in this system (enable/disable both zero)\n"));
+		ACPI_ERROR((AE_INFO,
+			    "No ACPI mode transition supported in this system (enable/disable both zero)"));
 		return_ACPI_STATUS(AE_OK);
 	}
 
@@ -154,8 +155,8 @@ acpi_status acpi_hw_set_mode(u32 mode)
 	}
 
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("Could not write mode change, %s\n",
-				   acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status,
+				"Could not write ACPI mode change"));
 		return_ACPI_STATUS(status);
 	}
 
@@ -175,7 +176,7 @@ acpi_status acpi_hw_set_mode(u32 mode)
 		retry--;
 	}
 
-	ACPI_REPORT_ERROR(("Hardware never changed modes\n"));
+	ACPI_ERROR((AE_INFO, "Hardware did not change modes"));
 	return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
 }
 
@@ -204,18 +205,18 @@ u32 acpi_hw_get_mode(void)
 	 * system does not support mode transition.
 	 */
 	if (!acpi_gbl_FADT->smi_cmd) {
-		return_VALUE(ACPI_SYS_MODE_ACPI);
+		return_UINT32(ACPI_SYS_MODE_ACPI);
 	}
 
 	status =
 	    acpi_get_register(ACPI_BITREG_SCI_ENABLE, &value, ACPI_MTX_LOCK);
 	if (ACPI_FAILURE(status)) {
-		return_VALUE(ACPI_SYS_MODE_LEGACY);
+		return_UINT32(ACPI_SYS_MODE_LEGACY);
 	}
 
 	if (value) {
-		return_VALUE(ACPI_SYS_MODE_ACPI);
+		return_UINT32(ACPI_SYS_MODE_ACPI);
 	} else {
-		return_VALUE(ACPI_SYS_MODE_LEGACY);
+		return_UINT32(ACPI_SYS_MODE_LEGACY);
 	}
 }
diff --git a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c
index 5c8e5df..d84942d 100644
--- a/drivers/acpi/hardware/hwgpe.c
+++ b/drivers/acpi/hardware/hwgpe.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
index 536a7ae..e1fe754 100644
--- a/drivers/acpi/hardware/hwregs.c
+++ b/drivers/acpi/hardware/hwregs.c
@@ -7,7 +7,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -144,7 +144,8 @@ acpi_get_sleep_type_data(u8 sleep_state,
 
 	info.parameters = NULL;
 	info.return_object = NULL;
-	sleep_state_name = (char *)acpi_gbl_sleep_state_names[sleep_state];
+	sleep_state_name =
+	    ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]);
 
 	status = acpi_ns_evaluate_by_name(sleep_state_name, &info);
 	if (ACPI_FAILURE(status)) {
@@ -159,15 +160,16 @@ acpi_get_sleep_type_data(u8 sleep_state,
 	/* Must have a return object */
 
 	if (!info.return_object) {
-		ACPI_REPORT_ERROR(("No Sleep State object returned from [%s]\n",
-				   sleep_state_name));
+		ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]",
+			    sleep_state_name));
 		status = AE_NOT_EXIST;
 	}
 
 	/* It must be of type Package */
 
 	else if (ACPI_GET_OBJECT_TYPE(info.return_object) != ACPI_TYPE_PACKAGE) {
-		ACPI_REPORT_ERROR(("Sleep State return object is not a Package\n"));
+		ACPI_ERROR((AE_INFO,
+			    "Sleep State return object is not a Package"));
 		status = AE_AML_OPERAND_TYPE;
 	}
 
@@ -179,7 +181,8 @@ acpi_get_sleep_type_data(u8 sleep_state,
 	 * one per sleep type (A/B).
 	 */
 	else if (info.return_object->package.count < 2) {
-		ACPI_REPORT_ERROR(("Sleep State return package does not have at least two elements\n"));
+		ACPI_ERROR((AE_INFO,
+			    "Sleep State return package does not have at least two elements"));
 		status = AE_AML_NO_OPERAND;
 	}
 
@@ -189,7 +192,12 @@ acpi_get_sleep_type_data(u8 sleep_state,
 		  != ACPI_TYPE_INTEGER) ||
 		 (ACPI_GET_OBJECT_TYPE(info.return_object->package.elements[1])
 		  != ACPI_TYPE_INTEGER)) {
-		ACPI_REPORT_ERROR(("Sleep State return package elements are not both Integers (%s, %s)\n", acpi_ut_get_object_type_name(info.return_object->package.elements[0]), acpi_ut_get_object_type_name(info.return_object->package.elements[1])));
+		ACPI_ERROR((AE_INFO,
+			    "Sleep State return package elements are not both Integers (%s, %s)",
+			    acpi_ut_get_object_type_name(info.return_object->
+							 package.elements[0]),
+			    acpi_ut_get_object_type_name(info.return_object->
+							 package.elements[1])));
 		status = AE_AML_OPERAND_TYPE;
 	} else {
 		/* Valid _Sx_ package size, type, and value */
@@ -201,12 +209,11 @@ acpi_get_sleep_type_data(u8 sleep_state,
 	}
 
 	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "%s While evaluating sleep_state [%s], bad Sleep object %p type %s\n",
-				  acpi_format_exception(status),
-				  sleep_state_name, info.return_object,
-				  acpi_ut_get_object_type_name(info.
-							       return_object)));
+		ACPI_EXCEPTION((AE_INFO, status,
+				"While evaluating sleep_state [%s], bad Sleep object %p type %s",
+				sleep_state_name, info.return_object,
+				acpi_ut_get_object_type_name(info.
+							     return_object)));
 	}
 
 	acpi_ut_remove_reference(info.return_object);
@@ -229,12 +236,11 @@ EXPORT_SYMBOL(acpi_get_sleep_type_data);
 
 struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id)
 {
-	ACPI_FUNCTION_NAME("hw_get_bit_register_info");
+	ACPI_FUNCTION_ENTRY();
 
 	if (register_id > ACPI_BITREG_MAX) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Invalid bit_register ID: %X\n",
-				  register_id));
+		ACPI_ERROR((AE_INFO, "Invalid bit_register ID: %X",
+			    register_id));
 		return (NULL);
 	}
 
@@ -334,8 +340,8 @@ acpi_status acpi_set_register(u32 regist
 
 	bit_reg_info = acpi_hw_get_bit_register_info(register_id);
 	if (!bit_reg_info) {
-		ACPI_REPORT_ERROR(("Bad ACPI HW register_id: %X\n",
-				   register_id));
+		ACPI_ERROR((AE_INFO, "Bad ACPI HW register_id: %X",
+			    register_id));
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
@@ -569,8 +575,7 @@ acpi_hw_register_read(u8 use_lock, u32 r
 		break;
 
 	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown Register ID: %X\n",
-				  register_id));
+		ACPI_ERROR((AE_INFO, "Unknown Register ID: %X", register_id));
 		status = AE_BAD_PARAMETER;
 		break;
 	}
@@ -765,9 +770,9 @@ acpi_hw_low_level_read(u32 width, u32 * 
 		break;
 
 	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Unsupported address space: %X\n",
-				  reg->address_space_id));
+		ACPI_ERROR((AE_INFO,
+			    "Unsupported address space: %X",
+			    reg->address_space_id));
 		return (AE_BAD_PARAMETER);
 	}
 
@@ -836,9 +841,9 @@ acpi_hw_low_level_write(u32 width, u32 v
 		break;
 
 	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Unsupported address space: %X\n",
-				  reg->address_space_id));
+		ACPI_ERROR((AE_INFO,
+			    "Unsupported address space: %X",
+			    reg->address_space_id));
 		return (AE_BAD_PARAMETER);
 	}
 
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
index 3451906..8926927 100644
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -199,8 +199,8 @@ acpi_status acpi_enter_sleep_state_prep(
 
 	status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
 	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
-		ACPI_REPORT_ERROR(("Method _SST failed, %s\n",
-				   acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status,
+				"While executing method _SST"));
 	}
 
 	return_ACPI_STATUS(AE_OK);
@@ -232,9 +232,8 @@ acpi_status asmlinkage acpi_enter_sleep_
 
 	if ((acpi_gbl_sleep_type_a > ACPI_SLEEP_TYPE_MAX) ||
 	    (acpi_gbl_sleep_type_b > ACPI_SLEEP_TYPE_MAX)) {
-		ACPI_REPORT_ERROR(("Sleep values out of range: A=%X B=%X\n",
-				   acpi_gbl_sleep_type_a,
-				   acpi_gbl_sleep_type_b));
+		ACPI_ERROR((AE_INFO, "Sleep values out of range: A=%X B=%X",
+			    acpi_gbl_sleep_type_a, acpi_gbl_sleep_type_b));
 		return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
 	}
 
@@ -533,21 +532,18 @@ acpi_status acpi_leave_sleep_state(u8 sl
 	arg.integer.value = ACPI_SST_WAKING;
 	status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
 	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
-		ACPI_REPORT_ERROR(("Method _SST failed, %s\n",
-				   acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status, "During Method _SST"));
 	}
 
 	arg.integer.value = sleep_state;
 	status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL);
 	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
-		ACPI_REPORT_ERROR(("Method _BFS failed, %s\n",
-				   acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS"));
 	}
 
 	status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, NULL);
 	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
-		ACPI_REPORT_ERROR(("Method _WAK failed, %s\n",
-				   acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status, "During Method _WAK"));
 	}
 	/* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
 
@@ -582,8 +578,7 @@ acpi_status acpi_leave_sleep_state(u8 sl
 	arg.integer.value = ACPI_SST_WORKING;
 	status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
 	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
-		ACPI_REPORT_ERROR(("Method _SST failed, %s\n",
-				   acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status, "During Method _SST"));
 	}
 
 	return_ACPI_STATUS(status);
diff --git a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c
index aff6dc1..fc10b7c 100644
--- a/drivers/acpi/hardware/hwtimer.c
+++ b/drivers/acpi/hardware/hwtimer.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/motherboard.c b/drivers/acpi/motherboard.c
index e928e8c..4682441 100644
--- a/drivers/acpi/motherboard.c
+++ b/drivers/acpi/motherboard.c
@@ -54,36 +54,36 @@ static acpi_status acpi_reserve_io_range
 
 	ACPI_FUNCTION_TRACE("acpi_reserve_io_ranges");
 
-	if (res->id == ACPI_RSTYPE_IO) {
+	if (res->type == ACPI_RESOURCE_TYPE_IO) {
 		struct acpi_resource_io *io_res = &res->data.io;
 
-		if (io_res->min_base_address != io_res->max_base_address)
+		if (io_res->minimum != io_res->maximum)
 			return_VALUE(AE_OK);
 		if (IS_RESERVED_ADDR
-		    (io_res->min_base_address, io_res->range_length)) {
+		    (io_res->minimum, io_res->address_length)) {
 			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 					  "Motherboard resources 0x%08x - 0x%08x\n",
-					  io_res->min_base_address,
-					  io_res->min_base_address +
-					  io_res->range_length));
+					  io_res->minimum,
+					  io_res->minimum +
+					  io_res->address_length));
 			requested_res =
-			    request_region(io_res->min_base_address,
-					   io_res->range_length, "motherboard");
+			    request_region(io_res->minimum,
+					   io_res->address_length, "motherboard");
 		}
-	} else if (res->id == ACPI_RSTYPE_FIXED_IO) {
+	} else if (res->type == ACPI_RESOURCE_TYPE_FIXED_IO) {
 		struct acpi_resource_fixed_io *fixed_io_res =
 		    &res->data.fixed_io;
 
 		if (IS_RESERVED_ADDR
-		    (fixed_io_res->base_address, fixed_io_res->range_length)) {
+		    (fixed_io_res->address, fixed_io_res->address_length)) {
 			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 					  "Motherboard resources 0x%08x - 0x%08x\n",
-					  fixed_io_res->base_address,
-					  fixed_io_res->base_address +
-					  fixed_io_res->range_length));
+					  fixed_io_res->address,
+					  fixed_io_res->address +
+					  fixed_io_res->address_length));
 			requested_res =
-			    request_region(fixed_io_res->base_address,
-					   fixed_io_res->range_length,
+			    request_region(fixed_io_res->address,
+					   fixed_io_res->address_length,
 					   "motherboard");
 		}
 	} else {
diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c
index edfbe34..1149bc1 100644
--- a/drivers/acpi/namespace/nsaccess.c
+++ b/drivers/acpi/namespace/nsaccess.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -110,10 +110,9 @@ acpi_status acpi_ns_root_initialize(void
 					ACPI_NS_NO_UPSEARCH, NULL, &new_node);
 
 		if (ACPI_FAILURE(status) || (!new_node)) {	/* Must be on same line for code converter */
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Could not create predefined name %s, %s\n",
-					  init_val->name,
-					  acpi_format_exception(status)));
+			ACPI_EXCEPTION((AE_INFO, status,
+					"Could not create predefined name %s",
+					init_val->name));
 		}
 
 		/*
@@ -124,9 +123,9 @@ acpi_status acpi_ns_root_initialize(void
 		if (init_val->val) {
 			status = acpi_os_predefined_override(init_val, &val);
 			if (ACPI_FAILURE(status)) {
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "Could not override predefined %s\n",
-						  init_val->name));
+				ACPI_ERROR((AE_INFO,
+					    "Could not override predefined %s",
+					    init_val->name));
 			}
 
 			if (!val) {
@@ -233,7 +232,9 @@ acpi_status acpi_ns_root_initialize(void
 
 			default:
 
-				ACPI_REPORT_ERROR(("Unsupported initial type value %X\n", init_val->type));
+				ACPI_ERROR((AE_INFO,
+					    "Unsupported initial type value %X",
+					    init_val->type));
 				acpi_ut_remove_reference(obj_desc);
 				obj_desc = NULL;
 				continue;
@@ -339,7 +340,9 @@ acpi_ns_lookup(union acpi_generic_state 
 		prefix_node = scope_info->scope.node;
 		if (ACPI_GET_DESCRIPTOR_TYPE(prefix_node) !=
 		    ACPI_DESC_TYPE_NAMED) {
-			ACPI_REPORT_ERROR(("ns_lookup: %p is not a namespace node [%s]\n", prefix_node, acpi_ut_get_descriptor_name(prefix_node)));
+			ACPI_ERROR((AE_INFO, "%p is not a namespace node [%s]",
+				    prefix_node,
+				    acpi_ut_get_descriptor_name(prefix_node)));
 			return_ACPI_STATUS(AE_AML_INTERNAL);
 		}
 
@@ -429,7 +432,8 @@ acpi_ns_lookup(union acpi_generic_state 
 				if (!this_node) {
 					/* Current scope has no parent scope */
 
-					ACPI_REPORT_ERROR(("ACPI path has too many parent prefixes (^) - reached beyond root node\n"));
+					ACPI_ERROR((AE_INFO,
+						    "ACPI path has too many parent prefixes (^) - reached beyond root node"));
 					return_ACPI_STATUS(AE_NOT_FOUND);
 				}
 			}
@@ -498,7 +502,7 @@ acpi_ns_lookup(union acpi_generic_state 
 			path++;
 
 			ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
-					  "Multi Pathname (%d Segments, Flags=%X) \n",
+					  "Multi Pathname (%d Segments, Flags=%X)\n",
 					  num_segments, flags));
 			break;
 
@@ -600,7 +604,12 @@ acpi_ns_lookup(union acpi_generic_state 
 		    (this_node->type != type_to_check_for)) {
 			/* Complain about a type mismatch */
 
-			ACPI_REPORT_WARNING(("ns_lookup: Type mismatch on %4.4s (%s), searching for (%s)\n", (char *)&simple_name, acpi_ut_get_type_name(this_node->type), acpi_ut_get_type_name(type_to_check_for)));
+			ACPI_WARNING((AE_INFO,
+				      "ns_lookup: Type mismatch on %4.4s (%s), searching for (%s)",
+				      ACPI_CAST_PTR(char, &simple_name),
+				      acpi_ut_get_type_name(this_node->type),
+				      acpi_ut_get_type_name
+				      (type_to_check_for)));
 		}
 
 		/*
diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c
index cc7a85f..9b871f3 100644
--- a/drivers/acpi/namespace/nsalloc.c
+++ b/drivers/acpi/namespace/nsalloc.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -272,9 +272,8 @@ void acpi_ns_delete_children(struct acpi
 		/* Grandchildren should have all been deleted already */
 
 		if (child_node->child) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Found a grandchild! P=%p C=%p\n",
-					  parent_node, child_node));
+			ACPI_ERROR((AE_INFO, "Found a grandchild! P=%p C=%p",
+				    parent_node, child_node));
 		}
 
 		/* Now we can free this child object */
@@ -302,7 +301,9 @@ void acpi_ns_delete_children(struct acpi
 		/* There should be only one reference remaining on this node */
 
 		if (child_node->reference_count != 1) {
-			ACPI_REPORT_WARNING(("Existing references (%d) on node being deleted (%p)\n", child_node->reference_count, child_node));
+			ACPI_WARNING((AE_INFO,
+				      "Existing references (%d) on node being deleted (%p)",
+				      child_node->reference_count, child_node));
 		}
 
 		/* Now we can delete the node */
diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c
index 9faf1d5..a280731 100644
--- a/drivers/acpi/namespace/nsdump.c
+++ b/drivers/acpi/namespace/nsdump.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -198,12 +198,13 @@ acpi_ns_dump_one_object(acpi_handle obj_
 		/* Check the node type and name */
 
 		if (type > ACPI_TYPE_LOCAL_MAX) {
-			ACPI_REPORT_WARNING(("Invalid ACPI Type %08X\n", type));
+			ACPI_WARNING((AE_INFO, "Invalid ACPI Object Type %08X",
+				      type));
 		}
 
 		if (!acpi_ut_valid_acpi_name(this_node->name.integer)) {
-			ACPI_REPORT_WARNING(("Invalid ACPI Name %08X\n",
-					     this_node->name.integer));
+			ACPI_WARNING((AE_INFO, "Invalid ACPI Name %08X",
+				      this_node->name.integer));
 		}
 
 		acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node));
@@ -212,7 +213,9 @@ acpi_ns_dump_one_object(acpi_handle obj_
 	/*
 	 * Now we can print out the pertinent information
 	 */
-	acpi_os_printf(" %-12s %p ", acpi_ut_get_type_name(type), this_node);
+	acpi_os_printf(" %-12s %p %2.2X ",
+		       acpi_ut_get_type_name(type), this_node,
+		       this_node->owner_id);
 
 	dbg_level = acpi_dbg_level;
 	acpi_dbg_level = 0;
diff --git a/drivers/acpi/namespace/nsdumpdv.c b/drivers/acpi/namespace/nsdumpdv.c
index 55de883..aff899a 100644
--- a/drivers/acpi/namespace/nsdumpdv.c
+++ b/drivers/acpi/namespace/nsdumpdv.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c
index 0191c7d..19d7b94 100644
--- a/drivers/acpi/namespace/nseval.c
+++ b/drivers/acpi/namespace/nseval.c
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -373,8 +373,7 @@ acpi_ns_execute_control_method(struct ac
 
 	info->obj_desc = acpi_ns_get_attached_object(info->node);
 	if (!info->obj_desc) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "No attached method object\n"));
+		ACPI_ERROR((AE_INFO, "No attached method object"));
 
 		(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 		return_ACPI_STATUS(AE_NULL_OBJECT);
diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c
index 0a08d2f..9f929e4 100644
--- a/drivers/acpi/namespace/nsinit.c
+++ b/drivers/acpi/namespace/nsinit.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -93,8 +93,7 @@ acpi_status acpi_ns_initialize_objects(v
 				     ACPI_UINT32_MAX, acpi_ns_init_one_object,
 				     &info, NULL);
 	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "walk_namespace failed! %s\n",
-				  acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status, "During walk_namespace"));
 	}
 
 	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
@@ -159,12 +158,11 @@ acpi_status acpi_ns_initialize_devices(v
 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 
 	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "walk_namespace failed! %s\n",
-				  acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status, "During walk_namespace"));
 	}
 
 	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
-			      "\n%hd Devices found containing: %hd _STA, %hd _INI methods\n",
+			      "\n%hd Devices found - executed %hd _STA, %hd _INI methods\n",
 			      info.device_count, info.num_STA, info.num_INI));
 
 	return_ACPI_STATUS(status);
@@ -289,12 +287,10 @@ acpi_ns_init_one_object(acpi_handle obj_
 	}
 
 	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT_RAW((ACPI_DB_ERROR, "\n"));
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Could not execute arguments for [%4.4s] (%s), %s\n",
-				  acpi_ut_get_node_name(node),
-				  acpi_ut_get_type_name(type),
-				  acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status,
+				"Could not execute arguments for [%4.4s] (%s)",
+				acpi_ut_get_node_name(node),
+				acpi_ut_get_type_name(type)));
 	}
 
 	/*
@@ -336,23 +332,22 @@ acpi_ns_init_one_device(acpi_handle obj_
 	struct acpi_parameter_info pinfo;
 	u32 flags;
 	acpi_status status;
+	struct acpi_namespace_node *ini_node;
+	struct acpi_namespace_node *device_node;
 
 	ACPI_FUNCTION_TRACE("ns_init_one_device");
 
-	pinfo.parameters = NULL;
-	pinfo.parameter_type = ACPI_PARAM_ARGS;
-
-	pinfo.node = acpi_ns_map_handle_to_node(obj_handle);
-	if (!pinfo.node) {
+	device_node = acpi_ns_map_handle_to_node(obj_handle);
+	if (!device_node) {
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
 	/*
 	 * We will run _STA/_INI on Devices, Processors and thermal_zones only
 	 */
-	if ((pinfo.node->type != ACPI_TYPE_DEVICE) &&
-	    (pinfo.node->type != ACPI_TYPE_PROCESSOR) &&
-	    (pinfo.node->type != ACPI_TYPE_THERMAL)) {
+	if ((device_node->type != ACPI_TYPE_DEVICE) &&
+	    (device_node->type != ACPI_TYPE_PROCESSOR) &&
+	    (device_node->type != ACPI_TYPE_THERMAL)) {
 		return_ACPI_STATUS(AE_OK);
 	}
 
@@ -364,57 +359,69 @@ acpi_ns_init_one_device(acpi_handle obj_
 	info->device_count++;
 
 	/*
-	 * Run _STA to determine if we can run _INI on the device.
+	 * Check if the _INI method exists for this device -
+	 * if _INI does not exist, there is no need to run _STA
+	 * No _INI means device requires no initialization
+	 */
+	status = acpi_ns_search_node(*ACPI_CAST_PTR(u32, METHOD_NAME__INI),
+				     device_node, ACPI_TYPE_METHOD, &ini_node);
+	if (ACPI_FAILURE(status)) {
+		/* No _INI method found - move on to next device */
+
+		return_ACPI_STATUS(AE_OK);
+	}
+
+	/*
+	 * Run _STA to determine if we can run _INI on the device -
+	 * the device must be present before _INI can be run.
+	 * However, _STA is not required - assume device present if no _STA
 	 */
 	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_METHOD,
-						      pinfo.node,
+						      device_node,
 						      METHOD_NAME__STA));
-	status = acpi_ut_execute_STA(pinfo.node, &flags);
 
+	pinfo.node = device_node;
+	pinfo.parameters = NULL;
+	pinfo.parameter_type = ACPI_PARAM_ARGS;
+
+	status = acpi_ut_execute_STA(pinfo.node, &flags);
 	if (ACPI_FAILURE(status)) {
-		if (pinfo.node->type == ACPI_TYPE_DEVICE) {
-			/* Ignore error and move on to next device */
+		/* Ignore error and move on to next device */
 
-			return_ACPI_STATUS(AE_OK);
-		}
+		return_ACPI_STATUS(AE_OK);
+	}
 
-		/* _STA is not required for Processor or thermal_zone objects */
-	} else {
+	if (flags != ACPI_UINT32_MAX) {
 		info->num_STA++;
+	}
 
-		if (!(flags & 0x01)) {
-			/* Don't look at children of a not present device */
+	if (!(flags & ACPI_STA_DEVICE_PRESENT)) {
+		/* Don't look at children of a not present device */
 
-			return_ACPI_STATUS(AE_CTRL_DEPTH);
-		}
+		return_ACPI_STATUS(AE_CTRL_DEPTH);
 	}
 
 	/*
-	 * The device is present. Run _INI.
+	 * The device is present and _INI exists. Run the _INI method.
+	 * (We already have the _INI node from above)
 	 */
 	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_METHOD,
 						      pinfo.node,
 						      METHOD_NAME__INI));
-	status = acpi_ns_evaluate_relative(METHOD_NAME__INI, &pinfo);
-	if (ACPI_FAILURE(status)) {
-		/* No _INI (AE_NOT_FOUND) means device requires no initialization */
 
-		if (status != AE_NOT_FOUND) {
-			/* Ignore error and move on to next device */
+	pinfo.node = ini_node;
+	status = acpi_ns_evaluate_by_handle(&pinfo);
+	if (ACPI_FAILURE(status)) {
+		/* Ignore error and move on to next device */
 
 #ifdef ACPI_DEBUG_OUTPUT
-			char *scope_name =
-			    acpi_ns_get_external_pathname(pinfo.node);
+		char *scope_name = acpi_ns_get_external_pathname(ini_node);
 
-			ACPI_DEBUG_PRINT((ACPI_DB_WARN, "%s._INI failed: %s\n",
-					  scope_name,
-					  acpi_format_exception(status)));
+		ACPI_WARNING((AE_INFO, "%s._INI failed: %s",
+			      scope_name, acpi_format_exception(status)));
 
-			ACPI_MEM_FREE(scope_name);
+		ACPI_MEM_FREE(scope_name);
 #endif
-		}
-
-		status = AE_OK;
 	} else {
 		/* Delete any return object (especially if implicit_return is enabled) */
 
@@ -434,5 +441,5 @@ acpi_ns_init_one_device(acpi_handle obj_
 		    acpi_gbl_init_handler(pinfo.node, ACPI_INIT_DEVICE_INI);
 	}
 
-	return_ACPI_STATUS(status);
+	return_ACPI_STATUS(AE_OK);
 }
diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c
index c28849d..4e0b052 100644
--- a/drivers/acpi/namespace/nsload.c
+++ b/drivers/acpi/namespace/nsload.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -92,7 +92,7 @@ acpi_ns_load_table(struct acpi_table_des
 	/* Check validity of the AML start and length */
 
 	if (!table_desc->aml_start) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Null AML pointer\n"));
+		ACPI_ERROR((AE_INFO, "Null AML pointer"));
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
@@ -102,8 +102,8 @@ acpi_ns_load_table(struct acpi_table_des
 	/* Ignore table if there is no AML contained within */
 
 	if (!table_desc->aml_length) {
-		ACPI_REPORT_WARNING(("Zero-length AML block in table [%4.4s]\n",
-				     table_desc->pointer->signature));
+		ACPI_WARNING((AE_INFO, "Zero-length AML block in table [%4.4s]",
+			      table_desc->pointer->signature));
 		return_ACPI_STATUS(AE_OK);
 	}
 
@@ -263,7 +263,7 @@ acpi_status acpi_ns_load_namespace(void)
 	/* There must be at least a DSDT installed */
 
 	if (acpi_gbl_DSDT == NULL) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "DSDT is not in memory\n"));
+		ACPI_ERROR((AE_INFO, "DSDT is not in memory"));
 		return_ACPI_STATUS(AE_NO_ACPI_TABLES);
 	}
 
diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c
index d5e8dea..639f653 100644
--- a/drivers/acpi/namespace/nsnames.c
+++ b/drivers/acpi/namespace/nsnames.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -75,7 +75,7 @@ acpi_ns_build_external_path(struct acpi_
 	acpi_size index;
 	struct acpi_namespace_node *parent_node;
 
-	ACPI_FUNCTION_NAME("ns_build_external_path");
+	ACPI_FUNCTION_ENTRY();
 
 	/* Special case for root */
 
@@ -110,9 +110,9 @@ acpi_ns_build_external_path(struct acpi_
 	name_buffer[index] = AML_ROOT_PREFIX;
 
 	if (index != 0) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Could not construct pathname; index=%X, size=%X, Path=%s\n",
-				  (u32) index, (u32) size, &name_buffer[size]));
+		ACPI_ERROR((AE_INFO,
+			    "Could not construct pathname; index=%X, size=%X, Path=%s",
+			    (u32) index, (u32) size, &name_buffer[size]));
 	}
 
 	return;
@@ -148,7 +148,7 @@ char *acpi_ns_get_external_pathname(stru
 
 	name_buffer = ACPI_MEM_CALLOCATE(size);
 	if (!name_buffer) {
-		ACPI_REPORT_ERROR(("ns_get_table_pathname: allocation failure\n"));
+		ACPI_ERROR((AE_INFO, "Allocation failure"));
 		return_PTR(NULL);
 	}
 
@@ -241,7 +241,7 @@ acpi_ns_handle_to_pathname(acpi_handle t
 
 	acpi_ns_build_external_path(node, required_size, buffer->pointer);
 
-	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s [%X] \n",
+	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s [%X]\n",
 			  (char *)buffer->pointer, (u32) required_size));
 	return_ACPI_STATUS(AE_OK);
 }
diff --git a/drivers/acpi/namespace/nsobject.c b/drivers/acpi/namespace/nsobject.c
index fc9be94..10ae629 100644
--- a/drivers/acpi/namespace/nsobject.c
+++ b/drivers/acpi/namespace/nsobject.c
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -84,22 +84,23 @@ acpi_ns_attach_object(struct acpi_namesp
 	if (!node) {
 		/* Invalid handle */
 
-		ACPI_REPORT_ERROR(("ns_attach_object: Null named_obj handle\n"));
+		ACPI_ERROR((AE_INFO, "Null named_obj handle"));
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
 	if (!object && (ACPI_TYPE_ANY != type)) {
 		/* Null object */
 
-		ACPI_REPORT_ERROR(("ns_attach_object: Null object, but type not ACPI_TYPE_ANY\n"));
+		ACPI_ERROR((AE_INFO,
+			    "Null object, but type not ACPI_TYPE_ANY"));
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
 	if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
 		/* Not a name handle */
 
-		ACPI_REPORT_ERROR(("ns_attach_object: Invalid handle %p [%s]\n",
-				   node, acpi_ut_get_descriptor_name(node)));
+		ACPI_ERROR((AE_INFO, "Invalid handle %p [%s]",
+			    node, acpi_ut_get_descriptor_name(node)));
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
@@ -254,7 +255,7 @@ union acpi_operand_object *acpi_ns_get_a
 	ACPI_FUNCTION_TRACE_PTR("ns_get_attached_object", node);
 
 	if (!node) {
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Null Node ptr\n"));
+		ACPI_WARNING((AE_INFO, "Null Node ptr"));
 		return_PTR(NULL);
 	}
 
diff --git a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c
index 433442a..232be43 100644
--- a/drivers/acpi/namespace/nsparse.c
+++ b/drivers/acpi/namespace/nsparse.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c
index 50a3ca5..d64b789 100644
--- a/drivers/acpi/namespace/nssearch.c
+++ b/drivers/acpi/namespace/nssearch.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -99,8 +99,8 @@ acpi_ns_search_node(u32 target_name,
 		if (scope_name) {
 			ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 					  "Searching %s (%p) For [%4.4s] (%s)\n",
-					  scope_name, node,
-					  (char *)&target_name,
+					  scope_name, node, ACPI_CAST_PTR(char,
+									  &target_name),
 					  acpi_ut_get_type_name(type)));
 
 			ACPI_MEM_FREE(scope_name);
@@ -131,7 +131,7 @@ acpi_ns_search_node(u32 target_name,
 			 */
 			ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 					  "Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n",
-					  (char *)&target_name,
+					  ACPI_CAST_PTR(char, &target_name),
 					  acpi_ut_get_type_name(next_node->
 								type),
 					  next_node,
@@ -160,7 +160,8 @@ acpi_ns_search_node(u32 target_name,
 
 	ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 			  "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n",
-			  (char *)&target_name, acpi_ut_get_type_name(type),
+			  ACPI_CAST_PTR(char, &target_name),
+			  acpi_ut_get_type_name(type),
 			  acpi_ut_get_node_name(node), node, node->child));
 
 	return_ACPI_STATUS(AE_NOT_FOUND);
@@ -210,14 +211,14 @@ acpi_ns_search_parent_tree(u32 target_na
 	 */
 	if (!parent_node) {
 		ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "[%4.4s] has no parent\n",
-				  (char *)&target_name));
+				  ACPI_CAST_PTR(char, &target_name)));
 		return_ACPI_STATUS(AE_NOT_FOUND);
 	}
 
 	if (acpi_ns_local(type)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 				  "[%4.4s] type [%s] must be local to this scope (no parent search)\n",
-				  (char *)&target_name,
+				  ACPI_CAST_PTR(char, &target_name),
 				  acpi_ut_get_type_name(type)));
 		return_ACPI_STATUS(AE_NOT_FOUND);
 	}
@@ -227,7 +228,7 @@ acpi_ns_search_parent_tree(u32 target_na
 	ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 			  "Searching parent [%4.4s] for [%4.4s]\n",
 			  acpi_ut_get_node_name(parent_node),
-			  (char *)&target_name));
+			  ACPI_CAST_PTR(char, &target_name)));
 
 	/*
 	 * Search parents until target is found or we have backed up to the root
@@ -297,18 +298,17 @@ acpi_ns_search_and_enter(u32 target_name
 	/* Parameter validation */
 
 	if (!node || !target_name || !return_node) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Null param: Node %p Name %X return_node %p\n",
-				  node, target_name, return_node));
-
-		ACPI_REPORT_ERROR(("ns_search_and_enter: Null parameter\n"));
+		ACPI_ERROR((AE_INFO,
+			    "Null param: Node %p Name %X return_node %p",
+			    node, target_name, return_node));
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
 	/* Name must consist of printable characters */
 
 	if (!acpi_ut_valid_acpi_name(target_name)) {
-		ACPI_REPORT_ERROR(("ns_search_and_enter: Bad character in ACPI Name: %X\n", target_name));
+		ACPI_ERROR((AE_INFO, "Bad character in ACPI Name: %X",
+			    target_name));
 		return_ACPI_STATUS(AE_BAD_CHARACTER);
 	}
 
@@ -360,7 +360,7 @@ acpi_ns_search_and_enter(u32 target_name
 	if (interpreter_mode == ACPI_IMODE_EXECUTE) {
 		ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 				  "%4.4s Not found in %p [Not adding]\n",
-				  (char *)&target_name, node));
+				  ACPI_CAST_PTR(char, &target_name), node));
 
 		return_ACPI_STATUS(AE_NOT_FOUND);
 	}
diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c
index ebec036..3e7cad5 100644
--- a/drivers/acpi/namespace/nsutils.c
+++ b/drivers/acpi/namespace/nsutils.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -63,7 +63,6 @@ acpi_name acpi_ns_find_parent_name(struc
  *
  * PARAMETERS:  module_name         - Caller's module name (for error output)
  *              line_number         - Caller's line number (for error output)
- *              component_id        - Caller's component ID (for error output)
  *              internal_name       - Name or path of the namespace node
  *              lookup_status       - Exception code from NS lookup
  *
@@ -76,19 +75,17 @@ acpi_name acpi_ns_find_parent_name(struc
 void
 acpi_ns_report_error(char *module_name,
 		     u32 line_number,
-		     u32 component_id,
 		     char *internal_name, acpi_status lookup_status)
 {
 	acpi_status status;
 	char *name = NULL;
 
-	acpi_os_printf("%8s-%04d: *** Error: Looking up ",
-		       module_name, line_number);
+	acpi_ut_report_error(module_name, line_number);
 
 	if (lookup_status == AE_BAD_CHARACTER) {
 		/* There is a non-ascii character in the name */
 
-		acpi_os_printf("[0x%4.4X] (NON-ASCII)\n",
+		acpi_os_printf("[0x%4.4X] (NON-ASCII)",
 			       *(ACPI_CAST_PTR(u32, internal_name)));
 	} else {
 		/* Convert path to external format */
@@ -109,7 +106,7 @@ acpi_ns_report_error(char *module_name,
 		}
 	}
 
-	acpi_os_printf(" in namespace, %s\n",
+	acpi_os_printf(" Namespace lookup failure, %s\n",
 		       acpi_format_exception(lookup_status));
 }
 
@@ -119,10 +116,9 @@ acpi_ns_report_error(char *module_name,
  *
  * PARAMETERS:  module_name         - Caller's module name (for error output)
  *              line_number         - Caller's line number (for error output)
- *              component_id        - Caller's component ID (for error output)
  *              Message             - Error message to use on failure
  *              prefix_node         - Prefix relative to the path
- *              Path                - Path to the node
+ *              Path                - Path to the node (optional)
  *              method_status       - Execution status
  *
  * RETURN:      None
@@ -134,7 +130,6 @@ acpi_ns_report_error(char *module_name,
 void
 acpi_ns_report_method_error(char *module_name,
 			    u32 line_number,
-			    u32 component_id,
 			    char *message,
 			    struct acpi_namespace_node *prefix_node,
 			    char *path, acpi_status method_status)
@@ -142,17 +137,16 @@ acpi_ns_report_method_error(char *module
 	acpi_status status;
 	struct acpi_namespace_node *node = prefix_node;
 
+	acpi_ut_report_error(module_name, line_number);
+
 	if (path) {
 		status = acpi_ns_get_node_by_path(path, prefix_node,
 						  ACPI_NS_NO_UPSEARCH, &node);
 		if (ACPI_FAILURE(status)) {
-			acpi_os_printf
-			    ("report_method_error: Could not get node\n");
-			return;
+			acpi_os_printf("[Could not get node by pathname]");
 		}
 	}
 
-	acpi_os_printf("%8s-%04d: *** Error: ", module_name, line_number);
 	acpi_ns_print_node_pathname(node, message);
 	acpi_os_printf(", %s\n", acpi_format_exception(method_status));
 }
@@ -248,11 +242,11 @@ acpi_object_type acpi_ns_get_type(struct
 	ACPI_FUNCTION_TRACE("ns_get_type");
 
 	if (!node) {
-		ACPI_REPORT_WARNING(("ns_get_type: Null Node input pointer\n"));
-		return_VALUE(ACPI_TYPE_ANY);
+		ACPI_WARNING((AE_INFO, "Null Node parameter"));
+		return_UINT32(ACPI_TYPE_ANY);
 	}
 
-	return_VALUE((acpi_object_type) node->type);
+	return_UINT32((acpi_object_type) node->type);
 }
 
 /*******************************************************************************
@@ -275,11 +269,11 @@ u32 acpi_ns_local(acpi_object_type type)
 	if (!acpi_ut_valid_object_type(type)) {
 		/* Type code out of range  */
 
-		ACPI_REPORT_WARNING(("ns_local: Invalid Object Type\n"));
-		return_VALUE(ACPI_NS_NORMAL);
+		ACPI_WARNING((AE_INFO, "Invalid Object Type %X", type));
+		return_UINT32(ACPI_NS_NORMAL);
 	}
 
-	return_VALUE((u32) acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL);
+	return_UINT32((u32) acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL);
 }
 
 /*******************************************************************************
@@ -627,7 +621,7 @@ acpi_ns_externalize_name(u32 internal_na
 	 * with internal_name (invalid format).
 	 */
 	if (required_length > internal_name_length) {
-		ACPI_REPORT_ERROR(("ns_externalize_name: Invalid internal name\n"));
+		ACPI_ERROR((AE_INFO, "Invalid internal name"));
 		return_ACPI_STATUS(AE_BAD_PATHNAME);
 	}
 
@@ -803,12 +797,11 @@ u32 acpi_ns_opens_scope(acpi_object_type
 	if (!acpi_ut_valid_object_type(type)) {
 		/* type code out of range  */
 
-		ACPI_REPORT_WARNING(("ns_opens_scope: Invalid Object Type %X\n",
-				     type));
-		return_VALUE(ACPI_NS_NORMAL);
+		ACPI_WARNING((AE_INFO, "Invalid Object Type %X", type));
+		return_UINT32(ACPI_NS_NORMAL);
 	}
 
-	return_VALUE(((u32) acpi_gbl_ns_properties[type]) & ACPI_NS_NEWSCOPE);
+	return_UINT32(((u32) acpi_gbl_ns_properties[type]) & ACPI_NS_NEWSCOPE);
 }
 
 /*******************************************************************************
diff --git a/drivers/acpi/namespace/nswalk.c b/drivers/acpi/namespace/nswalk.c
index 5f164c0..fcab1e7 100644
--- a/drivers/acpi/namespace/nswalk.c
+++ b/drivers/acpi/namespace/nswalk.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
index c07b046..a95f636 100644
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -112,8 +112,7 @@ acpi_evaluate_object_typed(acpi_handle h
 	if (return_buffer->length == 0) {
 		/* Error because caller specifically asked for a return value */
 
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No return value\n"));
-
+		ACPI_ERROR((AE_INFO, "No return value"));
 		return_ACPI_STATUS(AE_NULL_OBJECT);
 	}
 
@@ -125,11 +124,11 @@ acpi_evaluate_object_typed(acpi_handle h
 
 	/* Return object type does not match requested type */
 
-	ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-			  "Incorrect return type [%s] requested [%s]\n",
-			  acpi_ut_get_type_name(((union acpi_object *)
-						 return_buffer->pointer)->type),
-			  acpi_ut_get_type_name(return_type)));
+	ACPI_ERROR((AE_INFO,
+		    "Incorrect return type [%s] requested [%s]",
+		    acpi_ut_get_type_name(((union acpi_object *)return_buffer->
+					   pointer)->type),
+		    acpi_ut_get_type_name(return_type)));
 
 	if (must_free) {
 		/* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */
@@ -236,11 +235,11 @@ acpi_evaluate_object(acpi_handle handle,
 		 * qualified names above, this is an error
 		 */
 		if (!pathname) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Both Handle and Pathname are NULL\n"));
+			ACPI_ERROR((AE_INFO,
+				    "Both Handle and Pathname are NULL"));
 		} else {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Handle is NULL and Pathname is relative\n"));
+			ACPI_ERROR((AE_INFO,
+				    "Handle is NULL and Pathname is relative"));
 		}
 
 		status = AE_BAD_PARAMETER;
@@ -399,7 +398,7 @@ acpi_walk_namespace(acpi_object_type typ
 
 	/* Parameter validation */
 
-	if ((type > ACPI_TYPE_EXTERNAL_MAX) || (!max_depth) || (!user_function)) {
+	if ((type > ACPI_TYPE_LOCAL_MAX) || (!max_depth) || (!user_function)) {
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
@@ -473,8 +472,8 @@ acpi_ns_get_device_callback(acpi_handle 
 		return (AE_CTRL_DEPTH);
 	}
 
-	if (!(flags & 0x01)) {
-		/* Don't return at the device or children of the device if not there */
+	if (!(flags & ACPI_STA_DEVICE_PRESENT)) {
+		/* Don't examine children of the device if not present */
 
 		return (AE_CTRL_DEPTH);
 	}
diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c
index 6b5f8d4..8cd8675 100644
--- a/drivers/acpi/namespace/nsxfname.c
+++ b/drivers/acpi/namespace/nsxfname.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -300,8 +300,7 @@ acpi_get_object_info(acpi_handle handle,
 
 		status = acpi_ut_execute_CID(node, &cid_list);
 		if (ACPI_SUCCESS(status)) {
-			size += ((acpi_size) cid_list->count - 1) *
-			    sizeof(struct acpi_compatible_id);
+			size += cid_list->size;
 			info->valid |= ACPI_VALID_CID;
 		}
 
diff --git a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c
index 0856d42..a033259 100644
--- a/drivers/acpi/namespace/nsxfobj.c
+++ b/drivers/acpi/namespace/nsxfobj.c
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 20c9a37..ac5bbae 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -838,7 +838,7 @@ acpi_status acpi_os_wait_semaphore(acpi_
 			static const int quantum_ms = 1000 / HZ;
 
 			ret = down_trylock(sem);
-			for (i = timeout; (i > 0 && ret < 0); i -= quantum_ms) {
+			for (i = timeout; (i > 0 && ret != 0); i -= quantum_ms) {
 				schedule_timeout_interruptible(1);
 				ret = down_trylock(sem);
 			}
@@ -1060,13 +1060,11 @@ EXPORT_SYMBOL(max_cstate);
  * Acquire a spinlock.
  *
  * handle is a pointer to the spinlock_t.
- * flags is *not* the result of save_flags - it is an ACPI-specific flag variable
- *   that indicates whether we are at interrupt level.
  */
 
-unsigned long acpi_os_acquire_lock(acpi_handle handle)
+acpi_cpu_flags acpi_os_acquire_lock(acpi_handle handle)
 {
-	unsigned long flags;
+	acpi_cpu_flags flags;
 	spin_lock_irqsave((spinlock_t *) handle, flags);
 	return flags;
 }
@@ -1075,7 +1073,7 @@ unsigned long acpi_os_acquire_lock(acpi_
  * Release a spinlock. See above.
  */
 
-void acpi_os_release_lock(acpi_handle handle, unsigned long flags)
+void acpi_os_release_lock(acpi_handle handle, acpi_cpu_flags flags)
 {
 	spin_unlock_irqrestore((spinlock_t *) handle, flags);
 }
diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c
index 5858188..de573be 100644
--- a/drivers/acpi/parser/psargs.c
+++ b/drivers/acpi/parser/psargs.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -45,6 +45,7 @@
 #include <acpi/acparser.h>
 #include <acpi/amlcode.h>
 #include <acpi/acnamesp.h>
+#include <acpi/acdispat.h>
 
 #define _COMPONENT          ACPI_PARSER
 ACPI_MODULE_NAME("psargs")
@@ -62,61 +63,51 @@ static union acpi_parse_object *acpi_ps_
  *
  * PARAMETERS:  parser_state        - Current parser state object
  *
- * RETURN:      Decoded package length.  On completion, the AML pointer points
+ * RETURN:      Decoded package length. On completion, the AML pointer points
  *              past the length byte or bytes.
  *
- * DESCRIPTION: Decode and return a package length field
+ * DESCRIPTION: Decode and return a package length field.
+ *              Note: Largest package length is 28 bits, from ACPI specification
  *
  ******************************************************************************/
 
 static u32
 acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state)
 {
-	u32 encoded_length;
-	u32 length = 0;
+	u8 *aml = parser_state->aml;
+	u32 package_length = 0;
+	acpi_native_uint byte_count;
+	u8 byte_zero_mask = 0x3F;	/* Default [0:5] */
 
 	ACPI_FUNCTION_TRACE("ps_get_next_package_length");
 
-	encoded_length = (u32) ACPI_GET8(parser_state->aml);
-	parser_state->aml++;
-
-	switch (encoded_length >> 6) {	/* bits 6-7 contain encoding scheme */
-	case 0:		/* 1-byte encoding (bits 0-5) */
-
-		length = (encoded_length & 0x3F);
-		break;
-
-	case 1:		/* 2-byte encoding (next byte + bits 0-3) */
-
-		length = ((ACPI_GET8(parser_state->aml) << 04) |
-			  (encoded_length & 0x0F));
-		parser_state->aml++;
-		break;
-
-	case 2:		/* 3-byte encoding (next 2 bytes + bits 0-3) */
-
-		length = ((ACPI_GET8(parser_state->aml + 1) << 12) |
-			  (ACPI_GET8(parser_state->aml) << 04) |
-			  (encoded_length & 0x0F));
-		parser_state->aml += 2;
-		break;
+	/*
+	 * Byte 0 bits [6:7] contain the number of additional bytes
+	 * used to encode the package length, either 0,1,2, or 3
+	 */
+	byte_count = (aml[0] >> 6);
+	parser_state->aml += (byte_count + 1);
 
-	case 3:		/* 4-byte encoding (next 3 bytes + bits 0-3) */
+	/* Get bytes 3, 2, 1 as needed */
 
-		length = ((ACPI_GET8(parser_state->aml + 2) << 20) |
-			  (ACPI_GET8(parser_state->aml + 1) << 12) |
-			  (ACPI_GET8(parser_state->aml) << 04) |
-			  (encoded_length & 0x0F));
-		parser_state->aml += 3;
-		break;
-
-	default:
+	while (byte_count) {
+		/*
+		 * Final bit positions for the package length bytes:
+		 *      Byte3->[20:27]
+		 *      Byte2->[12:19]
+		 *      Byte1->[04:11]
+		 *      Byte0->[00:03]
+		 */
+		package_length |= (aml[byte_count] << ((byte_count << 3) - 4));
 
-		/* Can't get here, only 2 bits / 4 cases */
-		break;
+		byte_zero_mask = 0x0F;	/* Use bits [0:3] of byte 0 */
+		byte_count--;
 	}
 
-	return_VALUE(length);
+	/* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
+
+	package_length |= (aml[0] & byte_zero_mask);
+	return_UINT32(package_length);
 }
 
 /*******************************************************************************
@@ -135,16 +126,15 @@ acpi_ps_get_next_package_length(struct a
 u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state)
 {
 	u8 *start = parser_state->aml;
-	acpi_native_uint length;
+	u32 package_length;
 
 	ACPI_FUNCTION_TRACE("ps_get_next_package_end");
 
-	/* Function below changes parser_state->Aml */
+	/* Function below updates parser_state->Aml */
 
-	length =
-	    (acpi_native_uint) acpi_ps_get_next_package_length(parser_state);
+	package_length = acpi_ps_get_next_package_length(parser_state);
 
-	return_PTR(start + length);	/* end of package */
+	return_PTR(start + package_length);	/* end of package */
 }
 
 /*******************************************************************************
@@ -169,17 +159,15 @@ char *acpi_ps_get_next_namestring(struct
 
 	ACPI_FUNCTION_TRACE("ps_get_next_namestring");
 
-	/* Handle multiple prefix characters */
-
-	while (acpi_ps_is_prefix_char(ACPI_GET8(end))) {
-		/* Include prefix '\\' or '^' */
+	/* Point past any namestring prefix characters (backslash or carat) */
 
+	while (acpi_ps_is_prefix_char(*end)) {
 		end++;
 	}
 
-	/* Decode the path */
+	/* Decode the path prefix character */
 
-	switch (ACPI_GET8(end)) {
+	switch (*end) {
 	case 0:
 
 		/* null_name */
@@ -199,9 +187,9 @@ char *acpi_ps_get_next_namestring(struct
 
 	case AML_MULTI_NAME_PREFIX_OP:
 
-		/* Multiple name segments, 4 chars each */
+		/* Multiple name segments, 4 chars each, count in next byte */
 
-		end += 2 + ((acpi_size) ACPI_GET8(end + 1) * ACPI_NAME_SIZE);
+		end += 2 + (*(end + 1) * ACPI_NAME_SIZE);
 		break;
 
 	default:
@@ -212,7 +200,7 @@ char *acpi_ps_get_next_namestring(struct
 		break;
 	}
 
-	parser_state->aml = (u8 *) end;
+	parser_state->aml = end;
 	return_PTR((char *)start);
 }
 
@@ -224,7 +212,7 @@ char *acpi_ps_get_next_namestring(struct
  *              Arg                 - Where the namepath will be stored
  *              arg_count           - If the namepath points to a control method
  *                                    the method's argument is returned here.
- *              method_call         - Whether the namepath can possibly be the
+ *              possible_method_call - Whether the namepath can possibly be the
  *                                    start of a method call
  *
  * RETURN:      Status
@@ -240,11 +228,11 @@ char *acpi_ps_get_next_namestring(struct
 acpi_status
 acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
 			  struct acpi_parse_state *parser_state,
-			  union acpi_parse_object *arg, u8 method_call)
+			  union acpi_parse_object *arg, u8 possible_method_call)
 {
 	char *path;
 	union acpi_parse_object *name_op;
-	acpi_status status = AE_OK;
+	acpi_status status;
 	union acpi_operand_object *method_desc;
 	struct acpi_namespace_node *node;
 	union acpi_generic_state scope_info;
@@ -252,115 +240,129 @@ acpi_ps_get_next_namepath(struct acpi_wa
 	ACPI_FUNCTION_TRACE("ps_get_next_namepath");
 
 	path = acpi_ps_get_next_namestring(parser_state);
+	acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
 
-	/* Null path case is allowed */
+	/* Null path case is allowed, just exit */
 
-	if (path) {
-		/*
-		 * Lookup the name in the internal namespace
-		 */
-		scope_info.scope.node = NULL;
-		node = parser_state->start_node;
-		if (node) {
-			scope_info.scope.node = node;
-		}
+	if (!path) {
+		arg->common.value.name = path;
+		return_ACPI_STATUS(AE_OK);
+	}
 
-		/*
-		 * Lookup object.  We don't want to add anything new to the namespace
-		 * here, however.  So we use MODE_EXECUTE.  Allow searching of the
-		 * parent tree, but don't open a new scope -- we just want to lookup the
-		 * object  (MUST BE mode EXECUTE to perform upsearch)
-		 */
-		status = acpi_ns_lookup(&scope_info, path, ACPI_TYPE_ANY,
-					ACPI_IMODE_EXECUTE,
-					ACPI_NS_SEARCH_PARENT |
-					ACPI_NS_DONT_OPEN_SCOPE, NULL, &node);
-		if (ACPI_SUCCESS(status) && method_call) {
-			if (node->type == ACPI_TYPE_METHOD) {
-				/* This name is actually a control method invocation */
-
-				method_desc = acpi_ns_get_attached_object(node);
-				ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
-						  "Control Method - %p Desc %p Path=%p\n",
-						  node, method_desc, path));
+	/* Setup search scope info */
 
-				name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP);
-				if (!name_op) {
-					return_ACPI_STATUS(AE_NO_MEMORY);
-				}
+	scope_info.scope.node = NULL;
+	node = parser_state->start_node;
+	if (node) {
+		scope_info.scope.node = node;
+	}
 
-				/* Change arg into a METHOD CALL and attach name to it */
+	/*
+	 * Lookup the name in the internal namespace. We don't want to add
+	 * anything new to the namespace here, however, so we use MODE_EXECUTE.
+	 * Allow searching of the parent tree, but don't open a new scope -
+	 * we just want to lookup the object (must be mode EXECUTE to perform
+	 * the upsearch)
+	 */
+	status =
+	    acpi_ns_lookup(&scope_info, path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+			   ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
+			   NULL, &node);
 
-				acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
-				name_op->common.value.name = path;
+	/*
+	 * If this name is a control method invocation, we must
+	 * setup the method call
+	 */
+	if (ACPI_SUCCESS(status) &&
+	    possible_method_call && (node->type == ACPI_TYPE_METHOD)) {
+		/* This name is actually a control method invocation */
+
+		method_desc = acpi_ns_get_attached_object(node);
+		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
+				  "Control Method - %p Desc %p Path=%p\n", node,
+				  method_desc, path));
 
-				/* Point METHODCALL/NAME to the METHOD Node */
+		name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP);
+		if (!name_op) {
+			return_ACPI_STATUS(AE_NO_MEMORY);
+		}
 
-				name_op->common.node = node;
-				acpi_ps_append_arg(arg, name_op);
+		/* Change Arg into a METHOD CALL and attach name to it */
 
-				if (!method_desc) {
-					ACPI_REPORT_ERROR(("ps_get_next_namepath: Control Method %p has no attached object\n", node));
-					return_ACPI_STATUS(AE_AML_INTERNAL);
-				}
+		acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
+		name_op->common.value.name = path;
 
-				ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
-						  "Control Method - %p Args %X\n",
-						  node,
-						  method_desc->method.
-						  param_count));
-
-				/* Get the number of arguments to expect */
-
-				walk_state->arg_count =
-				    method_desc->method.param_count;
-				return_ACPI_STATUS(AE_OK);
-			}
+		/* Point METHODCALL/NAME to the METHOD Node */
 
-			/*
-			 * Else this is normal named object reference.
-			 * Just init the NAMEPATH object with the pathname.
-			 * (See code below)
-			 */
-		}
-
-		if (ACPI_FAILURE(status)) {
-			/*
-			 * 1) Any error other than NOT_FOUND is always severe
-			 * 2) NOT_FOUND is only important if we are executing a method.
-			 * 3) If executing a cond_ref_of opcode, NOT_FOUND is ok.
-			 */
-			if ((((walk_state->
-			       parse_flags & ACPI_PARSE_MODE_MASK) ==
-			      ACPI_PARSE_EXECUTE) && (status == AE_NOT_FOUND)
-			     && (walk_state->op->common.aml_opcode !=
-				 AML_COND_REF_OF_OP))
-			    || (status != AE_NOT_FOUND)) {
-				ACPI_REPORT_NSERROR(path, status);
-
-				acpi_os_printf
-				    ("search_node %p start_node %p return_node %p\n",
-				     scope_info.scope.node,
-				     parser_state->start_node, node);
-
-			} else {
-				/*
-				 * We got a NOT_FOUND during table load or we encountered
-				 * a cond_ref_of(x) where the target does not exist.
-				 * Either case is ok
-				 */
-				status = AE_OK;
-			}
+		name_op->common.node = node;
+		acpi_ps_append_arg(arg, name_op);
+
+		if (!method_desc) {
+			ACPI_ERROR((AE_INFO,
+				    "Control Method %p has no attached object",
+				    node));
+			return_ACPI_STATUS(AE_AML_INTERNAL);
 		}
+
+		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
+				  "Control Method - %p Args %X\n",
+				  node, method_desc->method.param_count));
+
+		/* Get the number of arguments to expect */
+
+		walk_state->arg_count = method_desc->method.param_count;
+		return_ACPI_STATUS(AE_OK);
 	}
 
 	/*
-	 * Regardless of success/failure above,
-	 * Just initialize the Op with the pathname.
+	 * Special handling if the name was not found during the lookup -
+	 * some not_found cases are allowed
 	 */
-	acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
-	arg->common.value.name = path;
+	if (status == AE_NOT_FOUND) {
+		/* 1) not_found is ok during load pass 1/2 (allow forward references) */
+
+		if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) !=
+		    ACPI_PARSE_EXECUTE) {
+			status = AE_OK;
+		}
+
+		/* 2) not_found during a cond_ref_of(x) is ok by definition */
+
+		else if (walk_state->op->common.aml_opcode ==
+			 AML_COND_REF_OF_OP) {
+			status = AE_OK;
+		}
+
+		/*
+		 * 3) not_found while building a Package is ok at this point, we
+		 * may flag as an error later if slack mode is not enabled.
+		 * (Some ASL code depends on allowing this behavior)
+		 */
+		else if ((arg->common.parent) &&
+			 ((arg->common.parent->common.aml_opcode ==
+			   AML_PACKAGE_OP)
+			  || (arg->common.parent->common.aml_opcode ==
+			      AML_VAR_PACKAGE_OP))) {
+			status = AE_OK;
+		}
+	}
+
+	/* Final exception check (may have been changed from code above) */
 
+	if (ACPI_FAILURE(status)) {
+		ACPI_ERROR_NAMESPACE(path, status);
+
+		if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) ==
+		    ACPI_PARSE_EXECUTE) {
+			/* Report a control method execution error */
+
+			status = acpi_ds_method_error(status, walk_state);
+		}
+	}
+
+	/* Save the namepath */
+
+	arg->common.value.name = path;
 	return_ACPI_STATUS(status);
 }
 
@@ -382,59 +384,63 @@ void
 acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
 			    u32 arg_type, union acpi_parse_object *arg)
 {
+	u32 length;
+	u16 opcode;
+	u8 *aml = parser_state->aml;
 
 	ACPI_FUNCTION_TRACE_U32("ps_get_next_simple_arg", arg_type);
 
 	switch (arg_type) {
 	case ARGP_BYTEDATA:
 
-		acpi_ps_init_op(arg, AML_BYTE_OP);
-		arg->common.value.integer = (u32) ACPI_GET8(parser_state->aml);
-		parser_state->aml++;
+		/* Get 1 byte from the AML stream */
+
+		opcode = AML_BYTE_OP;
+		arg->common.value.integer = (acpi_integer) * aml;
+		length = 1;
 		break;
 
 	case ARGP_WORDDATA:
 
-		acpi_ps_init_op(arg, AML_WORD_OP);
-
 		/* Get 2 bytes from the AML stream */
 
-		ACPI_MOVE_16_TO_32(&arg->common.value.integer,
-				   parser_state->aml);
-		parser_state->aml += 2;
+		opcode = AML_WORD_OP;
+		ACPI_MOVE_16_TO_64(&arg->common.value.integer, aml);
+		length = 2;
 		break;
 
 	case ARGP_DWORDDATA:
 
-		acpi_ps_init_op(arg, AML_DWORD_OP);
-
 		/* Get 4 bytes from the AML stream */
 
-		ACPI_MOVE_32_TO_32(&arg->common.value.integer,
-				   parser_state->aml);
-		parser_state->aml += 4;
+		opcode = AML_DWORD_OP;
+		ACPI_MOVE_32_TO_64(&arg->common.value.integer, aml);
+		length = 4;
 		break;
 
 	case ARGP_QWORDDATA:
 
-		acpi_ps_init_op(arg, AML_QWORD_OP);
-
 		/* Get 8 bytes from the AML stream */
 
-		ACPI_MOVE_64_TO_64(&arg->common.value.integer,
-				   parser_state->aml);
-		parser_state->aml += 8;
+		opcode = AML_QWORD_OP;
+		ACPI_MOVE_64_TO_64(&arg->common.value.integer, aml);
+		length = 8;
 		break;
 
 	case ARGP_CHARLIST:
 
-		acpi_ps_init_op(arg, AML_STRING_OP);
-		arg->common.value.string = (char *)parser_state->aml;
+		/* Get a pointer to the string, point past the string */
+
+		opcode = AML_STRING_OP;
+		arg->common.value.string = ACPI_CAST_PTR(char, aml);
 
-		while (ACPI_GET8(parser_state->aml) != '\0') {
-			parser_state->aml++;
+		/* Find the null terminator */
+
+		length = 0;
+		while (aml[length]) {
+			length++;
 		}
-		parser_state->aml++;
+		length++;
 		break;
 
 	case ARGP_NAME:
@@ -443,14 +449,16 @@ acpi_ps_get_next_simple_arg(struct acpi_
 		acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
 		arg->common.value.name =
 		    acpi_ps_get_next_namestring(parser_state);
-		break;
+		return_VOID;
 
 	default:
 
-		ACPI_REPORT_ERROR(("Invalid arg_type %X\n", arg_type));
-		break;
+		ACPI_ERROR((AE_INFO, "Invalid arg_type %X", arg_type));
+		return_VOID;
 	}
 
+	acpi_ps_init_op(arg, opcode);
+	parser_state->aml += length;
 	return_VOID;
 }
 
@@ -540,7 +548,7 @@ static union acpi_parse_object *acpi_ps_
 		 * access_type is first operand, access_attribute is second
 		 */
 		field->common.value.integer =
-		    (ACPI_GET8(parser_state->aml) << 8);
+		    (((u32) ACPI_GET8(parser_state->aml) << 8));
 		parser_state->aml++;
 		field->common.value.integer |= ACPI_GET8(parser_state->aml);
 		parser_state->aml++;
@@ -703,7 +711,7 @@ acpi_ps_get_next_arg(struct acpi_walk_st
 
 	default:
 
-		ACPI_REPORT_ERROR(("Invalid arg_type: %X\n", arg_type));
+		ACPI_ERROR((AE_INFO, "Invalid arg_type: %X", arg_type));
 		status = AE_AML_OPERAND_TYPE;
 		break;
 	}
diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c
index 088d339..00b072e 100644
--- a/drivers/acpi/parser/psloop.c
+++ b/drivers/acpi/parser/psloop.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -123,16 +123,12 @@ acpi_status acpi_ps_parse_loop(struct ac
 				    && ((status & AE_CODE_MASK) !=
 					AE_CODE_CONTROL)) {
 					if (status == AE_AML_NO_RETURN_VALUE) {
-						ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-								  "Invoked method did not return a value, %s\n",
-								  acpi_format_exception
-								  (status)));
+						ACPI_EXCEPTION((AE_INFO, status,
+								"Invoked method did not return a value"));
 
 					}
-					ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-							  "get_predicate Failed, %s\n",
-							  acpi_format_exception
-							  (status)));
+					ACPI_EXCEPTION((AE_INFO, status,
+							"get_predicate Failed"));
 					return_ACPI_STATUS(status);
 				}
 
@@ -190,11 +186,11 @@ acpi_status acpi_ps_parse_loop(struct ac
 
 				/* The opcode is unrecognized.  Just skip unknown opcodes */
 
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "Found unknown opcode %X at AML address %p offset %X, ignoring\n",
-						  walk_state->opcode,
-						  parser_state->aml,
-						  walk_state->aml_offset));
+				ACPI_ERROR((AE_INFO,
+					    "Found unknown opcode %X at AML address %p offset %X, ignoring",
+					    walk_state->opcode,
+					    parser_state->aml,
+					    walk_state->aml_offset));
 
 				ACPI_DUMP_BUFFER(parser_state->aml, 128);
 
@@ -281,10 +277,8 @@ acpi_status acpi_ps_parse_loop(struct ac
 				    walk_state->descending_callback(walk_state,
 								    &op);
 				if (ACPI_FAILURE(status)) {
-					ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-							  "During name lookup/catalog, %s\n",
-							  acpi_format_exception
-							  (status)));
+					ACPI_EXCEPTION((AE_INFO, status,
+							"During name lookup/catalog"));
 					goto close_this_op;
 				}
 
@@ -704,6 +698,15 @@ acpi_status acpi_ps_parse_loop(struct ac
 				acpi_ps_pop_scope(parser_state, &op,
 						  &walk_state->arg_types,
 						  &walk_state->arg_count);
+
+				if (op->common.aml_opcode != AML_WHILE_OP) {
+					status2 =
+					    acpi_ds_result_stack_pop
+					    (walk_state);
+					if (ACPI_FAILURE(status2)) {
+						return_ACPI_STATUS(status2);
+					}
+				}
 			}
 
 			/* Close this iteration of the While loop */
diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c
index 229ae86..11d6351 100644
--- a/drivers/acpi/parser/psopcode.c
+++ b/drivers/acpi/parser/psopcode.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -747,7 +747,7 @@ const struct acpi_opcode_info *acpi_ps_g
 
 	/* Unknown AML opcode */
 
-	ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+	ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 			  "Unknown AML opcode [%4.4X]\n", opcode));
 
 	return (&acpi_gbl_aml_op_info[_UNK]);
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c
index 76d4d64..a9f3229 100644
--- a/drivers/acpi/parser/psparse.c
+++ b/drivers/acpi/parser/psparse.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -333,7 +333,6 @@ acpi_ps_next_parse_state(struct acpi_wal
 
 	switch (callback_status) {
 	case AE_CTRL_TERMINATE:
-
 		/*
 		 * A control method was terminated via a RETURN statement.
 		 * The walk of this method is complete.
@@ -346,13 +345,19 @@ acpi_ps_next_parse_state(struct acpi_wal
 
 		parser_state->aml = walk_state->aml_last_while;
 		walk_state->control_state->common.value = FALSE;
-		status = AE_CTRL_BREAK;
+		status = acpi_ds_result_stack_pop(walk_state);
+		if (ACPI_SUCCESS(status)) {
+			status = AE_CTRL_BREAK;
+		}
 		break;
 
 	case AE_CTRL_CONTINUE:
 
 		parser_state->aml = walk_state->aml_last_while;
-		status = AE_CTRL_CONTINUE;
+		status = acpi_ds_result_stack_pop(walk_state);
+		if (ACPI_SUCCESS(status)) {
+			status = AE_CTRL_CONTINUE;
+		}
 		break;
 
 	case AE_CTRL_PENDING:
@@ -369,16 +374,18 @@ acpi_ps_next_parse_state(struct acpi_wal
 #endif
 
 	case AE_CTRL_TRUE:
-
 		/*
 		 * Predicate of an IF was true, and we are at the matching ELSE.
 		 * Just close out this package
 		 */
 		parser_state->aml = acpi_ps_get_next_package_end(parser_state);
+		status = acpi_ds_result_stack_pop(walk_state);
+		if (ACPI_SUCCESS(status)) {
+			status = AE_CTRL_PENDING;
+		}
 		break;
 
 	case AE_CTRL_FALSE:
-
 		/*
 		 * Either an IF/WHILE Predicate was false or we encountered a BREAK
 		 * opcode.  In both cases, we do not execute the rest of the
@@ -503,22 +510,23 @@ acpi_status acpi_ps_parse_aml(struct acp
 		} else if (status == AE_CTRL_TERMINATE) {
 			status = AE_OK;
 		} else if ((status != AE_OK) && (walk_state->method_desc)) {
-			ACPI_REPORT_METHOD_ERROR("Method execution failed",
-						 walk_state->method_node, NULL,
-						 status);
-
-			/* Ensure proper cleanup */
+			/* Either the method parse or actual execution failed */
 
-			walk_state->parse_flags |= ACPI_PARSE_EXECUTE;
+			ACPI_ERROR_METHOD("Method parse/execution failed",
+					  walk_state->method_node, NULL,
+					  status);
 
 			/* Check for possible multi-thread reentrancy problem */
 
 			if ((status == AE_ALREADY_EXISTS) &&
 			    (!walk_state->method_desc->method.semaphore)) {
 				/*
-				 * This method is marked not_serialized, but it tried to create
+				 * Method tried to create an object twice. The probable cause is
+				 * that the method cannot handle reentrancy.
+				 *
+				 * The method is marked not_serialized, but it tried to create
 				 * a named object, causing the second thread entrance to fail.
-				 * We will workaround this by marking the method permanently
+				 * Workaround this problem by marking the method permanently
 				 * as Serialized.
 				 */
 				walk_state->method_desc->method.method_flags |=
@@ -536,15 +544,23 @@ acpi_status acpi_ps_parse_aml(struct acp
 		acpi_ds_scope_stack_clear(walk_state);
 
 		/*
-		 * If we just returned from the execution of a control method,
-		 * there's lots of cleanup to do
+		 * If we just returned from the execution of a control method or if we
+		 * encountered an error during the method parse phase, there's lots of
+		 * cleanup to do
 		 */
-		if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) ==
-		    ACPI_PARSE_EXECUTE) {
+		if (((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) ==
+		     ACPI_PARSE_EXECUTE) || (ACPI_FAILURE(status))) {
 			if (walk_state->method_desc) {
 				/* Decrement the thread count on the method parse tree */
 
-				walk_state->method_desc->method.thread_count--;
+				if (walk_state->method_desc->method.
+				    thread_count) {
+					walk_state->method_desc->method.
+					    thread_count--;
+				} else {
+					ACPI_ERROR((AE_INFO,
+						    "Invalid zero thread count in method"));
+				}
 			}
 
 			acpi_ds_terminate_control_method(walk_state);
@@ -553,7 +569,6 @@ acpi_status acpi_ps_parse_aml(struct acp
 		/* Delete this walk state and all linked control states */
 
 		acpi_ps_cleanup_scope(&walk_state->parser_state);
-
 		previous_walk_state = walk_state;
 
 		ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
diff --git a/drivers/acpi/parser/psscope.c b/drivers/acpi/parser/psscope.c
index 1c953b6..bc6047c 100644
--- a/drivers/acpi/parser/psscope.c
+++ b/drivers/acpi/parser/psscope.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/parser/pstree.c b/drivers/acpi/parser/pstree.c
index f0e7558..dd6f167 100644
--- a/drivers/acpi/parser/pstree.c
+++ b/drivers/acpi/parser/pstree.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -132,7 +132,8 @@ acpi_ps_append_arg(union acpi_parse_obje
 	if (op_info->class == AML_CLASS_UNKNOWN) {
 		/* Invalid opcode */
 
-		ACPI_REPORT_ERROR(("ps_append_arg: Invalid AML Opcode: 0x%2.2X\n", op->common.aml_opcode));
+		ACPI_ERROR((AE_INFO, "Invalid AML Opcode: 0x%2.2X",
+			    op->common.aml_opcode));
 		return;
 	}
 
diff --git a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c
index 2075efb..3e07cb9 100644
--- a/drivers/acpi/parser/psutils.c
+++ b/drivers/acpi/parser/psutils.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/parser/pswalk.c b/drivers/acpi/parser/pswalk.c
index 08f2321..06f05bf 100644
--- a/drivers/acpi/parser/pswalk.c
+++ b/drivers/acpi/parser/pswalk.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c
index 4dcbd44..2dd48cb 100644
--- a/drivers/acpi/parser/psxface.c
+++ b/drivers/acpi/parser/psxface.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -50,6 +50,10 @@
 ACPI_MODULE_NAME("psxface")
 
 /* Local Prototypes */
+static void acpi_ps_start_trace(struct acpi_parameter_info *info);
+
+static void acpi_ps_stop_trace(struct acpi_parameter_info *info);
+
 static acpi_status acpi_ps_execute_pass(struct acpi_parameter_info *info);
 
 static void
@@ -57,6 +61,136 @@ acpi_ps_update_parameter_list(struct acp
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_debug_trace
+ *
+ * PARAMETERS:  method_name     - Valid ACPI name string
+ *              debug_level     - Optional level mask. 0 to use default
+ *              debug_layer     - Optional layer mask. 0 to use default
+ *              Flags           - bit 1: one shot(1) or persistent(0)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: External interface to enable debug tracing during control
+ *              method execution
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_debug_trace(char *name, u32 debug_level, u32 debug_layer, u32 flags)
+{
+	acpi_status status;
+
+	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	/* TBDs: Validate name, allow full path or just nameseg */
+
+	acpi_gbl_trace_method_name = *ACPI_CAST_PTR(u32, name);
+	acpi_gbl_trace_flags = flags;
+
+	if (debug_level) {
+		acpi_gbl_trace_dbg_level = debug_level;
+	}
+	if (debug_layer) {
+		acpi_gbl_trace_dbg_layer = debug_layer;
+	}
+
+	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_start_trace
+ *
+ * PARAMETERS:  Info        - Method info struct
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Start control method execution trace
+ *
+ ******************************************************************************/
+
+static void acpi_ps_start_trace(struct acpi_parameter_info *info)
+{
+	acpi_status status;
+
+	ACPI_FUNCTION_ENTRY();
+
+	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE(status)) {
+		return;
+	}
+
+	if ((!acpi_gbl_trace_method_name) ||
+	    (acpi_gbl_trace_method_name != info->node->name.integer)) {
+		goto exit;
+	}
+
+	acpi_gbl_original_dbg_level = acpi_dbg_level;
+	acpi_gbl_original_dbg_layer = acpi_dbg_layer;
+
+	acpi_dbg_level = 0x00FFFFFF;
+	acpi_dbg_layer = ACPI_UINT32_MAX;
+
+	if (acpi_gbl_trace_dbg_level) {
+		acpi_dbg_level = acpi_gbl_trace_dbg_level;
+	}
+	if (acpi_gbl_trace_dbg_layer) {
+		acpi_dbg_layer = acpi_gbl_trace_dbg_layer;
+	}
+
+      exit:
+	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_stop_trace
+ *
+ * PARAMETERS:  Info        - Method info struct
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Stop control method execution trace
+ *
+ ******************************************************************************/
+
+static void acpi_ps_stop_trace(struct acpi_parameter_info *info)
+{
+	acpi_status status;
+
+	ACPI_FUNCTION_ENTRY();
+
+	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE(status)) {
+		return;
+	}
+
+	if ((!acpi_gbl_trace_method_name) ||
+	    (acpi_gbl_trace_method_name != info->node->name.integer)) {
+		goto exit;
+	}
+
+	/* Disable further tracing if type is one-shot */
+
+	if (acpi_gbl_trace_flags & 1) {
+		acpi_gbl_trace_method_name = 0;
+		acpi_gbl_trace_dbg_level = 0;
+		acpi_gbl_trace_dbg_layer = 0;
+	}
+
+	acpi_dbg_level = acpi_gbl_original_dbg_level;
+	acpi_dbg_layer = acpi_gbl_original_dbg_layer;
+
+      exit:
+	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+}
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_ps_execute_method
  *
  * PARAMETERS:  Info            - Method info block, contains:
@@ -104,6 +238,10 @@ acpi_status acpi_ps_execute_method(struc
 	 */
 	acpi_ps_update_parameter_list(info, REF_INCREMENT);
 
+	/* Begin tracing if requested */
+
+	acpi_ps_start_trace(info);
+
 	/*
 	 * 1) Perform the first pass parse of the method to enter any
 	 *    named objects that it creates into the namespace
@@ -129,6 +267,10 @@ acpi_status acpi_ps_execute_method(struc
 	status = acpi_ps_execute_pass(info);
 
       cleanup:
+	/* End optional tracing */
+
+	acpi_ps_stop_trace(info);
+
 	/* Take away the extra reference that we gave the parameters above */
 
 	acpi_ps_update_parameter_list(info, REF_DECREMENT);
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index e567c03..65aee79 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -258,7 +258,7 @@ typedef int (*irq_lookup_func) (struct a
 
 static int
 acpi_pci_allocate_irq(struct acpi_prt_entry *entry,
-		      int *edge_level, int *active_high_low, char **link)
+		      int *triggering, int *polarity, char **link)
 {
 	int irq;
 
@@ -266,8 +266,8 @@ acpi_pci_allocate_irq(struct acpi_prt_en
 
 	if (entry->link.handle) {
 		irq = acpi_pci_link_allocate_irq(entry->link.handle,
-						 entry->link.index, edge_level,
-						 active_high_low, link);
+						 entry->link.index, triggering,
+						 polarity, link);
 		if (irq < 0) {
 			ACPI_DEBUG_PRINT((ACPI_DB_WARN,
 					  "Invalid IRQ link routing entry\n"));
@@ -275,8 +275,8 @@ acpi_pci_allocate_irq(struct acpi_prt_en
 		}
 	} else {
 		irq = entry->link.index;
-		*edge_level = ACPI_LEVEL_SENSITIVE;
-		*active_high_low = ACPI_ACTIVE_LOW;
+		*triggering = ACPI_LEVEL_SENSITIVE;
+		*polarity = ACPI_ACTIVE_LOW;
 	}
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", irq));
@@ -285,7 +285,7 @@ acpi_pci_allocate_irq(struct acpi_prt_en
 
 static int
 acpi_pci_free_irq(struct acpi_prt_entry *entry,
-		  int *edge_level, int *active_high_low, char **link)
+		  int *triggering, int *polarity, char **link)
 {
 	int irq;
 
@@ -307,8 +307,8 @@ static int
 acpi_pci_irq_lookup(struct pci_bus *bus,
 		    int device,
 		    int pin,
-		    int *edge_level,
-		    int *active_high_low, char **link, irq_lookup_func func)
+		    int *triggering,
+		    int *polarity, char **link, irq_lookup_func func)
 {
 	struct acpi_prt_entry *entry = NULL;
 	int segment = pci_domain_nr(bus);
@@ -327,7 +327,7 @@ acpi_pci_irq_lookup(struct pci_bus *bus,
 		return_VALUE(-1);
 	}
 
-	ret = func(entry, edge_level, active_high_low, link);
+	ret = func(entry, triggering, polarity, link);
 	return_VALUE(ret);
 }
 
@@ -339,8 +339,8 @@ acpi_pci_irq_lookup(struct pci_bus *bus,
 static int
 acpi_pci_irq_derive(struct pci_dev *dev,
 		    int pin,
-		    int *edge_level,
-		    int *active_high_low, char **link, irq_lookup_func func)
+		    int *triggering,
+		    int *polarity, char **link, irq_lookup_func func)
 {
 	struct pci_dev *bridge = dev;
 	int irq = -1;
@@ -374,7 +374,7 @@ acpi_pci_irq_derive(struct pci_dev *dev,
 		}
 
 		irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn),
-					  pin, edge_level, active_high_low,
+					  pin, triggering, polarity,
 					  link, func);
 	}
 
@@ -401,8 +401,8 @@ int acpi_pci_irq_enable(struct pci_dev *
 {
 	int irq = 0;
 	u8 pin = 0;
-	int edge_level = ACPI_LEVEL_SENSITIVE;
-	int active_high_low = ACPI_ACTIVE_LOW;
+	int triggering = ACPI_LEVEL_SENSITIVE;
+	int polarity = ACPI_ACTIVE_LOW;
 	char *link = NULL;
 	int rc;
 
@@ -431,7 +431,7 @@ int acpi_pci_irq_enable(struct pci_dev *
 	 * values override any BIOS-assigned IRQs set during boot.
 	 */
 	irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
-				  &edge_level, &active_high_low, &link,
+				  &triggering, &polarity, &link,
 				  acpi_pci_allocate_irq);
 
 	/*
@@ -439,8 +439,8 @@ int acpi_pci_irq_enable(struct pci_dev *
 	 * device's parent bridge.
 	 */
 	if (irq < 0)
-		irq = acpi_pci_irq_derive(dev, pin, &edge_level,
-					  &active_high_low, &link,
+		irq = acpi_pci_irq_derive(dev, pin, &triggering,
+					  &polarity, &link,
 					  acpi_pci_allocate_irq);
 
 	/*
@@ -462,7 +462,7 @@ int acpi_pci_irq_enable(struct pci_dev *
 		}
 	}
 
-	rc = acpi_register_gsi(irq, edge_level, active_high_low);
+	rc = acpi_register_gsi(irq, triggering, polarity);
 	if (rc < 0) {
 		printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: failed "
 		       "to register GSI\n", pci_name(dev), ('A' + pin));
@@ -477,8 +477,8 @@ int acpi_pci_irq_enable(struct pci_dev *
 		printk("Link [%s] -> ", link);
 
 	printk("GSI %u (%s, %s) -> IRQ %d\n", irq,
-	       (edge_level == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
-	       (active_high_low == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq);
+	       (triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
+	       (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq);
 
 	return_VALUE(0);
 }
@@ -494,8 +494,8 @@ void acpi_pci_irq_disable(struct pci_dev
 {
 	int gsi = 0;
 	u8 pin = 0;
-	int edge_level = ACPI_LEVEL_SENSITIVE;
-	int active_high_low = ACPI_ACTIVE_LOW;
+	int triggering = ACPI_LEVEL_SENSITIVE;
+	int polarity = ACPI_ACTIVE_LOW;
 
 	ACPI_FUNCTION_TRACE("acpi_pci_irq_disable");
 
@@ -511,7 +511,7 @@ void acpi_pci_irq_disable(struct pci_dev
 	 * First we check the PCI IRQ routing table (PRT) for an IRQ.
 	 */
 	gsi = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
-				  &edge_level, &active_high_low, NULL,
+				  &triggering, &polarity, NULL,
 				  acpi_pci_free_irq);
 	/*
 	 * If no PRT entry was found, we'll try to derive an IRQ from the
@@ -519,7 +519,7 @@ void acpi_pci_irq_disable(struct pci_dev
 	 */
 	if (gsi < 0)
 		gsi = acpi_pci_irq_derive(dev, pin,
-					  &edge_level, &active_high_low, NULL,
+					  &triggering, &polarity, NULL,
 					  acpi_pci_free_irq);
 	if (gsi < 0)
 		return_VOID;
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 78927c0..07bc6df 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -70,8 +70,8 @@ static struct acpi_driver acpi_pci_link_
  */
 struct acpi_pci_link_irq {
 	u8 active;		/* Current IRQ */
-	u8 edge_level;		/* All IRQs */
-	u8 active_high_low;	/* All IRQs */
+	u8 triggering;		/* All IRQs */
+	u8 polarity;	/* All IRQs */
 	u8 resource_type;
 	u8 possible_count;
 	u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
@@ -108,19 +108,19 @@ acpi_pci_link_check_possible(struct acpi
 
 	ACPI_FUNCTION_TRACE("acpi_pci_link_check_possible");
 
-	switch (resource->id) {
-	case ACPI_RSTYPE_START_DPF:
+	switch (resource->type) {
+	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
 		return_ACPI_STATUS(AE_OK);
-	case ACPI_RSTYPE_IRQ:
+	case ACPI_RESOURCE_TYPE_IRQ:
 		{
 			struct acpi_resource_irq *p = &resource->data.irq;
-			if (!p || !p->number_of_interrupts) {
+			if (!p || !p->interrupt_count) {
 				ACPI_DEBUG_PRINT((ACPI_DB_WARN,
 						  "Blank IRQ resource\n"));
 				return_ACPI_STATUS(AE_OK);
 			}
 			for (i = 0;
-			     (i < p->number_of_interrupts
+			     (i < p->interrupt_count
 			      && i < ACPI_PCI_LINK_MAX_POSSIBLE); i++) {
 				if (!p->interrupts[i]) {
 					ACPI_DEBUG_PRINT((ACPI_DB_WARN,
@@ -131,22 +131,22 @@ acpi_pci_link_check_possible(struct acpi
 				link->irq.possible[i] = p->interrupts[i];
 				link->irq.possible_count++;
 			}
-			link->irq.edge_level = p->edge_level;
-			link->irq.active_high_low = p->active_high_low;
-			link->irq.resource_type = ACPI_RSTYPE_IRQ;
+			link->irq.triggering = p->triggering;
+			link->irq.polarity = p->polarity;
+			link->irq.resource_type = ACPI_RESOURCE_TYPE_IRQ;
 			break;
 		}
-	case ACPI_RSTYPE_EXT_IRQ:
+	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
 		{
-			struct acpi_resource_ext_irq *p =
+			struct acpi_resource_extended_irq *p =
 			    &resource->data.extended_irq;
-			if (!p || !p->number_of_interrupts) {
+			if (!p || !p->interrupt_count) {
 				ACPI_DEBUG_PRINT((ACPI_DB_WARN,
 						  "Blank EXT IRQ resource\n"));
 				return_ACPI_STATUS(AE_OK);
 			}
 			for (i = 0;
-			     (i < p->number_of_interrupts
+			     (i < p->interrupt_count
 			      && i < ACPI_PCI_LINK_MAX_POSSIBLE); i++) {
 				if (!p->interrupts[i]) {
 					ACPI_DEBUG_PRINT((ACPI_DB_WARN,
@@ -157,9 +157,9 @@ acpi_pci_link_check_possible(struct acpi
 				link->irq.possible[i] = p->interrupts[i];
 				link->irq.possible_count++;
 			}
-			link->irq.edge_level = p->edge_level;
-			link->irq.active_high_low = p->active_high_low;
-			link->irq.resource_type = ACPI_RSTYPE_EXT_IRQ;
+			link->irq.triggering = p->triggering;
+			link->irq.polarity = p->polarity;
+			link->irq.resource_type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ;
 			break;
 		}
 	default:
@@ -201,11 +201,11 @@ acpi_pci_link_check_current(struct acpi_
 
 	ACPI_FUNCTION_TRACE("acpi_pci_link_check_current");
 
-	switch (resource->id) {
-	case ACPI_RSTYPE_IRQ:
+	switch (resource->type) {
+	case ACPI_RESOURCE_TYPE_IRQ:
 		{
 			struct acpi_resource_irq *p = &resource->data.irq;
-			if (!p || !p->number_of_interrupts) {
+			if (!p || !p->interrupt_count) {
 				/*
 				 * IRQ descriptors may have no IRQ# bits set,
 				 * particularly those those w/ _STA disabled
@@ -217,11 +217,11 @@ acpi_pci_link_check_current(struct acpi_
 			*irq = p->interrupts[0];
 			break;
 		}
-	case ACPI_RSTYPE_EXT_IRQ:
+	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
 		{
-			struct acpi_resource_ext_irq *p =
+			struct acpi_resource_extended_irq *p =
 			    &resource->data.extended_irq;
-			if (!p || !p->number_of_interrupts) {
+			if (!p || !p->interrupt_count) {
 				/*
 				 * extended IRQ descriptors must
 				 * return at least 1 IRQ
@@ -233,8 +233,10 @@ acpi_pci_link_check_current(struct acpi_
 			*irq = p->interrupts[0];
 			break;
 		}
+		break;
 	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Resource isn't an IRQ\n"));
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Resource %d isn't an IRQ\n", resource->type));
+	case ACPI_RESOURCE_TYPE_END_TAG:
 		return_ACPI_STATUS(AE_OK);
 	}
 	return_ACPI_STATUS(AE_CTRL_TERMINATE);
@@ -325,36 +327,36 @@ static int acpi_pci_link_set(struct acpi
 	buffer.pointer = resource;
 
 	switch (link->irq.resource_type) {
-	case ACPI_RSTYPE_IRQ:
-		resource->res.id = ACPI_RSTYPE_IRQ;
+	case ACPI_RESOURCE_TYPE_IRQ:
+		resource->res.type = ACPI_RESOURCE_TYPE_IRQ;
 		resource->res.length = sizeof(struct acpi_resource);
-		resource->res.data.irq.edge_level = link->irq.edge_level;
-		resource->res.data.irq.active_high_low =
-		    link->irq.active_high_low;
-		if (link->irq.edge_level == ACPI_EDGE_SENSITIVE)
-			resource->res.data.irq.shared_exclusive =
+		resource->res.data.irq.triggering = link->irq.triggering;
+		resource->res.data.irq.polarity =
+		    link->irq.polarity;
+		if (link->irq.triggering == ACPI_EDGE_SENSITIVE)
+			resource->res.data.irq.sharable =
 			    ACPI_EXCLUSIVE;
 		else
-			resource->res.data.irq.shared_exclusive = ACPI_SHARED;
-		resource->res.data.irq.number_of_interrupts = 1;
+			resource->res.data.irq.sharable = ACPI_SHARED;
+		resource->res.data.irq.interrupt_count = 1;
 		resource->res.data.irq.interrupts[0] = irq;
 		break;
 
-	case ACPI_RSTYPE_EXT_IRQ:
-		resource->res.id = ACPI_RSTYPE_EXT_IRQ;
+	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+		resource->res.type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ;
 		resource->res.length = sizeof(struct acpi_resource);
 		resource->res.data.extended_irq.producer_consumer =
 		    ACPI_CONSUMER;
-		resource->res.data.extended_irq.edge_level =
-		    link->irq.edge_level;
-		resource->res.data.extended_irq.active_high_low =
-		    link->irq.active_high_low;
-		if (link->irq.edge_level == ACPI_EDGE_SENSITIVE)
-			resource->res.data.irq.shared_exclusive =
+		resource->res.data.extended_irq.triggering =
+		    link->irq.triggering;
+		resource->res.data.extended_irq.polarity =
+		    link->irq.polarity;
+		if (link->irq.triggering == ACPI_EDGE_SENSITIVE)
+			resource->res.data.irq.sharable =
 			    ACPI_EXCLUSIVE;
 		else
-			resource->res.data.irq.shared_exclusive = ACPI_SHARED;
-		resource->res.data.extended_irq.number_of_interrupts = 1;
+			resource->res.data.irq.sharable = ACPI_SHARED;
+		resource->res.data.extended_irq.interrupt_count = 1;
 		resource->res.data.extended_irq.interrupts[0] = irq;
 		/* ignore resource_source, it's optional */
 		break;
@@ -364,7 +366,7 @@ static int acpi_pci_link_set(struct acpi
 		goto end;
 
 	}
-	resource->end.id = ACPI_RSTYPE_END_TAG;
+	resource->end.type = ACPI_RESOURCE_TYPE_END_TAG;
 
 	/* Attempt to set the resource */
 	status = acpi_set_current_resources(link->handle, &buffer);
@@ -613,7 +615,7 @@ static int acpi_pci_link_allocate(struct
 int
 acpi_pci_link_allocate_irq(acpi_handle handle,
 			   int index,
-			   int *edge_level, int *active_high_low, char **name)
+			   int *triggering, int *polarity, char **name)
 {
 	int result = 0;
 	struct acpi_device *device = NULL;
@@ -653,10 +655,10 @@ acpi_pci_link_allocate_irq(acpi_handle h
 	link->refcnt++;
 	up(&acpi_link_lock);
 
-	if (edge_level)
-		*edge_level = link->irq.edge_level;
-	if (active_high_low)
-		*active_high_low = link->irq.active_high_low;
+	if (triggering)
+		*triggering = link->irq.triggering;
+	if (polarity)
+		*polarity = link->irq.polarity;
 	if (name)
 		*name = acpi_device_bid(link->device);
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 0fd9988..4c313ea 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -122,15 +122,15 @@ get_root_bridge_busnr_callback(struct ac
 	int *busnr = (int *)data;
 	struct acpi_resource_address64 address;
 
-	if (resource->id != ACPI_RSTYPE_ADDRESS16 &&
-	    resource->id != ACPI_RSTYPE_ADDRESS32 &&
-	    resource->id != ACPI_RSTYPE_ADDRESS64)
+	if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
+	    resource->type != ACPI_RESOURCE_TYPE_ADDRESS32 &&
+	    resource->type != ACPI_RESOURCE_TYPE_ADDRESS64)
 		return AE_OK;
 
 	acpi_resource_to_address64(resource, &address);
 	if ((address.address_length > 0) &&
 	    (address.resource_type == ACPI_BUS_NUMBER_RANGE))
-		*busnr = address.min_address_range;
+		*busnr = address.minimum;
 
 	return AE_OK;
 }
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 1278aca..99a3a28 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -253,31 +253,21 @@ static int acpi_processor_errata(struct 
  * _PDC is required for a BIOS-OS handshake for most of the newer
  * ACPI processor features.
  */
-
-int acpi_processor_set_pdc(struct acpi_processor *pr,
-			   struct acpi_object_list *pdc_in)
+static int acpi_processor_set_pdc(struct acpi_processor *pr)
 {
+	struct acpi_object_list *pdc_in = pr->pdc;
 	acpi_status status = AE_OK;
-	u32 arg0_buf[3];
-	union acpi_object arg0 = { ACPI_TYPE_BUFFER };
-	struct acpi_object_list no_object = { 1, &arg0 };
-	struct acpi_object_list *pdc;
 
 	ACPI_FUNCTION_TRACE("acpi_processor_set_pdc");
 
-	arg0.buffer.length = 12;
-	arg0.buffer.pointer = (u8 *) arg0_buf;
-	arg0_buf[0] = ACPI_PDC_REVISION_ID;
-	arg0_buf[1] = 0;
-	arg0_buf[2] = 0;
-
-	pdc = (pdc_in) ? pdc_in : &no_object;
+	if (!pdc_in)
+		return_VALUE(status);
 
-	status = acpi_evaluate_object(pr->handle, "_PDC", pdc, NULL);
+	status = acpi_evaluate_object(pr->handle, "_PDC", pdc_in, NULL);
 
-	if ((ACPI_FAILURE(status)) && (pdc_in))
+	if (ACPI_FAILURE(status))
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Error evaluating _PDC, using legacy perf. control...\n"));
+		    "Could not evaluate _PDC, using legacy perf. control...\n"));
 
 	return_VALUE(status);
 }
@@ -357,7 +347,6 @@ static int acpi_processor_add_fs(struct 
 				  ACPI_PROCESSOR_FILE_THROTTLING));
 	else {
 		entry->proc_fops = &acpi_processor_throttling_fops;
-		entry->proc_fops->write = acpi_processor_write_throttling;
 		entry->data = acpi_driver_data(device);
 		entry->owner = THIS_MODULE;
 	}
@@ -372,7 +361,6 @@ static int acpi_processor_add_fs(struct 
 				  ACPI_PROCESSOR_FILE_LIMIT));
 	else {
 		entry->proc_fops = &acpi_processor_limit_fops;
-		entry->proc_fops->write = acpi_processor_write_limit;
 		entry->data = acpi_driver_data(device);
 		entry->owner = THIS_MODULE;
 	}
@@ -589,6 +577,10 @@ static int acpi_processor_start(struct a
 				  "Error installing device notify handler\n"));
 	}
 
+	/* _PDC call should be done before doing anything else (if reqd.). */
+	arch_acpi_processor_init_pdc(pr);
+	acpi_processor_set_pdc(pr);
+
 	acpi_processor_power_init(pr, device);
 
 	if (pr->flags.throttling) {
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index cc04933..be2dae5 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -95,22 +95,57 @@ static int set_max_cstate(struct dmi_sys
 }
 
 static struct dmi_system_id __initdata processor_power_dmi_table[] = {
-	{set_max_cstate, "IBM ThinkPad R40e", {
-					       DMI_MATCH(DMI_BIOS_VENDOR,
-							 "IBM"),
-					       DMI_MATCH(DMI_BIOS_VERSION,
-							 "1SET60WW")},
-	 (void *)1},
-	{set_max_cstate, "Medion 41700", {
-					  DMI_MATCH(DMI_BIOS_VENDOR,
-						    "Phoenix Technologies LTD"),
-					  DMI_MATCH(DMI_BIOS_VERSION,
-						    "R01-A1J")}, (void *)1},
-	{set_max_cstate, "Clevo 5600D", {
-					 DMI_MATCH(DMI_BIOS_VENDOR,
-						   "Phoenix Technologies LTD"),
-					 DMI_MATCH(DMI_BIOS_VERSION,
-						   "SHE845M0.86C.0013.D.0302131307")},
+	{ set_max_cstate, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW")}, (void *)1},
+	{ set_max_cstate, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET43WW") }, (void*)1},
+	{ set_max_cstate, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET45WW") }, (void*)1},
+	{ set_max_cstate, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET47WW") }, (void*)1},
+	{ set_max_cstate, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET50WW") }, (void*)1},
+	{ set_max_cstate, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET52WW") }, (void*)1},
+	{ set_max_cstate, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET55WW") }, (void*)1},
+	{ set_max_cstate, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET56WW") }, (void*)1},
+	{ set_max_cstate, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET59WW") }, (void*)1},
+	{ set_max_cstate, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }, (void*)1},
+	{ set_max_cstate, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET61WW") }, (void*)1},
+	{ set_max_cstate, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET62WW") }, (void*)1},
+	{ set_max_cstate, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET64WW") }, (void*)1},
+	{ set_max_cstate, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET65WW") }, (void*)1},
+	{ set_max_cstate, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET68WW") }, (void*)1},
+	{ set_max_cstate, "Medion 41700", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J")}, (void *)1},
+	{ set_max_cstate, "Clevo 5600D", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
 	 (void *)2},
 	{},
 };
@@ -550,18 +585,10 @@ static int acpi_processor_get_power_info
 	if (!pr->pblk)
 		return_VALUE(-ENODEV);
 
-	memset(pr->power.states, 0, sizeof(pr->power.states));
-
 	/* if info is obtained from pblk/fadt, type equals state */
-	pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
 	pr->power.states[ACPI_STATE_C2].type = ACPI_STATE_C2;
 	pr->power.states[ACPI_STATE_C3].type = ACPI_STATE_C3;
 
-	/* the C0 state only exists as a filler in our array,
-	 * and all processors need to support C1 */
-	pr->power.states[ACPI_STATE_C0].valid = 1;
-	pr->power.states[ACPI_STATE_C1].valid = 1;
-
 #ifndef CONFIG_HOTPLUG_CPU
 	/*
 	 * Check for P_LVL2_UP flag before entering C2 and above on
@@ -591,12 +618,11 @@ static int acpi_processor_get_power_info
 {
 	ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_default_c1");
 
+	/* Zero initialize all the C-states info. */
 	memset(pr->power.states, 0, sizeof(pr->power.states));
 
-	/* if info is obtained from pblk/fadt, type equals state */
+	/* set the first C-State to C1 */
 	pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
-	pr->power.states[ACPI_STATE_C2].type = ACPI_STATE_C2;
-	pr->power.states[ACPI_STATE_C3].type = ACPI_STATE_C3;
 
 	/* the C0 state only exists as a filler in our array,
 	 * and all processors need to support C1 */
@@ -610,6 +636,7 @@ static int acpi_processor_get_power_info
 {
 	acpi_status status = 0;
 	acpi_integer count;
+	int current_count;
 	int i;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 	union acpi_object *cst;
@@ -619,10 +646,12 @@ static int acpi_processor_get_power_info
 	if (nocst)
 		return_VALUE(-ENODEV);
 
-	pr->power.count = 0;
-	for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++)
-		memset(&(pr->power.states[i]), 0,
-		       sizeof(struct acpi_processor_cx));
+	current_count = 1;
+
+	/* Zero initialize C2 onwards and prepare for fresh CST lookup */
+	for (i = 2; i < ACPI_PROCESSOR_MAX_POWER; i++)
+		memset(&(pr->power.states[i]), 0, 
+				sizeof(struct acpi_processor_cx));
 
 	status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer);
 	if (ACPI_FAILURE(status)) {
@@ -650,16 +679,6 @@ static int acpi_processor_get_power_info
 		goto end;
 	}
 
-	/* We support up to ACPI_PROCESSOR_MAX_POWER. */
-	if (count > ACPI_PROCESSOR_MAX_POWER) {
-		printk(KERN_WARNING
-		       "Limiting number of power states to max (%d)\n",
-		       ACPI_PROCESSOR_MAX_POWER);
-		printk(KERN_WARNING
-		       "Please increase ACPI_PROCESSOR_MAX_POWER if needed.\n");
-		count = ACPI_PROCESSOR_MAX_POWER;
-	}
-
 	/* Tell driver that at least _CST is supported. */
 	pr->flags.has_cst = 1;
 
@@ -703,7 +722,7 @@ static int acpi_processor_get_power_info
 		    (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO))
 			continue;
 
-		if ((cx.type < ACPI_STATE_C1) || (cx.type > ACPI_STATE_C3))
+		if ((cx.type < ACPI_STATE_C2) || (cx.type > ACPI_STATE_C3))
 			continue;
 
 		obj = (union acpi_object *)&(element->package.elements[2]);
@@ -718,15 +737,28 @@ static int acpi_processor_get_power_info
 
 		cx.power = obj->integer.value;
 
-		(pr->power.count)++;
-		memcpy(&(pr->power.states[pr->power.count]), &cx, sizeof(cx));
+		current_count++;
+		memcpy(&(pr->power.states[current_count]), &cx, sizeof(cx));
+
+		/*
+		 * We support total ACPI_PROCESSOR_MAX_POWER - 1
+		 * (From 1 through ACPI_PROCESSOR_MAX_POWER - 1)
+		 */
+		if (current_count >= (ACPI_PROCESSOR_MAX_POWER - 1)) {
+			printk(KERN_WARNING
+			       "Limiting number of power states to max (%d)\n",
+			       ACPI_PROCESSOR_MAX_POWER);
+			printk(KERN_WARNING
+			       "Please increase ACPI_PROCESSOR_MAX_POWER if needed.\n");
+			break;
+		}
 	}
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d power states\n",
-			  pr->power.count));
+			  current_count));
 
 	/* Validate number of power states discovered */
-	if (pr->power.count < 2)
+	if (current_count < 2)
 		status = -EFAULT;
 
       end:
@@ -892,12 +924,13 @@ static int acpi_processor_get_power_info
 	/* NOTE: the idle thread may not be running while calling
 	 * this function */
 
+	/* Adding C1 state */
+	acpi_processor_get_power_info_default_c1(pr);
 	result = acpi_processor_get_power_info_cst(pr);
 	if (result == -ENODEV)
-		result = acpi_processor_get_power_info_fadt(pr);
+		acpi_processor_get_power_info_fadt(pr);
 
-	if ((result) || (acpi_processor_power_verify(pr) < 2))
-		result = acpi_processor_get_power_info_default_c1(pr);
+	pr->power.count = acpi_processor_power_verify(pr);
 
 	/*
 	 * Set Default Policy
@@ -1066,8 +1099,6 @@ int acpi_processor_power_init(struct acp
 		}
 	}
 
-	acpi_processor_power_init_pdc(&(pr->power), pr->id);
-	acpi_processor_set_pdc(pr, pr->power.pdc);
 	acpi_processor_get_power_info(pr);
 
 	/*
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 22c7bb6..abbdb37 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -315,8 +315,6 @@ static int acpi_processor_get_performanc
 	if (!pr || !pr->performance || !pr->handle)
 		return_VALUE(-EINVAL);
 
-	acpi_processor_set_pdc(pr, pr->performance->pdc);
-
 	status = acpi_get_handle(pr->handle, "_PCT", &handle);
 	if (ACPI_FAILURE(status)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -520,8 +518,8 @@ static void acpi_cpufreq_add_file(struct
 				  "Unable to create '%s' fs entry\n",
 				  ACPI_PROCESSOR_FILE_PERFORMANCE));
 	else {
+		acpi_processor_perf_fops.write = acpi_processor_write_performance;
 		entry->proc_fops = &acpi_processor_perf_fops;
-		entry->proc_fops->write = acpi_processor_write_performance;
 		entry->data = acpi_driver_data(device);
 		entry->owner = THIS_MODULE;
 	}
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index dc9817c..f99ad05 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -348,9 +348,9 @@ static int acpi_processor_limit_open_fs(
 			   PDE(inode)->data);
 }
 
-ssize_t acpi_processor_write_limit(struct file * file,
-				   const char __user * buffer,
-				   size_t count, loff_t * data)
+static ssize_t acpi_processor_write_limit(struct file * file,
+					  const char __user * buffer,
+					  size_t count, loff_t * data)
 {
 	int result = 0;
 	struct seq_file *m = (struct seq_file *)file->private_data;
@@ -394,6 +394,7 @@ ssize_t acpi_processor_write_limit(struc
 struct file_operations acpi_processor_limit_fops = {
 	.open = acpi_processor_limit_open_fs,
 	.read = seq_read,
+	.write = acpi_processor_write_limit,
 	.llseek = seq_lseek,
 	.release = single_release,
 };
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 74a52d4..b966549 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -306,9 +306,9 @@ static int acpi_processor_throttling_ope
 			   PDE(inode)->data);
 }
 
-ssize_t acpi_processor_write_throttling(struct file * file,
-					const char __user * buffer,
-					size_t count, loff_t * data)
+static ssize_t acpi_processor_write_throttling(struct file * file,
+					       const char __user * buffer,
+					       size_t count, loff_t * data)
 {
 	int result = 0;
 	struct seq_file *m = (struct seq_file *)file->private_data;
@@ -337,6 +337,7 @@ ssize_t acpi_processor_write_throttling(
 struct file_operations acpi_processor_throttling_fops = {
 	.open = acpi_processor_throttling_open_fs,
 	.read = seq_read,
+	.write = acpi_processor_write_throttling,
 	.llseek = seq_lseek,
 	.release = single_release,
 };
diff --git a/drivers/acpi/resources/Makefile b/drivers/acpi/resources/Makefile
index 2130b74..8de4f69 100644
--- a/drivers/acpi/resources/Makefile
+++ b/drivers/acpi/resources/Makefile
@@ -2,7 +2,7 @@
 # Makefile for all Linux ACPI interpreter subdirectories
 #
 
-obj-y := rsaddr.o  rscreate.o  rsio.o   rslist.o    rsmisc.o   rsxface.o \
+obj-y := rsaddr.o rscreate.o rsinfo.o rsio.o rslist.o rsmisc.o rsxface.o \
 	 rscalc.o  rsirq.o  rsmemory.o  rsutils.o
 
 obj-$(ACPI_FUTURE_USAGE) += rsdump.o
diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c
index 23b54ba..8fa3213 100644
--- a/drivers/acpi/resources/rsaddr.c
+++ b/drivers/acpi/resources/rsaddr.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -47,1072 +47,334 @@
 #define _COMPONENT          ACPI_RESOURCES
 ACPI_MODULE_NAME("rsaddr")
 
-/* Local prototypes */
-static void
-acpi_rs_decode_general_flags(union acpi_resource_data *resource, u8 flags);
-
-static u8 acpi_rs_encode_general_flags(union acpi_resource_data *resource);
-
-static void
-acpi_rs_decode_specific_flags(union acpi_resource_data *resource, u8 flags);
-
-static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource);
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_rs_decode_general_flags
- *
- * PARAMETERS:  Resource            - Address resource data struct
- *              Flags               - Actual flag byte
- *
- * RETURN:      Decoded flag bits in resource struct
- *
- * DESCRIPTION: Decode a general flag byte to an address resource struct
- *
- ******************************************************************************/
-
-static void
-acpi_rs_decode_general_flags(union acpi_resource_data *resource, u8 flags)
-{
-	ACPI_FUNCTION_ENTRY();
-
-	/* Producer / Consumer - flag bit[0] */
-
-	resource->address.producer_consumer = (u32) (flags & 0x01);
-
-	/* Decode (_DEC) - flag bit[1] */
-
-	resource->address.decode = (u32) ((flags >> 1) & 0x01);
-
-	/* Min Address Fixed (_MIF) - flag bit[2] */
-
-	resource->address.min_address_fixed = (u32) ((flags >> 2) & 0x01);
-
-	/* Max Address Fixed (_MAF) - flag bit[3] */
-
-	resource->address.max_address_fixed = (u32) ((flags >> 3) & 0x01);
-}
-
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_encode_general_flags
- *
- * PARAMETERS:  Resource            - Address resource data struct
- *
- * RETURN:      Encoded general flag byte
- *
- * DESCRIPTION: Construct a general flag byte from an address resource struct
+ * acpi_rs_convert_address16 - All WORD (16-bit) address resources
  *
  ******************************************************************************/
+struct acpi_rsconvert_info acpi_rs_convert_address16[5] = {
+	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS16,
+	 ACPI_RS_SIZE(struct acpi_resource_address16),
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address16)},
 
-static u8 acpi_rs_encode_general_flags(union acpi_resource_data *resource)
-{
-	u8 flags;
-
-	ACPI_FUNCTION_ENTRY();
-
-	/* Producer / Consumer - flag bit[0] */
-
-	flags = (u8) (resource->address.producer_consumer & 0x01);
-
-	/* Decode (_DEC) - flag bit[1] */
-
-	flags |= (u8) ((resource->address.decode & 0x01) << 1);
-
-	/* Min Address Fixed (_MIF) - flag bit[2] */
-
-	flags |= (u8) ((resource->address.min_address_fixed & 0x01) << 2);
+	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS16,
+	 sizeof(struct aml_resource_address16),
+	 0},
 
-	/* Max Address Fixed (_MAF) - flag bit[3] */
+	/* Resource Type, General Flags, and Type-Specific Flags */
 
-	flags |= (u8) ((resource->address.max_address_fixed & 0x01) << 3);
+	{ACPI_RSC_ADDRESS, 0, 0, 0},
 
-	return (flags);
-}
+	/*
+	 * These fields are contiguous in both the source and destination:
+	 * Address Granularity
+	 * Address Range Minimum
+	 * Address Range Maximum
+	 * Address Translation Offset
+	 * Address Length
+	 */
+	{ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.address16.granularity),
+	 AML_OFFSET(address16.granularity),
+	 5},
+
+	/* Optional resource_source (Index and String) */
+
+	{ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address16.resource_source),
+	 0,
+	 sizeof(struct aml_resource_address16)}
+};
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_decode_specific_flags
- *
- * PARAMETERS:  Resource            - Address resource data struct
- *              Flags               - Actual flag byte
- *
- * RETURN:      Decoded flag bits in attribute struct
- *
- * DESCRIPTION: Decode a type-specific flag byte to an attribute struct.
- *              Type-specific flags are only defined for the Memory and IO
- *              resource types.
+ * acpi_rs_convert_address32 - All DWORD (32-bit) address resources
  *
  ******************************************************************************/
 
-static void
-acpi_rs_decode_specific_flags(union acpi_resource_data *resource, u8 flags)
-{
-	ACPI_FUNCTION_ENTRY();
-
-	if (resource->address.resource_type == ACPI_MEMORY_RANGE) {
-		/* Write Status (_RW) - flag bit[0] */
+struct acpi_rsconvert_info acpi_rs_convert_address32[5] = {
+	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS32,
+	 ACPI_RS_SIZE(struct acpi_resource_address32),
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address32)},
 
-		resource->address.attribute.memory.read_write_attribute =
-		    (u16) (flags & 0x01);
+	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS32,
+	 sizeof(struct aml_resource_address32),
+	 0},
 
-		/* Memory Attributes (_MEM) - flag bits[2:1] */
+	/* Resource Type, General Flags, and Type-Specific Flags */
 
-		resource->address.attribute.memory.cache_attribute =
-		    (u16) ((flags >> 1) & 0x03);
-	} else if (resource->address.resource_type == ACPI_IO_RANGE) {
-		/* Ranges (_RNG) - flag bits[1:0] */
+	{ACPI_RSC_ADDRESS, 0, 0, 0},
 
-		resource->address.attribute.io.range_attribute =
-		    (u16) (flags & 0x03);
-
-		/* Translations (_TTP and _TRS) - flag bits[5:4] */
-
-		resource->address.attribute.io.translation_attribute =
-		    (u16) ((flags >> 4) & 0x03);
-	}
-}
+	/*
+	 * These fields are contiguous in both the source and destination:
+	 * Address Granularity
+	 * Address Range Minimum
+	 * Address Range Maximum
+	 * Address Translation Offset
+	 * Address Length
+	 */
+	{ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.address32.granularity),
+	 AML_OFFSET(address32.granularity),
+	 5},
+
+	/* Optional resource_source (Index and String) */
+
+	{ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address32.resource_source),
+	 0,
+	 sizeof(struct aml_resource_address32)}
+};
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_encode_specific_flags
- *
- * PARAMETERS:  Resource            - Address resource data struct
- *
- * RETURN:      Encoded type-specific flag byte
- *
- * DESCRIPTION: Construct a type-specific flag byte from an attribute struct.
- *              Type-specific flags are only defined for the Memory and IO
- *              resource types.
+ * acpi_rs_convert_address64 - All QWORD (64-bit) address resources
  *
  ******************************************************************************/
 
-static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource)
-{
-	u8 flags = 0;
-
-	ACPI_FUNCTION_ENTRY();
-
-	if (resource->address.resource_type == ACPI_MEMORY_RANGE) {
-		/* Write Status (_RW) - flag bit[0] */
-
-		flags = (u8)
-		    (resource->address.attribute.memory.
-		     read_write_attribute & 0x01);
+struct acpi_rsconvert_info acpi_rs_convert_address64[5] = {
+	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS64,
+	 ACPI_RS_SIZE(struct acpi_resource_address64),
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address64)},
 
-		/* Memory Attributes (_MEM) - flag bits[2:1] */
+	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS64,
+	 sizeof(struct aml_resource_address64),
+	 0},
 
-		flags |= (u8)
-		    ((resource->address.attribute.memory.
-		      cache_attribute & 0x03) << 1);
-	} else if (resource->address.resource_type == ACPI_IO_RANGE) {
-		/* Ranges (_RNG) - flag bits[1:0] */
+	/* Resource Type, General Flags, and Type-Specific Flags */
 
-		flags = (u8)
-		    (resource->address.attribute.io.range_attribute & 0x03);
+	{ACPI_RSC_ADDRESS, 0, 0, 0},
 
-		/* Translations (_TTP and _TRS) - flag bits[5:4] */
-
-		flags |= (u8)
-		    ((resource->address.attribute.io.
-		      translation_attribute & 0x03) << 4);
-	}
-
-	return (flags);
-}
+	/*
+	 * These fields are contiguous in both the source and destination:
+	 * Address Granularity
+	 * Address Range Minimum
+	 * Address Range Maximum
+	 * Address Translation Offset
+	 * Address Length
+	 */
+	{ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.address64.granularity),
+	 AML_OFFSET(address64.granularity),
+	 5},
+
+	/* Optional resource_source (Index and String) */
+
+	{ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address64.resource_source),
+	 0,
+	 sizeof(struct aml_resource_address64)}
+};
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_address16_resource
- *
- * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
- *                                        stream
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        consumed the byte_stream_buffer is
- *                                        returned
- *              output_buffer           - Pointer to the return data buffer
- *              structure_size          - Pointer to where the number of bytes
- *                                        in the return data struct is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *              structure pointed to by the output_buffer. Return the
- *              number of bytes consumed from the byte stream.
+ * acpi_rs_convert_ext_address64 - All Extended (64-bit) address resources
  *
  ******************************************************************************/
 
-acpi_status
-acpi_rs_address16_resource(u8 * byte_stream_buffer,
-			   acpi_size * bytes_consumed,
-			   u8 ** output_buffer, acpi_size * structure_size)
-{
-	u32 index;
-	u16 temp16;
-	u8 temp8;
-	u8 *temp_ptr;
-	u8 *buffer = byte_stream_buffer;
-	struct acpi_resource *output_struct = (void *)*output_buffer;
-	acpi_size struct_size =
-	    ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16);
-
-	ACPI_FUNCTION_TRACE("rs_address16_resource");
-
-	/* Get the Descriptor Length field */
-
-	buffer += 1;
-	ACPI_MOVE_16_TO_16(&temp16, buffer);
-
-	/* Validate minimum descriptor length */
-
-	if (temp16 < 13) {
-		return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
-	}
-
-	*bytes_consumed = temp16 + 3;
-	output_struct->id = ACPI_RSTYPE_ADDRESS16;
-
-	/* Get the Resource Type (Byte3) */
-
-	buffer += 2;
-	temp8 = *buffer;
-
-	/* Values 0-2 and 0xC0-0xFF are valid */
-
-	if ((temp8 > 2) && (temp8 < 0xC0)) {
-		return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
-	}
-
-	output_struct->data.address16.resource_type = temp8;
-
-	/* Get the General Flags (Byte4) */
-
-	buffer += 1;
-	acpi_rs_decode_general_flags(&output_struct->data, *buffer);
-
-	/* Get the Type Specific Flags (Byte5) */
-
-	buffer += 1;
-	acpi_rs_decode_specific_flags(&output_struct->data, *buffer);
-
-	/* Get Granularity (Bytes 6-7) */
-
-	buffer += 1;
-	ACPI_MOVE_16_TO_32(&output_struct->data.address16.granularity, buffer);
-
-	/* Get min_address_range (Bytes 8-9) */
-
-	buffer += 2;
-	ACPI_MOVE_16_TO_32(&output_struct->data.address16.min_address_range,
-			   buffer);
-
-	/* Get max_address_range (Bytes 10-11) */
-
-	buffer += 2;
-	ACPI_MOVE_16_TO_32(&output_struct->data.address16.max_address_range,
-			   buffer);
-
-	/* Get address_translation_offset (Bytes 12-13) */
+struct acpi_rsconvert_info acpi_rs_convert_ext_address64[5] = {
+	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64,
+	 ACPI_RS_SIZE(struct acpi_resource_extended_address64),
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_ext_address64)},
 
-	buffer += 2;
-	ACPI_MOVE_16_TO_32(&output_struct->data.address16.
-			   address_translation_offset, buffer);
+	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64,
+	 sizeof(struct aml_resource_extended_address64),
+	 0},
 
-	/* Get address_length (Bytes 14-15) */
+	/* Resource Type, General Flags, and Type-Specific Flags */
 
-	buffer += 2;
-	ACPI_MOVE_16_TO_32(&output_struct->data.address16.address_length,
-			   buffer);
+	{ACPI_RSC_ADDRESS, 0, 0, 0},
 
-	/* Resource Source Index (if present) */
-
-	buffer += 2;
+	/* Revision ID */
 
+	{ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.ext_address64.revision_iD),
+	 AML_OFFSET(ext_address64.revision_iD),
+	 1},
 	/*
-	 * This will leave us pointing to the Resource Source Index
-	 * If it is present, then save it off and calculate the
-	 * pointer to where the null terminated string goes:
-	 * Each Interrupt takes 32-bits + the 5 bytes of the
-	 * stream that are default.
-	 *
-	 * Note: Some resource descriptors will have an additional null, so
-	 * we add 1 to the length.
+	 * These fields are contiguous in both the source and destination:
+	 * Address Granularity
+	 * Address Range Minimum
+	 * Address Range Maximum
+	 * Address Translation Offset
+	 * Address Length
+	 * Type-Specific Attribute
 	 */
-	if (*bytes_consumed > (16 + 1)) {
-		/* Dereference the Index */
-
-		output_struct->data.address16.resource_source.index =
-		    (u32) * buffer;
-
-		/* Point to the String */
-
-		buffer += 1;
-
-		/* Point the String pointer to the end of this structure */
-
-		output_struct->data.address16.resource_source.string_ptr =
-		    (char *)((u8 *) output_struct + struct_size);
-
-		temp_ptr = (u8 *)
-		    output_struct->data.address16.resource_source.string_ptr;
-
-		/* Copy the resource_source string into the buffer */
-
-		index = 0;
-		while (*buffer) {
-			*temp_ptr = *buffer;
-
-			temp_ptr++;
-			buffer++;
-			index++;
-		}
-
-		/* Add the terminating null and set the string length */
-
-		*temp_ptr = 0;
-		output_struct->data.address16.resource_source.string_length =
-		    index + 1;
-
-		/*
-		 * In order for the struct_size to fall on a 32-bit boundary,
-		 * calculate the length of the string and expand the
-		 * struct_size to the next 32-bit boundary.
-		 */
-		temp8 = (u8) (index + 1);
-		struct_size += ACPI_ROUND_UP_to_32_bITS(temp8);
-	} else {
-		output_struct->data.address16.resource_source.index = 0;
-		output_struct->data.address16.resource_source.string_length = 0;
-		output_struct->data.address16.resource_source.string_ptr = NULL;
-	}
-
-	/* Set the Length parameter */
-
-	output_struct->length = (u32) struct_size;
-
-	/* Return the final size of the structure */
-
-	*structure_size = struct_size;
-	return_ACPI_STATUS(AE_OK);
-}
+	{ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.ext_address64.granularity),
+	 AML_OFFSET(ext_address64.granularity),
+	 6}
+};
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_address16_stream
- *
- * PARAMETERS:  linked_list             - Pointer to the resource linked list
- *              output_buffer           - Pointer to the user's return buffer
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        used in the output_buffer is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the linked list resource structure and fills in the
- *              the appropriate bytes in a byte stream
+ * acpi_rs_convert_general_flags - Flags common to all address descriptors
  *
  ******************************************************************************/
 
-acpi_status
-acpi_rs_address16_stream(struct acpi_resource *linked_list,
-			 u8 ** output_buffer, acpi_size * bytes_consumed)
-{
-	u8 *buffer = *output_buffer;
-	u8 *length_field;
-	acpi_size actual_bytes;
-
-	ACPI_FUNCTION_TRACE("rs_address16_stream");
-
-	/* Set the Descriptor Type field */
-
-	*buffer = ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE;
-	buffer += 1;
-
-	/* Save a pointer to the Length field - to be filled in later */
-
-	length_field = buffer;
-	buffer += 2;
-
-	/* Set the Resource Type (Memory, Io, bus_number) */
-
-	*buffer = (u8) (linked_list->data.address16.resource_type & 0x03);
-	buffer += 1;
-
-	/* Set the general flags */
-
-	*buffer = acpi_rs_encode_general_flags(&linked_list->data);
-	buffer += 1;
-
-	/* Set the type specific flags */
-
-	*buffer = acpi_rs_encode_specific_flags(&linked_list->data);
-	buffer += 1;
-
-	/* Set the address space granularity */
+static struct acpi_rsconvert_info acpi_rs_convert_general_flags[6] = {
+	{ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.flags),
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_general_flags)},
 
-	ACPI_MOVE_32_TO_16(buffer, &linked_list->data.address16.granularity);
-	buffer += 2;
+	/* Resource Type (Memory, Io, bus_number, etc.) */
 
-	/* Set the address range minimum */
+	{ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.address.resource_type),
+	 AML_OFFSET(address.resource_type),
+	 1},
 
-	ACPI_MOVE_32_TO_16(buffer,
-			   &linked_list->data.address16.min_address_range);
-	buffer += 2;
+	/* General Flags - Consume, Decode, min_fixed, max_fixed */
 
-	/* Set the address range maximum */
+	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.producer_consumer),
+	 AML_OFFSET(address.flags),
+	 0},
 
-	ACPI_MOVE_32_TO_16(buffer,
-			   &linked_list->data.address16.max_address_range);
-	buffer += 2;
+	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.decode),
+	 AML_OFFSET(address.flags),
+	 1},
 
-	/* Set the address translation offset */
+	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.min_address_fixed),
+	 AML_OFFSET(address.flags),
+	 2},
 
-	ACPI_MOVE_32_TO_16(buffer,
-			   &linked_list->data.address16.
-			   address_translation_offset);
-	buffer += 2;
-
-	/* Set the address length */
-
-	ACPI_MOVE_32_TO_16(buffer, &linked_list->data.address16.address_length);
-	buffer += 2;
-
-	/* Resource Source Index and Resource Source are optional */
-
-	if (linked_list->data.address16.resource_source.string_length) {
-		*buffer =
-		    (u8) linked_list->data.address16.resource_source.index;
-		buffer += 1;
-
-		/* Copy the resource_source string */
-
-		ACPI_STRCPY((char *)buffer,
-			    linked_list->data.address16.resource_source.
-			    string_ptr);
-
-		/*
-		 * Buffer needs to be set to the length of the string + one for the
-		 * terminating null
-		 */
-		buffer +=
-		    (acpi_size) (ACPI_STRLEN
-				 (linked_list->data.address16.resource_source.
-				  string_ptr) + 1);
-	}
-
-	/* Return the number of bytes consumed in this operation */
-
-	actual_bytes = ACPI_PTR_DIFF(buffer, *output_buffer);
-	*bytes_consumed = actual_bytes;
-
-	/*
-	 * Set the length field to the number of bytes consumed
-	 * minus the header size (3 bytes)
-	 */
-	actual_bytes -= 3;
-	ACPI_MOVE_SIZE_TO_16(length_field, &actual_bytes);
-	return_ACPI_STATUS(AE_OK);
-}
+	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.max_address_fixed),
+	 AML_OFFSET(address.flags),
+	 3}
+};
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_address32_resource
- *
- * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
- *                                        stream
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        consumed the byte_stream_buffer is
- *                                        returned
- *              output_buffer           - Pointer to the return data buffer
- *              structure_size          - Pointer to where the number of bytes
- *                                        in the return data struct is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *              structure pointed to by the output_buffer. Return the
- *              number of bytes consumed from the byte stream.
+ * acpi_rs_convert_mem_flags - Flags common to Memory address descriptors
  *
  ******************************************************************************/
 
-acpi_status
-acpi_rs_address32_resource(u8 * byte_stream_buffer,
-			   acpi_size * bytes_consumed,
-			   u8 ** output_buffer, acpi_size * structure_size)
-{
-	u16 temp16;
-	u8 temp8;
-	u8 *temp_ptr;
-	u32 index;
-	u8 *buffer = byte_stream_buffer;
-	struct acpi_resource *output_struct = (void *)*output_buffer;
-	acpi_size struct_size =
-	    ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32);
-
-	ACPI_FUNCTION_TRACE("rs_address32_resource");
-
-	/* Get the Descriptor Length field */
-
-	buffer += 1;
-	ACPI_MOVE_16_TO_16(&temp16, buffer);
+static struct acpi_rsconvert_info acpi_rs_convert_mem_flags[5] = {
+	{ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags),
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_mem_flags)},
 
-	/* Validate minimum descriptor length */
+	/* Memory-specific flags */
 
-	if (temp16 < 23) {
-		return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
-	}
-
-	*bytes_consumed = temp16 + 3;
-	output_struct->id = ACPI_RSTYPE_ADDRESS32;
-
-	/* Get the Resource Type (Byte3) */
-
-	buffer += 2;
-	temp8 = *buffer;
-
-	/* Values 0-2 and 0xC0-0xFF are valid */
-
-	if ((temp8 > 2) && (temp8 < 0xC0)) {
-		return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
-	}
-
-	output_struct->data.address32.resource_type = temp8;
-
-	/* Get the General Flags (Byte4) */
-
-	buffer += 1;
-	acpi_rs_decode_general_flags(&output_struct->data, *buffer);
-
-	/* Get the Type Specific Flags (Byte5) */
-
-	buffer += 1;
-	acpi_rs_decode_specific_flags(&output_struct->data, *buffer);
-
-	/* Get Granularity (Bytes 6-9) */
-
-	buffer += 1;
-	ACPI_MOVE_32_TO_32(&output_struct->data.address32.granularity, buffer);
-
-	/* Get min_address_range (Bytes 10-13) */
-
-	buffer += 4;
-	ACPI_MOVE_32_TO_32(&output_struct->data.address32.min_address_range,
-			   buffer);
-
-	/* Get max_address_range (Bytes 14-17) */
-
-	buffer += 4;
-	ACPI_MOVE_32_TO_32(&output_struct->data.address32.max_address_range,
-			   buffer);
+	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.write_protect),
+	 AML_OFFSET(address.specific_flags),
+	 0},
 
-	/* Get address_translation_offset (Bytes 18-21) */
+	{ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.caching),
+	 AML_OFFSET(address.specific_flags),
+	 1},
 
-	buffer += 4;
-	ACPI_MOVE_32_TO_32(&output_struct->data.address32.
-			   address_translation_offset, buffer);
+	{ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.range_type),
+	 AML_OFFSET(address.specific_flags),
+	 3},
 
-	/* Get address_length (Bytes 22-25) */
-
-	buffer += 4;
-	ACPI_MOVE_32_TO_32(&output_struct->data.address32.address_length,
-			   buffer);
-
-	/* Resource Source Index (if present) */
-
-	buffer += 4;
-
-	/*
-	 * This will leave us pointing to the Resource Source Index
-	 * If it is present, then save it off and calculate the
-	 * pointer to where the null terminated string goes:
-	 *
-	 * Note: Some resource descriptors will have an additional null, so
-	 * we add 1 to the length.
-	 */
-	if (*bytes_consumed > (26 + 1)) {
-		/* Dereference the Index */
-
-		output_struct->data.address32.resource_source.index =
-		    (u32) * buffer;
-
-		/* Point to the String */
-
-		buffer += 1;
-
-		/* Point the String pointer to the end of this structure */
-
-		output_struct->data.address32.resource_source.string_ptr =
-		    (char *)((u8 *) output_struct + struct_size);
-
-		temp_ptr = (u8 *)
-		    output_struct->data.address32.resource_source.string_ptr;
-
-		/* Copy the resource_source string into the buffer */
-
-		index = 0;
-		while (*buffer) {
-			*temp_ptr = *buffer;
-
-			temp_ptr++;
-			buffer++;
-			index++;
-		}
-
-		/* Add the terminating null and set the string length */
-
-		*temp_ptr = 0;
-		output_struct->data.address32.resource_source.string_length =
-		    index + 1;
-
-		/*
-		 * In order for the struct_size to fall on a 32-bit boundary,
-		 * calculate the length of the string and expand the
-		 * struct_size to the next 32-bit boundary.
-		 */
-		temp8 = (u8) (index + 1);
-		struct_size += ACPI_ROUND_UP_to_32_bITS(temp8);
-	} else {
-		output_struct->data.address32.resource_source.index = 0;
-		output_struct->data.address32.resource_source.string_length = 0;
-		output_struct->data.address32.resource_source.string_ptr = NULL;
-	}
-
-	/* Set the Length parameter */
-
-	output_struct->length = (u32) struct_size;
-
-	/* Return the final size of the structure */
-
-	*structure_size = struct_size;
-	return_ACPI_STATUS(AE_OK);
-}
+	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.translation),
+	 AML_OFFSET(address.specific_flags),
+	 5}
+};
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_address32_stream
- *
- * PARAMETERS:  linked_list             - Pointer to the resource linked list
- *              output_buffer           - Pointer to the user's return buffer
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        used in the output_buffer is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the linked list resource structure and fills in the
- *              the appropriate bytes in a byte stream
+ * acpi_rs_convert_io_flags - Flags common to I/O address descriptors
  *
  ******************************************************************************/
 
-acpi_status
-acpi_rs_address32_stream(struct acpi_resource *linked_list,
-			 u8 ** output_buffer, acpi_size * bytes_consumed)
-{
-	u8 *buffer;
-	u16 *length_field;
-
-	ACPI_FUNCTION_TRACE("rs_address32_stream");
-
-	buffer = *output_buffer;
-
-	/* Set the Descriptor Type field */
-
-	*buffer = ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE;
-	buffer += 1;
-
-	/* Save a pointer to the Length field - to be filled in later */
-
-	length_field = ACPI_CAST_PTR(u16, buffer);
-	buffer += 2;
-
-	/* Set the Resource Type (Memory, Io, bus_number) */
-
-	*buffer = (u8) (linked_list->data.address32.resource_type & 0x03);
-	buffer += 1;
-
-	/* Set the general flags */
-
-	*buffer = acpi_rs_encode_general_flags(&linked_list->data);
-	buffer += 1;
-
-	/* Set the type specific flags */
-
-	*buffer = acpi_rs_encode_specific_flags(&linked_list->data);
-	buffer += 1;
-
-	/* Set the address space granularity */
-
-	ACPI_MOVE_32_TO_32(buffer, &linked_list->data.address32.granularity);
-	buffer += 4;
-
-	/* Set the address range minimum */
-
-	ACPI_MOVE_32_TO_32(buffer,
-			   &linked_list->data.address32.min_address_range);
-	buffer += 4;
-
-	/* Set the address range maximum */
-
-	ACPI_MOVE_32_TO_32(buffer,
-			   &linked_list->data.address32.max_address_range);
-	buffer += 4;
-
-	/* Set the address translation offset */
-
-	ACPI_MOVE_32_TO_32(buffer,
-			   &linked_list->data.address32.
-			   address_translation_offset);
-	buffer += 4;
-
-	/* Set the address length */
-
-	ACPI_MOVE_32_TO_32(buffer, &linked_list->data.address32.address_length);
-	buffer += 4;
-
-	/* Resource Source Index and Resource Source are optional */
-
-	if (linked_list->data.address32.resource_source.string_length) {
-		*buffer =
-		    (u8) linked_list->data.address32.resource_source.index;
-		buffer += 1;
+static struct acpi_rsconvert_info acpi_rs_convert_io_flags[4] = {
+	{ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags),
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_io_flags)},
 
-		/* Copy the resource_source string */
+	/* I/O-specific flags */
 
-		ACPI_STRCPY((char *)buffer,
-			    linked_list->data.address32.resource_source.
-			    string_ptr);
+	{ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.io.range_type),
+	 AML_OFFSET(address.specific_flags),
+	 0},
 
-		/*
-		 * Buffer needs to be set to the length of the string + one for the
-		 *  terminating null
-		 */
-		buffer +=
-		    (acpi_size) (ACPI_STRLEN
-				 (linked_list->data.address32.resource_source.
-				  string_ptr) + 1);
-	}
-
-	/* Return the number of bytes consumed in this operation */
+	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.io.translation),
+	 AML_OFFSET(address.specific_flags),
+	 4},
 
-	*bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
-
-	/*
-	 * Set the length field to the number of bytes consumed
-	 * minus the header size (3 bytes)
-	 */
-	*length_field = (u16) (*bytes_consumed - 3);
-	return_ACPI_STATUS(AE_OK);
-}
+	{ACPI_RSC_1BITFLAG,
+	 ACPI_RS_OFFSET(data.address.info.io.translation_type),
+	 AML_OFFSET(address.specific_flags),
+	 5}
+};
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_address64_resource
+ * FUNCTION:    acpi_rs_get_address_common
+ *
+ * PARAMETERS:  Resource            - Pointer to the internal resource struct
+ *              Aml                 - Pointer to the AML resource descriptor
  *
- * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
- *                                        stream
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        consumed the byte_stream_buffer is
- *                                        returned
- *              output_buffer           - Pointer to the return data buffer
- *              structure_size          - Pointer to where the number of bytes
- *                                        in the return data struct is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *              structure pointed to by the output_buffer. Return the
- *              number of bytes consumed from the byte stream.
+ * RETURN:      TRUE if the resource_type field is OK, FALSE otherwise
+ *
+ * DESCRIPTION: Convert common flag fields from a raw AML resource descriptor
+ *              to an internal resource descriptor
  *
  ******************************************************************************/
 
-acpi_status
-acpi_rs_address64_resource(u8 * byte_stream_buffer,
-			   acpi_size * bytes_consumed,
-			   u8 ** output_buffer, acpi_size * structure_size)
+u8
+acpi_rs_get_address_common(struct acpi_resource *resource,
+			   union aml_resource *aml)
 {
-	u16 temp16;
-	u8 temp8;
-	u8 resource_type;
-	u8 *temp_ptr;
-	u32 index;
-	u8 *buffer = byte_stream_buffer;
-	struct acpi_resource *output_struct = (void *)*output_buffer;
-	acpi_size struct_size =
-	    ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64);
-
-	ACPI_FUNCTION_TRACE("rs_address64_resource");
-
-	/* Get the Descriptor Type */
-
-	resource_type = *buffer;
-
-	/* Get the Descriptor Length field */
-
-	buffer += 1;
-	ACPI_MOVE_16_TO_16(&temp16, buffer);
-
-	/* Validate minimum descriptor length */
-
-	if (temp16 < 43) {
-		return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
-	}
-
-	*bytes_consumed = temp16 + 3;
-	output_struct->id = ACPI_RSTYPE_ADDRESS64;
-
-	/* Get the Resource Type (Byte3) */
-
-	buffer += 2;
-	temp8 = *buffer;
-
-	/* Values 0-2 and 0xC0-0xFF are valid */
-
-	if ((temp8 > 2) && (temp8 < 0xC0)) {
-		return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
-	}
-
-	output_struct->data.address64.resource_type = temp8;
-
-	/* Get the General Flags (Byte4) */
-
-	buffer += 1;
-	acpi_rs_decode_general_flags(&output_struct->data, *buffer);
-
-	/* Get the Type Specific Flags (Byte5) */
-
-	buffer += 1;
-	acpi_rs_decode_specific_flags(&output_struct->data, *buffer);
+	ACPI_FUNCTION_ENTRY();
 
-	if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) {
-		/* Move past revision_id and Reserved byte */
+	/* Validate the Resource Type */
 
-		buffer += 2;
+	if ((aml->address.resource_type > 2)
+	    && (aml->address.resource_type < 0xC0)) {
+		return (FALSE);
 	}
 
-	/* Get Granularity (Bytes 6-13) or (Bytes 8-15) */
-
-	buffer += 1;
-	ACPI_MOVE_64_TO_64(&output_struct->data.address64.granularity, buffer);
-
-	/* Get min_address_range (Bytes 14-21) or (Bytes 16-23) */
-
-	buffer += 8;
-	ACPI_MOVE_64_TO_64(&output_struct->data.address64.min_address_range,
-			   buffer);
-
-	/* Get max_address_range (Bytes 22-29) or (Bytes 24-31) */
-
-	buffer += 8;
-	ACPI_MOVE_64_TO_64(&output_struct->data.address64.max_address_range,
-			   buffer);
-
-	/* Get address_translation_offset (Bytes 30-37) or (Bytes 32-39) */
-
-	buffer += 8;
-	ACPI_MOVE_64_TO_64(&output_struct->data.address64.
-			   address_translation_offset, buffer);
-
-	/* Get address_length (Bytes 38-45) or (Bytes 40-47) */
+	/* Get the Resource Type and General Flags */
 
-	buffer += 8;
-	ACPI_MOVE_64_TO_64(&output_struct->data.address64.address_length,
-			   buffer);
+	(void)acpi_rs_convert_aml_to_resource(resource, aml,
+					      acpi_rs_convert_general_flags);
 
-	output_struct->data.address64.resource_source.index = 0;
-	output_struct->data.address64.resource_source.string_length = 0;
-	output_struct->data.address64.resource_source.string_ptr = NULL;
+	/* Get the Type-Specific Flags (Memory and I/O descriptors only) */
 
-	if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) {
-		/* Get type_specific_attribute (Bytes 48-55) */
-
-		buffer += 8;
-		ACPI_MOVE_64_TO_64(&output_struct->data.address64.
-				   type_specific_attributes, buffer);
+	if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) {
+		(void)acpi_rs_convert_aml_to_resource(resource, aml,
+						      acpi_rs_convert_mem_flags);
+	} else if (resource->data.address.resource_type == ACPI_IO_RANGE) {
+		(void)acpi_rs_convert_aml_to_resource(resource, aml,
+						      acpi_rs_convert_io_flags);
 	} else {
-		output_struct->data.address64.type_specific_attributes = 0;
-
-		/* Resource Source Index (if present) */
-
-		buffer += 8;
+		/* Generic resource type, just grab the type_specific byte */
 
-		/*
-		 * This will leave us pointing to the Resource Source Index
-		 * If it is present, then save it off and calculate the
-		 * pointer to where the null terminated string goes:
-		 * Each Interrupt takes 32-bits + the 5 bytes of the
-		 * stream that are default.
-		 *
-		 * Note: Some resource descriptors will have an additional null, so
-		 * we add 1 to the length.
-		 */
-		if (*bytes_consumed > (46 + 1)) {
-			/* Dereference the Index */
-
-			output_struct->data.address64.resource_source.index =
-			    (u32) * buffer;
-
-			/* Point to the String */
-
-			buffer += 1;
-
-			/* Point the String pointer to the end of this structure */
-
-			output_struct->data.address64.resource_source.
-			    string_ptr =
-			    (char *)((u8 *) output_struct + struct_size);
-
-			temp_ptr = (u8 *)
-			    output_struct->data.address64.resource_source.
-			    string_ptr;
-
-			/* Copy the resource_source string into the buffer */
-
-			index = 0;
-			while (*buffer) {
-				*temp_ptr = *buffer;
-
-				temp_ptr++;
-				buffer++;
-				index++;
-			}
-
-			/*
-			 * Add the terminating null and set the string length
-			 */
-			*temp_ptr = 0;
-			output_struct->data.address64.resource_source.
-			    string_length = index + 1;
-
-			/*
-			 * In order for the struct_size to fall on a 32-bit boundary,
-			 * calculate the length of the string and expand the
-			 * struct_size to the next 32-bit boundary.
-			 */
-			temp8 = (u8) (index + 1);
-			struct_size += ACPI_ROUND_UP_to_32_bITS(temp8);
-		}
+		resource->data.address.info.type_specific =
+		    aml->address.specific_flags;
 	}
 
-	/* Set the Length parameter */
-
-	output_struct->length = (u32) struct_size;
-
-	/* Return the final size of the structure */
-
-	*structure_size = struct_size;
-	return_ACPI_STATUS(AE_OK);
+	return (TRUE);
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_address64_stream
+ * FUNCTION:    acpi_rs_set_address_common
  *
- * PARAMETERS:  linked_list             - Pointer to the resource linked list
- *              output_buffer           - Pointer to the user's return buffer
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        used in the output_buffer is returned
+ * PARAMETERS:  Aml                 - Pointer to the AML resource descriptor
+ *              Resource            - Pointer to the internal resource struct
  *
- * RETURN:      Status
+ * RETURN:      None
  *
- * DESCRIPTION: Take the linked list resource structure and fills in the
- *              the appropriate bytes in a byte stream
+ * DESCRIPTION: Convert common flag fields from a resource descriptor to an
+ *              AML descriptor
  *
  ******************************************************************************/
 
-acpi_status
-acpi_rs_address64_stream(struct acpi_resource *linked_list,
-			 u8 ** output_buffer, acpi_size * bytes_consumed)
+void
+acpi_rs_set_address_common(union aml_resource *aml,
+			   struct acpi_resource *resource)
 {
-	u8 *buffer;
-	u16 *length_field;
-
-	ACPI_FUNCTION_TRACE("rs_address64_stream");
-
-	buffer = *output_buffer;
-
-	/* Set the Descriptor Type field */
-
-	*buffer = ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE;
-	buffer += 1;
-
-	/* Save a pointer to the Length field - to be filled in later */
-
-	length_field = ACPI_CAST_PTR(u16, buffer);
-	buffer += 2;
-
-	/* Set the Resource Type (Memory, Io, bus_number) */
-
-	*buffer = (u8) (linked_list->data.address64.resource_type & 0x03);
-	buffer += 1;
-
-	/* Set the general flags */
-
-	*buffer = acpi_rs_encode_general_flags(&linked_list->data);
-	buffer += 1;
-
-	/* Set the type specific flags */
-
-	*buffer = acpi_rs_encode_specific_flags(&linked_list->data);
-	buffer += 1;
-
-	/* Set the address space granularity */
-
-	ACPI_MOVE_64_TO_64(buffer, &linked_list->data.address64.granularity);
-	buffer += 8;
-
-	/* Set the address range minimum */
-
-	ACPI_MOVE_64_TO_64(buffer,
-			   &linked_list->data.address64.min_address_range);
-	buffer += 8;
-
-	/* Set the address range maximum */
-
-	ACPI_MOVE_64_TO_64(buffer,
-			   &linked_list->data.address64.max_address_range);
-	buffer += 8;
-
-	/* Set the address translation offset */
-
-	ACPI_MOVE_64_TO_64(buffer,
-			   &linked_list->data.address64.
-			   address_translation_offset);
-	buffer += 8;
-
-	/* Set the address length */
-
-	ACPI_MOVE_64_TO_64(buffer, &linked_list->data.address64.address_length);
-	buffer += 8;
+	ACPI_FUNCTION_ENTRY();
 
-	/* Resource Source Index and Resource Source are optional */
+	/* Set the Resource Type and General Flags */
 
-	if (linked_list->data.address64.resource_source.string_length) {
-		*buffer =
-		    (u8) linked_list->data.address64.resource_source.index;
-		buffer += 1;
+	(void)acpi_rs_convert_resource_to_aml(resource, aml,
+					      acpi_rs_convert_general_flags);
 
-		/* Copy the resource_source string */
+	/* Set the Type-Specific Flags (Memory and I/O descriptors only) */
 
-		ACPI_STRCPY((char *)buffer,
-			    linked_list->data.address64.resource_source.
-			    string_ptr);
+	if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) {
+		(void)acpi_rs_convert_resource_to_aml(resource, aml,
+						      acpi_rs_convert_mem_flags);
+	} else if (resource->data.address.resource_type == ACPI_IO_RANGE) {
+		(void)acpi_rs_convert_resource_to_aml(resource, aml,
+						      acpi_rs_convert_io_flags);
+	} else {
+		/* Generic resource type, just copy the type_specific byte */
 
-		/*
-		 * Buffer needs to be set to the length of the string + one for the
-		 * terminating null
-		 */
-		buffer +=
-		    (acpi_size) (ACPI_STRLEN
-				 (linked_list->data.address64.resource_source.
-				  string_ptr) + 1);
+		aml->address.specific_flags =
+		    resource->data.address.info.type_specific;
 	}
-
-	/* Return the number of bytes consumed in this operation */
-
-	*bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
-
-	/*
-	 * Set the length field to the number of bytes consumed
-	 * minus the header size (3 bytes)
-	 */
-	*length_field = (u16) (*bytes_consumed - 3);
-	return_ACPI_STATUS(AE_OK);
 }
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
index 378f583..7d6481d 100644
--- a/drivers/acpi/resources/rscalc.c
+++ b/drivers/acpi/resources/rscalc.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -49,652 +49,433 @@
 #define _COMPONENT          ACPI_RESOURCES
 ACPI_MODULE_NAME("rscalc")
 
+/* Local prototypes */
+static u8 acpi_rs_count_set_bits(u16 bit_field);
+
+static acpi_rs_length
+acpi_rs_struct_option_length(struct acpi_resource_source *resource_source);
+
+static u32
+acpi_rs_stream_option_length(u32 resource_length, u32 minimum_total_length);
+
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_get_byte_stream_length
+ * FUNCTION:    acpi_rs_count_set_bits
  *
- * PARAMETERS:  linked_list         - Pointer to the resource linked list
- *              size_needed         - u32 pointer of the size buffer needed
- *                                    to properly return the parsed data
+ * PARAMETERS:  bit_field       - Field in which to count bits
  *
- * RETURN:      Status
+ * RETURN:      Number of bits set within the field
  *
- * DESCRIPTION: Takes the resource byte stream and parses it once, calculating
- *              the size buffer needed to hold the linked list that conveys
- *              the resource data.
+ * DESCRIPTION: Count the number of bits set in a resource field. Used for
+ *              (Short descriptor) interrupt and DMA lists.
  *
  ******************************************************************************/
-acpi_status
-acpi_rs_get_byte_stream_length(struct acpi_resource *linked_list,
-			       acpi_size * size_needed)
-{
-	acpi_size byte_stream_size_needed = 0;
-	acpi_size segment_size;
-	u8 done = FALSE;
-
-	ACPI_FUNCTION_TRACE("rs_get_byte_stream_length");
-
-	while (!done) {
-		/* Init the variable that will hold the size to add to the total. */
-
-		segment_size = 0;
-
-		switch (linked_list->id) {
-		case ACPI_RSTYPE_IRQ:
-			/*
-			 * IRQ Resource
-			 * For an IRQ Resource, Byte 3, although optional, will always be
-			 * created - it holds IRQ information.
-			 */
-			segment_size = 4;
-			break;
-
-		case ACPI_RSTYPE_DMA:
-			/*
-			 * DMA Resource
-			 * For this resource the size is static
-			 */
-			segment_size = 3;
-			break;
-
-		case ACPI_RSTYPE_START_DPF:
-			/*
-			 * Start Dependent Functions Resource
-			 * For a start_dependent_functions Resource, Byte 1, although
-			 * optional, will always be created.
-			 */
-			segment_size = 2;
-			break;
-
-		case ACPI_RSTYPE_END_DPF:
-			/*
-			 * End Dependent Functions Resource
-			 * For this resource the size is static
-			 */
-			segment_size = 1;
-			break;
-
-		case ACPI_RSTYPE_IO:
-			/*
-			 * IO Port Resource
-			 * For this resource the size is static
-			 */
-			segment_size = 8;
-			break;
 
-		case ACPI_RSTYPE_FIXED_IO:
-			/*
-			 * Fixed IO Port Resource
-			 * For this resource the size is static
-			 */
-			segment_size = 4;
-			break;
-
-		case ACPI_RSTYPE_VENDOR:
-			/*
-			 * Vendor Defined Resource
-			 * For a Vendor Specific resource, if the Length is between 1 and 7
-			 * it will be created as a Small Resource data type, otherwise it
-			 * is a Large Resource data type.
-			 */
-			if (linked_list->data.vendor_specific.length > 7) {
-				segment_size = 3;
-			} else {
-				segment_size = 1;
-			}
-			segment_size +=
-			    linked_list->data.vendor_specific.length;
-			break;
-
-		case ACPI_RSTYPE_END_TAG:
-			/*
-			 * End Tag
-			 * For this resource the size is static
-			 */
-			segment_size = 2;
-			done = TRUE;
-			break;
-
-		case ACPI_RSTYPE_MEM24:
-			/*
-			 * 24-Bit Memory Resource
-			 * For this resource the size is static
-			 */
-			segment_size = 12;
-			break;
+static u8 acpi_rs_count_set_bits(u16 bit_field)
+{
+	u8 bits_set;
 
-		case ACPI_RSTYPE_MEM32:
-			/*
-			 * 32-Bit Memory Range Resource
-			 * For this resource the size is static
-			 */
-			segment_size = 20;
-			break;
+	ACPI_FUNCTION_ENTRY();
 
-		case ACPI_RSTYPE_FIXED_MEM32:
-			/*
-			 * 32-Bit Fixed Memory Resource
-			 * For this resource the size is static
-			 */
-			segment_size = 12;
-			break;
+	for (bits_set = 0; bit_field; bits_set++) {
+		/* Zero the least significant bit that is set */
 
-		case ACPI_RSTYPE_ADDRESS16:
-			/*
-			 * 16-Bit Address Resource
-			 * The base size of this byte stream is 16. If a Resource Source
-			 * string is not NULL, add 1 for the Index + the length of the null
-			 * terminated string Resource Source + 1 for the null.
-			 */
-			segment_size = 16;
-
-			if (linked_list->data.address16.resource_source.
-			    string_ptr) {
-				segment_size +=
-				    linked_list->data.address16.resource_source.
-				    string_length;
-				segment_size++;
-			}
-			break;
+		bit_field &= (bit_field - 1);
+	}
 
-		case ACPI_RSTYPE_ADDRESS32:
-			/*
-			 * 32-Bit Address Resource
-			 * The base size of this byte stream is 26. If a Resource
-			 * Source string is not NULL, add 1 for the Index + the
-			 * length of the null terminated string Resource Source +
-			 * 1 for the null.
-			 */
-			segment_size = 26;
-
-			if (linked_list->data.address32.resource_source.
-			    string_ptr) {
-				segment_size +=
-				    linked_list->data.address32.resource_source.
-				    string_length;
-				segment_size++;
-			}
-			break;
+	return (bits_set);
+}
 
-		case ACPI_RSTYPE_ADDRESS64:
-			/*
-			 * 64-Bit Address Resource
-			 * The base size of this byte stream is 46. If a resource_source
-			 * string is not NULL, add 1 for the Index + the length of the null
-			 * terminated string Resource Source + 1 for the null.
-			 */
-			segment_size = 46;
-
-			if (linked_list->data.address64.resource_source.
-			    string_ptr) {
-				segment_size +=
-				    linked_list->data.address64.resource_source.
-				    string_length;
-				segment_size++;
-			}
-			break;
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_struct_option_length
+ *
+ * PARAMETERS:  resource_source     - Pointer to optional descriptor field
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Common code to handle optional resource_source_index and
+ *              resource_source fields in some Large descriptors. Used during
+ *              list-to-stream conversion
+ *
+ ******************************************************************************/
 
-		case ACPI_RSTYPE_EXT_IRQ:
-			/*
-			 * Extended IRQ Resource
-			 * The base size of this byte stream is 9. This is for an Interrupt
-			 * table length of 1.  For each additional interrupt, add 4.
-			 * If a Resource Source string is not NULL, add 1 for the
-			 * Index + the length of the null terminated string
-			 * Resource Source + 1 for the null.
-			 */
-			segment_size = 9 + (((acpi_size)
-					     linked_list->data.extended_irq.
-					     number_of_interrupts - 1) * 4);
-
-			if (linked_list->data.extended_irq.resource_source.
-			    string_ptr) {
-				segment_size +=
-				    linked_list->data.extended_irq.
-				    resource_source.string_length;
-				segment_size++;
-			}
-			break;
+static acpi_rs_length
+acpi_rs_struct_option_length(struct acpi_resource_source *resource_source)
+{
+	ACPI_FUNCTION_ENTRY();
 
-		default:
+	/*
+	 * If the resource_source string is valid, return the size of the string
+	 * (string_length includes the NULL terminator) plus the size of the
+	 * resource_source_index (1).
+	 */
+	if (resource_source->string_ptr) {
+		return ((acpi_rs_length) (resource_source->string_length + 1));
+	}
 
-			/* If we get here, everything is out of sync, exit with error */
+	return (0);
+}
 
-			return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_stream_option_length
+ *
+ * PARAMETERS:  resource_length     - Length from the resource header
+ *              minimum_total_length - Minimum length of this resource, before
+ *                                    any optional fields. Includes header size
+ *
+ * RETURN:      Length of optional string (0 if no string present)
+ *
+ * DESCRIPTION: Common code to handle optional resource_source_index and
+ *              resource_source fields in some Large descriptors. Used during
+ *              stream-to-list conversion
+ *
+ ******************************************************************************/
 
-		}		/* switch (linked_list->Id) */
+static u32
+acpi_rs_stream_option_length(u32 resource_length,
+			     u32 minimum_aml_resource_length)
+{
+	u32 string_length = 0;
 
-		/* Update the total */
+	ACPI_FUNCTION_ENTRY();
 
-		byte_stream_size_needed += segment_size;
+	/*
+	 * The resource_source_index and resource_source are optional elements of some
+	 * Large-type resource descriptors.
+	 */
 
-		/* Point to the next object */
+	/*
+	 * If the length of the actual resource descriptor is greater than the ACPI
+	 * spec-defined minimum length, it means that a resource_source_index exists
+	 * and is followed by a (required) null terminated string. The string length
+	 * (including the null terminator) is the resource length minus the minimum
+	 * length, minus one byte for the resource_source_index itself.
+	 */
+	if (resource_length > minimum_aml_resource_length) {
+		/* Compute the length of the optional string */
 
-		linked_list = ACPI_PTR_ADD(struct acpi_resource,
-					   linked_list, linked_list->length);
+		string_length =
+		    resource_length - minimum_aml_resource_length - 1;
 	}
 
-	/* This is the data the caller needs */
+	/* Round up length to 32 bits for internal structure alignment */
 
-	*size_needed = byte_stream_size_needed;
-	return_ACPI_STATUS(AE_OK);
+	return (ACPI_ROUND_UP_to_32_bITS(string_length));
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_get_list_length
+ * FUNCTION:    acpi_rs_get_aml_length
  *
- * PARAMETERS:  byte_stream_buffer      - Pointer to the resource byte stream
- *              byte_stream_buffer_length - Size of byte_stream_buffer
- *              size_needed             - u32 pointer of the size buffer
- *                                        needed to properly return the
- *                                        parsed data
+ * PARAMETERS:  Resource            - Pointer to the resource linked list
+ *              size_needed         - Where the required size is returned
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Takes the resource byte stream and parses it once, calculating
- *              the size buffer needed to hold the linked list that conveys
- *              the resource data.
+ * DESCRIPTION: Takes a linked list of internal resource descriptors and
+ *              calculates the size buffer needed to hold the corresponding
+ *              external resource byte stream.
  *
  ******************************************************************************/
 
 acpi_status
-acpi_rs_get_list_length(u8 * byte_stream_buffer,
-			u32 byte_stream_buffer_length, acpi_size * size_needed)
+acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed)
 {
-	u32 buffer_size = 0;
-	u32 bytes_parsed = 0;
-	u8 number_of_interrupts = 0;
-	u8 number_of_channels = 0;
-	u8 resource_type;
-	u32 structure_size;
-	u32 bytes_consumed;
-	u8 *buffer;
-	u8 temp8;
-	u16 temp16;
-	u8 index;
-	u8 additional_bytes;
+	acpi_size aml_size_needed = 0;
+	acpi_rs_length total_size;
 
-	ACPI_FUNCTION_TRACE("rs_get_list_length");
-
-	while (bytes_parsed < byte_stream_buffer_length) {
-		/* The next byte in the stream is the resource type */
+	ACPI_FUNCTION_TRACE("rs_get_aml_length");
 
-		resource_type = acpi_rs_get_resource_type(*byte_stream_buffer);
+	/* Traverse entire list of internal resource descriptors */
 
-		switch (resource_type) {
-		case ACPI_RDESC_TYPE_MEMORY_24:
-			/*
-			 * 24-Bit Memory Resource
-			 */
-			bytes_consumed = 12;
+	while (resource) {
+		/* Validate the descriptor type */
 
-			structure_size =
-			    ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem24);
-			break;
-
-		case ACPI_RDESC_TYPE_LARGE_VENDOR:
-			/*
-			 * Vendor Defined Resource
-			 */
-			buffer = byte_stream_buffer;
-			++buffer;
-
-			ACPI_MOVE_16_TO_16(&temp16, buffer);
-			bytes_consumed = temp16 + 3;
-
-			/* Ensure a 32-bit boundary for the structure */
+		if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
+			return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
+		}
 
-			temp16 = (u16) ACPI_ROUND_UP_to_32_bITS(temp16);
+		/* Get the base size of the (external stream) resource descriptor */
 
-			structure_size =
-			    ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor) +
-			    (temp16 * sizeof(u8));
-			break;
+		total_size = acpi_gbl_aml_resource_sizes[resource->type];
 
-		case ACPI_RDESC_TYPE_MEMORY_32:
+		/*
+		 * Augment the base size for descriptors with optional and/or
+		 * variable-length fields
+		 */
+		switch (resource->type) {
+		case ACPI_RESOURCE_TYPE_VENDOR:
 			/*
-			 * 32-Bit Memory Range Resource
+			 * Vendor Defined Resource:
+			 * For a Vendor Specific resource, if the Length is between 1 and 7
+			 * it will be created as a Small Resource data type, otherwise it
+			 * is a Large Resource data type.
 			 */
-			bytes_consumed = 20;
+			if (resource->data.vendor.byte_length > 7) {
+				/* Base size of a Large resource descriptor */
 
-			structure_size =
-			    ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem32);
-			break;
+				total_size =
+				    sizeof(struct aml_resource_large_header);
+			}
 
-		case ACPI_RDESC_TYPE_FIXED_MEMORY_32:
-			/*
-			 * 32-Bit Fixed Memory Resource
-			 */
-			bytes_consumed = 12;
+			/* Add the size of the vendor-specific data */
 
-			structure_size =
-			    ACPI_SIZEOF_RESOURCE(struct
-						 acpi_resource_fixed_mem32);
+			total_size = (acpi_rs_length)
+			    (total_size + resource->data.vendor.byte_length);
 			break;
 
-		case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE:
+		case ACPI_RESOURCE_TYPE_END_TAG:
 			/*
-			 * 64-Bit Address Resource
+			 * End Tag:
+			 * We are done -- return the accumulated total size.
 			 */
-			buffer = byte_stream_buffer;
+			*size_needed = aml_size_needed + total_size;
 
-			++buffer;
-			ACPI_MOVE_16_TO_16(&temp16, buffer);
+			/* Normal exit */
 
-			bytes_consumed = temp16 + 3;
-			structure_size =
-			    ACPI_SIZEOF_RESOURCE(struct
-						 acpi_resource_address64);
-			break;
+			return_ACPI_STATUS(AE_OK);
 
-		case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE:
+		case ACPI_RESOURCE_TYPE_ADDRESS16:
 			/*
-			 * 64-Bit Address Resource
+			 * 16-Bit Address Resource:
+			 * Add the size of the optional resource_source info
 			 */
-			buffer = byte_stream_buffer;
-
-			++buffer;
-			ACPI_MOVE_16_TO_16(&temp16, buffer);
-
-			bytes_consumed = temp16 + 3;
+			total_size = (acpi_rs_length)
+			    (total_size +
+			     acpi_rs_struct_option_length(&resource->data.
+							  address16.
+							  resource_source));
+			break;
 
+		case ACPI_RESOURCE_TYPE_ADDRESS32:
 			/*
-			 * Resource Source Index and Resource Source are optional elements.
-			 * Check the length of the Bytestream.  If it is greater than 43,
-			 * that means that an Index exists and is followed by a null
-			 * terminated string.  Therefore, set the temp variable to the
-			 * length minus the minimum byte stream length plus the byte for
-			 * the Index to determine the size of the NULL terminated string.
+			 * 32-Bit Address Resource:
+			 * Add the size of the optional resource_source info
 			 */
-			if (43 < temp16) {
-				temp8 = (u8) (temp16 - 44);
-			} else {
-				temp8 = 0;
-			}
-
-			/* Ensure a 64-bit boundary for the structure */
-
-			temp8 = (u8) ACPI_ROUND_UP_to_64_bITS(temp8);
-
-			structure_size =
-			    ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64)
-			    + (temp8 * sizeof(u8));
+			total_size = (acpi_rs_length)
+			    (total_size +
+			     acpi_rs_struct_option_length(&resource->data.
+							  address32.
+							  resource_source));
 			break;
 
-		case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE:
+		case ACPI_RESOURCE_TYPE_ADDRESS64:
 			/*
-			 * 32-Bit Address Resource
+			 * 64-Bit Address Resource:
+			 * Add the size of the optional resource_source info
 			 */
-			buffer = byte_stream_buffer;
-
-			++buffer;
-			ACPI_MOVE_16_TO_16(&temp16, buffer);
-
-			bytes_consumed = temp16 + 3;
+			total_size = (acpi_rs_length)
+			    (total_size +
+			     acpi_rs_struct_option_length(&resource->data.
+							  address64.
+							  resource_source));
+			break;
 
+		case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
 			/*
-			 * Resource Source Index and Resource Source are optional elements.
-			 * Check the length of the Bytestream.  If it is greater than 23,
-			 * that means that an Index exists and is followed by a null
-			 * terminated string.  Therefore, set the temp variable to the
-			 * length minus the minimum byte stream length plus the byte for
-			 * the Index to determine the size of the NULL terminated string.
+			 * Extended IRQ Resource:
+			 * Add the size of each additional optional interrupt beyond the
+			 * required 1 (4 bytes for each u32 interrupt number)
 			 */
-			if (23 < temp16) {
-				temp8 = (u8) (temp16 - 24);
-			} else {
-				temp8 = 0;
-			}
-
-			/* Ensure a 32-bit boundary for the structure */
-
-			temp8 = (u8) ACPI_ROUND_UP_to_32_bITS(temp8);
+			total_size = (acpi_rs_length)
+			    (total_size +
+			     ((resource->data.extended_irq.interrupt_count -
+			       1) * 4) +
+			     /* Add the size of the optional resource_source info */
+			     acpi_rs_struct_option_length(&resource->data.
+							  extended_irq.
+							  resource_source));
+			break;
 
-			structure_size =
-			    ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32)
-			    + (temp8 * sizeof(u8));
+		default:
 			break;
+		}
 
-		case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE:
-			/*
-			 * 16-Bit Address Resource
-			 */
-			buffer = byte_stream_buffer;
+		/* Update the total */
 
-			++buffer;
-			ACPI_MOVE_16_TO_16(&temp16, buffer);
+		aml_size_needed += total_size;
 
-			bytes_consumed = temp16 + 3;
+		/* Point to the next object */
 
-			/*
-			 * Resource Source Index and Resource Source are optional elements.
-			 * Check the length of the Bytestream.  If it is greater than 13,
-			 * that means that an Index exists and is followed by a null
-			 * terminated string.  Therefore, set the temp variable to the
-			 * length minus the minimum byte stream length plus the byte for
-			 * the Index to determine the size of the NULL terminated string.
-			 */
-			if (13 < temp16) {
-				temp8 = (u8) (temp16 - 14);
-			} else {
-				temp8 = 0;
-			}
+		resource =
+		    ACPI_ADD_PTR(struct acpi_resource, resource,
+				 resource->length);
+	}
 
-			/* Ensure a 32-bit boundary for the structure */
+	/* Did not find an end_tag resource descriptor */
 
-			temp8 = (u8) ACPI_ROUND_UP_to_32_bITS(temp8);
+	return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
+}
 
-			structure_size =
-			    ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16)
-			    + (temp8 * sizeof(u8));
-			break;
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_get_list_length
+ *
+ * PARAMETERS:  aml_buffer          - Pointer to the resource byte stream
+ *              aml_buffer_length   - Size of aml_buffer
+ *              size_needed         - Where the size needed is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Takes an external resource byte stream and calculates the size
+ *              buffer needed to hold the corresponding internal resource
+ *              descriptor linked list.
+ *
+ ******************************************************************************/
 
-		case ACPI_RDESC_TYPE_EXTENDED_XRUPT:
-			/*
-			 * Extended IRQ
-			 */
-			buffer = byte_stream_buffer;
+acpi_status
+acpi_rs_get_list_length(u8 * aml_buffer,
+			u32 aml_buffer_length, acpi_size * size_needed)
+{
+	acpi_status status;
+	u8 *end_aml;
+	u8 *buffer;
+	u32 buffer_size = 0;
+	u16 temp16;
+	u16 resource_length;
+	u32 extra_struct_bytes;
+	u8 resource_index;
+	u8 minimum_aml_resource_length;
 
-			++buffer;
-			ACPI_MOVE_16_TO_16(&temp16, buffer);
+	ACPI_FUNCTION_TRACE("rs_get_list_length");
 
-			bytes_consumed = temp16 + 3;
+	end_aml = aml_buffer + aml_buffer_length;
 
-			/*
-			 * Point past the length field and the Interrupt vector flags to
-			 * save off the Interrupt table length to the Temp8 variable.
-			 */
-			buffer += 3;
-			temp8 = *buffer;
+	/* Walk the list of AML resource descriptors */
 
-			/*
-			 * To compensate for multiple interrupt numbers, add 4 bytes for
-			 * each additional interrupts greater than 1
-			 */
-			additional_bytes = (u8) ((temp8 - 1) * 4);
+	while (aml_buffer < end_aml) {
+		/* Validate the Resource Type and Resource Length */
 
-			/*
-			 * Resource Source Index and Resource Source are optional elements.
-			 * Check the length of the Bytestream.  If it is greater than 9,
-			 * that means that an Index exists and is followed by a null
-			 * terminated string.  Therefore, set the temp variable to the
-			 * length minus the minimum byte stream length plus the byte for
-			 * the Index to determine the size of the NULL terminated string.
-			 */
-			if (9 + additional_bytes < temp16) {
-				temp8 = (u8) (temp16 - (9 + additional_bytes));
-			} else {
-				temp8 = 0;
-			}
+		status = acpi_ut_validate_resource(aml_buffer, &resource_index);
+		if (ACPI_FAILURE(status)) {
+			return_ACPI_STATUS(status);
+		}
 
-			/* Ensure a 32-bit boundary for the structure */
+		/* Get the resource length and base (minimum) AML size */
 
-			temp8 = (u8) ACPI_ROUND_UP_to_32_bITS(temp8);
+		resource_length = acpi_ut_get_resource_length(aml_buffer);
+		minimum_aml_resource_length =
+		    acpi_gbl_resource_aml_sizes[resource_index];
 
-			structure_size =
-			    ACPI_SIZEOF_RESOURCE(struct acpi_resource_ext_irq) +
-			    (additional_bytes * sizeof(u8)) +
-			    (temp8 * sizeof(u8));
-			break;
+		/*
+		 * Augment the size for descriptors with optional
+		 * and/or variable length fields
+		 */
+		extra_struct_bytes = 0;
+		buffer =
+		    aml_buffer + acpi_ut_get_resource_header_length(aml_buffer);
 
-		case ACPI_RDESC_TYPE_IRQ_FORMAT:
+		switch (acpi_ut_get_resource_type(aml_buffer)) {
+		case ACPI_RESOURCE_NAME_IRQ:
 			/*
-			 * IRQ Resource.
-			 * Determine if it there are two or three trailing bytes
+			 * IRQ Resource:
+			 * Get the number of bits set in the 16-bit IRQ mask
 			 */
-			buffer = byte_stream_buffer;
-			temp8 = *buffer;
-
-			if (temp8 & 0x01) {
-				bytes_consumed = 4;
-			} else {
-				bytes_consumed = 3;
-			}
-
-			/* Point past the descriptor */
-
-			++buffer;
-
-			/* Look at the number of bits set */
-
 			ACPI_MOVE_16_TO_16(&temp16, buffer);
-
-			for (index = 0; index < 16; index++) {
-				if (temp16 & 0x1) {
-					++number_of_interrupts;
-				}
-
-				temp16 >>= 1;
-			}
-
-			structure_size =
-			    ACPI_SIZEOF_RESOURCE(struct acpi_resource_io) +
-			    (number_of_interrupts * sizeof(u32));
+			extra_struct_bytes = acpi_rs_count_set_bits(temp16);
 			break;
 
-		case ACPI_RDESC_TYPE_DMA_FORMAT:
+		case ACPI_RESOURCE_NAME_DMA:
 			/*
-			 * DMA Resource
+			 * DMA Resource:
+			 * Get the number of bits set in the 8-bit DMA mask
 			 */
-			buffer = byte_stream_buffer;
-			bytes_consumed = 3;
-
-			/* Point past the descriptor */
-
-			++buffer;
-
-			/* Look at the number of bits set */
-
-			temp8 = *buffer;
-
-			for (index = 0; index < 8; index++) {
-				if (temp8 & 0x1) {
-					++number_of_channels;
-				}
-
-				temp8 >>= 1;
-			}
-
-			structure_size =
-			    ACPI_SIZEOF_RESOURCE(struct acpi_resource_dma) +
-			    (number_of_channels * sizeof(u32));
+			extra_struct_bytes = acpi_rs_count_set_bits(*buffer);
 			break;
 
-		case ACPI_RDESC_TYPE_START_DEPENDENT:
+		case ACPI_RESOURCE_NAME_VENDOR_SMALL:
 			/*
-			 * Start Dependent Functions Resource
-			 * Determine if it there are two or three trailing bytes
+			 * Vendor Resource:
+			 * Ensure a 32-bit boundary for the structure
 			 */
-			buffer = byte_stream_buffer;
-			temp8 = *buffer;
-
-			if (temp8 & 0x01) {
-				bytes_consumed = 2;
-			} else {
-				bytes_consumed = 1;
-			}
-
-			structure_size =
-			    ACPI_SIZEOF_RESOURCE(struct
-						 acpi_resource_start_dpf);
+			extra_struct_bytes =
+			    ACPI_ROUND_UP_to_32_bITS(resource_length) -
+			    resource_length;
 			break;
 
-		case ACPI_RDESC_TYPE_END_DEPENDENT:
+		case ACPI_RESOURCE_NAME_END_TAG:
 			/*
-			 * End Dependent Functions Resource
+			 * End Tag: This is the normal exit, add size of end_tag
 			 */
-			bytes_consumed = 1;
-			structure_size = ACPI_RESOURCE_LENGTH;
-			break;
+			*size_needed = buffer_size + ACPI_RS_SIZE_MIN;
+			return_ACPI_STATUS(AE_OK);
 
-		case ACPI_RDESC_TYPE_IO_PORT:
+		case ACPI_RESOURCE_NAME_VENDOR_LARGE:
 			/*
-			 * IO Port Resource
+			 * Vendor Resource:
+			 * Add vendor data and ensure a 32-bit boundary for the structure
 			 */
-			bytes_consumed = 8;
-			structure_size =
-			    ACPI_SIZEOF_RESOURCE(struct acpi_resource_io);
+			extra_struct_bytes =
+			    ACPI_ROUND_UP_to_32_bITS(resource_length) -
+			    resource_length;
 			break;
 
-		case ACPI_RDESC_TYPE_FIXED_IO_PORT:
+		case ACPI_RESOURCE_NAME_ADDRESS32:
+		case ACPI_RESOURCE_NAME_ADDRESS16:
 			/*
-			 * Fixed IO Port Resource
+			 * 32-Bit or 16-bit Address Resource:
+			 * Add the size of any optional data (resource_source)
 			 */
-			bytes_consumed = 4;
-			structure_size =
-			    ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_io);
+			extra_struct_bytes =
+			    acpi_rs_stream_option_length(resource_length,
+							 minimum_aml_resource_length);
 			break;
 
-		case ACPI_RDESC_TYPE_SMALL_VENDOR:
+		case ACPI_RESOURCE_NAME_EXTENDED_IRQ:
 			/*
-			 * Vendor Specific Resource
+			 * Extended IRQ:
+			 * Point past the interrupt_vector_flags to get the
+			 * interrupt_table_length.
 			 */
-			buffer = byte_stream_buffer;
+			buffer++;
 
-			temp8 = *buffer;
-			temp8 = (u8) (temp8 & 0x7);
-			bytes_consumed = temp8 + 1;
-
-			/* Ensure a 32-bit boundary for the structure */
-
-			temp8 = (u8) ACPI_ROUND_UP_to_32_bITS(temp8);
-			structure_size =
-			    ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor) +
-			    (temp8 * sizeof(u8));
+			extra_struct_bytes =
+			    /*
+			     * Add 4 bytes for each additional interrupt. Note: at
+			     * least one interrupt is required and is included in
+			     * the minimum descriptor size
+			     */
+			    ((*buffer - 1) * sizeof(u32)) +
+			    /* Add the size of any optional data (resource_source) */
+			    acpi_rs_stream_option_length(resource_length -
+							 extra_struct_bytes,
+							 minimum_aml_resource_length);
 			break;
 
-		case ACPI_RDESC_TYPE_END_TAG:
+		case ACPI_RESOURCE_NAME_ADDRESS64:
 			/*
-			 * End Tag
+			 * 64-Bit Address Resource:
+			 * Add the size of any optional data (resource_source)
+			 * Ensure a 64-bit boundary for the structure
 			 */
-			bytes_consumed = 2;
-			structure_size = ACPI_RESOURCE_LENGTH;
-			byte_stream_buffer_length = bytes_parsed;
+			extra_struct_bytes =
+			    ACPI_ROUND_UP_to_64_bITS
+			    (acpi_rs_stream_option_length
+			     (resource_length, minimum_aml_resource_length));
 			break;
 
 		default:
-			/*
-			 * If we get here, everything is out of sync,
-			 * exit with an error
-			 */
-			return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
+			break;
 		}
 
-		/* Update the return value and counter */
-
-		buffer_size += (u32) ACPI_ALIGN_RESOURCE_SIZE(structure_size);
-		bytes_parsed += bytes_consumed;
+		/* Update the required buffer size for the internal descriptor structs */
 
-		/* Set the byte stream to point to the next resource */
+		temp16 = (u16) (acpi_gbl_resource_struct_sizes[resource_index] +
+				extra_struct_bytes);
+		buffer_size += (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(temp16);
 
-		byte_stream_buffer += bytes_consumed;
+		/*
+		 * Point to the next resource within the stream
+		 * using the size of the header plus the length contained in the header
+		 */
+		aml_buffer += acpi_ut_get_descriptor_length(aml_buffer);
 	}
 
-	/* This is the data the caller needs */
+	/* Did not find an end_tag resource descriptor */
 
-	*size_needed = buffer_size;
-	return_ACPI_STATUS(AE_OK);
+	return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
 }
 
 /*******************************************************************************
@@ -760,13 +541,13 @@ acpi_rs_get_pci_routing_table_length(uni
 
 		for (table_index = 0; table_index < 4 && !name_found;
 		     table_index++) {
-			if ((ACPI_TYPE_STRING ==
-			     ACPI_GET_OBJECT_TYPE(*sub_object_list))
-			    ||
-			    ((ACPI_TYPE_LOCAL_REFERENCE ==
-			      ACPI_GET_OBJECT_TYPE(*sub_object_list))
-			     && ((*sub_object_list)->reference.opcode ==
-				 AML_INT_NAMEPATH_OP))) {
+			if (*sub_object_list &&	/* Null object allowed */
+			    ((ACPI_TYPE_STRING ==
+			      ACPI_GET_OBJECT_TYPE(*sub_object_list)) ||
+			     ((ACPI_TYPE_LOCAL_REFERENCE ==
+			       ACPI_GET_OBJECT_TYPE(*sub_object_list)) &&
+			      ((*sub_object_list)->reference.opcode ==
+			       AML_INT_NAMEPATH_OP)))) {
 				name_found = TRUE;
 			} else {
 				/* Look at the next element */
diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c
index 0911526..8c128de 100644
--- a/drivers/acpi/resources/rscreate.c
+++ b/drivers/acpi/resources/rscreate.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -53,10 +53,10 @@ ACPI_MODULE_NAME("rscreate")
  *
  * FUNCTION:    acpi_rs_create_resource_list
  *
- * PARAMETERS:  byte_stream_buffer      - Pointer to the resource byte stream
- *              output_buffer           - Pointer to the user's buffer
+ * PARAMETERS:  aml_buffer          - Pointer to the resource byte stream
+ *              output_buffer       - Pointer to the user's buffer
  *
- * RETURN:      Status  - AE_OK if okay, else a valid acpi_status code
+ * RETURN:      Status: AE_OK if okay, else a valid acpi_status code
  *              If output_buffer is not large enough, output_buffer_length
  *              indicates how large output_buffer should be, else it
  *              indicates how may u8 elements of output_buffer are valid.
@@ -67,33 +67,30 @@ ACPI_MODULE_NAME("rscreate")
  *
  ******************************************************************************/
 acpi_status
-acpi_rs_create_resource_list(union acpi_operand_object *byte_stream_buffer,
+acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer,
 			     struct acpi_buffer *output_buffer)
 {
 
 	acpi_status status;
-	u8 *byte_stream_start;
+	u8 *aml_start;
 	acpi_size list_size_needed = 0;
-	u32 byte_stream_buffer_length;
+	u32 aml_buffer_length;
 
 	ACPI_FUNCTION_TRACE("rs_create_resource_list");
 
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "byte_stream_buffer = %p\n",
-			  byte_stream_buffer));
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "aml_buffer = %p\n", aml_buffer));
 
 	/* Params already validated, so we don't re-validate here */
 
-	byte_stream_buffer_length = byte_stream_buffer->buffer.length;
-	byte_stream_start = byte_stream_buffer->buffer.pointer;
+	aml_buffer_length = aml_buffer->buffer.length;
+	aml_start = aml_buffer->buffer.pointer;
 
 	/*
-	 * Pass the byte_stream_buffer into a module that can calculate
+	 * Pass the aml_buffer into a module that can calculate
 	 * the buffer size needed for the linked list
 	 */
-	status =
-	    acpi_rs_get_list_length(byte_stream_start,
-				    byte_stream_buffer_length,
-				    &list_size_needed);
+	status = acpi_rs_get_list_length(aml_start, aml_buffer_length,
+					 &list_size_needed);
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Status=%X list_size_needed=%X\n",
 			  status, (u32) list_size_needed));
@@ -110,10 +107,8 @@ acpi_rs_create_resource_list(union acpi_
 
 	/* Do the conversion */
 
-	status =
-	    acpi_rs_byte_stream_to_list(byte_stream_start,
-					byte_stream_buffer_length,
-					output_buffer->pointer);
+	status = acpi_rs_convert_aml_to_resources(aml_start, aml_buffer_length,
+						  output_buffer->pointer);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -212,21 +207,20 @@ acpi_rs_create_pci_routing_table(union a
 		/* Each element of the top-level package must also be a package */
 
 		if (ACPI_GET_OBJECT_TYPE(*top_object_list) != ACPI_TYPE_PACKAGE) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "(PRT[%X]) Need sub-package, found %s\n",
-					  index,
-					  acpi_ut_get_object_type_name
-					  (*top_object_list)));
+			ACPI_ERROR((AE_INFO,
+				    "(PRT[%X]) Need sub-package, found %s",
+				    index,
+				    acpi_ut_get_object_type_name
+				    (*top_object_list)));
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 		}
 
 		/* Each sub-package must be of length 4 */
 
 		if ((*top_object_list)->package.count != 4) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "(PRT[%X]) Need package of length 4, found length %d\n",
-					  index,
-					  (*top_object_list)->package.count));
+			ACPI_ERROR((AE_INFO,
+				    "(PRT[%X]) Need package of length 4, found length %d",
+				    index, (*top_object_list)->package.count));
 			return_ACPI_STATUS(AE_AML_PACKAGE_LIMIT);
 		}
 
@@ -243,11 +237,10 @@ acpi_rs_create_pci_routing_table(union a
 		if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
 			user_prt->address = obj_desc->integer.value;
 		} else {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "(PRT[%X].Address) Need Integer, found %s\n",
-					  index,
-					  acpi_ut_get_object_type_name
-					  (obj_desc)));
+			ACPI_ERROR((AE_INFO,
+				    "(PRT[%X].Address) Need Integer, found %s",
+				    index,
+				    acpi_ut_get_object_type_name(obj_desc)));
 			return_ACPI_STATUS(AE_BAD_DATA);
 		}
 
@@ -257,76 +250,83 @@ acpi_rs_create_pci_routing_table(union a
 		if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
 			user_prt->pin = (u32) obj_desc->integer.value;
 		} else {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "(PRT[%X].Pin) Need Integer, found %s\n",
-					  index,
-					  acpi_ut_get_object_type_name
-					  (obj_desc)));
+			ACPI_ERROR((AE_INFO,
+				    "(PRT[%X].Pin) Need Integer, found %s",
+				    index,
+				    acpi_ut_get_object_type_name(obj_desc)));
 			return_ACPI_STATUS(AE_BAD_DATA);
 		}
 
-		/* 3) Third subobject: Dereference the PRT.source_name */
-
+		/*
+		 * 3) Third subobject: Dereference the PRT.source_name
+		 * The name may be unresolved (slack mode), so allow a null object
+		 */
 		obj_desc = sub_object_list[2];
-		switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
-		case ACPI_TYPE_LOCAL_REFERENCE:
-
-			if (obj_desc->reference.opcode != AML_INT_NAMEPATH_OP) {
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "(PRT[%X].Source) Need name, found reference op %X\n",
-						  index,
-						  obj_desc->reference.opcode));
+		if (obj_desc) {
+			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			case ACPI_TYPE_LOCAL_REFERENCE:
+
+				if (obj_desc->reference.opcode !=
+				    AML_INT_NAMEPATH_OP) {
+					ACPI_ERROR((AE_INFO,
+						    "(PRT[%X].Source) Need name, found reference op %X",
+						    index,
+						    obj_desc->reference.
+						    opcode));
+					return_ACPI_STATUS(AE_BAD_DATA);
+				}
+
+				node = obj_desc->reference.node;
+
+				/* Use *remaining* length of the buffer as max for pathname */
+
+				path_buffer.length = output_buffer->length -
+				    (u32) ((u8 *) user_prt->source -
+					   (u8 *) output_buffer->pointer);
+				path_buffer.pointer = user_prt->source;
+
+				status =
+				    acpi_ns_handle_to_pathname((acpi_handle)
+							       node,
+							       &path_buffer);
+
+				/* +1 to include null terminator */
+
+				user_prt->length +=
+				    (u32) ACPI_STRLEN(user_prt->source) + 1;
+				break;
+
+			case ACPI_TYPE_STRING:
+
+				ACPI_STRCPY(user_prt->source,
+					    obj_desc->string.pointer);
+
+				/*
+				 * Add to the Length field the length of the string
+				 * (add 1 for terminator)
+				 */
+				user_prt->length += obj_desc->string.length + 1;
+				break;
+
+			case ACPI_TYPE_INTEGER:
+				/*
+				 * If this is a number, then the Source Name is NULL, since the
+				 * entire buffer was zeroed out, we can leave this alone.
+				 *
+				 * Add to the Length field the length of the u32 NULL
+				 */
+				user_prt->length += sizeof(u32);
+				break;
+
+			default:
+
+				ACPI_ERROR((AE_INFO,
+					    "(PRT[%X].Source) Need Ref/String/Integer, found %s",
+					    index,
+					    acpi_ut_get_object_type_name
+					    (obj_desc)));
 				return_ACPI_STATUS(AE_BAD_DATA);
 			}
-
-			node = obj_desc->reference.node;
-
-			/* Use *remaining* length of the buffer as max for pathname */
-
-			path_buffer.length = output_buffer->length -
-			    (u32) ((u8 *) user_prt->source -
-				   (u8 *) output_buffer->pointer);
-			path_buffer.pointer = user_prt->source;
-
-			status =
-			    acpi_ns_handle_to_pathname((acpi_handle) node,
-						       &path_buffer);
-
-			/* +1 to include null terminator */
-
-			user_prt->length +=
-			    (u32) ACPI_STRLEN(user_prt->source) + 1;
-			break;
-
-		case ACPI_TYPE_STRING:
-
-			ACPI_STRCPY(user_prt->source, obj_desc->string.pointer);
-
-			/*
-			 * Add to the Length field the length of the string
-			 * (add 1 for terminator)
-			 */
-			user_prt->length += obj_desc->string.length + 1;
-			break;
-
-		case ACPI_TYPE_INTEGER:
-			/*
-			 * If this is a number, then the Source Name is NULL, since the
-			 * entire buffer was zeroed out, we can leave this alone.
-			 *
-			 * Add to the Length field the length of the u32 NULL
-			 */
-			user_prt->length += sizeof(u32);
-			break;
-
-		default:
-
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "(PRT[%X].Source) Need Ref/String/Integer, found %s\n",
-					  index,
-					  acpi_ut_get_object_type_name
-					  (obj_desc)));
-			return_ACPI_STATUS(AE_BAD_DATA);
 		}
 
 		/* Now align the current length */
@@ -340,11 +340,10 @@ acpi_rs_create_pci_routing_table(union a
 		if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
 			user_prt->source_index = (u32) obj_desc->integer.value;
 		} else {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "(PRT[%X].source_index) Need Integer, found %s\n",
-					  index,
-					  acpi_ut_get_object_type_name
-					  (obj_desc)));
+			ACPI_ERROR((AE_INFO,
+				    "(PRT[%X].source_index) Need Integer, found %s",
+				    index,
+				    acpi_ut_get_object_type_name(obj_desc)));
 			return_ACPI_STATUS(AE_BAD_DATA);
 		}
 
@@ -360,7 +359,7 @@ acpi_rs_create_pci_routing_table(union a
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_create_byte_stream
+ * FUNCTION:    acpi_rs_create_aml_resources
  *
  * PARAMETERS:  linked_list_buffer      - Pointer to the resource linked list
  *              output_buffer           - Pointer to the user's buffer
@@ -377,13 +376,13 @@ acpi_rs_create_pci_routing_table(union a
  ******************************************************************************/
 
 acpi_status
-acpi_rs_create_byte_stream(struct acpi_resource *linked_list_buffer,
-			   struct acpi_buffer *output_buffer)
+acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer,
+			     struct acpi_buffer *output_buffer)
 {
 	acpi_status status;
-	acpi_size byte_stream_size_needed = 0;
+	acpi_size aml_size_needed = 0;
 
-	ACPI_FUNCTION_TRACE("rs_create_byte_stream");
+	ACPI_FUNCTION_TRACE("rs_create_aml_resources");
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "linked_list_buffer = %p\n",
 			  linked_list_buffer));
@@ -394,11 +393,10 @@ acpi_rs_create_byte_stream(struct acpi_r
 	 * Pass the linked_list_buffer into a module that calculates
 	 * the buffer size needed for the byte stream.
 	 */
-	status = acpi_rs_get_byte_stream_length(linked_list_buffer,
-						&byte_stream_size_needed);
+	status = acpi_rs_get_aml_length(linked_list_buffer, &aml_size_needed);
 
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "byte_stream_size_needed=%X, %s\n",
-			  (u32) byte_stream_size_needed,
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "aml_size_needed=%X, %s\n",
+			  (u32) aml_size_needed,
 			  acpi_format_exception(status)));
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
@@ -406,8 +404,7 @@ acpi_rs_create_byte_stream(struct acpi_r
 
 	/* Validate/Allocate/Clear caller buffer */
 
-	status =
-	    acpi_ut_initialize_buffer(output_buffer, byte_stream_size_needed);
+	status = acpi_ut_initialize_buffer(output_buffer, aml_size_needed);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -415,9 +412,9 @@ acpi_rs_create_byte_stream(struct acpi_r
 	/* Do the conversion */
 
 	status =
-	    acpi_rs_list_to_byte_stream(linked_list_buffer,
-					byte_stream_size_needed,
-					output_buffer->pointer);
+	    acpi_rs_convert_resources_to_aml(linked_list_buffer,
+					     aml_size_needed,
+					     output_buffer->pointer);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c
index 75bd34d..e7de061 100644
--- a/drivers/acpi/resources/rsdump.c
+++ b/drivers/acpi/resources/rsdump.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -49,1063 +49,720 @@ ACPI_MODULE_NAME("rsdump")
 
 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
 /* Local prototypes */
-static void acpi_rs_dump_irq(union acpi_resource_data *data);
+static void acpi_rs_out_string(char *title, char *value);
 
-static void acpi_rs_dump_address16(union acpi_resource_data *data);
+static void acpi_rs_out_integer8(char *title, u8 value);
 
-static void acpi_rs_dump_address32(union acpi_resource_data *data);
+static void acpi_rs_out_integer16(char *title, u16 value);
 
-static void acpi_rs_dump_address64(union acpi_resource_data *data);
+static void acpi_rs_out_integer32(char *title, u32 value);
 
-static void acpi_rs_dump_dma(union acpi_resource_data *data);
+static void acpi_rs_out_integer64(char *title, u64 value);
+
+static void acpi_rs_out_title(char *title);
+
+static void acpi_rs_dump_byte_list(u16 length, u8 * data);
+
+static void acpi_rs_dump_dword_list(u8 length, u32 * data);
+
+static void acpi_rs_dump_short_byte_list(u8 length, u8 * data);
+
+static void
+acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source);
+
+static void acpi_rs_dump_address_common(union acpi_resource_data *resource);
+
+static void
+acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table);
+
+#define ACPI_RSD_OFFSET(f)          (u8) ACPI_OFFSET (union acpi_resource_data,f)
+#define ACPI_PRT_OFFSET(f)          (u8) ACPI_OFFSET (struct acpi_pci_routing_table,f)
+#define ACPI_RSD_TABLE_SIZE(name)   (sizeof(name) / sizeof (struct acpi_rsdump_info))
+
+/*******************************************************************************
+ *
+ * Resource Descriptor info tables
+ *
+ * Note: The first table entry must be a Title or Literal and must contain
+ * the table length (number of table entries)
+ *
+ ******************************************************************************/
+
+struct acpi_rsdump_info acpi_rs_dump_irq[6] = {
+	{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_irq), "IRQ", NULL},
+	{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.triggering), "Triggering",
+	 acpi_gbl_HEdecode},
+	{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.polarity), "Polarity",
+	 acpi_gbl_LLdecode},
+	{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.sharable), "Sharing",
+	 acpi_gbl_SHRdecode},
+	{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(irq.interrupt_count),
+	 "Interrupt Count", NULL},
+	{ACPI_RSD_SHORTLIST, ACPI_RSD_OFFSET(irq.interrupts[0]),
+	 "Interrupt List", NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_dma[6] = {
+	{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_dma), "DMA", NULL},
+	{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(dma.type), "Speed",
+	 acpi_gbl_TYPdecode},
+	{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(dma.bus_master), "Mastering",
+	 acpi_gbl_BMdecode},
+	{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(dma.transfer), "Transfer Type",
+	 acpi_gbl_SIZdecode},
+	{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(dma.channel_count), "Channel Count",
+	 NULL},
+	{ACPI_RSD_SHORTLIST, ACPI_RSD_OFFSET(dma.channels[0]), "Channel List",
+	 NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_start_dpf[3] = {
+	{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_start_dpf),
+	 "Start-Dependent-Functions", NULL},
+	{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.compatibility_priority),
+	 "Compatibility Priority", acpi_gbl_config_decode},
+	{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.performance_robustness),
+	 "Performance/Robustness", acpi_gbl_config_decode}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_end_dpf[1] = {
+	{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_end_dpf),
+	 "End-Dependent-Functions", NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_io[6] = {
+	{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_io), "I/O", NULL},
+	{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(io.io_decode), "Address Decoding",
+	 acpi_gbl_io_decode},
+	{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(io.minimum), "Address Minimum", NULL},
+	{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(io.maximum), "Address Maximum", NULL},
+	{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(io.alignment), "Alignment", NULL},
+	{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(io.address_length), "Address Length",
+	 NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_fixed_io[3] = {
+	{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_io),
+	 "Fixed I/O", NULL},
+	{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(fixed_io.address), "Address", NULL},
+	{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(fixed_io.address_length),
+	 "Address Length", NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_vendor[3] = {
+	{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_vendor),
+	 "Vendor Specific", NULL},
+	{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(vendor.byte_length), "Length", NULL},
+	{ACPI_RSD_LONGLIST, ACPI_RSD_OFFSET(vendor.byte_data[0]), "Vendor Data",
+	 NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_end_tag[1] = {
+	{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_end_tag), "end_tag",
+	 NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_memory24[6] = {
+	{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory24),
+	 "24-Bit Memory Range", NULL},
+	{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(memory24.write_protect),
+	 "Write Protect", acpi_gbl_RWdecode},
+	{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.minimum), "Address Minimum",
+	 NULL},
+	{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.maximum), "Address Maximum",
+	 NULL},
+	{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.alignment), "Alignment",
+	 NULL},
+	{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.address_length),
+	 "Address Length", NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_memory32[6] = {
+	{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory32),
+	 "32-Bit Memory Range", NULL},
+	{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(memory32.write_protect),
+	 "Write Protect", acpi_gbl_RWdecode},
+	{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.minimum), "Address Minimum",
+	 NULL},
+	{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.maximum), "Address Maximum",
+	 NULL},
+	{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.alignment), "Alignment",
+	 NULL},
+	{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.address_length),
+	 "Address Length", NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_fixed_memory32[4] = {
+	{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_memory32),
+	 "32-Bit Fixed Memory Range", NULL},
+	{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(fixed_memory32.write_protect),
+	 "Write Protect", acpi_gbl_RWdecode},
+	{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(fixed_memory32.address), "Address",
+	 NULL},
+	{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(fixed_memory32.address_length),
+	 "Address Length", NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_address16[8] = {
+	{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address16),
+	 "16-Bit WORD Address Space", NULL},
+	{ACPI_RSD_ADDRESS, 0, NULL, NULL},
+	{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.granularity), "Granularity",
+	 NULL},
+	{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.minimum), "Address Minimum",
+	 NULL},
+	{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.maximum), "Address Maximum",
+	 NULL},
+	{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.translation_offset),
+	 "Translation Offset", NULL},
+	{ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.address_length),
+	 "Address Length", NULL},
+	{ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address16.resource_source), NULL, NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_address32[8] = {
+	{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address32),
+	 "32-Bit DWORD Address Space", NULL},
+	{ACPI_RSD_ADDRESS, 0, NULL, NULL},
+	{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.granularity), "Granularity",
+	 NULL},
+	{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.minimum), "Address Minimum",
+	 NULL},
+	{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.maximum), "Address Maximum",
+	 NULL},
+	{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.translation_offset),
+	 "Translation Offset", NULL},
+	{ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.address_length),
+	 "Address Length", NULL},
+	{ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address32.resource_source), NULL, NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_address64[8] = {
+	{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address64),
+	 "64-Bit QWORD Address Space", NULL},
+	{ACPI_RSD_ADDRESS, 0, NULL, NULL},
+	{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.granularity), "Granularity",
+	 NULL},
+	{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.minimum), "Address Minimum",
+	 NULL},
+	{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.maximum), "Address Maximum",
+	 NULL},
+	{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.translation_offset),
+	 "Translation Offset", NULL},
+	{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.address_length),
+	 "Address Length", NULL},
+	{ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address64.resource_source), NULL, NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_ext_address64[8] = {
+	{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_ext_address64),
+	 "64-Bit Extended Address Space", NULL},
+	{ACPI_RSD_ADDRESS, 0, NULL, NULL},
+	{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.granularity),
+	 "Granularity", NULL},
+	{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.minimum),
+	 "Address Minimum", NULL},
+	{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.maximum),
+	 "Address Maximum", NULL},
+	{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.translation_offset),
+	 "Translation Offset", NULL},
+	{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.address_length),
+	 "Address Length", NULL},
+	{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.type_specific),
+	 "Type-Specific Attribute", NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_ext_irq[8] = {
+	{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_ext_irq),
+	 "Extended IRQ", NULL},
+	{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.producer_consumer),
+	 "Type", acpi_gbl_consume_decode},
+	{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.triggering),
+	 "Triggering", acpi_gbl_HEdecode},
+	{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.polarity), "Polarity",
+	 acpi_gbl_LLdecode},
+	{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.sharable), "Sharing",
+	 acpi_gbl_SHRdecode},
+	{ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(extended_irq.resource_source), NULL,
+	 NULL},
+	{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(extended_irq.interrupt_count),
+	 "Interrupt Count", NULL},
+	{ACPI_RSD_DWORDLIST, ACPI_RSD_OFFSET(extended_irq.interrupts[0]),
+	 "Interrupt List", NULL}
+};
+
+struct acpi_rsdump_info acpi_rs_dump_generic_reg[6] = {
+	{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_generic_reg),
+	 "Generic Register", NULL},
+	{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.space_id), "Space ID",
+	 NULL},
+	{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.bit_width), "Bit Width",
+	 NULL},
+	{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.bit_offset), "Bit Offset",
+	 NULL},
+	{ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.access_size),
+	 "Access Size", NULL},
+	{ACPI_RSD_UINT64, ACPI_RSD_OFFSET(generic_reg.address), "Address", NULL}
+};
 
-static void acpi_rs_dump_io(union acpi_resource_data *data);
-
-static void acpi_rs_dump_extended_irq(union acpi_resource_data *data);
-
-static void acpi_rs_dump_fixed_io(union acpi_resource_data *data);
-
-static void acpi_rs_dump_fixed_memory32(union acpi_resource_data *data);
-
-static void acpi_rs_dump_memory24(union acpi_resource_data *data);
-
-static void acpi_rs_dump_memory32(union acpi_resource_data *data);
-
-static void acpi_rs_dump_start_depend_fns(union acpi_resource_data *data);
+/*
+ * Tables used for common address descriptor flag fields
+ */
+static struct acpi_rsdump_info acpi_rs_dump_general_flags[5] = {
+	{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_general_flags), NULL,
+	 NULL},
+	{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.producer_consumer),
+	 "Consumer/Producer", acpi_gbl_consume_decode},
+	{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.decode), "Address Decode",
+	 acpi_gbl_DECdecode},
+	{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.min_address_fixed),
+	 "Min Relocatability", acpi_gbl_min_decode},
+	{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.max_address_fixed),
+	 "Max Relocatability", acpi_gbl_max_decode}
+};
+
+static struct acpi_rsdump_info acpi_rs_dump_memory_flags[5] = {
+	{ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory_flags),
+	 "Resource Type", (void *)"Memory Range"},
+	{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.mem.write_protect),
+	 "Write Protect", acpi_gbl_RWdecode},
+	{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.mem.caching),
+	 "Caching", acpi_gbl_MEMdecode},
+	{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.mem.range_type),
+	 "Range Type", acpi_gbl_MTPdecode},
+	{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.mem.translation),
+	 "Translation", acpi_gbl_TTPdecode}
+};
+
+static struct acpi_rsdump_info acpi_rs_dump_io_flags[4] = {
+	{ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_io_flags),
+	 "Resource Type", (void *)"I/O Range"},
+	{ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.io.range_type),
+	 "Range Type", acpi_gbl_RNGdecode},
+	{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.io.translation),
+	 "Translation", acpi_gbl_TTPdecode},
+	{ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.io.translation_type),
+	 "Translation Type", acpi_gbl_TRSdecode}
+};
 
-static void acpi_rs_dump_vendor_specific(union acpi_resource_data *data);
+/*
+ * Table used to dump _PRT contents
+ */
+static struct acpi_rsdump_info acpi_rs_dump_prt[5] = {
+	{ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_prt), NULL, NULL},
+	{ACPI_RSD_UINT64, ACPI_PRT_OFFSET(address), "Address", NULL},
+	{ACPI_RSD_UINT32, ACPI_PRT_OFFSET(pin), "Pin", NULL},
+	{ACPI_RSD_STRING, ACPI_PRT_OFFSET(source[0]), "Source", NULL},
+	{ACPI_RSD_UINT32, ACPI_PRT_OFFSET(source_index), "Source Index", NULL}
+};
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_dump_irq
+ * FUNCTION:    acpi_rs_dump_descriptor
  *
- * PARAMETERS:  Data            - pointer to the resource structure to dump.
+ * PARAMETERS:  Resource
  *
  * RETURN:      None
  *
- * DESCRIPTION: Prints out the various members of the Data structure type.
+ * DESCRIPTION:
  *
  ******************************************************************************/
 
-static void acpi_rs_dump_irq(union acpi_resource_data *data)
+static void
+acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table)
 {
-	struct acpi_resource_irq *irq_data = (struct acpi_resource_irq *)data;
-	u8 index = 0;
-
-	ACPI_FUNCTION_ENTRY();
-
-	acpi_os_printf("IRQ Resource\n");
+	u8 *target = NULL;
+	u8 *previous_target;
+	char *name;
+	u8 count;
 
-	acpi_os_printf("  %s Triggered\n",
-		       ACPI_LEVEL_SENSITIVE ==
-		       irq_data->edge_level ? "Level" : "Edge");
+	/* First table entry must contain the table length (# of table entries) */
 
-	acpi_os_printf("  Active %s\n",
-		       ACPI_ACTIVE_LOW ==
-		       irq_data->active_high_low ? "Low" : "High");
+	count = table->offset;
 
-	acpi_os_printf("  %s\n",
-		       ACPI_SHARED ==
-		       irq_data->shared_exclusive ? "Shared" : "Exclusive");
+	while (count) {
+		previous_target = target;
+		target = ACPI_ADD_PTR(u8, resource, table->offset);
+		name = table->name;
 
-	acpi_os_printf("  %X Interrupts ( ", irq_data->number_of_interrupts);
-
-	for (index = 0; index < irq_data->number_of_interrupts; index++) {
-		acpi_os_printf("%X ", irq_data->interrupts[index]);
-	}
+		switch (table->opcode) {
+		case ACPI_RSD_TITLE:
+			/*
+			 * Optional resource title
+			 */
+			if (table->name) {
+				acpi_os_printf("%s Resource\n", name);
+			}
+			break;
 
-	acpi_os_printf(")\n");
-	return;
-}
+			/* Strings */
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_rs_dump_dma
- *
- * PARAMETERS:  Data            - pointer to the resource structure to dump.
- *
- * RETURN:      None
- *
- * DESCRIPTION: Prints out the various members of the Data structure type.
- *
- ******************************************************************************/
+		case ACPI_RSD_LITERAL:
+			acpi_rs_out_string(name,
+					   ACPI_CAST_PTR(char, table->pointer));
+			break;
 
-static void acpi_rs_dump_dma(union acpi_resource_data *data)
-{
-	struct acpi_resource_dma *dma_data = (struct acpi_resource_dma *)data;
-	u8 index = 0;
+		case ACPI_RSD_STRING:
+			acpi_rs_out_string(name, ACPI_CAST_PTR(char, target));
+			break;
 
-	ACPI_FUNCTION_ENTRY();
+			/* Data items, 8/16/32/64 bit */
 
-	acpi_os_printf("DMA Resource\n");
+		case ACPI_RSD_UINT8:
+			acpi_rs_out_integer8(name, ACPI_GET8(target));
+			break;
 
-	switch (dma_data->type) {
-	case ACPI_COMPATIBILITY:
-		acpi_os_printf("  Compatibility mode\n");
-		break;
+		case ACPI_RSD_UINT16:
+			acpi_rs_out_integer16(name, ACPI_GET16(target));
+			break;
 
-	case ACPI_TYPE_A:
-		acpi_os_printf("  Type A\n");
-		break;
+		case ACPI_RSD_UINT32:
+			acpi_rs_out_integer32(name, ACPI_GET32(target));
+			break;
 
-	case ACPI_TYPE_B:
-		acpi_os_printf("  Type B\n");
-		break;
+		case ACPI_RSD_UINT64:
+			acpi_rs_out_integer64(name, ACPI_GET64(target));
+			break;
 
-	case ACPI_TYPE_F:
-		acpi_os_printf("  Type F\n");
-		break;
+			/* Flags: 1-bit and 2-bit flags supported */
 
-	default:
-		acpi_os_printf("  Invalid DMA type\n");
-		break;
-	}
+		case ACPI_RSD_1BITFLAG:
+			acpi_rs_out_string(name, ACPI_CAST_PTR(char,
+							       table->
+							       pointer[*target &
+								       0x01]));
+			break;
 
-	acpi_os_printf("  %sBus Master\n",
-		       ACPI_BUS_MASTER == dma_data->bus_master ? "" : "Not a ");
+		case ACPI_RSD_2BITFLAG:
+			acpi_rs_out_string(name, ACPI_CAST_PTR(char,
+							       table->
+							       pointer[*target &
+								       0x03]));
+			break;
 
-	switch (dma_data->transfer) {
-	case ACPI_TRANSFER_8:
-		acpi_os_printf("  8-bit only transfer\n");
-		break;
+		case ACPI_RSD_SHORTLIST:
+			/*
+			 * Short byte list (single line output) for DMA and IRQ resources
+			 * Note: The list length is obtained from the previous table entry
+			 */
+			if (previous_target) {
+				acpi_rs_out_title(name);
+				acpi_rs_dump_short_byte_list(*previous_target,
+							     target);
+			}
+			break;
 
-	case ACPI_TRANSFER_8_16:
-		acpi_os_printf("  8 and 16-bit transfer\n");
-		break;
+		case ACPI_RSD_LONGLIST:
+			/*
+			 * Long byte list for Vendor resource data
+			 * Note: The list length is obtained from the previous table entry
+			 */
+			if (previous_target) {
+				acpi_rs_dump_byte_list(ACPI_GET16
+						       (previous_target),
+						       target);
+			}
+			break;
 
-	case ACPI_TRANSFER_16:
-		acpi_os_printf("  16 bit only transfer\n");
-		break;
+		case ACPI_RSD_DWORDLIST:
+			/*
+			 * Dword list for Extended Interrupt resources
+			 * Note: The list length is obtained from the previous table entry
+			 */
+			if (previous_target) {
+				acpi_rs_dump_dword_list(*previous_target,
+							ACPI_CAST_PTR(u32,
+								      target));
+			}
+			break;
 
-	default:
-		acpi_os_printf("  Invalid transfer preference\n");
-		break;
-	}
+		case ACPI_RSD_ADDRESS:
+			/*
+			 * Common flags for all Address resources
+			 */
+			acpi_rs_dump_address_common(ACPI_CAST_PTR
+						    (union acpi_resource_data,
+						     target));
+			break;
+
+		case ACPI_RSD_SOURCE:
+			/*
+			 * Optional resource_source for Address resources
+			 */
+			acpi_rs_dump_resource_source(ACPI_CAST_PTR
+						     (struct
+						      acpi_resource_source,
+						      target));
+			break;
 
-	acpi_os_printf("  Number of Channels: %X ( ",
-		       dma_data->number_of_channels);
+		default:
+			acpi_os_printf("**** Invalid table opcode [%X] ****\n",
+				       table->opcode);
+			return;
+		}
 
-	for (index = 0; index < dma_data->number_of_channels; index++) {
-		acpi_os_printf("%X ", dma_data->channels[index]);
+		table++;
+		count--;
 	}
-
-	acpi_os_printf(")\n");
-	return;
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_dump_start_depend_fns
+ * FUNCTION:    acpi_rs_dump_resource_source
  *
- * PARAMETERS:  Data            - pointer to the resource structure to dump.
+ * PARAMETERS:  resource_source     - Pointer to a Resource Source struct
  *
  * RETURN:      None
  *
- * DESCRIPTION: Prints out the various members of the Data structure type.
+ * DESCRIPTION: Common routine for dumping the optional resource_source and the
+ *              corresponding resource_source_index.
  *
  ******************************************************************************/
 
-static void acpi_rs_dump_start_depend_fns(union acpi_resource_data *data)
+static void
+acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source)
 {
-	struct acpi_resource_start_dpf *sdf_data =
-	    (struct acpi_resource_start_dpf *)data;
-
 	ACPI_FUNCTION_ENTRY();
 
-	acpi_os_printf("Start Dependent Functions Resource\n");
-
-	switch (sdf_data->compatibility_priority) {
-	case ACPI_GOOD_CONFIGURATION:
-		acpi_os_printf("  Good configuration\n");
-		break;
-
-	case ACPI_ACCEPTABLE_CONFIGURATION:
-		acpi_os_printf("  Acceptable configuration\n");
-		break;
-
-	case ACPI_SUB_OPTIMAL_CONFIGURATION:
-		acpi_os_printf("  Sub-optimal configuration\n");
-		break;
-
-	default:
-		acpi_os_printf("  Invalid compatibility priority\n");
-		break;
-	}
-
-	switch (sdf_data->performance_robustness) {
-	case ACPI_GOOD_CONFIGURATION:
-		acpi_os_printf("  Good configuration\n");
-		break;
-
-	case ACPI_ACCEPTABLE_CONFIGURATION:
-		acpi_os_printf("  Acceptable configuration\n");
-		break;
-
-	case ACPI_SUB_OPTIMAL_CONFIGURATION:
-		acpi_os_printf("  Sub-optimal configuration\n");
-		break;
-
-	default:
-		acpi_os_printf("  Invalid performance robustness preference\n");
-		break;
+	if (resource_source->index == 0xFF) {
+		return;
 	}
 
-	return;
-}
+	acpi_rs_out_integer8("Resource Source Index", resource_source->index);
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_rs_dump_io
- *
- * PARAMETERS:  Data            - pointer to the resource structure to dump.
- *
- * RETURN:      None
- *
- * DESCRIPTION: Prints out the various members of the Data structure type.
- *
- ******************************************************************************/
-
-static void acpi_rs_dump_io(union acpi_resource_data *data)
-{
-	struct acpi_resource_io *io_data = (struct acpi_resource_io *)data;
-
-	ACPI_FUNCTION_ENTRY();
-
-	acpi_os_printf("Io Resource\n");
-
-	acpi_os_printf("  %d bit decode\n",
-		       ACPI_DECODE_16 == io_data->io_decode ? 16 : 10);
-
-	acpi_os_printf("  Range minimum base: %08X\n",
-		       io_data->min_base_address);
-
-	acpi_os_printf("  Range maximum base: %08X\n",
-		       io_data->max_base_address);
-
-	acpi_os_printf("  Alignment: %08X\n", io_data->alignment);
-
-	acpi_os_printf("  Range Length: %08X\n", io_data->range_length);
-
-	return;
+	acpi_rs_out_string("Resource Source",
+			   resource_source->string_ptr ?
+			   resource_source->string_ptr : "[Not Specified]");
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_dump_fixed_io
+ * FUNCTION:    acpi_rs_dump_address_common
  *
- * PARAMETERS:  Data            - pointer to the resource structure to dump.
+ * PARAMETERS:  Resource        - Pointer to an internal resource descriptor
  *
  * RETURN:      None
  *
- * DESCRIPTION: Prints out the various members of the Data structure type.
+ * DESCRIPTION: Dump the fields that are common to all Address resource
+ *              descriptors
  *
  ******************************************************************************/
 
-static void acpi_rs_dump_fixed_io(union acpi_resource_data *data)
+static void acpi_rs_dump_address_common(union acpi_resource_data *resource)
 {
-	struct acpi_resource_fixed_io *fixed_io_data =
-	    (struct acpi_resource_fixed_io *)data;
-
 	ACPI_FUNCTION_ENTRY();
 
-	acpi_os_printf("Fixed Io Resource\n");
-	acpi_os_printf("  Range base address: %08X",
-		       fixed_io_data->base_address);
+	/* Decode the type-specific flags */
 
-	acpi_os_printf("  Range length: %08X", fixed_io_data->range_length);
-
-	return;
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_rs_dump_vendor_specific
- *
- * PARAMETERS:  Data            - pointer to the resource structure to dump.
- *
- * RETURN:      None
- *
- * DESCRIPTION: Prints out the various members of the Data structure type.
- *
- ******************************************************************************/
-
-static void acpi_rs_dump_vendor_specific(union acpi_resource_data *data)
-{
-	struct acpi_resource_vendor *vendor_data =
-	    (struct acpi_resource_vendor *)data;
-	u16 index = 0;
-
-	ACPI_FUNCTION_ENTRY();
-
-	acpi_os_printf("Vendor Specific Resource\n");
-
-	acpi_os_printf("  Length: %08X\n", vendor_data->length);
-
-	for (index = 0; index < vendor_data->length; index++) {
-		acpi_os_printf("  Byte %X: %08X\n",
-			       index, vendor_data->reserved[index]);
-	}
-
-	return;
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_rs_dump_memory24
- *
- * PARAMETERS:  Data            - pointer to the resource structure to dump.
- *
- * RETURN:      None
- *
- * DESCRIPTION: Prints out the various members of the Data structure type.
- *
- ******************************************************************************/
-
-static void acpi_rs_dump_memory24(union acpi_resource_data *data)
-{
-	struct acpi_resource_mem24 *memory24_data =
-	    (struct acpi_resource_mem24 *)data;
-
-	ACPI_FUNCTION_ENTRY();
-
-	acpi_os_printf("24-Bit Memory Range Resource\n");
-
-	acpi_os_printf("  Read%s\n",
-		       ACPI_READ_WRITE_MEMORY ==
-		       memory24_data->read_write_attribute ?
-		       "/Write" : " only");
-
-	acpi_os_printf("  Range minimum base: %08X\n",
-		       memory24_data->min_base_address);
-
-	acpi_os_printf("  Range maximum base: %08X\n",
-		       memory24_data->max_base_address);
-
-	acpi_os_printf("  Alignment: %08X\n", memory24_data->alignment);
-
-	acpi_os_printf("  Range length: %08X\n", memory24_data->range_length);
-
-	return;
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_rs_dump_memory32
- *
- * PARAMETERS:  Data            - pointer to the resource structure to dump.
- *
- * RETURN:      None
- *
- * DESCRIPTION: Prints out the various members of the Data structure type.
- *
- ******************************************************************************/
-
-static void acpi_rs_dump_memory32(union acpi_resource_data *data)
-{
-	struct acpi_resource_mem32 *memory32_data =
-	    (struct acpi_resource_mem32 *)data;
-
-	ACPI_FUNCTION_ENTRY();
-
-	acpi_os_printf("32-Bit Memory Range Resource\n");
-
-	acpi_os_printf("  Read%s\n",
-		       ACPI_READ_WRITE_MEMORY ==
-		       memory32_data->read_write_attribute ?
-		       "/Write" : " only");
-
-	acpi_os_printf("  Range minimum base: %08X\n",
-		       memory32_data->min_base_address);
-
-	acpi_os_printf("  Range maximum base: %08X\n",
-		       memory32_data->max_base_address);
-
-	acpi_os_printf("  Alignment: %08X\n", memory32_data->alignment);
-
-	acpi_os_printf("  Range length: %08X\n", memory32_data->range_length);
-
-	return;
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_rs_dump_fixed_memory32
- *
- * PARAMETERS:  Data            - pointer to the resource structure to dump.
- *
- * RETURN:
- *
- * DESCRIPTION: Prints out the various members of the Data structure type.
- *
- ******************************************************************************/
-
-static void acpi_rs_dump_fixed_memory32(union acpi_resource_data *data)
-{
-	struct acpi_resource_fixed_mem32 *fixed_memory32_data =
-	    (struct acpi_resource_fixed_mem32 *)data;
-
-	ACPI_FUNCTION_ENTRY();
-
-	acpi_os_printf("32-Bit Fixed Location Memory Range Resource\n");
-
-	acpi_os_printf("  Read%s\n",
-		       ACPI_READ_WRITE_MEMORY ==
-		       fixed_memory32_data->
-		       read_write_attribute ? "/Write" : " Only");
-
-	acpi_os_printf("  Range base address: %08X\n",
-		       fixed_memory32_data->range_base_address);
-
-	acpi_os_printf("  Range length: %08X\n",
-		       fixed_memory32_data->range_length);
-
-	return;
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_rs_dump_address16
- *
- * PARAMETERS:  Data            - pointer to the resource structure to dump.
- *
- * RETURN:      None
- *
- * DESCRIPTION: Prints out the various members of the Data structure type.
- *
- ******************************************************************************/
-
-static void acpi_rs_dump_address16(union acpi_resource_data *data)
-{
-	struct acpi_resource_address16 *address16_data =
-	    (struct acpi_resource_address16 *)data;
-
-	ACPI_FUNCTION_ENTRY();
-
-	acpi_os_printf("16-Bit Address Space Resource\n");
-	acpi_os_printf("  Resource Type: ");
-
-	switch (address16_data->resource_type) {
+	switch (resource->address.resource_type) {
 	case ACPI_MEMORY_RANGE:
 
-		acpi_os_printf("Memory Range\n");
-
-		switch (address16_data->attribute.memory.cache_attribute) {
-		case ACPI_NON_CACHEABLE_MEMORY:
-			acpi_os_printf
-			    ("  Type Specific: Noncacheable memory\n");
-			break;
-
-		case ACPI_CACHABLE_MEMORY:
-			acpi_os_printf("  Type Specific: Cacheable memory\n");
-			break;
-
-		case ACPI_WRITE_COMBINING_MEMORY:
-			acpi_os_printf
-			    ("  Type Specific: Write-combining memory\n");
-			break;
-
-		case ACPI_PREFETCHABLE_MEMORY:
-			acpi_os_printf
-			    ("  Type Specific: Prefetchable memory\n");
-			break;
-
-		default:
-			acpi_os_printf
-			    ("  Type Specific: Invalid cache attribute\n");
-			break;
-		}
-
-		acpi_os_printf("  Type Specific: Read%s\n",
-			       ACPI_READ_WRITE_MEMORY ==
-			       address16_data->attribute.memory.
-			       read_write_attribute ? "/Write" : " Only");
+		acpi_rs_dump_descriptor(resource, acpi_rs_dump_memory_flags);
 		break;
 
 	case ACPI_IO_RANGE:
 
-		acpi_os_printf("I/O Range\n");
-
-		switch (address16_data->attribute.io.range_attribute) {
-		case ACPI_NON_ISA_ONLY_RANGES:
-			acpi_os_printf
-			    ("  Type Specific: Non-ISA Io Addresses\n");
-			break;
-
-		case ACPI_ISA_ONLY_RANGES:
-			acpi_os_printf("  Type Specific: ISA Io Addresses\n");
-			break;
-
-		case ACPI_ENTIRE_RANGE:
-			acpi_os_printf
-			    ("  Type Specific: ISA and non-ISA Io Addresses\n");
-			break;
-
-		default:
-			acpi_os_printf
-			    ("  Type Specific: Invalid range attribute\n");
-			break;
-		}
-
-		acpi_os_printf("  Type Specific: %s Translation\n",
-			       ACPI_SPARSE_TRANSLATION ==
-			       address16_data->attribute.io.
-			       translation_attribute ? "Sparse" : "Dense");
+		acpi_rs_dump_descriptor(resource, acpi_rs_dump_io_flags);
 		break;
 
 	case ACPI_BUS_NUMBER_RANGE:
 
-		acpi_os_printf("Bus Number Range\n");
+		acpi_rs_out_string("Resource Type", "Bus Number Range");
 		break;
 
 	default:
 
-		acpi_os_printf("0x%2.2X\n", address16_data->resource_type);
+		acpi_rs_out_integer8("Resource Type",
+				     (u8) resource->address.resource_type);
 		break;
 	}
 
-	acpi_os_printf("  Resource %s\n",
-		       ACPI_CONSUMER == address16_data->producer_consumer ?
-		       "Consumer" : "Producer");
-
-	acpi_os_printf("  %s decode\n",
-		       ACPI_SUB_DECODE == address16_data->decode ?
-		       "Subtractive" : "Positive");
-
-	acpi_os_printf("  Min address is %s fixed\n",
-		       ACPI_ADDRESS_FIXED == address16_data->min_address_fixed ?
-		       "" : "not");
-
-	acpi_os_printf("  Max address is %s fixed\n",
-		       ACPI_ADDRESS_FIXED == address16_data->max_address_fixed ?
-		       "" : "not");
-
-	acpi_os_printf("  Granularity: %08X\n", address16_data->granularity);
+	/* Decode the general flags */
 
-	acpi_os_printf("  Address range min: %08X\n",
-		       address16_data->min_address_range);
-
-	acpi_os_printf("  Address range max: %08X\n",
-		       address16_data->max_address_range);
-
-	acpi_os_printf("  Address translation offset: %08X\n",
-		       address16_data->address_translation_offset);
-
-	acpi_os_printf("  Address Length: %08X\n",
-		       address16_data->address_length);
-
-	if (0xFF != address16_data->resource_source.index) {
-		acpi_os_printf("  Resource Source Index: %X\n",
-			       address16_data->resource_source.index);
-
-		acpi_os_printf("  Resource Source: %s\n",
-			       address16_data->resource_source.string_ptr);
-	}
-
-	return;
+	acpi_rs_dump_descriptor(resource, acpi_rs_dump_general_flags);
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_dump_address32
+ * FUNCTION:    acpi_rs_dump_resource_list
  *
- * PARAMETERS:  Data            - pointer to the resource structure to dump.
+ * PARAMETERS:  resource_list       - Pointer to a resource descriptor list
  *
  * RETURN:      None
  *
- * DESCRIPTION: Prints out the various members of the Data structure type.
+ * DESCRIPTION: Dispatches the structure to the correct dump routine.
  *
  ******************************************************************************/
 
-static void acpi_rs_dump_address32(union acpi_resource_data *data)
+void acpi_rs_dump_resource_list(struct acpi_resource *resource_list)
 {
-	struct acpi_resource_address32 *address32_data =
-	    (struct acpi_resource_address32 *)data;
+	u32 count = 0;
+	u32 type;
 
 	ACPI_FUNCTION_ENTRY();
 
-	acpi_os_printf("32-Bit Address Space Resource\n");
-
-	switch (address32_data->resource_type) {
-	case ACPI_MEMORY_RANGE:
-
-		acpi_os_printf("  Resource Type: Memory Range\n");
-
-		switch (address32_data->attribute.memory.cache_attribute) {
-		case ACPI_NON_CACHEABLE_MEMORY:
-			acpi_os_printf
-			    ("  Type Specific: Noncacheable memory\n");
-			break;
-
-		case ACPI_CACHABLE_MEMORY:
-			acpi_os_printf("  Type Specific: Cacheable memory\n");
-			break;
-
-		case ACPI_WRITE_COMBINING_MEMORY:
-			acpi_os_printf
-			    ("  Type Specific: Write-combining memory\n");
-			break;
-
-		case ACPI_PREFETCHABLE_MEMORY:
-			acpi_os_printf
-			    ("  Type Specific: Prefetchable memory\n");
-			break;
-
-		default:
-			acpi_os_printf
-			    ("  Type Specific: Invalid cache attribute\n");
-			break;
-		}
-
-		acpi_os_printf("  Type Specific: Read%s\n",
-			       ACPI_READ_WRITE_MEMORY ==
-			       address32_data->attribute.memory.
-			       read_write_attribute ? "/Write" : " Only");
-		break;
-
-	case ACPI_IO_RANGE:
-
-		acpi_os_printf("  Resource Type: Io Range\n");
+	if (!(acpi_dbg_level & ACPI_LV_RESOURCES)
+	    || !(_COMPONENT & acpi_dbg_layer)) {
+		return;
+	}
 
-		switch (address32_data->attribute.io.range_attribute) {
-		case ACPI_NON_ISA_ONLY_RANGES:
-			acpi_os_printf
-			    ("  Type Specific: Non-ISA Io Addresses\n");
-			break;
+	/* Walk list and dump all resource descriptors (END_TAG terminates) */
 
-		case ACPI_ISA_ONLY_RANGES:
-			acpi_os_printf("  Type Specific: ISA Io Addresses\n");
-			break;
+	do {
+		acpi_os_printf("\n[%02X] ", count);
+		count++;
 
-		case ACPI_ENTIRE_RANGE:
-			acpi_os_printf
-			    ("  Type Specific: ISA and non-ISA Io Addresses\n");
-			break;
+		/* Validate Type before dispatch */
 
-		default:
+		type = resource_list->type;
+		if (type > ACPI_RESOURCE_TYPE_MAX) {
 			acpi_os_printf
-			    ("  Type Specific: Invalid Range attribute");
-			break;
+			    ("Invalid descriptor type (%X) in resource list\n",
+			     resource_list->type);
+			return;
 		}
 
-		acpi_os_printf("  Type Specific: %s Translation\n",
-			       ACPI_SPARSE_TRANSLATION ==
-			       address32_data->attribute.io.
-			       translation_attribute ? "Sparse" : "Dense");
-		break;
+		/* Dump the resource descriptor */
 
-	case ACPI_BUS_NUMBER_RANGE:
+		acpi_rs_dump_descriptor(&resource_list->data,
+					acpi_gbl_dump_resource_dispatch[type]);
 
-		acpi_os_printf("  Resource Type: Bus Number Range\n");
-		break;
-
-	default:
-
-		acpi_os_printf("  Resource Type: 0x%2.2X\n",
-			       address32_data->resource_type);
-		break;
-	}
-
-	acpi_os_printf("  Resource %s\n",
-		       ACPI_CONSUMER == address32_data->producer_consumer ?
-		       "Consumer" : "Producer");
-
-	acpi_os_printf("  %s decode\n",
-		       ACPI_SUB_DECODE == address32_data->decode ?
-		       "Subtractive" : "Positive");
-
-	acpi_os_printf("  Min address is %s fixed\n",
-		       ACPI_ADDRESS_FIXED == address32_data->min_address_fixed ?
-		       "" : "not ");
-
-	acpi_os_printf("  Max address is %s fixed\n",
-		       ACPI_ADDRESS_FIXED == address32_data->max_address_fixed ?
-		       "" : "not ");
-
-	acpi_os_printf("  Granularity: %08X\n", address32_data->granularity);
-
-	acpi_os_printf("  Address range min: %08X\n",
-		       address32_data->min_address_range);
+		/* Point to the next resource structure */
 
-	acpi_os_printf("  Address range max: %08X\n",
-		       address32_data->max_address_range);
+		resource_list =
+		    ACPI_ADD_PTR(struct acpi_resource, resource_list,
+				 resource_list->length);
 
-	acpi_os_printf("  Address translation offset: %08X\n",
-		       address32_data->address_translation_offset);
+		/* Exit when END_TAG descriptor is reached */
 
-	acpi_os_printf("  Address Length: %08X\n",
-		       address32_data->address_length);
-
-	if (0xFF != address32_data->resource_source.index) {
-		acpi_os_printf("  Resource Source Index: %X\n",
-			       address32_data->resource_source.index);
-
-		acpi_os_printf("  Resource Source: %s\n",
-			       address32_data->resource_source.string_ptr);
-	}
-
-	return;
+	} while (type != ACPI_RESOURCE_TYPE_END_TAG);
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_dump_address64
+ * FUNCTION:    acpi_rs_dump_irq_list
  *
- * PARAMETERS:  Data            - pointer to the resource structure to dump.
+ * PARAMETERS:  route_table     - Pointer to the routing table to dump.
  *
  * RETURN:      None
  *
- * DESCRIPTION: Prints out the various members of the Data structure type.
+ * DESCRIPTION: Print IRQ routing table
  *
  ******************************************************************************/
 
-static void acpi_rs_dump_address64(union acpi_resource_data *data)
+void acpi_rs_dump_irq_list(u8 * route_table)
 {
-	struct acpi_resource_address64 *address64_data =
-	    (struct acpi_resource_address64 *)data;
+	struct acpi_pci_routing_table *prt_element;
+	u8 count;
 
 	ACPI_FUNCTION_ENTRY();
 
-	acpi_os_printf("64-Bit Address Space Resource\n");
-
-	switch (address64_data->resource_type) {
-	case ACPI_MEMORY_RANGE:
-
-		acpi_os_printf("  Resource Type: Memory Range\n");
-
-		switch (address64_data->attribute.memory.cache_attribute) {
-		case ACPI_NON_CACHEABLE_MEMORY:
-			acpi_os_printf
-			    ("  Type Specific: Noncacheable memory\n");
-			break;
-
-		case ACPI_CACHABLE_MEMORY:
-			acpi_os_printf("  Type Specific: Cacheable memory\n");
-			break;
-
-		case ACPI_WRITE_COMBINING_MEMORY:
-			acpi_os_printf
-			    ("  Type Specific: Write-combining memory\n");
-			break;
-
-		case ACPI_PREFETCHABLE_MEMORY:
-			acpi_os_printf
-			    ("  Type Specific: Prefetchable memory\n");
-			break;
-
-		default:
-			acpi_os_printf
-			    ("  Type Specific: Invalid cache attribute\n");
-			break;
-		}
-
-		acpi_os_printf("  Type Specific: Read%s\n",
-			       ACPI_READ_WRITE_MEMORY ==
-			       address64_data->attribute.memory.
-			       read_write_attribute ? "/Write" : " Only");
-		break;
-
-	case ACPI_IO_RANGE:
-
-		acpi_os_printf("  Resource Type: Io Range\n");
-
-		switch (address64_data->attribute.io.range_attribute) {
-		case ACPI_NON_ISA_ONLY_RANGES:
-			acpi_os_printf
-			    ("  Type Specific: Non-ISA Io Addresses\n");
-			break;
-
-		case ACPI_ISA_ONLY_RANGES:
-			acpi_os_printf("  Type Specific: ISA Io Addresses\n");
-			break;
-
-		case ACPI_ENTIRE_RANGE:
-			acpi_os_printf
-			    ("  Type Specific: ISA and non-ISA Io Addresses\n");
-			break;
-
-		default:
-			acpi_os_printf
-			    ("  Type Specific: Invalid Range attribute");
-			break;
-		}
-
-		acpi_os_printf("  Type Specific: %s Translation\n",
-			       ACPI_SPARSE_TRANSLATION ==
-			       address64_data->attribute.io.
-			       translation_attribute ? "Sparse" : "Dense");
-		break;
-
-	case ACPI_BUS_NUMBER_RANGE:
-
-		acpi_os_printf("  Resource Type: Bus Number Range\n");
-		break;
-
-	default:
-
-		acpi_os_printf("  Resource Type: 0x%2.2X\n",
-			       address64_data->resource_type);
-		break;
+	if (!(acpi_dbg_level & ACPI_LV_RESOURCES)
+	    || !(_COMPONENT & acpi_dbg_layer)) {
+		return;
 	}
 
-	acpi_os_printf("  Resource %s\n",
-		       ACPI_CONSUMER == address64_data->producer_consumer ?
-		       "Consumer" : "Producer");
-
-	acpi_os_printf("  %s decode\n",
-		       ACPI_SUB_DECODE == address64_data->decode ?
-		       "Subtractive" : "Positive");
-
-	acpi_os_printf("  Min address is %s fixed\n",
-		       ACPI_ADDRESS_FIXED == address64_data->min_address_fixed ?
-		       "" : "not ");
-
-	acpi_os_printf("  Max address is %s fixed\n",
-		       ACPI_ADDRESS_FIXED == address64_data->max_address_fixed ?
-		       "" : "not ");
-
-	acpi_os_printf("  Granularity: %8.8X%8.8X\n",
-		       ACPI_FORMAT_UINT64(address64_data->granularity));
-
-	acpi_os_printf("  Address range min: %8.8X%8.8X\n",
-		       ACPI_FORMAT_UINT64(address64_data->min_address_range));
-
-	acpi_os_printf("  Address range max: %8.8X%8.8X\n",
-		       ACPI_FORMAT_UINT64(address64_data->max_address_range));
-
-	acpi_os_printf("  Address translation offset: %8.8X%8.8X\n",
-		       ACPI_FORMAT_UINT64(address64_data->
-					  address_translation_offset));
-
-	acpi_os_printf("  Address Length: %8.8X%8.8X\n",
-		       ACPI_FORMAT_UINT64(address64_data->address_length));
+	prt_element = ACPI_CAST_PTR(struct acpi_pci_routing_table, route_table);
 
-	acpi_os_printf("  Type Specific Attributes: %8.8X%8.8X\n",
-		       ACPI_FORMAT_UINT64(address64_data->
-					  type_specific_attributes));
+	/* Dump all table elements, Exit on zero length element */
 
-	if (0xFF != address64_data->resource_source.index) {
-		acpi_os_printf("  Resource Source Index: %X\n",
-			       address64_data->resource_source.index);
+	for (count = 0; prt_element->length; count++) {
+		acpi_os_printf("\n[%02X] PCI IRQ Routing Table Package\n",
+			       count);
+		acpi_rs_dump_descriptor(prt_element, acpi_rs_dump_prt);
 
-		acpi_os_printf("  Resource Source: %s\n",
-			       address64_data->resource_source.string_ptr);
+		prt_element = ACPI_ADD_PTR(struct acpi_pci_routing_table,
+					   prt_element, prt_element->length);
 	}
-
-	return;
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_dump_extended_irq
+ * FUNCTION:    acpi_rs_out*
  *
- * PARAMETERS:  Data            - pointer to the resource structure to dump.
+ * PARAMETERS:  Title       - Name of the resource field
+ *              Value       - Value of the resource field
  *
  * RETURN:      None
  *
- * DESCRIPTION: Prints out the various members of the Data structure type.
+ * DESCRIPTION: Miscellaneous helper functions to consistently format the
+ *              output of the resource dump routines
  *
  ******************************************************************************/
 
-static void acpi_rs_dump_extended_irq(union acpi_resource_data *data)
+static void acpi_rs_out_string(char *title, char *value)
 {
-	struct acpi_resource_ext_irq *ext_irq_data =
-	    (struct acpi_resource_ext_irq *)data;
-	u8 index = 0;
-
-	ACPI_FUNCTION_ENTRY();
-
-	acpi_os_printf("Extended IRQ Resource\n");
-
-	acpi_os_printf("  Resource %s\n",
-		       ACPI_CONSUMER == ext_irq_data->producer_consumer ?
-		       "Consumer" : "Producer");
-
-	acpi_os_printf("  %s\n",
-		       ACPI_LEVEL_SENSITIVE == ext_irq_data->edge_level ?
-		       "Level" : "Edge");
-
-	acpi_os_printf("  Active %s\n",
-		       ACPI_ACTIVE_LOW == ext_irq_data->active_high_low ?
-		       "low" : "high");
-
-	acpi_os_printf("  %s\n",
-		       ACPI_SHARED == ext_irq_data->shared_exclusive ?
-		       "Shared" : "Exclusive");
-
-	acpi_os_printf("  Interrupts : %X ( ",
-		       ext_irq_data->number_of_interrupts);
-
-	for (index = 0; index < ext_irq_data->number_of_interrupts; index++) {
-		acpi_os_printf("%X ", ext_irq_data->interrupts[index]);
+	acpi_os_printf("%27s : %s", title, value);
+	if (!*value) {
+		acpi_os_printf("[NULL NAMESTRING]");
 	}
+	acpi_os_printf("\n");
+}
 
-	acpi_os_printf(")\n");
+static void acpi_rs_out_integer8(char *title, u8 value)
+{
+	acpi_os_printf("%27s : %2.2X\n", title, value);
+}
 
-	if (0xFF != ext_irq_data->resource_source.index) {
-		acpi_os_printf("  Resource Source Index: %X",
-			       ext_irq_data->resource_source.index);
+static void acpi_rs_out_integer16(char *title, u16 value)
+{
+	acpi_os_printf("%27s : %4.4X\n", title, value);
+}
 
-		acpi_os_printf("  Resource Source: %s",
-			       ext_irq_data->resource_source.string_ptr);
-	}
+static void acpi_rs_out_integer32(char *title, u32 value)
+{
+	acpi_os_printf("%27s : %8.8X\n", title, value);
+}
+
+static void acpi_rs_out_integer64(char *title, u64 value)
+{
+	acpi_os_printf("%27s : %8.8X%8.8X\n", title, ACPI_FORMAT_UINT64(value));
+}
 
-	return;
+static void acpi_rs_out_title(char *title)
+{
+	acpi_os_printf("%27s : ", title);
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_dump_resource_list
+ * FUNCTION:    acpi_rs_dump*List
  *
- * PARAMETERS:  Resource        - pointer to the resource structure to dump.
+ * PARAMETERS:  Length      - Number of elements in the list
+ *              Data        - Start of the list
  *
  * RETURN:      None
  *
- * DESCRIPTION: Dispatches the structure to the correct dump routine.
+ * DESCRIPTION: Miscellaneous functions to dump lists of raw data
  *
  ******************************************************************************/
 
-void acpi_rs_dump_resource_list(struct acpi_resource *resource)
+static void acpi_rs_dump_byte_list(u16 length, u8 * data)
 {
-	u8 count = 0;
-	u8 done = FALSE;
+	u8 i;
 
-	ACPI_FUNCTION_ENTRY();
-
-	if (acpi_dbg_level & ACPI_LV_RESOURCES && _COMPONENT & acpi_dbg_layer) {
-		while (!done) {
-			acpi_os_printf("Resource structure %X.\n", count++);
-
-			switch (resource->id) {
-			case ACPI_RSTYPE_IRQ:
-				acpi_rs_dump_irq(&resource->data);
-				break;
-
-			case ACPI_RSTYPE_DMA:
-				acpi_rs_dump_dma(&resource->data);
-				break;
-
-			case ACPI_RSTYPE_START_DPF:
-				acpi_rs_dump_start_depend_fns(&resource->data);
-				break;
-
-			case ACPI_RSTYPE_END_DPF:
-				acpi_os_printf
-				    ("end_dependent_functions Resource\n");
-				/* acpi_rs_dump_end_dependent_functions (Resource->Data); */
-				break;
-
-			case ACPI_RSTYPE_IO:
-				acpi_rs_dump_io(&resource->data);
-				break;
-
-			case ACPI_RSTYPE_FIXED_IO:
-				acpi_rs_dump_fixed_io(&resource->data);
-				break;
-
-			case ACPI_RSTYPE_VENDOR:
-				acpi_rs_dump_vendor_specific(&resource->data);
-				break;
-
-			case ACPI_RSTYPE_END_TAG:
-				/*rs_dump_end_tag (Resource->Data); */
-				acpi_os_printf("end_tag Resource\n");
-				done = TRUE;
-				break;
-
-			case ACPI_RSTYPE_MEM24:
-				acpi_rs_dump_memory24(&resource->data);
-				break;
-
-			case ACPI_RSTYPE_MEM32:
-				acpi_rs_dump_memory32(&resource->data);
-				break;
-
-			case ACPI_RSTYPE_FIXED_MEM32:
-				acpi_rs_dump_fixed_memory32(&resource->data);
-				break;
-
-			case ACPI_RSTYPE_ADDRESS16:
-				acpi_rs_dump_address16(&resource->data);
-				break;
-
-			case ACPI_RSTYPE_ADDRESS32:
-				acpi_rs_dump_address32(&resource->data);
-				break;
-
-			case ACPI_RSTYPE_ADDRESS64:
-				acpi_rs_dump_address64(&resource->data);
-				break;
-
-			case ACPI_RSTYPE_EXT_IRQ:
-				acpi_rs_dump_extended_irq(&resource->data);
-				break;
-
-			default:
-				acpi_os_printf("Invalid resource type\n");
-				break;
+	for (i = 0; i < length; i++) {
+		acpi_os_printf("%25s%2.2X : %2.2X\n", "Byte", i, data[i]);
+	}
+}
 
-			}
+static void acpi_rs_dump_short_byte_list(u8 length, u8 * data)
+{
+	u8 i;
 
-			resource =
-			    ACPI_PTR_ADD(struct acpi_resource, resource,
-					 resource->length);
-		}
+	for (i = 0; i < length; i++) {
+		acpi_os_printf("%X ", data[i]);
 	}
-
-	return;
+	acpi_os_printf("\n");
 }
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_rs_dump_irq_list
- *
- * PARAMETERS:  route_table     - pointer to the routing table to dump.
- *
- * RETURN:      None
- *
- * DESCRIPTION: Dispatches the structures to the correct dump routine.
- *
- ******************************************************************************/
-
-void acpi_rs_dump_irq_list(u8 * route_table)
+static void acpi_rs_dump_dword_list(u8 length, u32 * data)
 {
-	u8 *buffer = route_table;
-	u8 count = 0;
-	u8 done = FALSE;
-	struct acpi_pci_routing_table *prt_element;
-
-	ACPI_FUNCTION_ENTRY();
+	u8 i;
 
-	if (acpi_dbg_level & ACPI_LV_RESOURCES && _COMPONENT & acpi_dbg_layer) {
-		prt_element =
-		    ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer);
-
-		while (!done) {
-			acpi_os_printf("PCI IRQ Routing Table structure %X.\n",
-				       count++);
-
-			acpi_os_printf("  Address: %8.8X%8.8X\n",
-				       ACPI_FORMAT_UINT64(prt_element->
-							  address));
-
-			acpi_os_printf("  Pin: %X\n", prt_element->pin);
-
-			acpi_os_printf("  Source: %s\n", prt_element->source);
-
-			acpi_os_printf("  source_index: %X\n",
-				       prt_element->source_index);
-
-			buffer += prt_element->length;
-			prt_element =
-			    ACPI_CAST_PTR(struct acpi_pci_routing_table,
-					  buffer);
-			if (0 == prt_element->length) {
-				done = TRUE;
-			}
-		}
+	for (i = 0; i < length; i++) {
+		acpi_os_printf("%25s%2.2X : %8.8X\n", "Dword", i, data[i]);
 	}
-
-	return;
 }
 
 #endif
diff --git a/drivers/acpi/resources/rsinfo.c b/drivers/acpi/resources/rsinfo.c
new file mode 100644
index 0000000..d9ae64b
--- /dev/null
+++ b/drivers/acpi/resources/rsinfo.c
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ *
+ * Module Name: rsinfo - Dispatch and Info tables
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2006, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include <acpi/acresrc.h>
+
+#define _COMPONENT          ACPI_RESOURCES
+ACPI_MODULE_NAME("rsinfo")
+
+/*
+ * Resource dispatch and information tables. Any new resource types (either
+ * Large or Small) must be reflected in each of these tables, so they are here
+ * in one place.
+ *
+ * The tables for Large descriptors are indexed by bits 6:0 of the AML
+ * descriptor type byte. The tables for Small descriptors are indexed by
+ * bits 6:3 of the descriptor byte. The tables for internal resource
+ * descriptors are indexed by the acpi_resource_type field.
+ */
+/* Dispatch table for resource-to-AML (Set Resource) conversion functions */
+struct acpi_rsconvert_info *acpi_gbl_set_resource_dispatch[] = {
+	acpi_rs_set_irq,	/* 0x00, ACPI_RESOURCE_TYPE_IRQ */
+	acpi_rs_convert_dma,	/* 0x01, ACPI_RESOURCE_TYPE_DMA */
+	acpi_rs_set_start_dpf,	/* 0x02, ACPI_RESOURCE_TYPE_START_DEPENDENT */
+	acpi_rs_convert_end_dpf,	/* 0x03, ACPI_RESOURCE_TYPE_END_DEPENDENT */
+	acpi_rs_convert_io,	/* 0x04, ACPI_RESOURCE_TYPE_IO */
+	acpi_rs_convert_fixed_io,	/* 0x05, ACPI_RESOURCE_TYPE_FIXED_IO */
+	acpi_rs_set_vendor,	/* 0x06, ACPI_RESOURCE_TYPE_VENDOR */
+	acpi_rs_convert_end_tag,	/* 0x07, ACPI_RESOURCE_TYPE_END_TAG */
+	acpi_rs_convert_memory24,	/* 0x08, ACPI_RESOURCE_TYPE_MEMORY24 */
+	acpi_rs_convert_memory32,	/* 0x09, ACPI_RESOURCE_TYPE_MEMORY32 */
+	acpi_rs_convert_fixed_memory32,	/* 0x0A, ACPI_RESOURCE_TYPE_FIXED_MEMORY32 */
+	acpi_rs_convert_address16,	/* 0x0B, ACPI_RESOURCE_TYPE_ADDRESS16 */
+	acpi_rs_convert_address32,	/* 0x0C, ACPI_RESOURCE_TYPE_ADDRESS32 */
+	acpi_rs_convert_address64,	/* 0x0D, ACPI_RESOURCE_TYPE_ADDRESS64 */
+	acpi_rs_convert_ext_address64,	/* 0x0E, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 */
+	acpi_rs_convert_ext_irq,	/* 0x0F, ACPI_RESOURCE_TYPE_EXTENDED_IRQ */
+	acpi_rs_convert_generic_reg	/* 0x10, ACPI_RESOURCE_TYPE_GENERIC_REGISTER */
+};
+
+/* Dispatch tables for AML-to-resource (Get Resource) conversion functions */
+
+struct acpi_rsconvert_info *acpi_gbl_get_resource_dispatch[] = {
+	/* Small descriptors */
+
+	NULL,			/* 0x00, Reserved */
+	NULL,			/* 0x01, Reserved */
+	NULL,			/* 0x02, Reserved */
+	NULL,			/* 0x03, Reserved */
+	acpi_rs_get_irq,	/* 0x04, ACPI_RESOURCE_NAME_IRQ */
+	acpi_rs_convert_dma,	/* 0x05, ACPI_RESOURCE_NAME_DMA */
+	acpi_rs_get_start_dpf,	/* 0x06, ACPI_RESOURCE_NAME_START_DEPENDENT */
+	acpi_rs_convert_end_dpf,	/* 0x07, ACPI_RESOURCE_NAME_END_DEPENDENT */
+	acpi_rs_convert_io,	/* 0x08, ACPI_RESOURCE_NAME_IO */
+	acpi_rs_convert_fixed_io,	/* 0x09, ACPI_RESOURCE_NAME_FIXED_IO */
+	NULL,			/* 0x0A, Reserved */
+	NULL,			/* 0x0B, Reserved */
+	NULL,			/* 0x0C, Reserved */
+	NULL,			/* 0x0D, Reserved */
+	acpi_rs_get_vendor_small,	/* 0x0E, ACPI_RESOURCE_NAME_VENDOR_SMALL */
+	acpi_rs_convert_end_tag,	/* 0x0F, ACPI_RESOURCE_NAME_END_TAG */
+
+	/* Large descriptors */
+
+	NULL,			/* 0x00, Reserved */
+	acpi_rs_convert_memory24,	/* 0x01, ACPI_RESOURCE_NAME_MEMORY24 */
+	acpi_rs_convert_generic_reg,	/* 0x02, ACPI_RESOURCE_NAME_GENERIC_REGISTER */
+	NULL,			/* 0x03, Reserved */
+	acpi_rs_get_vendor_large,	/* 0x04, ACPI_RESOURCE_NAME_VENDOR_LARGE */
+	acpi_rs_convert_memory32,	/* 0x05, ACPI_RESOURCE_NAME_MEMORY32 */
+	acpi_rs_convert_fixed_memory32,	/* 0x06, ACPI_RESOURCE_NAME_FIXED_MEMORY32 */
+	acpi_rs_convert_address32,	/* 0x07, ACPI_RESOURCE_NAME_ADDRESS32 */
+	acpi_rs_convert_address16,	/* 0x08, ACPI_RESOURCE_NAME_ADDRESS16 */
+	acpi_rs_convert_ext_irq,	/* 0x09, ACPI_RESOURCE_NAME_EXTENDED_IRQ */
+	acpi_rs_convert_address64,	/* 0x0A, ACPI_RESOURCE_NAME_ADDRESS64 */
+	acpi_rs_convert_ext_address64	/* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64 */
+};
+
+#ifdef ACPI_FUTURE_USAGE
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+
+/* Dispatch table for resource dump functions */
+
+struct acpi_rsdump_info *acpi_gbl_dump_resource_dispatch[] = {
+	acpi_rs_dump_irq,	/* ACPI_RESOURCE_TYPE_IRQ */
+	acpi_rs_dump_dma,	/* ACPI_RESOURCE_TYPE_DMA */
+	acpi_rs_dump_start_dpf,	/* ACPI_RESOURCE_TYPE_START_DEPENDENT */
+	acpi_rs_dump_end_dpf,	/* ACPI_RESOURCE_TYPE_END_DEPENDENT */
+	acpi_rs_dump_io,	/* ACPI_RESOURCE_TYPE_IO */
+	acpi_rs_dump_fixed_io,	/* ACPI_RESOURCE_TYPE_FIXED_IO */
+	acpi_rs_dump_vendor,	/* ACPI_RESOURCE_TYPE_VENDOR */
+	acpi_rs_dump_end_tag,	/* ACPI_RESOURCE_TYPE_END_TAG */
+	acpi_rs_dump_memory24,	/* ACPI_RESOURCE_TYPE_MEMORY24 */
+	acpi_rs_dump_memory32,	/* ACPI_RESOURCE_TYPE_MEMORY32 */
+	acpi_rs_dump_fixed_memory32,	/* ACPI_RESOURCE_TYPE_FIXED_MEMORY32 */
+	acpi_rs_dump_address16,	/* ACPI_RESOURCE_TYPE_ADDRESS16 */
+	acpi_rs_dump_address32,	/* ACPI_RESOURCE_TYPE_ADDRESS32 */
+	acpi_rs_dump_address64,	/* ACPI_RESOURCE_TYPE_ADDRESS64 */
+	acpi_rs_dump_ext_address64,	/* ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 */
+	acpi_rs_dump_ext_irq,	/* ACPI_RESOURCE_TYPE_EXTENDED_IRQ */
+	acpi_rs_dump_generic_reg,	/* ACPI_RESOURCE_TYPE_GENERIC_REGISTER */
+};
+#endif
+#endif	/* ACPI_FUTURE_USAGE */
+/*
+ * Base sizes for external AML resource descriptors, indexed by internal type.
+ * Includes size of the descriptor header (1 byte for small descriptors,
+ * 3 bytes for large descriptors)
+ */
+const u8 acpi_gbl_aml_resource_sizes[] = {
+	sizeof(struct aml_resource_irq),	/* ACPI_RESOURCE_TYPE_IRQ (optional Byte 3 always created) */
+	sizeof(struct aml_resource_dma),	/* ACPI_RESOURCE_TYPE_DMA */
+	sizeof(struct aml_resource_start_dependent),	/* ACPI_RESOURCE_TYPE_START_DEPENDENT (optional Byte 1 always created) */
+	sizeof(struct aml_resource_end_dependent),	/* ACPI_RESOURCE_TYPE_END_DEPENDENT */
+	sizeof(struct aml_resource_io),	/* ACPI_RESOURCE_TYPE_IO */
+	sizeof(struct aml_resource_fixed_io),	/* ACPI_RESOURCE_TYPE_FIXED_IO */
+	sizeof(struct aml_resource_vendor_small),	/* ACPI_RESOURCE_TYPE_VENDOR */
+	sizeof(struct aml_resource_end_tag),	/* ACPI_RESOURCE_TYPE_END_TAG */
+	sizeof(struct aml_resource_memory24),	/* ACPI_RESOURCE_TYPE_MEMORY24 */
+	sizeof(struct aml_resource_memory32),	/* ACPI_RESOURCE_TYPE_MEMORY32 */
+	sizeof(struct aml_resource_fixed_memory32),	/* ACPI_RESOURCE_TYPE_FIXED_MEMORY32 */
+	sizeof(struct aml_resource_address16),	/* ACPI_RESOURCE_TYPE_ADDRESS16 */
+	sizeof(struct aml_resource_address32),	/* ACPI_RESOURCE_TYPE_ADDRESS32 */
+	sizeof(struct aml_resource_address64),	/* ACPI_RESOURCE_TYPE_ADDRESS64 */
+	sizeof(struct aml_resource_extended_address64),	/*ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 */
+	sizeof(struct aml_resource_extended_irq),	/* ACPI_RESOURCE_TYPE_EXTENDED_IRQ */
+	sizeof(struct aml_resource_generic_register)	/* ACPI_RESOURCE_TYPE_GENERIC_REGISTER */
+};
+
+const u8 acpi_gbl_resource_struct_sizes[] = {
+	/* Small descriptors */
+
+	0,
+	0,
+	0,
+	0,
+	ACPI_RS_SIZE(struct acpi_resource_irq),
+	ACPI_RS_SIZE(struct acpi_resource_dma),
+	ACPI_RS_SIZE(struct acpi_resource_start_dependent),
+	ACPI_RS_SIZE_MIN,
+	ACPI_RS_SIZE(struct acpi_resource_io),
+	ACPI_RS_SIZE(struct acpi_resource_fixed_io),
+	0,
+	0,
+	0,
+	0,
+	ACPI_RS_SIZE(struct acpi_resource_vendor),
+	ACPI_RS_SIZE_MIN,
+
+	/* Large descriptors */
+
+	0,
+	ACPI_RS_SIZE(struct acpi_resource_memory24),
+	ACPI_RS_SIZE(struct acpi_resource_generic_register),
+	0,
+	ACPI_RS_SIZE(struct acpi_resource_vendor),
+	ACPI_RS_SIZE(struct acpi_resource_memory32),
+	ACPI_RS_SIZE(struct acpi_resource_fixed_memory32),
+	ACPI_RS_SIZE(struct acpi_resource_address32),
+	ACPI_RS_SIZE(struct acpi_resource_address16),
+	ACPI_RS_SIZE(struct acpi_resource_extended_irq),
+	ACPI_RS_SIZE(struct acpi_resource_address64),
+	ACPI_RS_SIZE(struct acpi_resource_extended_address64)
+};
diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c
index d53bbe8..ea56716 100644
--- a/drivers/acpi/resources/rsio.c
+++ b/drivers/acpi/resources/rsio.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -49,428 +49,206 @@ ACPI_MODULE_NAME("rsio")
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_io_resource
- *
- * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
- *                                        stream
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        consumed the byte_stream_buffer is
- *                                        returned
- *              output_buffer           - Pointer to the return data buffer
- *              structure_size          - Pointer to where the number of bytes
- *                                        in the return data struct is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *              structure pointed to by the output_buffer. Return the
- *              number of bytes consumed from the byte stream.
+ * acpi_rs_convert_io
  *
  ******************************************************************************/
-acpi_status
-acpi_rs_io_resource(u8 * byte_stream_buffer,
-		    acpi_size * bytes_consumed,
-		    u8 ** output_buffer, acpi_size * structure_size)
-{
-	u8 *buffer = byte_stream_buffer;
-	struct acpi_resource *output_struct = (void *)*output_buffer;
-	u16 temp16 = 0;
-	u8 temp8 = 0;
-	acpi_size struct_size = ACPI_SIZEOF_RESOURCE(struct acpi_resource_io);
-
-	ACPI_FUNCTION_TRACE("rs_io_resource");
-
-	/* The number of bytes consumed are Constant */
-
-	*bytes_consumed = 8;
-
-	output_struct->id = ACPI_RSTYPE_IO;
-
-	/* Check Decode */
-
-	buffer += 1;
-	temp8 = *buffer;
-
-	output_struct->data.io.io_decode = temp8 & 0x01;
-
-	/* Check min_base Address */
-
-	buffer += 1;
-	ACPI_MOVE_16_TO_16(&temp16, buffer);
-
-	output_struct->data.io.min_base_address = temp16;
-
-	/* Check max_base Address */
+struct acpi_rsconvert_info acpi_rs_convert_io[5] = {
+	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IO,
+	 ACPI_RS_SIZE(struct acpi_resource_io),
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_io)},
 
-	buffer += 2;
-	ACPI_MOVE_16_TO_16(&temp16, buffer);
+	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IO,
+	 sizeof(struct aml_resource_io),
+	 0},
 
-	output_struct->data.io.max_base_address = temp16;
+	/* Decode flag */
 
-	/* Check Base alignment */
+	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.io.io_decode),
+	 AML_OFFSET(io.flags),
+	 0},
+	/*
+	 * These fields are contiguous in both the source and destination:
+	 * Address Alignment
+	 * Length
+	 * Minimum Base Address
+	 * Maximum Base Address
+	 */
+	{ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.io.alignment),
+	 AML_OFFSET(io.alignment),
+	 2},
 
-	buffer += 2;
-	temp8 = *buffer;
-
-	output_struct->data.io.alignment = temp8;
-
-	/* Check range_length */
-
-	buffer += 1;
-	temp8 = *buffer;
-
-	output_struct->data.io.range_length = temp8;
-
-	/* Set the Length parameter */
-
-	output_struct->length = (u32) struct_size;
-
-	/* Return the final size of the structure */
-
-	*structure_size = struct_size;
-	return_ACPI_STATUS(AE_OK);
-}
+	{ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.io.minimum),
+	 AML_OFFSET(io.minimum),
+	 2}
+};
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_fixed_io_resource
- *
- * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
- *                                        stream
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        consumed the byte_stream_buffer is
- *                                        returned
- *              output_buffer           - Pointer to the return data buffer
- *              structure_size          - Pointer to where the number of bytes
- *                                        in the return data struct is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *              structure pointed to by the output_buffer. Return the
- *              number of bytes consumed from the byte stream.
+ * acpi_rs_convert_fixed_io
  *
  ******************************************************************************/
 
-acpi_status
-acpi_rs_fixed_io_resource(u8 * byte_stream_buffer,
-			  acpi_size * bytes_consumed,
-			  u8 ** output_buffer, acpi_size * structure_size)
-{
-	u8 *buffer = byte_stream_buffer;
-	struct acpi_resource *output_struct = (void *)*output_buffer;
-	u16 temp16 = 0;
-	u8 temp8 = 0;
-	acpi_size struct_size =
-	    ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_io);
-
-	ACPI_FUNCTION_TRACE("rs_fixed_io_resource");
-
-	/* The number of bytes consumed are Constant */
-
-	*bytes_consumed = 4;
+struct acpi_rsconvert_info acpi_rs_convert_fixed_io[4] = {
+	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_FIXED_IO,
+	 ACPI_RS_SIZE(struct acpi_resource_fixed_io),
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_fixed_io)},
 
-	output_struct->id = ACPI_RSTYPE_FIXED_IO;
+	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_FIXED_IO,
+	 sizeof(struct aml_resource_fixed_io),
+	 0},
+	/*
+	 * These fields are contiguous in both the source and destination:
+	 * Base Address
+	 * Length
+	 */
+	{ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.fixed_io.address_length),
+	 AML_OFFSET(fixed_io.address_length),
+	 1},
 
-	/* Check Range Base Address */
-
-	buffer += 1;
-	ACPI_MOVE_16_TO_16(&temp16, buffer);
-
-	output_struct->data.fixed_io.base_address = temp16;
-
-	/* Check range_length */
-
-	buffer += 2;
-	temp8 = *buffer;
-
-	output_struct->data.fixed_io.range_length = temp8;
-
-	/* Set the Length parameter */
-
-	output_struct->length = (u32) struct_size;
-
-	/* Return the final size of the structure */
-
-	*structure_size = struct_size;
-	return_ACPI_STATUS(AE_OK);
-}
+	{ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.fixed_io.address),
+	 AML_OFFSET(fixed_io.address),
+	 1}
+};
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_io_stream
- *
- * PARAMETERS:  linked_list             - Pointer to the resource linked list
- *              output_buffer           - Pointer to the user's return buffer
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        used in the output_buffer is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the linked list resource structure and fills in the
- *              the appropriate bytes in a byte stream
+ * acpi_rs_convert_generic_reg
  *
  ******************************************************************************/
 
-acpi_status
-acpi_rs_io_stream(struct acpi_resource *linked_list,
-		  u8 ** output_buffer, acpi_size * bytes_consumed)
-{
-	u8 *buffer = *output_buffer;
-	u16 temp16 = 0;
-	u8 temp8 = 0;
-
-	ACPI_FUNCTION_TRACE("rs_io_stream");
-
-	/* The descriptor field is static */
-
-	*buffer = 0x47;
-	buffer += 1;
-
-	/* Io Information Byte */
-
-	temp8 = (u8) (linked_list->data.io.io_decode & 0x01);
-
-	*buffer = temp8;
-	buffer += 1;
-
-	/* Set the Range minimum base address */
-
-	temp16 = (u16) linked_list->data.io.min_base_address;
-
-	ACPI_MOVE_16_TO_16(buffer, &temp16);
-	buffer += 2;
-
-	/* Set the Range maximum base address */
-
-	temp16 = (u16) linked_list->data.io.max_base_address;
+struct acpi_rsconvert_info acpi_rs_convert_generic_reg[4] = {
+	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_GENERIC_REGISTER,
+	 ACPI_RS_SIZE(struct acpi_resource_generic_register),
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_generic_reg)},
 
-	ACPI_MOVE_16_TO_16(buffer, &temp16);
-	buffer += 2;
+	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_GENERIC_REGISTER,
+	 sizeof(struct aml_resource_generic_register),
+	 0},
+	/*
+	 * These fields are contiguous in both the source and destination:
+	 * Address Space ID
+	 * Register Bit Width
+	 * Register Bit Offset
+	 * Access Size
+	 */
+	{ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.generic_reg.space_id),
+	 AML_OFFSET(generic_reg.address_space_id),
+	 4},
 
-	/* Set the base alignment */
+	/* Get the Register Address */
 
-	temp8 = (u8) linked_list->data.io.alignment;
-
-	*buffer = temp8;
-	buffer += 1;
-
-	/* Set the range length */
-
-	temp8 = (u8) linked_list->data.io.range_length;
-
-	*buffer = temp8;
-	buffer += 1;
-
-	/* Return the number of bytes consumed in this operation */
-
-	*bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
-	return_ACPI_STATUS(AE_OK);
-}
+	{ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.generic_reg.address),
+	 AML_OFFSET(generic_reg.address),
+	 1}
+};
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_fixed_io_stream
- *
- * PARAMETERS:  linked_list             - Pointer to the resource linked list
- *              output_buffer           - Pointer to the user's return buffer
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        used in the output_buffer is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the linked list resource structure and fills in the
- *              the appropriate bytes in a byte stream
+ * acpi_rs_convert_end_dpf
  *
  ******************************************************************************/
 
-acpi_status
-acpi_rs_fixed_io_stream(struct acpi_resource *linked_list,
-			u8 ** output_buffer, acpi_size * bytes_consumed)
-{
-	u8 *buffer = *output_buffer;
-	u16 temp16 = 0;
-	u8 temp8 = 0;
-
-	ACPI_FUNCTION_TRACE("rs_fixed_io_stream");
-
-	/* The descriptor field is static */
-
-	*buffer = 0x4B;
+struct acpi_rsconvert_info acpi_rs_convert_end_dpf[2] = {
+	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_END_DEPENDENT,
+	 ACPI_RS_SIZE_MIN,
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_end_dpf)},
 
-	buffer += 1;
-
-	/* Set the Range base address */
-
-	temp16 = (u16) linked_list->data.fixed_io.base_address;
-
-	ACPI_MOVE_16_TO_16(buffer, &temp16);
-	buffer += 2;
-
-	/* Set the range length */
-
-	temp8 = (u8) linked_list->data.fixed_io.range_length;
-
-	*buffer = temp8;
-	buffer += 1;
-
-	/* Return the number of bytes consumed in this operation */
-
-	*bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
-	return_ACPI_STATUS(AE_OK);
-}
+	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_END_DEPENDENT,
+	 sizeof(struct aml_resource_end_dependent),
+	 0}
+};
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_dma_resource
- *
- * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
- *                                        stream
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        consumed the byte_stream_buffer is
- *                                        returned
- *              output_buffer           - Pointer to the return data buffer
- *              structure_size          - Pointer to where the number of bytes
- *                                        in the return data struct is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *              structure pointed to by the output_buffer. Return the
- *              number of bytes consumed from the byte stream.
+ * acpi_rs_convert_end_tag
  *
  ******************************************************************************/
 
-acpi_status
-acpi_rs_dma_resource(u8 * byte_stream_buffer,
-		     acpi_size * bytes_consumed,
-		     u8 ** output_buffer, acpi_size * structure_size)
-{
-	u8 *buffer = byte_stream_buffer;
-	struct acpi_resource *output_struct = (void *)*output_buffer;
-	u8 temp8 = 0;
-	u8 index;
-	u8 i;
-	acpi_size struct_size = ACPI_SIZEOF_RESOURCE(struct acpi_resource_dma);
-
-	ACPI_FUNCTION_TRACE("rs_dma_resource");
-
-	/* The number of bytes consumed are Constant */
+struct acpi_rsconvert_info acpi_rs_convert_end_tag[2] = {
+	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_END_TAG,
+	 ACPI_RS_SIZE_MIN,
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_end_tag)},
 
-	*bytes_consumed = 3;
-	output_struct->id = ACPI_RSTYPE_DMA;
+	/*
+	 * Note: The checksum field is set to zero, meaning that the resource
+	 * data is treated as if the checksum operation succeeded.
+	 * (ACPI Spec 1.0b Section 6.4.2.8)
+	 */
+	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_END_TAG,
+	 sizeof(struct aml_resource_end_tag),
+	 0}
+};
 
-	/* Point to the 8-bits of Byte 1 */
-
-	buffer += 1;
-	temp8 = *buffer;
-
-	/* Decode the DMA channel bits */
-
-	for (i = 0, index = 0; index < 8; index++) {
-		if ((temp8 >> index) & 0x01) {
-			output_struct->data.dma.channels[i] = index;
-			i++;
-		}
-	}
-
-	/* Zero DMA channels is valid */
-
-	output_struct->data.dma.number_of_channels = i;
-	if (i > 0) {
-		/* Calculate the structure size based upon the number of interrupts */
-
-		struct_size += ((acpi_size) i - 1) * 4;
-	}
-
-	/* Point to Byte 2 */
-
-	buffer += 1;
-	temp8 = *buffer;
-
-	/* Check for transfer preference (Bits[1:0]) */
-
-	output_struct->data.dma.transfer = temp8 & 0x03;
-
-	if (0x03 == output_struct->data.dma.transfer) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Invalid DMA.Transfer preference (3)\n"));
-		return_ACPI_STATUS(AE_BAD_DATA);
-	}
+/*******************************************************************************
+ *
+ * acpi_rs_get_start_dpf
+ *
+ ******************************************************************************/
 
-	/* Get bus master preference (Bit[2]) */
+struct acpi_rsconvert_info acpi_rs_get_start_dpf[5] = {
+	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_START_DEPENDENT,
+	 ACPI_RS_SIZE(struct acpi_resource_start_dependent),
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_get_start_dpf)},
 
-	output_struct->data.dma.bus_master = (temp8 >> 2) & 0x01;
+	/* Defaults for Compatibility and Performance priorities */
 
-	/* Get channel speed support (Bits[6:5]) */
+	{ACPI_RSC_SET8, ACPI_RS_OFFSET(data.start_dpf.compatibility_priority),
+	 ACPI_ACCEPTABLE_CONFIGURATION,
+	 2},
 
-	output_struct->data.dma.type = (temp8 >> 5) & 0x03;
+	/* All done if there is no flag byte present in the descriptor */
 
-	/* Set the Length parameter */
+	{ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 1},
 
-	output_struct->length = (u32) struct_size;
+	/* Flag byte is present, get the flags */
 
-	/* Return the final size of the structure */
+	{ACPI_RSC_2BITFLAG,
+	 ACPI_RS_OFFSET(data.start_dpf.compatibility_priority),
+	 AML_OFFSET(start_dpf.flags),
+	 0},
 
-	*structure_size = struct_size;
-	return_ACPI_STATUS(AE_OK);
-}
+	{ACPI_RSC_2BITFLAG,
+	 ACPI_RS_OFFSET(data.start_dpf.performance_robustness),
+	 AML_OFFSET(start_dpf.flags),
+	 2}
+};
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_dma_stream
- *
- * PARAMETERS:  linked_list             - Pointer to the resource linked list
- *              output_buffer           - Pointer to the user's return buffer
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        used in the output_buffer is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the linked list resource structure and fills in the
- *              the appropriate bytes in a byte stream
+ * acpi_rs_set_start_dpf
  *
  ******************************************************************************/
 
-acpi_status
-acpi_rs_dma_stream(struct acpi_resource *linked_list,
-		   u8 ** output_buffer, acpi_size * bytes_consumed)
-{
-	u8 *buffer = *output_buffer;
-	u16 temp16 = 0;
-	u8 temp8 = 0;
-	u8 index;
-
-	ACPI_FUNCTION_TRACE("rs_dma_stream");
-
-	/* The descriptor field is static */
-
-	*buffer = 0x2A;
-	buffer += 1;
-	temp8 = 0;
-
-	/* Loop through all of the Channels and set the mask bits */
-
-	for (index = 0;
-	     index < linked_list->data.dma.number_of_channels; index++) {
-		temp16 = (u16) linked_list->data.dma.channels[index];
-		temp8 |= 0x1 << temp16;
-	}
+struct acpi_rsconvert_info acpi_rs_set_start_dpf[6] = {
+	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_START_DEPENDENT,
+	 sizeof(struct aml_resource_start_dependent),
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_set_start_dpf)},
 
-	*buffer = temp8;
-	buffer += 1;
+	/* Set the default flag values */
 
-	/* Set the DMA Info */
+	{ACPI_RSC_2BITFLAG,
+	 ACPI_RS_OFFSET(data.start_dpf.compatibility_priority),
+	 AML_OFFSET(start_dpf.flags),
+	 0},
 
-	temp8 = (u8) ((linked_list->data.dma.type & 0x03) << 5);
-	temp8 |= ((linked_list->data.dma.bus_master & 0x01) << 2);
-	temp8 |= (linked_list->data.dma.transfer & 0x03);
+	{ACPI_RSC_2BITFLAG,
+	 ACPI_RS_OFFSET(data.start_dpf.performance_robustness),
+	 AML_OFFSET(start_dpf.flags),
+	 2},
+	/*
+	 * All done if flags byte is necessary -- if either priority value
+	 * is not ACPI_ACCEPTABLE_CONFIGURATION
+	 */
+	{ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE,
+	 ACPI_RS_OFFSET(data.start_dpf.compatibility_priority),
+	 ACPI_ACCEPTABLE_CONFIGURATION},
 
-	*buffer = temp8;
-	buffer += 1;
+	{ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE,
+	 ACPI_RS_OFFSET(data.start_dpf.performance_robustness),
+	 ACPI_ACCEPTABLE_CONFIGURATION},
 
-	/* Return the number of bytes consumed in this operation */
+	/* Flag byte is not necessary */
 
-	*bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
-	return_ACPI_STATUS(AE_OK);
-}
+	{ACPI_RSC_LENGTH, 0, 0,
+	 sizeof(struct aml_resource_start_dependent_noprio)}
+};
diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c
index 56043fe..1fa63bc 100644
--- a/drivers/acpi/resources/rsirq.c
+++ b/drivers/acpi/resources/rsirq.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -49,504 +49,182 @@ ACPI_MODULE_NAME("rsirq")
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_irq_resource
- *
- * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
- *                                        stream
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        consumed the byte_stream_buffer is
- *                                        returned
- *              output_buffer           - Pointer to the return data buffer
- *              structure_size          - Pointer to where the number of bytes
- *                                        in the return data struct is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *              structure pointed to by the output_buffer. Return the
- *              number of bytes consumed from the byte stream.
- *
- ******************************************************************************/
-acpi_status
-acpi_rs_irq_resource(u8 * byte_stream_buffer,
-		     acpi_size * bytes_consumed,
-		     u8 ** output_buffer, acpi_size * structure_size)
-{
-	u8 *buffer = byte_stream_buffer;
-	struct acpi_resource *output_struct = (void *)*output_buffer;
-	u16 temp16 = 0;
-	u8 temp8 = 0;
-	u8 index;
-	u8 i;
-	acpi_size struct_size = ACPI_SIZEOF_RESOURCE(struct acpi_resource_irq);
-
-	ACPI_FUNCTION_TRACE("rs_irq_resource");
-
-	/*
-	 * The number of bytes consumed are contained in the descriptor
-	 * (Bits:0-1)
-	 */
-	temp8 = *buffer;
-	*bytes_consumed = (temp8 & 0x03) + 1;
-	output_struct->id = ACPI_RSTYPE_IRQ;
-
-	/* Point to the 16-bits of Bytes 1 and 2 */
-
-	buffer += 1;
-	ACPI_MOVE_16_TO_16(&temp16, buffer);
-
-	output_struct->data.irq.number_of_interrupts = 0;
-
-	/* Decode the IRQ bits */
-
-	for (i = 0, index = 0; index < 16; index++) {
-		if ((temp16 >> index) & 0x01) {
-			output_struct->data.irq.interrupts[i] = index;
-			i++;
-		}
-	}
-
-	/* Zero interrupts is valid */
-
-	output_struct->data.irq.number_of_interrupts = i;
-	if (i > 0) {
-		/* Calculate the structure size based upon the number of interrupts */
-
-		struct_size += ((acpi_size) i - 1) * 4;
-	}
-
-	/* Point to Byte 3 if it is used */
-
-	if (4 == *bytes_consumed) {
-		buffer += 2;
-		temp8 = *buffer;
-
-		/* Check for HE, LL interrupts */
-
-		switch (temp8 & 0x09) {
-		case 0x01:	/* HE */
-			output_struct->data.irq.edge_level =
-			    ACPI_EDGE_SENSITIVE;
-			output_struct->data.irq.active_high_low =
-			    ACPI_ACTIVE_HIGH;
-			break;
-
-		case 0x08:	/* LL */
-			output_struct->data.irq.edge_level =
-			    ACPI_LEVEL_SENSITIVE;
-			output_struct->data.irq.active_high_low =
-			    ACPI_ACTIVE_LOW;
-			break;
-
-		default:
-			/*
-			 * Only _LL and _HE polarity/trigger interrupts
-			 * are allowed (ACPI spec, section "IRQ Format")
-			 * so 0x00 and 0x09 are illegal.
-			 */
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Invalid interrupt polarity/trigger in resource list, %X\n",
-					  temp8));
-			return_ACPI_STATUS(AE_BAD_DATA);
-		}
-
-		/* Check for sharable */
-
-		output_struct->data.irq.shared_exclusive = (temp8 >> 3) & 0x01;
-	} else {
-		/*
-		 * Assume Edge Sensitive, Active High, Non-Sharable
-		 * per ACPI Specification
-		 */
-		output_struct->data.irq.edge_level = ACPI_EDGE_SENSITIVE;
-		output_struct->data.irq.active_high_low = ACPI_ACTIVE_HIGH;
-		output_struct->data.irq.shared_exclusive = ACPI_EXCLUSIVE;
-	}
-
-	/* Set the Length parameter */
-
-	output_struct->length = (u32) struct_size;
-
-	/* Return the final size of the structure */
-
-	*structure_size = struct_size;
-	return_ACPI_STATUS(AE_OK);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_rs_irq_stream
- *
- * PARAMETERS:  linked_list             - Pointer to the resource linked list
- *              output_buffer           - Pointer to the user's return buffer
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        used in the output_buffer is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the linked list resource structure and fills in the
- *              the appropriate bytes in a byte stream
- *
- ******************************************************************************/
-
-acpi_status
-acpi_rs_irq_stream(struct acpi_resource *linked_list,
-		   u8 ** output_buffer, acpi_size * bytes_consumed)
-{
-	u8 *buffer = *output_buffer;
-	u16 temp16 = 0;
-	u8 temp8 = 0;
-	u8 index;
-	u8 IRqinfo_byte_needed;
-
-	ACPI_FUNCTION_TRACE("rs_irq_stream");
-
-	/*
-	 * The descriptor field is set based upon whether a third byte is
-	 * needed to contain the IRQ Information.
-	 */
-	if (ACPI_EDGE_SENSITIVE == linked_list->data.irq.edge_level &&
-	    ACPI_ACTIVE_HIGH == linked_list->data.irq.active_high_low &&
-	    ACPI_EXCLUSIVE == linked_list->data.irq.shared_exclusive) {
-		*buffer = 0x22;
-		IRqinfo_byte_needed = FALSE;
-	} else {
-		*buffer = 0x23;
-		IRqinfo_byte_needed = TRUE;
-	}
-
-	buffer += 1;
-	temp16 = 0;
-
-	/* Loop through all of the interrupts and set the mask bits */
-
-	for (index = 0;
-	     index < linked_list->data.irq.number_of_interrupts; index++) {
-		temp8 = (u8) linked_list->data.irq.interrupts[index];
-		temp16 |= 0x1 << temp8;
-	}
-
-	ACPI_MOVE_16_TO_16(buffer, &temp16);
-	buffer += 2;
-
-	/* Set the IRQ Info byte if needed. */
-
-	if (IRqinfo_byte_needed) {
-		temp8 = 0;
-		temp8 = (u8) ((linked_list->data.irq.shared_exclusive &
-			       0x01) << 4);
-
-		if (ACPI_LEVEL_SENSITIVE == linked_list->data.irq.edge_level &&
-		    ACPI_ACTIVE_LOW == linked_list->data.irq.active_high_low) {
-			temp8 |= 0x08;
-		} else {
-			temp8 |= 0x01;
-		}
-
-		*buffer = temp8;
-		buffer += 1;
-	}
-
-	/* Return the number of bytes consumed in this operation */
-
-	*bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
-	return_ACPI_STATUS(AE_OK);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_rs_extended_irq_resource
- *
- * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
- *                                        stream
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        consumed the byte_stream_buffer is
- *                                        returned
- *              output_buffer           - Pointer to the return data buffer
- *              structure_size          - Pointer to where the number of bytes
- *                                        in the return data struct is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *              structure pointed to by the output_buffer. Return the
- *              number of bytes consumed from the byte stream.
+ * acpi_rs_get_irq
  *
  ******************************************************************************/
+struct acpi_rsconvert_info acpi_rs_get_irq[7] = {
+	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IRQ,
+	 ACPI_RS_SIZE(struct acpi_resource_irq),
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_get_irq)},
 
-acpi_status
-acpi_rs_extended_irq_resource(u8 * byte_stream_buffer,
-			      acpi_size * bytes_consumed,
-			      u8 ** output_buffer, acpi_size * structure_size)
-{
-	u8 *buffer = byte_stream_buffer;
-	struct acpi_resource *output_struct = (void *)*output_buffer;
-	u16 temp16 = 0;
-	u8 temp8 = 0;
-	u8 *temp_ptr;
-	u8 index;
-	acpi_size struct_size =
-	    ACPI_SIZEOF_RESOURCE(struct acpi_resource_ext_irq);
-
-	ACPI_FUNCTION_TRACE("rs_extended_irq_resource");
-
-	/* Get the Descriptor Length field */
-
-	buffer += 1;
-	ACPI_MOVE_16_TO_16(&temp16, buffer);
-
-	/* Validate minimum descriptor length */
-
-	if (temp16 < 6) {
-		return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
-	}
-
-	*bytes_consumed = temp16 + 3;
-	output_struct->id = ACPI_RSTYPE_EXT_IRQ;
+	/* Get the IRQ mask (bytes 1:2) */
 
-	/* Point to the Byte3 */
+	{ACPI_RSC_BITMASK16, ACPI_RS_OFFSET(data.irq.interrupts[0]),
+	 AML_OFFSET(irq.irq_mask),
+	 ACPI_RS_OFFSET(data.irq.interrupt_count)},
 
-	buffer += 2;
-	temp8 = *buffer;
+	/* Set default flags (others are zero) */
 
-	output_struct->data.extended_irq.producer_consumer = temp8 & 0x01;
+	{ACPI_RSC_SET8, ACPI_RS_OFFSET(data.irq.triggering),
+	 ACPI_EDGE_SENSITIVE,
+	 1},
 
-	/*
-	 * Check for Interrupt Mode
-	 *
-	 * The definition of an Extended IRQ changed between ACPI spec v1.0b
-	 * and ACPI spec 2.0 (section 6.4.3.6 in both).
-	 *
-	 * - Edge/Level are defined opposite in the table vs the headers
-	 */
-	output_struct->data.extended_irq.edge_level =
-	    (temp8 & 0x2) ? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
+	/* All done if no flag byte present in descriptor */
 
-	/* Check Interrupt Polarity */
+	{ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 3},
 
-	output_struct->data.extended_irq.active_high_low = (temp8 >> 2) & 0x1;
+	/* Get flags: Triggering[0], Polarity[3], Sharing[4] */
 
-	/* Check for sharable */
+	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering),
+	 AML_OFFSET(irq.flags),
+	 0},
 
-	output_struct->data.extended_irq.shared_exclusive = (temp8 >> 3) & 0x01;
+	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.polarity),
+	 AML_OFFSET(irq.flags),
+	 3},
 
-	/* Point to Byte4 (IRQ Table length) */
+	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable),
+	 AML_OFFSET(irq.flags),
+	 4}
+};
 
-	buffer += 1;
-	temp8 = *buffer;
-
-	/* Must have at least one IRQ */
-
-	if (temp8 < 1) {
-		return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
-	}
-
-	output_struct->data.extended_irq.number_of_interrupts = temp8;
-
-	/*
-	 * Add any additional structure size to properly calculate
-	 * the next pointer at the end of this function
-	 */
-	struct_size += (temp8 - 1) * 4;
+/*******************************************************************************
+ *
+ * acpi_rs_set_irq
+ *
+ ******************************************************************************/
 
-	/* Point to Byte5 (First IRQ Number) */
+struct acpi_rsconvert_info acpi_rs_set_irq[9] = {
+	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IRQ,
+	 sizeof(struct aml_resource_irq),
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_set_irq)},
 
-	buffer += 1;
+	/* Convert interrupt list to 16-bit IRQ bitmask */
 
-	/* Cycle through every IRQ in the table */
+	{ACPI_RSC_BITMASK16, ACPI_RS_OFFSET(data.irq.interrupts[0]),
+	 AML_OFFSET(irq.irq_mask),
+	 ACPI_RS_OFFSET(data.irq.interrupt_count)},
 
-	for (index = 0; index < temp8; index++) {
-		ACPI_MOVE_32_TO_32(&output_struct->data.extended_irq.
-				   interrupts[index], buffer);
+	/* Set the flags byte by default */
 
-		/* Point to the next IRQ */
+	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering),
+	 AML_OFFSET(irq.flags),
+	 0},
 
-		buffer += 4;
-	}
+	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.polarity),
+	 AML_OFFSET(irq.flags),
+	 3},
 
+	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable),
+	 AML_OFFSET(irq.flags),
+	 4},
 	/*
-	 * This will leave us pointing to the Resource Source Index
-	 * If it is present, then save it off and calculate the
-	 * pointer to where the null terminated string goes:
-	 * Each Interrupt takes 32-bits + the 5 bytes of the
-	 * stream that are default.
-	 *
-	 * Note: Some resource descriptors will have an additional null, so
-	 * we add 1 to the length.
+	 * Check if the flags byte is necessary. Not needed if the flags are:
+	 * ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH, ACPI_EXCLUSIVE
 	 */
-	if (*bytes_consumed >
-	    ((acpi_size) output_struct->data.extended_irq.number_of_interrupts *
-	     4) + (5 + 1)) {
-		/* Dereference the Index */
-
-		temp8 = *buffer;
-		output_struct->data.extended_irq.resource_source.index =
-		    (u32) temp8;
-
-		/* Point to the String */
-
-		buffer += 1;
-
-		/* Point the String pointer to the end of this structure. */
-
-		output_struct->data.extended_irq.resource_source.string_ptr =
-		    (char *)((char *)output_struct + struct_size);
-
-		temp_ptr = (u8 *)
-		    output_struct->data.extended_irq.resource_source.string_ptr;
-
-		/* Copy the string into the buffer */
+	{ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE,
+	 ACPI_RS_OFFSET(data.irq.triggering),
+	 ACPI_EDGE_SENSITIVE},
 
-		index = 0;
-		while (*buffer) {
-			*temp_ptr = *buffer;
+	{ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE,
+	 ACPI_RS_OFFSET(data.irq.polarity),
+	 ACPI_ACTIVE_HIGH},
 
-			temp_ptr += 1;
-			buffer += 1;
-			index += 1;
-		}
+	{ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE,
+	 ACPI_RS_OFFSET(data.irq.sharable),
+	 ACPI_EXCLUSIVE},
 
-		/* Add the terminating null */
+	/* irq_no_flags() descriptor can be used */
 
-		*temp_ptr = 0;
-		output_struct->data.extended_irq.resource_source.string_length =
-		    index + 1;
-
-		/*
-		 * In order for the struct_size to fall on a 32-bit boundary,
-		 * calculate the length of the string and expand the
-		 * struct_size to the next 32-bit boundary.
-		 */
-		temp8 = (u8) (index + 1);
-		struct_size += ACPI_ROUND_UP_to_32_bITS(temp8);
-	} else {
-		output_struct->data.extended_irq.resource_source.index = 0;
-		output_struct->data.extended_irq.resource_source.string_length =
-		    0;
-		output_struct->data.extended_irq.resource_source.string_ptr =
-		    NULL;
-	}
-
-	/* Set the Length parameter */
-
-	output_struct->length = (u32) struct_size;
-
-	/* Return the final size of the structure */
-
-	*structure_size = struct_size;
-	return_ACPI_STATUS(AE_OK);
-}
+	{ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)}
+};
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_extended_irq_stream
- *
- * PARAMETERS:  linked_list             - Pointer to the resource linked list
- *              output_buffer           - Pointer to the user's return buffer
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        used in the output_buffer is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the linked list resource structure and fills in the
- *              the appropriate bytes in a byte stream
+ * acpi_rs_convert_ext_irq
  *
  ******************************************************************************/
 
-acpi_status
-acpi_rs_extended_irq_stream(struct acpi_resource *linked_list,
-			    u8 ** output_buffer, acpi_size * bytes_consumed)
-{
-	u8 *buffer = *output_buffer;
-	u16 *length_field;
-	u8 temp8 = 0;
-	u8 index;
+struct acpi_rsconvert_info acpi_rs_convert_ext_irq[9] = {
+	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_IRQ,
+	 ACPI_RS_SIZE(struct acpi_resource_extended_irq),
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_ext_irq)},
 
-	ACPI_FUNCTION_TRACE("rs_extended_irq_stream");
+	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_IRQ,
+	 sizeof(struct aml_resource_extended_irq),
+	 0},
 
-	/* Set the Descriptor Type field */
+	/* Flag bits */
 
-	*buffer = ACPI_RDESC_TYPE_EXTENDED_XRUPT;
-	buffer += 1;
+	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.producer_consumer),
+	 AML_OFFSET(extended_irq.flags),
+	 0},
 
-	/* Save a pointer to the Length field - to be filled in later */
+	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.triggering),
+	 AML_OFFSET(extended_irq.flags),
+	 1},
 
-	length_field = ACPI_CAST_PTR(u16, buffer);
-	buffer += 2;
+	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.polarity),
+	 AML_OFFSET(extended_irq.flags),
+	 2},
 
-	/* Set the Interrupt vector flags */
+	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.sharable),
+	 AML_OFFSET(extended_irq.flags),
+	 3},
 
-	temp8 = (u8) (linked_list->data.extended_irq.producer_consumer & 0x01);
-	temp8 |=
-	    ((linked_list->data.extended_irq.shared_exclusive & 0x01) << 3);
+	/* IRQ Table length (Byte4) */
 
-	/*
-	 * Set the Interrupt Mode
-	 *
-	 * The definition of an Extended IRQ changed between ACPI spec v1.0b
-	 * and ACPI spec 2.0 (section 6.4.3.6 in both).  This code does not
-	 * implement the more restrictive definition of 1.0b
-	 *
-	 * - Edge/Level are defined opposite in the table vs the headers
-	 */
-	if (ACPI_EDGE_SENSITIVE == linked_list->data.extended_irq.edge_level) {
-		temp8 |= 0x2;
-	}
-
-	/* Set the Interrupt Polarity */
-
-	temp8 |= ((linked_list->data.extended_irq.active_high_low & 0x1) << 2);
-
-	*buffer = temp8;
-	buffer += 1;
-
-	/* Set the Interrupt table length */
-
-	temp8 = (u8) linked_list->data.extended_irq.number_of_interrupts;
-
-	*buffer = temp8;
-	buffer += 1;
-
-	for (index = 0;
-	     index < linked_list->data.extended_irq.number_of_interrupts;
-	     index++) {
-		ACPI_MOVE_32_TO_32(buffer,
-				   &linked_list->data.extended_irq.
-				   interrupts[index]);
-		buffer += 4;
-	}
+	{ACPI_RSC_COUNT, ACPI_RS_OFFSET(data.extended_irq.interrupt_count),
+	 AML_OFFSET(extended_irq.interrupt_count),
+	 sizeof(u32)}
+	,
 
-	/* Resource Source Index and Resource Source are optional */
+	/* Copy every IRQ in the table, each is 32 bits */
 
-	if (0 != linked_list->data.extended_irq.resource_source.string_length) {
-		*buffer =
-		    (u8) linked_list->data.extended_irq.resource_source.index;
-		buffer += 1;
+	{ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.extended_irq.interrupts[0]),
+	 AML_OFFSET(extended_irq.interrupts[0]),
+	 0}
+	,
 
-		/* Copy the string */
+	/* Optional resource_source (Index and String) */
 
-		ACPI_STRCPY((char *)buffer,
-			    linked_list->data.extended_irq.resource_source.
-			    string_ptr);
+	{ACPI_RSC_SOURCEX, ACPI_RS_OFFSET(data.extended_irq.resource_source),
+	 ACPI_RS_OFFSET(data.extended_irq.interrupts[0]),
+	 sizeof(struct aml_resource_extended_irq)}
+};
 
-		/*
-		 * Buffer needs to be set to the length of the string + one for the
-		 * terminating null
-		 */
-		buffer +=
-		    (acpi_size) (ACPI_STRLEN
-				 (linked_list->data.extended_irq.
-				  resource_source.string_ptr) + 1);
-	}
-
-	/* Return the number of bytes consumed in this operation */
-
-	*bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
+/*******************************************************************************
+ *
+ * acpi_rs_convert_dma
+ *
+ ******************************************************************************/
 
-	/*
-	 * Set the length field to the number of bytes consumed
-	 * minus the header size (3 bytes)
-	 */
-	*length_field = (u16) (*bytes_consumed - 3);
-	return_ACPI_STATUS(AE_OK);
-}
+struct acpi_rsconvert_info acpi_rs_convert_dma[6] = {
+	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_DMA,
+	 ACPI_RS_SIZE(struct acpi_resource_dma),
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_dma)},
+
+	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_DMA,
+	 sizeof(struct aml_resource_dma),
+	 0},
+
+	/* Flags: transfer preference, bus mastering, channel speed */
+
+	{ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.dma.transfer),
+	 AML_OFFSET(dma.flags),
+	 0},
+
+	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.dma.bus_master),
+	 AML_OFFSET(dma.flags),
+	 2},
+
+	{ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.dma.type),
+	 AML_OFFSET(dma.flags),
+	 5},
+
+	/* DMA channel mask bits */
+
+	{ACPI_RSC_BITMASK, ACPI_RS_OFFSET(data.dma.channels[0]),
+	 AML_OFFSET(dma.dma_channel_mask),
+	 ACPI_RS_OFFSET(data.dma.channel_count)}
+};
diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c
index 103eb31..1434e78 100644
--- a/drivers/acpi/resources/rslist.c
+++ b/drivers/acpi/resources/rslist.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -49,52 +49,12 @@ ACPI_MODULE_NAME("rslist")
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_get_resource_type
+ * FUNCTION:    acpi_rs_convert_aml_to_resources
  *
- * PARAMETERS:  resource_start_byte     - Byte 0 of a resource descriptor
- *
- * RETURN:      The Resource Type with no extraneous bits
- *
- * DESCRIPTION: Extract the Resource Type/Name from the first byte of
- *              a resource descriptor.
- *
- ******************************************************************************/
-u8 acpi_rs_get_resource_type(u8 resource_start_byte)
-{
-
-	ACPI_FUNCTION_ENTRY();
-
-	/* Determine if this is a small or large resource */
-
-	switch (resource_start_byte & ACPI_RDESC_TYPE_MASK) {
-	case ACPI_RDESC_TYPE_SMALL:
-
-		/* Small Resource Type -- Only bits 6:3 are valid */
-
-		return ((u8) (resource_start_byte & ACPI_RDESC_SMALL_MASK));
-
-	case ACPI_RDESC_TYPE_LARGE:
-
-		/* Large Resource Type -- All bits are valid */
-
-		return (resource_start_byte);
-
-	default:
-		/* Invalid type */
-		break;
-	}
-
-	return (0xFF);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_rs_byte_stream_to_list
- *
- * PARAMETERS:  byte_stream_buffer      - Pointer to the resource byte stream
- *              byte_stream_buffer_length - Length of byte_stream_buffer
- *              output_buffer           - Pointer to the buffer that will
- *                                        contain the output structures
+ * PARAMETERS:  Aml                 - Pointer to the resource byte stream
+ *              aml_length          - Length of Aml
+ *              output_buffer       - Pointer to the buffer that will
+ *                                    contain the output structures
  *
  * RETURN:      Status
  *
@@ -102,241 +62,78 @@ u8 acpi_rs_get_resource_type(u8 resource
  *              linked list of resources in the caller's output buffer
  *
  ******************************************************************************/
-
 acpi_status
-acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer,
-			    u32 byte_stream_buffer_length, u8 * output_buffer)
+acpi_rs_convert_aml_to_resources(u8 * aml, u32 aml_length, u8 * output_buffer)
 {
+	struct acpi_resource *resource = (void *)output_buffer;
 	acpi_status status;
-	acpi_size bytes_parsed = 0;
-	u8 resource_type = 0;
-	acpi_size bytes_consumed = 0;
-	u8 *buffer = output_buffer;
-	acpi_size structure_size = 0;
-	u8 end_tag_processed = FALSE;
-	struct acpi_resource *resource;
-
-	ACPI_FUNCTION_TRACE("rs_byte_stream_to_list");
-
-	while (bytes_parsed < byte_stream_buffer_length && !end_tag_processed) {
-		/* The next byte in the stream is the resource type */
-
-		resource_type = acpi_rs_get_resource_type(*byte_stream_buffer);
-
-		switch (resource_type) {
-		case ACPI_RDESC_TYPE_MEMORY_24:
-			/*
-			 * 24-Bit Memory Resource
-			 */
-			status = acpi_rs_memory24_resource(byte_stream_buffer,
-							   &bytes_consumed,
-							   &buffer,
-							   &structure_size);
-			break;
-
-		case ACPI_RDESC_TYPE_LARGE_VENDOR:
-			/*
-			 * Vendor Defined Resource
-			 */
-			status = acpi_rs_vendor_resource(byte_stream_buffer,
-							 &bytes_consumed,
-							 &buffer,
-							 &structure_size);
-			break;
-
-		case ACPI_RDESC_TYPE_MEMORY_32:
-			/*
-			 * 32-Bit Memory Range Resource
-			 */
-			status =
-			    acpi_rs_memory32_range_resource(byte_stream_buffer,
-							    &bytes_consumed,
-							    &buffer,
-							    &structure_size);
-			break;
-
-		case ACPI_RDESC_TYPE_FIXED_MEMORY_32:
-			/*
-			 * 32-Bit Fixed Memory Resource
-			 */
-			status =
-			    acpi_rs_fixed_memory32_resource(byte_stream_buffer,
-							    &bytes_consumed,
-							    &buffer,
-							    &structure_size);
-			break;
-
-		case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE:
-		case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE:
-			/*
-			 * 64-Bit Address Resource
-			 */
-			status = acpi_rs_address64_resource(byte_stream_buffer,
-							    &bytes_consumed,
-							    &buffer,
-							    &structure_size);
-			break;
-
-		case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE:
-			/*
-			 * 32-Bit Address Resource
-			 */
-			status = acpi_rs_address32_resource(byte_stream_buffer,
-							    &bytes_consumed,
-							    &buffer,
-							    &structure_size);
-			break;
-
-		case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE:
-			/*
-			 * 16-Bit Address Resource
-			 */
-			status = acpi_rs_address16_resource(byte_stream_buffer,
-							    &bytes_consumed,
-							    &buffer,
-							    &structure_size);
-			break;
-
-		case ACPI_RDESC_TYPE_EXTENDED_XRUPT:
-			/*
-			 * Extended IRQ
-			 */
-			status =
-			    acpi_rs_extended_irq_resource(byte_stream_buffer,
-							  &bytes_consumed,
-							  &buffer,
-							  &structure_size);
-			break;
-
-		case ACPI_RDESC_TYPE_IRQ_FORMAT:
-			/*
-			 * IRQ Resource
-			 */
-			status = acpi_rs_irq_resource(byte_stream_buffer,
-						      &bytes_consumed, &buffer,
-						      &structure_size);
-			break;
-
-		case ACPI_RDESC_TYPE_DMA_FORMAT:
-			/*
-			 * DMA Resource
-			 */
-			status = acpi_rs_dma_resource(byte_stream_buffer,
-						      &bytes_consumed, &buffer,
-						      &structure_size);
-			break;
-
-		case ACPI_RDESC_TYPE_START_DEPENDENT:
-			/*
-			 * Start Dependent Functions Resource
-			 */
-			status =
-			    acpi_rs_start_depend_fns_resource
-			    (byte_stream_buffer, &bytes_consumed, &buffer,
-			     &structure_size);
-			break;
-
-		case ACPI_RDESC_TYPE_END_DEPENDENT:
-			/*
-			 * End Dependent Functions Resource
-			 */
-			status =
-			    acpi_rs_end_depend_fns_resource(byte_stream_buffer,
-							    &bytes_consumed,
-							    &buffer,
-							    &structure_size);
-			break;
-
-		case ACPI_RDESC_TYPE_IO_PORT:
-			/*
-			 * IO Port Resource
-			 */
-			status = acpi_rs_io_resource(byte_stream_buffer,
-						     &bytes_consumed, &buffer,
-						     &structure_size);
-			break;
-
-		case ACPI_RDESC_TYPE_FIXED_IO_PORT:
-			/*
-			 * Fixed IO Port Resource
-			 */
-			status = acpi_rs_fixed_io_resource(byte_stream_buffer,
-							   &bytes_consumed,
-							   &buffer,
-							   &structure_size);
-			break;
-
-		case ACPI_RDESC_TYPE_SMALL_VENDOR:
-			/*
-			 * Vendor Specific Resource
-			 */
-			status = acpi_rs_vendor_resource(byte_stream_buffer,
-							 &bytes_consumed,
-							 &buffer,
-							 &structure_size);
-			break;
-
-		case ACPI_RDESC_TYPE_END_TAG:
-			/*
-			 * End Tag
-			 */
-			end_tag_processed = TRUE;
-			status = acpi_rs_end_tag_resource(byte_stream_buffer,
-							  &bytes_consumed,
-							  &buffer,
-							  &structure_size);
-			break;
-
-		default:
-			/*
-			 * Invalid/Unknown resource type
-			 */
-			status = AE_AML_INVALID_RESOURCE_TYPE;
-			break;
-		}
+	u8 resource_index;
+	u8 *end_aml;
 
+	ACPI_FUNCTION_TRACE("rs_convert_aml_to_resources");
+
+	end_aml = aml + aml_length;
+
+	/* Loop until end-of-buffer or an end_tag is found */
+
+	while (aml < end_aml) {
+		/* Validate the Resource Type and Resource Length */
+
+		status = acpi_ut_validate_resource(aml, &resource_index);
 		if (ACPI_FAILURE(status)) {
 			return_ACPI_STATUS(status);
 		}
 
-		/* Update the return value and counter */
+		/* Convert the AML byte stream resource to a local resource struct */
 
-		bytes_parsed += bytes_consumed;
+		status =
+		    acpi_rs_convert_aml_to_resource(resource,
+						    ACPI_CAST_PTR(union
+								  aml_resource,
+								  aml),
+						    acpi_gbl_get_resource_dispatch
+						    [resource_index]);
+		if (ACPI_FAILURE(status)) {
+			ACPI_EXCEPTION((AE_INFO, status,
+					"Could not convert AML resource (Type %X)",
+					*aml));
+			return_ACPI_STATUS(status);
+		}
 
-		/* Set the byte stream to point to the next resource */
+		/* Normal exit on completion of an end_tag resource descriptor */
 
-		byte_stream_buffer += bytes_consumed;
+		if (acpi_ut_get_resource_type(aml) ==
+		    ACPI_RESOURCE_NAME_END_TAG) {
+			return_ACPI_STATUS(AE_OK);
+		}
 
-		/* Set the Buffer to the next structure */
+		/* Point to the next input AML resource */
 
-		resource = ACPI_CAST_PTR(struct acpi_resource, buffer);
-		resource->length =
-		    (u32) ACPI_ALIGN_RESOURCE_SIZE(resource->length);
-		buffer += ACPI_ALIGN_RESOURCE_SIZE(structure_size);
-	}
+		aml += acpi_ut_get_descriptor_length(aml);
 
-	/* Check the reason for exiting the while loop */
+		/* Point to the next structure in the output buffer */
 
-	if (!end_tag_processed) {
-		return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
+		resource =
+		    ACPI_ADD_PTR(struct acpi_resource, resource,
+				 resource->length);
 	}
 
-	return_ACPI_STATUS(AE_OK);
+	/* Did not find an end_tag resource descriptor */
+
+	return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_list_to_byte_stream
+ * FUNCTION:    acpi_rs_convert_resources_to_aml
  *
- * PARAMETERS:  linked_list             - Pointer to the resource linked list
- *              byte_steam_size_needed  - Calculated size of the byte stream
- *                                        needed from calling
- *                                        acpi_rs_get_byte_stream_length()
- *                                        The size of the output_buffer is
- *                                        guaranteed to be >=
- *                                        byte_stream_size_needed
- *              output_buffer           - Pointer to the buffer that will
- *                                        contain the byte stream
+ * PARAMETERS:  Resource            - Pointer to the resource linked list
+ *              aml_size_needed     - Calculated size of the byte stream
+ *                                    needed from calling acpi_rs_get_aml_length()
+ *                                    The size of the output_buffer is
+ *                                    guaranteed to be >= aml_size_needed
+ *              output_buffer       - Pointer to the buffer that will
+ *                                    contain the byte stream
  *
  * RETURN:      Status
  *
@@ -346,180 +143,73 @@ acpi_rs_byte_stream_to_list(u8 * byte_st
  ******************************************************************************/
 
 acpi_status
-acpi_rs_list_to_byte_stream(struct acpi_resource *linked_list,
-			    acpi_size byte_stream_size_needed,
-			    u8 * output_buffer)
+acpi_rs_convert_resources_to_aml(struct acpi_resource *resource,
+				 acpi_size aml_size_needed, u8 * output_buffer)
 {
+	u8 *aml = output_buffer;
+	u8 *end_aml = output_buffer + aml_size_needed;
 	acpi_status status;
-	u8 *buffer = output_buffer;
-	acpi_size bytes_consumed = 0;
-	u8 done = FALSE;
-
-	ACPI_FUNCTION_TRACE("rs_list_to_byte_stream");
-
-	while (!done) {
-		switch (linked_list->id) {
-		case ACPI_RSTYPE_IRQ:
-			/*
-			 * IRQ Resource
-			 */
-			status =
-			    acpi_rs_irq_stream(linked_list, &buffer,
-					       &bytes_consumed);
-			break;
-
-		case ACPI_RSTYPE_DMA:
-			/*
-			 * DMA Resource
-			 */
-			status =
-			    acpi_rs_dma_stream(linked_list, &buffer,
-					       &bytes_consumed);
-			break;
-
-		case ACPI_RSTYPE_START_DPF:
-			/*
-			 * Start Dependent Functions Resource
-			 */
-			status = acpi_rs_start_depend_fns_stream(linked_list,
-								 &buffer,
-								 &bytes_consumed);
-			break;
-
-		case ACPI_RSTYPE_END_DPF:
-			/*
-			 * End Dependent Functions Resource
-			 */
-			status = acpi_rs_end_depend_fns_stream(linked_list,
-							       &buffer,
-							       &bytes_consumed);
-			break;
-
-		case ACPI_RSTYPE_IO:
-			/*
-			 * IO Port Resource
-			 */
-			status =
-			    acpi_rs_io_stream(linked_list, &buffer,
-					      &bytes_consumed);
-			break;
-
-		case ACPI_RSTYPE_FIXED_IO:
-			/*
-			 * Fixed IO Port Resource
-			 */
-			status =
-			    acpi_rs_fixed_io_stream(linked_list, &buffer,
-						    &bytes_consumed);
-			break;
-
-		case ACPI_RSTYPE_VENDOR:
-			/*
-			 * Vendor Defined Resource
-			 */
-			status =
-			    acpi_rs_vendor_stream(linked_list, &buffer,
-						  &bytes_consumed);
-			break;
-
-		case ACPI_RSTYPE_END_TAG:
-			/*
-			 * End Tag
-			 */
-			status =
-			    acpi_rs_end_tag_stream(linked_list, &buffer,
-						   &bytes_consumed);
-
-			/* An End Tag indicates the end of the Resource Template */
-
-			done = TRUE;
-			break;
-
-		case ACPI_RSTYPE_MEM24:
-			/*
-			 * 24-Bit Memory Resource
-			 */
-			status =
-			    acpi_rs_memory24_stream(linked_list, &buffer,
-						    &bytes_consumed);
-			break;
-
-		case ACPI_RSTYPE_MEM32:
-			/*
-			 * 32-Bit Memory Range Resource
-			 */
-			status =
-			    acpi_rs_memory32_range_stream(linked_list, &buffer,
-							  &bytes_consumed);
-			break;
-
-		case ACPI_RSTYPE_FIXED_MEM32:
-			/*
-			 * 32-Bit Fixed Memory Resource
-			 */
-			status =
-			    acpi_rs_fixed_memory32_stream(linked_list, &buffer,
-							  &bytes_consumed);
-			break;
-
-		case ACPI_RSTYPE_ADDRESS16:
-			/*
-			 * 16-Bit Address Descriptor Resource
-			 */
-			status = acpi_rs_address16_stream(linked_list, &buffer,
-							  &bytes_consumed);
-			break;
-
-		case ACPI_RSTYPE_ADDRESS32:
-			/*
-			 * 32-Bit Address Descriptor Resource
-			 */
-			status = acpi_rs_address32_stream(linked_list, &buffer,
-							  &bytes_consumed);
-			break;
-
-		case ACPI_RSTYPE_ADDRESS64:
-			/*
-			 * 64-Bit Address Descriptor Resource
-			 */
-			status = acpi_rs_address64_stream(linked_list, &buffer,
-							  &bytes_consumed);
-			break;
-
-		case ACPI_RSTYPE_EXT_IRQ:
-			/*
-			 * Extended IRQ Resource
-			 */
-			status =
-			    acpi_rs_extended_irq_stream(linked_list, &buffer,
-							&bytes_consumed);
-			break;
-
-		default:
-			/*
-			 * If we get here, everything is out of sync,
-			 * so exit with an error
-			 */
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Invalid descriptor type (%X) in resource list\n",
-					  linked_list->id));
-			status = AE_BAD_DATA;
-			break;
+
+	ACPI_FUNCTION_TRACE("rs_convert_resources_to_aml");
+
+	/* Walk the resource descriptor list, convert each descriptor */
+
+	while (aml < end_aml) {
+		/* Validate the (internal) Resource Type */
+
+		if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
+			ACPI_ERROR((AE_INFO,
+				    "Invalid descriptor type (%X) in resource list",
+				    resource->type));
+			return_ACPI_STATUS(AE_BAD_DATA);
 		}
 
+		/* Perform the conversion */
+
+		status = acpi_rs_convert_resource_to_aml(resource,
+							 ACPI_CAST_PTR(union
+								       aml_resource,
+								       aml),
+							 acpi_gbl_set_resource_dispatch
+							 [resource->type]);
 		if (ACPI_FAILURE(status)) {
+			ACPI_EXCEPTION((AE_INFO, status,
+					"Could not convert resource (type %X) to AML",
+					resource->type));
 			return_ACPI_STATUS(status);
 		}
 
-		/* Set the Buffer to point to the open byte */
+		/* Perform final sanity check on the new AML resource descriptor */
 
-		buffer += bytes_consumed;
+		status =
+		    acpi_ut_validate_resource(ACPI_CAST_PTR
+					      (union aml_resource, aml), NULL);
+		if (ACPI_FAILURE(status)) {
+			return_ACPI_STATUS(status);
+		}
+
+		/* Check for end-of-list, normal exit */
 
-		/* Point to the next object */
+		if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) {
+			/* An End Tag indicates the end of the input Resource Template */
 
-		linked_list = ACPI_PTR_ADD(struct acpi_resource,
-					   linked_list, linked_list->length);
+			return_ACPI_STATUS(AE_OK);
+		}
+
+		/*
+		 * Extract the total length of the new descriptor and set the
+		 * Aml to point to the next (output) resource descriptor
+		 */
+		aml += acpi_ut_get_descriptor_length(aml);
+
+		/* Point to the next input resource descriptor */
+
+		resource =
+		    ACPI_ADD_PTR(struct acpi_resource, resource,
+				 resource->length);
 	}
 
-	return_ACPI_STATUS(AE_OK);
+	/* Completed buffer, but did not find an end_tag resource descriptor */
+
+	return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
 }
diff --git a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c
index daba1a1..a513193 100644
--- a/drivers/acpi/resources/rsmemory.c
+++ b/drivers/acpi/resources/rsmemory.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -49,454 +49,187 @@ ACPI_MODULE_NAME("rsmemory")
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_memory24_resource
- *
- * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
- *                                        stream
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        consumed the byte_stream_buffer is
- *                                        returned
- *              output_buffer           - Pointer to the return data buffer
- *              structure_size          - Pointer to where the number of bytes
- *                                        in the return data struct is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *              structure pointed to by the output_buffer. Return the
- *              number of bytes consumed from the byte stream.
+ * acpi_rs_convert_memory24
  *
  ******************************************************************************/
-acpi_status
-acpi_rs_memory24_resource(u8 * byte_stream_buffer,
-			  acpi_size * bytes_consumed,
-			  u8 ** output_buffer, acpi_size * structure_size)
-{
-	u8 *buffer = byte_stream_buffer;
-	struct acpi_resource *output_struct = (void *)*output_buffer;
-	u16 temp16 = 0;
-	u8 temp8 = 0;
-	acpi_size struct_size =
-	    ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem24);
-
-	ACPI_FUNCTION_TRACE("rs_memory24_resource");
-
-	/* Point past the Descriptor to get the number of bytes consumed */
-
-	buffer += 1;
-
-	ACPI_MOVE_16_TO_16(&temp16, buffer);
-	buffer += 2;
-	*bytes_consumed = (acpi_size) temp16 + 3;
-	output_struct->id = ACPI_RSTYPE_MEM24;
-
-	/* Check Byte 3 the Read/Write bit */
-
-	temp8 = *buffer;
-	buffer += 1;
-	output_struct->data.memory24.read_write_attribute = temp8 & 0x01;
-
-	/* Get min_base_address (Bytes 4-5) */
-
-	ACPI_MOVE_16_TO_16(&temp16, buffer);
-	buffer += 2;
-	output_struct->data.memory24.min_base_address = temp16;
-
-	/* Get max_base_address (Bytes 6-7) */
-
-	ACPI_MOVE_16_TO_16(&temp16, buffer);
-	buffer += 2;
-	output_struct->data.memory24.max_base_address = temp16;
-
-	/* Get Alignment (Bytes 8-9) */
+struct acpi_rsconvert_info acpi_rs_convert_memory24[4] = {
+	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_MEMORY24,
+	 ACPI_RS_SIZE(struct acpi_resource_memory24),
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_memory24)},
 
-	ACPI_MOVE_16_TO_16(&temp16, buffer);
-	buffer += 2;
-	output_struct->data.memory24.alignment = temp16;
+	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_MEMORY24,
+	 sizeof(struct aml_resource_memory24),
+	 0},
 
-	/* Get range_length (Bytes 10-11) */
+	/* Read/Write bit */
 
-	ACPI_MOVE_16_TO_16(&temp16, buffer);
-	output_struct->data.memory24.range_length = temp16;
-
-	/* Set the Length parameter */
-
-	output_struct->length = (u32) struct_size;
-
-	/* Return the final size of the structure */
-
-	*structure_size = struct_size;
-	return_ACPI_STATUS(AE_OK);
-}
+	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.memory24.write_protect),
+	 AML_OFFSET(memory24.flags),
+	 0},
+	/*
+	 * These fields are contiguous in both the source and destination:
+	 * Minimum Base Address
+	 * Maximum Base Address
+	 * Address Base Alignment
+	 * Range Length
+	 */
+	{ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.memory24.minimum),
+	 AML_OFFSET(memory24.minimum),
+	 4}
+};
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_memory24_stream
- *
- * PARAMETERS:  linked_list             - Pointer to the resource linked list
- *              output_buffer           - Pointer to the user's return buffer
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        used in the output_buffer is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the linked list resource structure and fills in the
- *              the appropriate bytes in a byte stream
+ * acpi_rs_convert_memory32
  *
  ******************************************************************************/
 
-acpi_status
-acpi_rs_memory24_stream(struct acpi_resource *linked_list,
-			u8 ** output_buffer, acpi_size * bytes_consumed)
-{
-	u8 *buffer = *output_buffer;
-	u16 temp16 = 0;
-	u8 temp8 = 0;
-
-	ACPI_FUNCTION_TRACE("rs_memory24_stream");
-
-	/* The descriptor field is static */
-
-	*buffer = 0x81;
-	buffer += 1;
+struct acpi_rsconvert_info acpi_rs_convert_memory32[4] = {
+	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_MEMORY32,
+	 ACPI_RS_SIZE(struct acpi_resource_memory32),
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_memory32)},
 
-	/* The length field is static */
+	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_MEMORY32,
+	 sizeof(struct aml_resource_memory32),
+	 0},
 
-	temp16 = 0x09;
-	ACPI_MOVE_16_TO_16(buffer, &temp16);
-	buffer += 2;
+	/* Read/Write bit */
 
-	/* Set the Information Byte */
-
-	temp8 = (u8) (linked_list->data.memory24.read_write_attribute & 0x01);
-	*buffer = temp8;
-	buffer += 1;
-
-	/* Set the Range minimum base address */
-
-	ACPI_MOVE_32_TO_16(buffer,
-			   &linked_list->data.memory24.min_base_address);
-	buffer += 2;
-
-	/* Set the Range maximum base address */
-
-	ACPI_MOVE_32_TO_16(buffer,
-			   &linked_list->data.memory24.max_base_address);
-	buffer += 2;
-
-	/* Set the base alignment */
-
-	ACPI_MOVE_32_TO_16(buffer, &linked_list->data.memory24.alignment);
-	buffer += 2;
-
-	/* Set the range length */
-
-	ACPI_MOVE_32_TO_16(buffer, &linked_list->data.memory24.range_length);
-	buffer += 2;
-
-	/* Return the number of bytes consumed in this operation */
-
-	*bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
-	return_ACPI_STATUS(AE_OK);
-}
+	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.memory32.write_protect),
+	 AML_OFFSET(memory32.flags),
+	 0},
+	/*
+	 * These fields are contiguous in both the source and destination:
+	 * Minimum Base Address
+	 * Maximum Base Address
+	 * Address Base Alignment
+	 * Range Length
+	 */
+	{ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.memory32.minimum),
+	 AML_OFFSET(memory32.minimum),
+	 4}
+};
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_memory32_range_resource
- *
- * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
- *                                        stream
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        consumed the byte_stream_buffer is
- *                                        returned
- *              output_buffer           - Pointer to the return data buffer
- *              structure_size          - Pointer to where the number of bytes
- *                                        in the return data struct is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *              structure pointed to by the output_buffer. Return the
- *              number of bytes consumed from the byte stream.
+ * acpi_rs_convert_fixed_memory32
  *
  ******************************************************************************/
 
-acpi_status
-acpi_rs_memory32_range_resource(u8 * byte_stream_buffer,
-				acpi_size * bytes_consumed,
-				u8 ** output_buffer, acpi_size * structure_size)
-{
-	u8 *buffer = byte_stream_buffer;
-	struct acpi_resource *output_struct = (void *)*output_buffer;
-	u16 temp16 = 0;
-	u8 temp8 = 0;
-	acpi_size struct_size =
-	    ACPI_SIZEOF_RESOURCE(struct acpi_resource_mem32);
-
-	ACPI_FUNCTION_TRACE("rs_memory32_range_resource");
-
-	/* Point past the Descriptor to get the number of bytes consumed */
-
-	buffer += 1;
-
-	ACPI_MOVE_16_TO_16(&temp16, buffer);
-	buffer += 2;
-	*bytes_consumed = (acpi_size) temp16 + 3;
+struct acpi_rsconvert_info acpi_rs_convert_fixed_memory32[4] = {
+	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_FIXED_MEMORY32,
+	 ACPI_RS_SIZE(struct acpi_resource_fixed_memory32),
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_fixed_memory32)},
+
+	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_FIXED_MEMORY32,
+	 sizeof(struct aml_resource_fixed_memory32),
+	 0},
 
-	output_struct->id = ACPI_RSTYPE_MEM32;
+	/* Read/Write bit */
 
+	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.fixed_memory32.write_protect),
+	 AML_OFFSET(fixed_memory32.flags),
+	 0},
 	/*
-	 *  Point to the place in the output buffer where the data portion will
-	 *  begin.
-	 *  1. Set the RESOURCE_DATA * Data to point to its own address, then
-	 *  2. Set the pointer to the next address.
-	 *
-	 *  NOTE: output_struct->Data is cast to u8, otherwise, this addition adds
-	 *  4 * sizeof(RESOURCE_DATA) instead of 4 * sizeof(u8)
+	 * These fields are contiguous in both the source and destination:
+	 * Base Address
+	 * Range Length
 	 */
-
-	/* Check Byte 3 the Read/Write bit */
-
-	temp8 = *buffer;
-	buffer += 1;
-
-	output_struct->data.memory32.read_write_attribute = temp8 & 0x01;
-
-	/* Get min_base_address (Bytes 4-7) */
-
-	ACPI_MOVE_32_TO_32(&output_struct->data.memory32.min_base_address,
-			   buffer);
-	buffer += 4;
-
-	/* Get max_base_address (Bytes 8-11) */
-
-	ACPI_MOVE_32_TO_32(&output_struct->data.memory32.max_base_address,
-			   buffer);
-	buffer += 4;
-
-	/* Get Alignment (Bytes 12-15) */
-
-	ACPI_MOVE_32_TO_32(&output_struct->data.memory32.alignment, buffer);
-	buffer += 4;
-
-	/* Get range_length (Bytes 16-19) */
-
-	ACPI_MOVE_32_TO_32(&output_struct->data.memory32.range_length, buffer);
-
-	/* Set the Length parameter */
-
-	output_struct->length = (u32) struct_size;
-
-	/* Return the final size of the structure */
-
-	*structure_size = struct_size;
-	return_ACPI_STATUS(AE_OK);
-}
+	{ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.fixed_memory32.address),
+	 AML_OFFSET(fixed_memory32.address),
+	 2}
+};
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_fixed_memory32_resource
- *
- * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
- *                                        stream
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        consumed the byte_stream_buffer is
- *                                        returned
- *              output_buffer           - Pointer to the return data buffer
- *              structure_size          - Pointer to where the number of bytes
- *                                        in the return data struct is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *              structure pointed to by the output_buffer. Return the
- *              number of bytes consumed from the byte stream.
+ * acpi_rs_get_vendor_small
  *
  ******************************************************************************/
 
-acpi_status
-acpi_rs_fixed_memory32_resource(u8 * byte_stream_buffer,
-				acpi_size * bytes_consumed,
-				u8 ** output_buffer, acpi_size * structure_size)
-{
-	u8 *buffer = byte_stream_buffer;
-	struct acpi_resource *output_struct = (void *)*output_buffer;
-	u16 temp16 = 0;
-	u8 temp8 = 0;
-	acpi_size struct_size =
-	    ACPI_SIZEOF_RESOURCE(struct acpi_resource_fixed_mem32);
-
-	ACPI_FUNCTION_TRACE("rs_fixed_memory32_resource");
-
-	/* Point past the Descriptor to get the number of bytes consumed */
-
-	buffer += 1;
-	ACPI_MOVE_16_TO_16(&temp16, buffer);
-
-	buffer += 2;
-	*bytes_consumed = (acpi_size) temp16 + 3;
-
-	output_struct->id = ACPI_RSTYPE_FIXED_MEM32;
+struct acpi_rsconvert_info acpi_rs_get_vendor_small[3] = {
+	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_VENDOR,
+	 ACPI_RS_SIZE(struct acpi_resource_vendor),
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_get_vendor_small)},
 
-	/* Check Byte 3 the Read/Write bit */
+	/* Length of the vendor data (byte count) */
 
-	temp8 = *buffer;
-	buffer += 1;
-	output_struct->data.fixed_memory32.read_write_attribute = temp8 & 0x01;
+	{ACPI_RSC_COUNT16, ACPI_RS_OFFSET(data.vendor.byte_length),
+	 0,
+	 sizeof(u8)}
+	,
 
-	/* Get range_base_address (Bytes 4-7) */
+	/* Vendor data */
 
-	ACPI_MOVE_32_TO_32(&output_struct->data.fixed_memory32.
-			   range_base_address, buffer);
-	buffer += 4;
-
-	/* Get range_length (Bytes 8-11) */
-
-	ACPI_MOVE_32_TO_32(&output_struct->data.fixed_memory32.range_length,
-			   buffer);
-
-	/* Set the Length parameter */
-
-	output_struct->length = (u32) struct_size;
-
-	/* Return the final size of the structure */
-
-	*structure_size = struct_size;
-	return_ACPI_STATUS(AE_OK);
-}
+	{ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.vendor.byte_data[0]),
+	 sizeof(struct aml_resource_small_header),
+	 0}
+};
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_memory32_range_stream
- *
- * PARAMETERS:  linked_list             - Pointer to the resource linked list
- *              output_buffer           - Pointer to the user's return buffer
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        used in the output_buffer is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the linked list resource structure and fills in the
- *              the appropriate bytes in a byte stream
+ * acpi_rs_get_vendor_large
  *
  ******************************************************************************/
 
-acpi_status
-acpi_rs_memory32_range_stream(struct acpi_resource *linked_list,
-			      u8 ** output_buffer, acpi_size * bytes_consumed)
-{
-	u8 *buffer = *output_buffer;
-	u16 temp16 = 0;
-	u8 temp8 = 0;
-
-	ACPI_FUNCTION_TRACE("rs_memory32_range_stream");
-
-	/* The descriptor field is static */
-
-	*buffer = 0x85;
-	buffer += 1;
+struct acpi_rsconvert_info acpi_rs_get_vendor_large[3] = {
+	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_VENDOR,
+	 ACPI_RS_SIZE(struct acpi_resource_vendor),
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_get_vendor_large)},
 
-	/* The length field is static */
+	/* Length of the vendor data (byte count) */
 
-	temp16 = 0x11;
+	{ACPI_RSC_COUNT16, ACPI_RS_OFFSET(data.vendor.byte_length),
+	 0,
+	 sizeof(u8)}
+	,
 
-	ACPI_MOVE_16_TO_16(buffer, &temp16);
-	buffer += 2;
+	/* Vendor data */
 
-	/* Set the Information Byte */
-
-	temp8 = (u8) (linked_list->data.memory32.read_write_attribute & 0x01);
-	*buffer = temp8;
-	buffer += 1;
-
-	/* Set the Range minimum base address */
-
-	ACPI_MOVE_32_TO_32(buffer,
-			   &linked_list->data.memory32.min_base_address);
-	buffer += 4;
-
-	/* Set the Range maximum base address */
-
-	ACPI_MOVE_32_TO_32(buffer,
-			   &linked_list->data.memory32.max_base_address);
-	buffer += 4;
-
-	/* Set the base alignment */
-
-	ACPI_MOVE_32_TO_32(buffer, &linked_list->data.memory32.alignment);
-	buffer += 4;
-
-	/* Set the range length */
-
-	ACPI_MOVE_32_TO_32(buffer, &linked_list->data.memory32.range_length);
-	buffer += 4;
-
-	/* Return the number of bytes consumed in this operation */
-
-	*bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
-	return_ACPI_STATUS(AE_OK);
-}
+	{ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.vendor.byte_data[0]),
+	 sizeof(struct aml_resource_large_header),
+	 0}
+};
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_fixed_memory32_stream
- *
- * PARAMETERS:  linked_list             - Pointer to the resource linked list
- *              output_buffer           - Pointer to the user's return buffer
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        used in the output_buffer is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the linked list resource structure and fills in the
- *              the appropriate bytes in a byte stream
+ * acpi_rs_set_vendor
  *
  ******************************************************************************/
 
-acpi_status
-acpi_rs_fixed_memory32_stream(struct acpi_resource *linked_list,
-			      u8 ** output_buffer, acpi_size * bytes_consumed)
-{
-	u8 *buffer = *output_buffer;
-	u16 temp16 = 0;
-	u8 temp8 = 0;
-
-	ACPI_FUNCTION_TRACE("rs_fixed_memory32_stream");
-
-	/* The descriptor field is static */
-
-	*buffer = 0x86;
-	buffer += 1;
-
-	/* The length field is static */
+struct acpi_rsconvert_info acpi_rs_set_vendor[7] = {
+	/* Default is a small vendor descriptor */
 
-	temp16 = 0x09;
+	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_VENDOR_SMALL,
+	 sizeof(struct aml_resource_small_header),
+	 ACPI_RSC_TABLE_SIZE(acpi_rs_set_vendor)},
 
-	ACPI_MOVE_16_TO_16(buffer, &temp16);
-	buffer += 2;
+	/* Get the length and copy the data */
 
-	/* Set the Information Byte */
+	{ACPI_RSC_COUNT16, ACPI_RS_OFFSET(data.vendor.byte_length),
+	 0,
+	 0},
 
-	temp8 =
-	    (u8) (linked_list->data.fixed_memory32.read_write_attribute & 0x01);
-	*buffer = temp8;
-	buffer += 1;
+	{ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.vendor.byte_data[0]),
+	 sizeof(struct aml_resource_small_header),
+	 0},
 
-	/* Set the Range base address */
-
-	ACPI_MOVE_32_TO_32(buffer,
-			   &linked_list->data.fixed_memory32.
-			   range_base_address);
-	buffer += 4;
-
-	/* Set the range length */
-
-	ACPI_MOVE_32_TO_32(buffer,
-			   &linked_list->data.fixed_memory32.range_length);
-	buffer += 4;
+	/*
+	 * All done if the Vendor byte length is 7 or less, meaning that it will
+	 * fit within a small descriptor
+	 */
+	{ACPI_RSC_EXIT_LE, 0, 0, 7},
 
-	/* Return the number of bytes consumed in this operation */
+	/* Must create a large vendor descriptor */
 
-	*bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
-	return_ACPI_STATUS(AE_OK);
-}
+	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_VENDOR_LARGE,
+	 sizeof(struct aml_resource_large_header),
+	 0},
+
+	{ACPI_RSC_COUNT16, ACPI_RS_OFFSET(data.vendor.byte_length),
+	 0,
+	 0},
+
+	{ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.vendor.byte_data[0]),
+	 sizeof(struct aml_resource_large_header),
+	 0}
+};
diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c
index 7a8a34e..ed866cf 100644
--- a/drivers/acpi/resources/rsmisc.c
+++ b/drivers/acpi/resources/rsmisc.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -47,481 +47,501 @@
 #define _COMPONENT          ACPI_RESOURCES
 ACPI_MODULE_NAME("rsmisc")
 
+#define INIT_RESOURCE_TYPE(i)       i->resource_offset
+#define INIT_RESOURCE_LENGTH(i)     i->aml_offset
+#define INIT_TABLE_LENGTH(i)        i->value
+#define COMPARE_OPCODE(i)           i->resource_offset
+#define COMPARE_TARGET(i)           i->aml_offset
+#define COMPARE_VALUE(i)            i->value
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_end_tag_resource
+ * FUNCTION:    acpi_rs_convert_aml_to_resource
  *
- * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
- *                                        stream
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        consumed the byte_stream_buffer is
- *                                        returned
- *              output_buffer           - Pointer to the return data buffer
- *              structure_size          - Pointer to where the number of bytes
- *                                        in the return data struct is returned
+ * PARAMETERS:  Resource            - Pointer to the resource descriptor
+ *              Aml                 - Where the AML descriptor is returned
+ *              Info                - Pointer to appropriate conversion table
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *              structure pointed to by the output_buffer. Return the
- *              number of bytes consumed from the byte stream.
+ * DESCRIPTION: Convert an external AML resource descriptor to the corresponding
+ *              internal resource descriptor
  *
  ******************************************************************************/
 acpi_status
-acpi_rs_end_tag_resource(u8 * byte_stream_buffer,
-			 acpi_size * bytes_consumed,
-			 u8 ** output_buffer, acpi_size * structure_size)
+acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
+				union aml_resource *aml,
+				struct acpi_rsconvert_info *info)
 {
-	struct acpi_resource *output_struct = (void *)*output_buffer;
-	acpi_size struct_size = ACPI_RESOURCE_LENGTH;
-
-	ACPI_FUNCTION_TRACE("rs_end_tag_resource");
-
-	/* The number of bytes consumed is static */
-
-	*bytes_consumed = 2;
-
-	/*  Fill out the structure */
-
-	output_struct->id = ACPI_RSTYPE_END_TAG;
-
-	/* Set the Length parameter */
-
-	output_struct->length = 0;
-
-	/* Return the final size of the structure */
-
-	*structure_size = struct_size;
-	return_ACPI_STATUS(AE_OK);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_rs_end_tag_stream
- *
- * PARAMETERS:  linked_list             - Pointer to the resource linked list
- *              output_buffer           - Pointer to the user's return buffer
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        used in the output_buffer is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the linked list resource structure and fills in the
- *              the appropriate bytes in a byte stream
- *
- ******************************************************************************/
-
-acpi_status
-acpi_rs_end_tag_stream(struct acpi_resource *linked_list,
-		       u8 ** output_buffer, acpi_size * bytes_consumed)
-{
-	u8 *buffer = *output_buffer;
-	u8 temp8 = 0;
-
-	ACPI_FUNCTION_TRACE("rs_end_tag_stream");
-
-	/* The descriptor field is static */
-
-	*buffer = 0x79;
-	buffer += 1;
-
-	/*
-	 * Set the Checksum - zero means that the resource data is treated as if
-	 * the checksum operation succeeded (ACPI Spec 1.0b Section 6.4.2.8)
-	 */
-	temp8 = 0;
-
-	*buffer = temp8;
-	buffer += 1;
-
-	/* Return the number of bytes consumed in this operation */
-
-	*bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
-	return_ACPI_STATUS(AE_OK);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_rs_vendor_resource
- *
- * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
- *                                        stream
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        consumed the byte_stream_buffer is
- *                                        returned
- *              output_buffer           - Pointer to the return data buffer
- *              structure_size          - Pointer to where the number of bytes
- *                                        in the return data struct is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *              structure pointed to by the output_buffer. Return the
- *              number of bytes consumed from the byte stream.
- *
- ******************************************************************************/
-
-acpi_status
-acpi_rs_vendor_resource(u8 * byte_stream_buffer,
-			acpi_size * bytes_consumed,
-			u8 ** output_buffer, acpi_size * structure_size)
-{
-	u8 *buffer = byte_stream_buffer;
-	struct acpi_resource *output_struct = (void *)*output_buffer;
+	acpi_rs_length aml_resource_length;
+	void *source;
+	void *destination;
+	char *target;
+	u8 count;
+	u8 flags_mode = FALSE;
+	u16 item_count = 0;
 	u16 temp16 = 0;
-	u8 temp8 = 0;
-	u8 index;
-	acpi_size struct_size =
-	    ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor);
-
-	ACPI_FUNCTION_TRACE("rs_vendor_resource");
-
-	/* Dereference the Descriptor to find if this is a large or small item. */
-
-	temp8 = *buffer;
-
-	if (temp8 & 0x80) {
-		/* Large Item, point to the length field */
-
-		buffer += 1;
-
-		/* Dereference */
-
-		ACPI_MOVE_16_TO_16(&temp16, buffer);
-
-		/* Calculate bytes consumed */
-
-		*bytes_consumed = (acpi_size) temp16 + 3;
-
-		/* Point to the first vendor byte */
-
-		buffer += 2;
-	} else {
-		/* Small Item, dereference the size */
-
-		temp16 = (u8) (*buffer & 0x07);
-
-		/* Calculate bytes consumed */
 
-		*bytes_consumed = (acpi_size) temp16 + 1;
+	ACPI_FUNCTION_TRACE("rs_get_resource");
 
-		/* Point to the first vendor byte */
+	if (((acpi_native_uint) resource) & 0x3) {
+		/* Each internal resource struct is expected to be 32-bit aligned */
 
-		buffer += 1;
+		ACPI_WARNING((AE_INFO,
+			      "Misaligned resource pointer (get): %p Type %2.2X Len %X",
+			      resource, resource->type, resource->length));
 	}
 
-	output_struct->id = ACPI_RSTYPE_VENDOR;
-	output_struct->data.vendor_specific.length = temp16;
+	/* Extract the resource Length field (does not include header length) */
 
-	for (index = 0; index < temp16; index++) {
-		output_struct->data.vendor_specific.reserved[index] = *buffer;
-		buffer += 1;
-	}
+	aml_resource_length = acpi_ut_get_resource_length(aml);
 
 	/*
-	 * In order for the struct_size to fall on a 32-bit boundary,
-	 * calculate the length of the vendor string and expand the
-	 * struct_size to the next 32-bit boundary.
+	 * First table entry must be ACPI_RSC_INITxxx and must contain the
+	 * table length (# of table entries)
 	 */
-	struct_size += ACPI_ROUND_UP_to_32_bITS(temp16);
-
-	/* Set the Length parameter */
-
-	output_struct->length = (u32) struct_size;
-
-	/* Return the final size of the structure */
-
-	*structure_size = struct_size;
-	return_ACPI_STATUS(AE_OK);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_rs_vendor_stream
- *
- * PARAMETERS:  linked_list             - Pointer to the resource linked list
- *              output_buffer           - Pointer to the user's return buffer
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        used in the output_buffer is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the linked list resource structure and fills in the
- *              the appropriate bytes in a byte stream
- *
- ******************************************************************************/
-
-acpi_status
-acpi_rs_vendor_stream(struct acpi_resource *linked_list,
-		      u8 ** output_buffer, acpi_size * bytes_consumed)
-{
-	u8 *buffer = *output_buffer;
-	u16 temp16 = 0;
-	u8 temp8 = 0;
-	u8 index;
-
-	ACPI_FUNCTION_TRACE("rs_vendor_stream");
-
-	/* Dereference the length to find if this is a large or small item. */
-
-	if (linked_list->data.vendor_specific.length > 7) {
-		/* Large Item, Set the descriptor field and length bytes */
-
-		*buffer = 0x84;
-		buffer += 1;
+	count = INIT_TABLE_LENGTH(info);
 
-		temp16 = (u16) linked_list->data.vendor_specific.length;
+	while (count) {
+		/*
+		 * Source is the external AML byte stream buffer,
+		 * destination is the internal resource descriptor
+		 */
+		source = ACPI_ADD_PTR(void, aml, info->aml_offset);
+		destination =
+		    ACPI_ADD_PTR(void, resource, info->resource_offset);
+
+		switch (info->opcode) {
+		case ACPI_RSC_INITGET:
+			/*
+			 * Get the resource type and the initial (minimum) length
+			 */
+			ACPI_MEMSET(resource, 0, INIT_RESOURCE_LENGTH(info));
+			resource->type = INIT_RESOURCE_TYPE(info);
+			resource->length = INIT_RESOURCE_LENGTH(info);
+			break;
+
+		case ACPI_RSC_INITSET:
+			break;
+
+		case ACPI_RSC_FLAGINIT:
+
+			flags_mode = TRUE;
+			break;
+
+		case ACPI_RSC_1BITFLAG:
+			/*
+			 * Mask and shift the flag bit
+			 */
+			ACPI_SET8(destination) = (u8)
+			    ((ACPI_GET8(source) >> info->value) & 0x01);
+			break;
+
+		case ACPI_RSC_2BITFLAG:
+			/*
+			 * Mask and shift the flag bits
+			 */
+			ACPI_SET8(destination) = (u8)
+			    ((ACPI_GET8(source) >> info->value) & 0x03);
+			break;
+
+		case ACPI_RSC_COUNT:
+
+			item_count = ACPI_GET8(source);
+			ACPI_SET8(destination) = (u8) item_count;
+
+			resource->length = resource->length +
+			    (info->value * (item_count - 1));
+			break;
+
+		case ACPI_RSC_COUNT16:
+
+			item_count = aml_resource_length;
+			ACPI_SET16(destination) = item_count;
+
+			resource->length = resource->length +
+			    (info->value * (item_count - 1));
+			break;
+
+		case ACPI_RSC_LENGTH:
+
+			resource->length = resource->length + info->value;
+			break;
+
+		case ACPI_RSC_MOVE8:
+		case ACPI_RSC_MOVE16:
+		case ACPI_RSC_MOVE32:
+		case ACPI_RSC_MOVE64:
+			/*
+			 * Raw data move. Use the Info value field unless item_count has
+			 * been previously initialized via a COUNT opcode
+			 */
+			if (info->value) {
+				item_count = info->value;
+			}
+			acpi_rs_move_data(destination, source, item_count,
+					  info->opcode);
+			break;
+
+		case ACPI_RSC_SET8:
+
+			ACPI_MEMSET(destination, info->aml_offset, info->value);
+			break;
+
+		case ACPI_RSC_DATA8:
+
+			target = ACPI_ADD_PTR(char, resource, info->value);
+			ACPI_MEMCPY(destination, source, ACPI_GET16(target));
+			break;
+
+		case ACPI_RSC_ADDRESS:
+			/*
+			 * Common handler for address descriptor flags
+			 */
+			if (!acpi_rs_get_address_common(resource, aml)) {
+				return_ACPI_STATUS
+				    (AE_AML_INVALID_RESOURCE_TYPE);
+			}
+			break;
+
+		case ACPI_RSC_SOURCE:
+			/*
+			 * Optional resource_source (Index and String)
+			 */
+			resource->length +=
+			    acpi_rs_get_resource_source(aml_resource_length,
+							info->value,
+							destination, aml, NULL);
+			break;
+
+		case ACPI_RSC_SOURCEX:
+			/*
+			 * Optional resource_source (Index and String). This is the more
+			 * complicated case used by the Interrupt() macro
+			 */
+			target =
+			    ACPI_ADD_PTR(char, resource,
+					 info->aml_offset + (item_count * 4));
+
+			resource->length +=
+			    acpi_rs_get_resource_source(aml_resource_length,
+							(acpi_rs_length) (((item_count - 1) * sizeof(u32)) + info->value), destination, aml, target);
+			break;
+
+		case ACPI_RSC_BITMASK:
+			/*
+			 * 8-bit encoded bitmask (DMA macro)
+			 */
+			item_count =
+			    acpi_rs_decode_bitmask(ACPI_GET8(source),
+						   destination);
+			if (item_count) {
+				resource->length += (item_count - 1);
+			}
+
+			target = ACPI_ADD_PTR(char, resource, info->value);
+			ACPI_SET8(target) = (u8) item_count;
+			break;
+
+		case ACPI_RSC_BITMASK16:
+			/*
+			 * 16-bit encoded bitmask (IRQ macro)
+			 */
+			ACPI_MOVE_16_TO_16(&temp16, source);
+
+			item_count =
+			    acpi_rs_decode_bitmask(temp16, destination);
+			if (item_count) {
+				resource->length += (item_count - 1);
+			}
+
+			target = ACPI_ADD_PTR(char, resource, info->value);
+			ACPI_SET8(target) = (u8) item_count;
+			break;
+
+		case ACPI_RSC_EXIT_NE:
+			/*
+			 * Control - Exit conversion if not equal
+			 */
+			switch (info->resource_offset) {
+			case ACPI_RSC_COMPARE_AML_LENGTH:
+				if (aml_resource_length != info->value) {
+					goto exit;
+				}
+				break;
+
+			case ACPI_RSC_COMPARE_VALUE:
+				if (ACPI_GET8(source) != info->value) {
+					goto exit;
+				}
+				break;
+
+			default:
+
+				ACPI_ERROR((AE_INFO,
+					    "Invalid conversion sub-opcode"));
+				return_ACPI_STATUS(AE_BAD_PARAMETER);
+			}
+			break;
 
-		ACPI_MOVE_16_TO_16(buffer, &temp16);
-		buffer += 2;
-	} else {
-		/* Small Item, Set the descriptor field */
+		default:
 
-		temp8 = 0x70;
-		temp8 |= (u8) linked_list->data.vendor_specific.length;
+			ACPI_ERROR((AE_INFO, "Invalid conversion opcode"));
+			return_ACPI_STATUS(AE_BAD_PARAMETER);
+		}
 
-		*buffer = temp8;
-		buffer += 1;
+		count--;
+		info++;
 	}
 
-	/* Loop through all of the Vendor Specific fields */
-
-	for (index = 0; index < linked_list->data.vendor_specific.length;
-	     index++) {
-		temp8 = linked_list->data.vendor_specific.reserved[index];
+      exit:
+	if (!flags_mode) {
+		/* Round the resource struct length up to the next 32-bit boundary */
 
-		*buffer = temp8;
-		buffer += 1;
+		resource->length = ACPI_ROUND_UP_to_32_bITS(resource->length);
 	}
-
-	/* Return the number of bytes consumed in this operation */
-
-	*bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
 	return_ACPI_STATUS(AE_OK);
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_rs_start_depend_fns_resource
+ * FUNCTION:    acpi_rs_convert_resource_to_aml
  *
- * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
- *                                        stream
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        consumed the byte_stream_buffer is
- *                                        returned
- *              output_buffer           - Pointer to the return data buffer
- *              structure_size          - Pointer to where the number of bytes
- *                                        in the return data struct is returned
+ * PARAMETERS:  Resource            - Pointer to the resource descriptor
+ *              Aml                 - Where the AML descriptor is returned
+ *              Info                - Pointer to appropriate conversion table
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *              structure pointed to by the output_buffer. Return the
- *              number of bytes consumed from the byte stream.
+ * DESCRIPTION: Convert an internal resource descriptor to the corresponding
+ *              external AML resource descriptor.
  *
  ******************************************************************************/
 
 acpi_status
-acpi_rs_start_depend_fns_resource(u8 * byte_stream_buffer,
-				  acpi_size * bytes_consumed,
-				  u8 ** output_buffer,
-				  acpi_size * structure_size)
+acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
+				union aml_resource *aml,
+				struct acpi_rsconvert_info *info)
 {
-	u8 *buffer = byte_stream_buffer;
-	struct acpi_resource *output_struct = (void *)*output_buffer;
-	u8 temp8 = 0;
-	acpi_size struct_size =
-	    ACPI_SIZEOF_RESOURCE(struct acpi_resource_start_dpf);
-
-	ACPI_FUNCTION_TRACE("rs_start_depend_fns_resource");
-
-	/* The number of bytes consumed are found in the descriptor (Bits:0-1) */
-
-	temp8 = *buffer;
-
-	*bytes_consumed = (temp8 & 0x01) + 1;
-
-	output_struct->id = ACPI_RSTYPE_START_DPF;
-
-	/* Point to Byte 1 if it is used */
-
-	if (2 == *bytes_consumed) {
-		buffer += 1;
-		temp8 = *buffer;
-
-		/* Check Compatibility priority */
+	void *source = NULL;
+	void *destination;
+	acpi_rsdesc_size aml_length = 0;
+	u8 count;
+	u16 temp16 = 0;
+	u16 item_count = 0;
 
-		output_struct->data.start_dpf.compatibility_priority =
-		    temp8 & 0x03;
+	ACPI_FUNCTION_TRACE("rs_convert_resource_to_aml");
 
-		if (3 == output_struct->data.start_dpf.compatibility_priority) {
-			return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE);
-		}
+	/*
+	 * First table entry must be ACPI_RSC_INITxxx and must contain the
+	 * table length (# of table entries)
+	 */
+	count = INIT_TABLE_LENGTH(info);
 
-		/* Check Performance/Robustness preference */
+	while (count) {
+		/*
+		 * Source is the internal resource descriptor,
+		 * destination is the external AML byte stream buffer
+		 */
+		source = ACPI_ADD_PTR(void, resource, info->resource_offset);
+		destination = ACPI_ADD_PTR(void, aml, info->aml_offset);
+
+		switch (info->opcode) {
+		case ACPI_RSC_INITSET:
+
+			ACPI_MEMSET(aml, 0, INIT_RESOURCE_LENGTH(info));
+			aml_length = INIT_RESOURCE_LENGTH(info);
+			acpi_rs_set_resource_header(INIT_RESOURCE_TYPE(info),
+						    aml_length, aml);
+			break;
+
+		case ACPI_RSC_INITGET:
+			break;
+
+		case ACPI_RSC_FLAGINIT:
+			/*
+			 * Clear the flag byte
+			 */
+			ACPI_SET8(destination) = 0;
+			break;
+
+		case ACPI_RSC_1BITFLAG:
+			/*
+			 * Mask and shift the flag bit
+			 */
+			ACPI_SET8(destination) |= (u8)
+			    ((ACPI_GET8(source) & 0x01) << info->value);
+			break;
+
+		case ACPI_RSC_2BITFLAG:
+			/*
+			 * Mask and shift the flag bits
+			 */
+			ACPI_SET8(destination) |= (u8)
+			    ((ACPI_GET8(source) & 0x03) << info->value);
+			break;
+
+		case ACPI_RSC_COUNT:
+
+			item_count = ACPI_GET8(source);
+			ACPI_SET8(destination) = (u8) item_count;
+
+			aml_length =
+			    (u16) (aml_length +
+				   (info->value * (item_count - 1)));
+			break;
+
+		case ACPI_RSC_COUNT16:
+
+			item_count = ACPI_GET16(source);
+			aml_length = (u16) (aml_length + item_count);
+			acpi_rs_set_resource_length(aml_length, aml);
+			break;
+
+		case ACPI_RSC_LENGTH:
+
+			acpi_rs_set_resource_length(info->value, aml);
+			break;
+
+		case ACPI_RSC_MOVE8:
+		case ACPI_RSC_MOVE16:
+		case ACPI_RSC_MOVE32:
+		case ACPI_RSC_MOVE64:
+
+			if (info->value) {
+				item_count = info->value;
+			}
+			acpi_rs_move_data(destination, source, item_count,
+					  info->opcode);
+			break;
+
+		case ACPI_RSC_ADDRESS:
+
+			/* Set the Resource Type, General Flags, and Type-Specific Flags */
+
+			acpi_rs_set_address_common(aml, resource);
+			break;
+
+		case ACPI_RSC_SOURCEX:
+			/*
+			 * Optional resource_source (Index and String)
+			 */
+			aml_length =
+			    acpi_rs_set_resource_source(aml,
+							(acpi_rs_length)
+							aml_length, source);
+			acpi_rs_set_resource_length(aml_length, aml);
+			break;
+
+		case ACPI_RSC_SOURCE:
+			/*
+			 * Optional resource_source (Index and String). This is the more
+			 * complicated case used by the Interrupt() macro
+			 */
+			aml_length =
+			    acpi_rs_set_resource_source(aml, info->value,
+							source);
+			acpi_rs_set_resource_length(aml_length, aml);
+			break;
+
+		case ACPI_RSC_BITMASK:
+			/*
+			 * 8-bit encoded bitmask (DMA macro)
+			 */
+			ACPI_SET8(destination) = (u8)
+			    acpi_rs_encode_bitmask(source,
+						   *ACPI_ADD_PTR(u8, resource,
+								 info->value));
+			break;
+
+		case ACPI_RSC_BITMASK16:
+			/*
+			 * 16-bit encoded bitmask (IRQ macro)
+			 */
+			temp16 = acpi_rs_encode_bitmask(source,
+							*ACPI_ADD_PTR(u8,
+								      resource,
+								      info->
+								      value));
+			ACPI_MOVE_16_TO_16(destination, &temp16);
+			break;
+
+		case ACPI_RSC_EXIT_LE:
+			/*
+			 * Control - Exit conversion if less than or equal
+			 */
+			if (item_count <= info->value) {
+				goto exit;
+			}
+			break;
+
+		case ACPI_RSC_EXIT_NE:
+			/*
+			 * Control - Exit conversion if not equal
+			 */
+			switch (COMPARE_OPCODE(info)) {
+			case ACPI_RSC_COMPARE_VALUE:
+
+				if (*ACPI_ADD_PTR(u8, resource,
+						  COMPARE_TARGET(info)) !=
+				    COMPARE_VALUE(info)) {
+					goto exit;
+				}
+				break;
+
+			default:
+
+				ACPI_ERROR((AE_INFO,
+					    "Invalid conversion sub-opcode"));
+				return_ACPI_STATUS(AE_BAD_PARAMETER);
+			}
+			break;
 
-		output_struct->data.start_dpf.performance_robustness =
-		    (temp8 >> 2) & 0x03;
+		default:
 
-		if (3 == output_struct->data.start_dpf.performance_robustness) {
-			return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE);
+			ACPI_ERROR((AE_INFO, "Invalid conversion opcode"));
+			return_ACPI_STATUS(AE_BAD_PARAMETER);
 		}
-	} else {
-		output_struct->data.start_dpf.compatibility_priority =
-		    ACPI_ACCEPTABLE_CONFIGURATION;
 
-		output_struct->data.start_dpf.performance_robustness =
-		    ACPI_ACCEPTABLE_CONFIGURATION;
+		count--;
+		info++;
 	}
 
-	/* Set the Length parameter */
-
-	output_struct->length = (u32) struct_size;
-
-	/* Return the final size of the structure */
-
-	*structure_size = struct_size;
+      exit:
 	return_ACPI_STATUS(AE_OK);
 }
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_rs_end_depend_fns_resource
- *
- * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
- *                                        stream
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        consumed the byte_stream_buffer is
- *                                        returned
- *              output_buffer           - Pointer to the return data buffer
- *              structure_size          - Pointer to where the number of bytes
- *                                        in the return data struct is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the resource byte stream and fill out the appropriate
- *              structure pointed to by the output_buffer. Return the
- *              number of bytes consumed from the byte stream.
- *
- ******************************************************************************/
-
-acpi_status
-acpi_rs_end_depend_fns_resource(u8 * byte_stream_buffer,
-				acpi_size * bytes_consumed,
-				u8 ** output_buffer, acpi_size * structure_size)
-{
-	struct acpi_resource *output_struct = (void *)*output_buffer;
-	acpi_size struct_size = ACPI_RESOURCE_LENGTH;
-
-	ACPI_FUNCTION_TRACE("rs_end_depend_fns_resource");
-
-	/* The number of bytes consumed is static */
-
-	*bytes_consumed = 1;
-
-	/*  Fill out the structure */
+#if 0
+/* Previous resource validations */
 
-	output_struct->id = ACPI_RSTYPE_END_DPF;
-
-	/* Set the Length parameter */
-
-	output_struct->length = (u32) struct_size;
-
-	/* Return the final size of the structure */
-
-	*structure_size = struct_size;
-	return_ACPI_STATUS(AE_OK);
+if (aml->ext_address64.revision_iD != AML_RESOURCE_EXTENDED_ADDRESS_REVISION) {
+	return_ACPI_STATUS(AE_SUPPORT);
 }
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_rs_start_depend_fns_stream
- *
- * PARAMETERS:  linked_list             - Pointer to the resource linked list
- *              output_buffer           - Pointer to the user's return buffer
- *              bytes_consumed          - u32 pointer that is filled with
- *                                        the number of bytes of the
- *                                        output_buffer used
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the linked list resource structure and fills in the
- *              the appropriate bytes in a byte stream
- *
- ******************************************************************************/
-
-acpi_status
-acpi_rs_start_depend_fns_stream(struct acpi_resource *linked_list,
-				u8 ** output_buffer, acpi_size * bytes_consumed)
-{
-	u8 *buffer = *output_buffer;
-	u8 temp8 = 0;
-
-	ACPI_FUNCTION_TRACE("rs_start_depend_fns_stream");
+if (resource->data.start_dpf.performance_robustness >= 3) {
+	return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE);
+}
 
+if (((aml->irq.flags & 0x09) == 0x00) || ((aml->irq.flags & 0x09) == 0x09)) {
 	/*
-	 * The descriptor field is set based upon whether a byte is needed
-	 * to contain Priority data.
+	 * Only [active_high, edge_sensitive] or [active_low, level_sensitive]
+	 * polarity/trigger interrupts are allowed (ACPI spec, section
+	 * "IRQ Format"), so 0x00 and 0x09 are illegal.
 	 */
-	if (ACPI_ACCEPTABLE_CONFIGURATION ==
-	    linked_list->data.start_dpf.compatibility_priority &&
-	    ACPI_ACCEPTABLE_CONFIGURATION ==
-	    linked_list->data.start_dpf.performance_robustness) {
-		*buffer = 0x30;
-	} else {
-		*buffer = 0x31;
-		buffer += 1;
-
-		/* Set the Priority Byte Definition */
-
-		temp8 = 0;
-		temp8 =
-		    (u8) ((linked_list->data.start_dpf.
-			   performance_robustness & 0x03) << 2);
-		temp8 |=
-		    (linked_list->data.start_dpf.compatibility_priority & 0x03);
-		*buffer = temp8;
-	}
-
-	buffer += 1;
-
-	/* Return the number of bytes consumed in this operation */
-
-	*bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
-	return_ACPI_STATUS(AE_OK);
+	ACPI_ERROR((AE_INFO,
+		    "Invalid interrupt polarity/trigger in resource list, %X",
+		    aml->irq.flags));
+	return_ACPI_STATUS(AE_BAD_DATA);
 }
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_rs_end_depend_fns_stream
- *
- * PARAMETERS:  linked_list             - Pointer to the resource linked list
- *              output_buffer           - Pointer to the user's return buffer
- *              bytes_consumed          - Pointer to where the number of bytes
- *                                        used in the output_buffer is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Take the linked list resource structure and fills in the
- *              the appropriate bytes in a byte stream
- *
- ******************************************************************************/
-
-acpi_status
-acpi_rs_end_depend_fns_stream(struct acpi_resource *linked_list,
-			      u8 ** output_buffer, acpi_size * bytes_consumed)
-{
-	u8 *buffer = *output_buffer;
-
-	ACPI_FUNCTION_TRACE("rs_end_depend_fns_stream");
+resource->data.extended_irq.interrupt_count = temp8;
+if (temp8 < 1) {
+	/* Must have at least one IRQ */
 
-	/* The descriptor field is static */
-
-	*buffer = 0x38;
-	buffer += 1;
-
-	/* Return the number of bytes consumed in this operation */
+	return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
+}
 
-	*bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
-	return_ACPI_STATUS(AE_OK);
+if (resource->data.dma.transfer == 0x03) {
+	ACPI_ERROR((AE_INFO, "Invalid DMA.Transfer preference (3)"));
+	return_ACPI_STATUS(AE_BAD_DATA);
 }
+#endif
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c
index 4446778..25b5aed 100644
--- a/drivers/acpi/resources/rsutils.c
+++ b/drivers/acpi/resources/rsutils.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -50,6 +50,389 @@ ACPI_MODULE_NAME("rsutils")
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_rs_decode_bitmask
+ *
+ * PARAMETERS:  Mask            - Bitmask to decode
+ *              List            - Where the converted list is returned
+ *
+ * RETURN:      Count of bits set (length of list)
+ *
+ * DESCRIPTION: Convert a bit mask into a list of values
+ *
+ ******************************************************************************/
+u8 acpi_rs_decode_bitmask(u16 mask, u8 * list)
+{
+	acpi_native_uint i;
+	u8 bit_count;
+
+	ACPI_FUNCTION_ENTRY();
+
+	/* Decode the mask bits */
+
+	for (i = 0, bit_count = 0; mask; i++) {
+		if (mask & 0x0001) {
+			list[bit_count] = (u8) i;
+			bit_count++;
+		}
+
+		mask >>= 1;
+	}
+
+	return (bit_count);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_encode_bitmask
+ *
+ * PARAMETERS:  List            - List of values to encode
+ *              Count           - Length of list
+ *
+ * RETURN:      Encoded bitmask
+ *
+ * DESCRIPTION: Convert a list of values to an encoded bitmask
+ *
+ ******************************************************************************/
+
+u16 acpi_rs_encode_bitmask(u8 * list, u8 count)
+{
+	acpi_native_uint i;
+	u16 mask;
+
+	ACPI_FUNCTION_ENTRY();
+
+	/* Encode the list into a single bitmask */
+
+	for (i = 0, mask = 0; i < count; i++) {
+		mask |= (0x0001 << list[i]);
+	}
+
+	return (mask);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_move_data
+ *
+ * PARAMETERS:  Destination         - Pointer to the destination descriptor
+ *              Source              - Pointer to the source descriptor
+ *              item_count          - How many items to move
+ *              move_type           - Byte width
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Move multiple data items from one descriptor to another. Handles
+ *              alignment issues and endian issues if necessary, as configured
+ *              via the ACPI_MOVE_* macros. (This is why a memcpy is not used)
+ *
+ ******************************************************************************/
+
+void
+acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type)
+{
+	acpi_native_uint i;
+
+	ACPI_FUNCTION_ENTRY();
+
+	/* One move per item */
+
+	for (i = 0; i < item_count; i++) {
+		switch (move_type) {
+			/*
+			 * For the 8-bit case, we can perform the move all at once
+			 * since there are no alignment or endian issues
+			 */
+		case ACPI_RSC_MOVE8:
+			ACPI_MEMCPY(destination, source, item_count);
+			return;
+
+			/*
+			 * 16-, 32-, and 64-bit cases must use the move macros that perform
+			 * endian conversion and/or accomodate hardware that cannot perform
+			 * misaligned memory transfers
+			 */
+		case ACPI_RSC_MOVE16:
+			ACPI_MOVE_16_TO_16(&ACPI_CAST_PTR(u16, destination)[i],
+					   &ACPI_CAST_PTR(u16, source)[i]);
+			break;
+
+		case ACPI_RSC_MOVE32:
+			ACPI_MOVE_32_TO_32(&ACPI_CAST_PTR(u32, destination)[i],
+					   &ACPI_CAST_PTR(u32, source)[i]);
+			break;
+
+		case ACPI_RSC_MOVE64:
+			ACPI_MOVE_64_TO_64(&ACPI_CAST_PTR(u64, destination)[i],
+					   &ACPI_CAST_PTR(u64, source)[i]);
+			break;
+
+		default:
+			return;
+		}
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_set_resource_length
+ *
+ * PARAMETERS:  total_length        - Length of the AML descriptor, including
+ *                                    the header and length fields.
+ *              Aml                 - Pointer to the raw AML descriptor
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Set the resource_length field of an AML
+ *              resource descriptor, both Large and Small descriptors are
+ *              supported automatically. Note: Descriptor Type field must
+ *              be valid.
+ *
+ ******************************************************************************/
+
+void
+acpi_rs_set_resource_length(acpi_rsdesc_size total_length,
+			    union aml_resource *aml)
+{
+	acpi_rs_length resource_length;
+
+	ACPI_FUNCTION_ENTRY();
+
+	/* Length is the total descriptor length minus the header length */
+
+	resource_length = (acpi_rs_length)
+	    (total_length - acpi_ut_get_resource_header_length(aml));
+
+	/* Length is stored differently for large and small descriptors */
+
+	if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) {
+		/* Large descriptor -- bytes 1-2 contain the 16-bit length */
+
+		ACPI_MOVE_16_TO_16(&aml->large_header.resource_length,
+				   &resource_length);
+	} else {
+		/* Small descriptor -- bits 2:0 of byte 0 contain the length */
+
+		aml->small_header.descriptor_type = (u8)
+
+		    /* Clear any existing length, preserving descriptor type bits */
+		    ((aml->small_header.
+		      descriptor_type & ~ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK)
+
+		     | resource_length);
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_set_resource_header
+ *
+ * PARAMETERS:  descriptor_type     - Byte to be inserted as the type
+ *              total_length        - Length of the AML descriptor, including
+ *                                    the header and length fields.
+ *              Aml                 - Pointer to the raw AML descriptor
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Set the descriptor_type and resource_length fields of an AML
+ *              resource descriptor, both Large and Small descriptors are
+ *              supported automatically
+ *
+ ******************************************************************************/
+
+void
+acpi_rs_set_resource_header(u8 descriptor_type,
+			    acpi_rsdesc_size total_length,
+			    union aml_resource *aml)
+{
+	ACPI_FUNCTION_ENTRY();
+
+	/* Set the Resource Type */
+
+	aml->small_header.descriptor_type = descriptor_type;
+
+	/* Set the Resource Length */
+
+	acpi_rs_set_resource_length(total_length, aml);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_strcpy
+ *
+ * PARAMETERS:  Destination         - Pointer to the destination string
+ *              Source              - Pointer to the source string
+ *
+ * RETURN:      String length, including NULL terminator
+ *
+ * DESCRIPTION: Local string copy that returns the string length, saving a
+ *              strcpy followed by a strlen.
+ *
+ ******************************************************************************/
+
+static u16 acpi_rs_strcpy(char *destination, char *source)
+{
+	u16 i;
+
+	ACPI_FUNCTION_ENTRY();
+
+	for (i = 0; source[i]; i++) {
+		destination[i] = source[i];
+	}
+
+	destination[i] = 0;
+
+	/* Return string length including the NULL terminator */
+
+	return ((u16) (i + 1));
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_get_resource_source
+ *
+ * PARAMETERS:  resource_length     - Length field of the descriptor
+ *              minimum_length      - Minimum length of the descriptor (minus
+ *                                    any optional fields)
+ *              resource_source     - Where the resource_source is returned
+ *              Aml                 - Pointer to the raw AML descriptor
+ *              string_ptr          - (optional) where to store the actual
+ *                                    resource_source string
+ *
+ * RETURN:      Length of the string plus NULL terminator, rounded up to 32 bit
+ *
+ * DESCRIPTION: Copy the optional resource_source data from a raw AML descriptor
+ *              to an internal resource descriptor
+ *
+ ******************************************************************************/
+
+acpi_rs_length
+acpi_rs_get_resource_source(acpi_rs_length resource_length,
+			    acpi_rs_length minimum_length,
+			    struct acpi_resource_source * resource_source,
+			    union aml_resource * aml, char *string_ptr)
+{
+	acpi_rsdesc_size total_length;
+	u8 *aml_resource_source;
+
+	ACPI_FUNCTION_ENTRY();
+
+	total_length =
+	    resource_length + sizeof(struct aml_resource_large_header);
+	aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length);
+
+	/*
+	 * resource_source is present if the length of the descriptor is longer than
+	 * the minimum length.
+	 *
+	 * Note: Some resource descriptors will have an additional null, so
+	 * we add 1 to the minimum length.
+	 */
+	if (total_length > (acpi_rsdesc_size) (minimum_length + 1)) {
+		/* Get the resource_source_index */
+
+		resource_source->index = aml_resource_source[0];
+
+		resource_source->string_ptr = string_ptr;
+		if (!string_ptr) {
+			/*
+			 * String destination pointer is not specified; Set the String
+			 * pointer to the end of the current resource_source structure.
+			 */
+			resource_source->string_ptr =
+			    ACPI_ADD_PTR(char, resource_source,
+					 sizeof(struct acpi_resource_source));
+		}
+
+		/*
+		 * In order for the struct_size to fall on a 32-bit boundary, calculate
+		 * the length of the string (+1 for the NULL terminator) and expand the
+		 * struct_size to the next 32-bit boundary.
+		 *
+		 * Zero the entire area of the buffer.
+		 */
+		total_length =
+		    ACPI_ROUND_UP_to_32_bITS(ACPI_STRLEN
+					     ((char *)&aml_resource_source[1]) +
+					     1);
+		ACPI_MEMSET(resource_source->string_ptr, 0, total_length);
+
+		/* Copy the resource_source string to the destination */
+
+		resource_source->string_length =
+		    acpi_rs_strcpy(resource_source->string_ptr,
+				   (char *)&aml_resource_source[1]);
+
+		return ((acpi_rs_length) total_length);
+	}
+
+	/* resource_source is not present */
+
+	resource_source->index = 0;
+	resource_source->string_length = 0;
+	resource_source->string_ptr = NULL;
+	return (0);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_set_resource_source
+ *
+ * PARAMETERS:  Aml                 - Pointer to the raw AML descriptor
+ *              minimum_length      - Minimum length of the descriptor (minus
+ *                                    any optional fields)
+ *              resource_source     - Internal resource_source
+
+ *
+ * RETURN:      Total length of the AML descriptor
+ *
+ * DESCRIPTION: Convert an optional resource_source from internal format to a
+ *              raw AML resource descriptor
+ *
+ ******************************************************************************/
+
+acpi_rsdesc_size
+acpi_rs_set_resource_source(union aml_resource * aml,
+			    acpi_rs_length minimum_length,
+			    struct acpi_resource_source * resource_source)
+{
+	u8 *aml_resource_source;
+	acpi_rsdesc_size descriptor_length;
+
+	ACPI_FUNCTION_ENTRY();
+
+	descriptor_length = minimum_length;
+
+	/* Non-zero string length indicates presence of a resource_source */
+
+	if (resource_source->string_length) {
+		/* Point to the end of the AML descriptor */
+
+		aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length);
+
+		/* Copy the resource_source_index */
+
+		aml_resource_source[0] = (u8) resource_source->index;
+
+		/* Copy the resource_source string */
+
+		ACPI_STRCPY((char *)&aml_resource_source[1],
+			    resource_source->string_ptr);
+
+		/*
+		 * Add the length of the string (+ 1 for null terminator) to the
+		 * final descriptor length
+		 */
+		descriptor_length +=
+		    ((acpi_rsdesc_size) resource_source->string_length + 1);
+	}
+
+	/* Return the new total length of the AML descriptor */
+
+	return (descriptor_length);
+}
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_rs_get_prt_method_data
  *
  * PARAMETERS:  Handle          - a handle to the containing object
@@ -65,8 +448,9 @@ ACPI_MODULE_NAME("rsutils")
  *              and the contents of the callers buffer is undefined.
  *
  ******************************************************************************/
+
 acpi_status
-acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer)
+acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer * ret_buffer)
 {
 	union acpi_operand_object *obj_desc;
 	acpi_status status;
@@ -284,7 +668,7 @@ acpi_rs_set_srs_method_data(acpi_handle 
 	 * Convert the linked list into a byte stream
 	 */
 	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
-	status = acpi_rs_create_byte_stream(in_buffer->pointer, &buffer);
+	status = acpi_rs_create_aml_resources(in_buffer->pointer, &buffer);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c
index ee5a5c5..88b6707 100644
--- a/drivers/acpi/resources/rsxface.c
+++ b/drivers/acpi/resources/rsxface.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -57,13 +57,17 @@ ACPI_MODULE_NAME("rsxface")
 	ACPI_COPY_FIELD(out, in, decode);                    \
 	ACPI_COPY_FIELD(out, in, min_address_fixed);         \
 	ACPI_COPY_FIELD(out, in, max_address_fixed);         \
-	ACPI_COPY_FIELD(out, in, attribute);                 \
+	ACPI_COPY_FIELD(out, in, info);                      \
 	ACPI_COPY_FIELD(out, in, granularity);               \
-	ACPI_COPY_FIELD(out, in, min_address_range);         \
-	ACPI_COPY_FIELD(out, in, max_address_range);         \
-	ACPI_COPY_FIELD(out, in, address_translation_offset); \
+	ACPI_COPY_FIELD(out, in, minimum);                   \
+	ACPI_COPY_FIELD(out, in, maximum);                   \
+	ACPI_COPY_FIELD(out, in, translation_offset);        \
 	ACPI_COPY_FIELD(out, in, address_length);            \
 	ACPI_COPY_FIELD(out, in, resource_source);
+/* Local prototypes */
+static acpi_status
+acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context);
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_get_irq_routing_table
@@ -86,6 +90,7 @@ ACPI_MODULE_NAME("rsxface")
  *              the object indicated by the passed device_handle.
  *
  ******************************************************************************/
+
 acpi_status
 acpi_get_irq_routing_table(acpi_handle device_handle,
 			   struct acpi_buffer *ret_buffer)
@@ -222,12 +227,12 @@ EXPORT_SYMBOL(acpi_get_possible_resource
  *
  * FUNCTION:    acpi_walk_resources
  *
- * PARAMETERS:  device_handle   - a handle to the device object for the
+ * PARAMETERS:  device_handle   - Handle to the device object for the
  *                                device we are querying
- *              Path            - method name of the resources we want
+ *              Name            - Method name of the resources we want
  *                                (METHOD_NAME__CRS or METHOD_NAME__PRS)
- *              user_function   - called for each resource
- *              Context         - passed to user_function
+ *              user_function   - Called for each resource
+ *              Context         - Passed to user_function
  *
  * RETURN:      Status
  *
@@ -239,79 +244,74 @@ EXPORT_SYMBOL(acpi_get_possible_resource
 
 acpi_status
 acpi_walk_resources(acpi_handle device_handle,
-		    char *path,
+		    char *name,
 		    ACPI_WALK_RESOURCE_CALLBACK user_function, void *context)
 {
 	acpi_status status;
-	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	struct acpi_buffer buffer;
 	struct acpi_resource *resource;
-	struct acpi_resource *buffer_end;
+	struct acpi_resource *resource_end;
 
 	ACPI_FUNCTION_TRACE("acpi_walk_resources");
 
-	if (!device_handle ||
-	    (ACPI_STRNCMP(path, METHOD_NAME__CRS, sizeof(METHOD_NAME__CRS)) &&
-	     ACPI_STRNCMP(path, METHOD_NAME__PRS, sizeof(METHOD_NAME__PRS)))) {
+	/* Parameter validation */
+
+	if (!device_handle || !user_function || !name ||
+	    (ACPI_STRNCMP(name, METHOD_NAME__CRS, sizeof(METHOD_NAME__CRS)) &&
+	     ACPI_STRNCMP(name, METHOD_NAME__PRS, sizeof(METHOD_NAME__PRS)))) {
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
-	status = acpi_rs_get_method_data(device_handle, path, &buffer);
+	/* Get the _CRS or _PRS resource list */
+
+	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+	status = acpi_rs_get_method_data(device_handle, name, &buffer);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
 
-	/* Setup pointers */
+	/* Buffer now contains the resource list */
 
-	resource = (struct acpi_resource *)buffer.pointer;
-	buffer_end = ACPI_CAST_PTR(struct acpi_resource,
-				   ((u8 *) buffer.pointer + buffer.length));
+	resource = ACPI_CAST_PTR(struct acpi_resource, buffer.pointer);
+	resource_end =
+	    ACPI_ADD_PTR(struct acpi_resource, buffer.pointer, buffer.length);
 
-	/* Walk the resource list */
+	/* Walk the resource list until the end_tag is found (or buffer end) */
 
-	for (;;) {
-		if (!resource || resource->id == ACPI_RSTYPE_END_TAG) {
+	while (resource < resource_end) {
+		/* Sanity check the resource */
+
+		if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
+			status = AE_AML_INVALID_RESOURCE_TYPE;
 			break;
 		}
 
-		status = user_function(resource, context);
-
-		switch (status) {
-		case AE_OK:
-		case AE_CTRL_DEPTH:
+		/* Invoke the user function, abort on any error returned */
 
-			/* Just keep going */
+		status = user_function(resource, context);
+		if (ACPI_FAILURE(status)) {
+			if (status == AE_CTRL_TERMINATE) {
+				/* This is an OK termination by the user function */
 
-			status = AE_OK;
+				status = AE_OK;
+			}
 			break;
+		}
 
-		case AE_CTRL_TERMINATE:
-
-			/* Exit now, with OK stats */
-
-			status = AE_OK;
-			goto cleanup;
-
-		default:
-
-			/* All others are valid exceptions */
+		/* end_tag indicates end-of-list */
 
-			goto cleanup;
+		if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) {
+			break;
 		}
 
 		/* Get the next resource descriptor */
 
-		resource = ACPI_NEXT_RESOURCE(resource);
-
-		/* Check for end-of-buffer */
-
-		if (resource >= buffer_end) {
-			goto cleanup;
-		}
+		resource =
+		    ACPI_ADD_PTR(struct acpi_resource, resource,
+				 resource->length);
 	}
 
-      cleanup:
-
-	acpi_os_free(buffer.pointer);
+	ACPI_MEM_FREE(buffer.pointer);
 	return_ACPI_STATUS(status);
 }
 
@@ -360,8 +360,8 @@ EXPORT_SYMBOL(acpi_set_current_resources
  *
  * FUNCTION:    acpi_resource_to_address64
  *
- * PARAMETERS:  resource                - Pointer to a resource
- *              out                     - Pointer to the users's return
+ * PARAMETERS:  Resource                - Pointer to a resource
+ *              Out                     - Pointer to the users's return
  *                                        buffer (a struct
  *                                        struct acpi_resource_address64)
  *
@@ -381,20 +381,26 @@ acpi_resource_to_address64(struct acpi_r
 	struct acpi_resource_address16 *address16;
 	struct acpi_resource_address32 *address32;
 
-	switch (resource->id) {
-	case ACPI_RSTYPE_ADDRESS16:
+	if (!resource || !out) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	/* Convert 16 or 32 address descriptor to 64 */
+
+	switch (resource->type) {
+	case ACPI_RESOURCE_TYPE_ADDRESS16:
 
 		address16 = (struct acpi_resource_address16 *)&resource->data;
 		ACPI_COPY_ADDRESS(out, address16);
 		break;
 
-	case ACPI_RSTYPE_ADDRESS32:
+	case ACPI_RESOURCE_TYPE_ADDRESS32:
 
 		address32 = (struct acpi_resource_address32 *)&resource->data;
 		ACPI_COPY_ADDRESS(out, address32);
 		break;
 
-	case ACPI_RSTYPE_ADDRESS64:
+	case ACPI_RESOURCE_TYPE_ADDRESS64:
 
 		/* Simple copy for 64 bit source */
 
@@ -410,3 +416,113 @@ acpi_resource_to_address64(struct acpi_r
 }
 
 EXPORT_SYMBOL(acpi_resource_to_address64);
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_get_vendor_resource
+ *
+ * PARAMETERS:  device_handle       - Handle for the parent device object
+ *              Name                - Method name for the parent resource
+ *                                    (METHOD_NAME__CRS or METHOD_NAME__PRS)
+ *              Uuid                - Pointer to the UUID to be matched.
+ *                                    includes both subtype and 16-byte UUID
+ *              ret_buffer          - Where the vendor resource is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Walk a resource template for the specified evice to find a
+ *              vendor-defined resource that matches the supplied UUID and
+ *              UUID subtype. Returns a struct acpi_resource of type Vendor.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_get_vendor_resource(acpi_handle device_handle,
+			 char *name,
+			 struct acpi_vendor_uuid * uuid,
+			 struct acpi_buffer * ret_buffer)
+{
+	struct acpi_vendor_walk_info info;
+	acpi_status status;
+
+	/* Other parameters are validated by acpi_walk_resources */
+
+	if (!uuid || !ret_buffer) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	info.uuid = uuid;
+	info.buffer = ret_buffer;
+	info.status = AE_NOT_EXIST;
+
+	/* Walk the _CRS or _PRS resource list for this device */
+
+	status =
+	    acpi_walk_resources(device_handle, name,
+				acpi_rs_match_vendor_resource, &info);
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	return (info.status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_rs_match_vendor_resource
+ *
+ * PARAMETERS:  ACPI_WALK_RESOURCE_CALLBACK
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context)
+{
+	struct acpi_vendor_walk_info *info = context;
+	struct acpi_resource_vendor_typed *vendor;
+	struct acpi_buffer *buffer;
+	acpi_status status;
+
+	/* Ignore all descriptors except Vendor */
+
+	if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) {
+		return (AE_OK);
+	}
+
+	vendor = &resource->data.vendor_typed;
+
+	/*
+	 * For a valid match, these conditions must hold:
+	 *
+	 * 1) Length of descriptor data must be at least as long as a UUID struct
+	 * 2) The UUID subtypes must match
+	 * 3) The UUID data must match
+	 */
+	if ((vendor->byte_length < (ACPI_UUID_LENGTH + 1)) ||
+	    (vendor->uuid_subtype != info->uuid->subtype) ||
+	    (ACPI_MEMCMP(vendor->uuid, info->uuid->data, ACPI_UUID_LENGTH))) {
+		return (AE_OK);
+	}
+
+	/* Validate/Allocate/Clear caller buffer */
+
+	buffer = info->buffer;
+	status = acpi_ut_initialize_buffer(buffer, resource->length);
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	/* Found the correct resource, copy and return it */
+
+	ACPI_MEMCPY(buffer->pointer, resource, resource->length);
+	buffer->length = resource->length;
+
+	/* Found the desired descriptor, terminate resource walk */
+
+	info->status = AE_OK;
+	return (AE_CTRL_TERMINATE);
+}
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 3b26a71..9271e52 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -851,7 +851,7 @@ static void acpi_device_set_id(struct ac
 	 * ----
 	 * Fix for the system root bus device -- the only root-level device.
 	 */
-	if ((parent == ACPI_ROOT_OBJECT) && (type == ACPI_BUS_TYPE_DEVICE)) {
+	if (((acpi_handle)parent == ACPI_ROOT_OBJECT) && (type == ACPI_BUS_TYPE_DEVICE)) {
 		hid = ACPI_BUS_HID;
 		strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
 		strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
diff --git a/drivers/acpi/sleep/poweroff.c b/drivers/acpi/sleep/poweroff.c
index af7935a..47fb4b3 100644
--- a/drivers/acpi/sleep/poweroff.c
+++ b/drivers/acpi/sleep/poweroff.c
@@ -33,9 +33,7 @@ int acpi_sleep_prepare(u32 acpi_state)
 	ACPI_FLUSH_CPU_CACHE();
 	acpi_enable_wakeup_device_prep(acpi_state);
 #endif
-	if (acpi_state == ACPI_STATE_S5) {
-		acpi_wakeup_gpe_poweroff_prepare();
-	}
+	acpi_gpe_sleep_prepare(acpi_state);
 	acpi_enter_sleep_state_prep(acpi_state);
 	return 0;
 }
@@ -53,11 +51,16 @@ void acpi_power_off(void)
 
 static int acpi_shutdown(struct sys_device *x)
 {
-	if (system_state == SYSTEM_POWER_OFF) {
-		/* Prepare if we are going to power off the system */
+	switch (system_state) {
+	case SYSTEM_POWER_OFF:
+		/* Prepare to power off the system */
 		return acpi_sleep_prepare(ACPI_STATE_S5);
+	case SYSTEM_SUSPEND_DISK:
+		/* Prepare to suspend the system to disk */
+		return acpi_sleep_prepare(ACPI_STATE_S4);
+	default:
+		return 0;
 	}
-	return 0;
 }
 
 static struct sysdev_class acpi_sysclass = {
diff --git a/drivers/acpi/sleep/sleep.h b/drivers/acpi/sleep/sleep.h
index efd0001..f3e7039 100644
--- a/drivers/acpi/sleep/sleep.h
+++ b/drivers/acpi/sleep/sleep.h
@@ -5,4 +5,4 @@ extern int acpi_suspend (u32 state);
 extern void acpi_enable_wakeup_device_prep(u8 sleep_state);
 extern void acpi_enable_wakeup_device(u8 sleep_state);
 extern void acpi_disable_wakeup_device(u8 sleep_state);
-extern void acpi_wakeup_gpe_poweroff_prepare(void);
+extern void acpi_gpe_sleep_prepare(u32 sleep_state);
diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c
index 4134ed4..85df0ce 100644
--- a/drivers/acpi/sleep/wakeup.c
+++ b/drivers/acpi/sleep/wakeup.c
@@ -192,7 +192,7 @@ late_initcall(acpi_wakeup_device_init);
  * RUNTIME GPEs, we simply mark all GPES that
  * are not enabled for wakeup from S5 as RUNTIME.
  */
-void acpi_wakeup_gpe_poweroff_prepare(void)
+void acpi_gpe_sleep_prepare(u32 sleep_state)
 {
 	struct list_head *node, *next;
 
@@ -201,8 +201,8 @@ void acpi_wakeup_gpe_poweroff_prepare(vo
 						       struct acpi_device,
 						       wakeup_list);
 
-		/* The GPE can wakeup system from S5, don't touch it */
-		if ((u32) dev->wakeup.sleep_state == ACPI_STATE_S5)
+		/* The GPE can wakeup system from this state, don't touch it */
+		if ((u32) dev->wakeup.sleep_state >= sleep_state)
 			continue;
 		/* acpi_set_gpe_type will automatically disable GPE */
 		acpi_set_gpe_type(dev->wakeup.gpe_device,
diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c
index a039393..03b37d2 100644
--- a/drivers/acpi/tables/tbconvrt.c
+++ b/drivers/acpi/tables/tbconvrt.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -501,8 +501,8 @@ acpi_status acpi_tb_convert_table_fadt(v
 	 * at least as long as the version 1.0 FADT
 	 */
 	if (acpi_gbl_FADT->length < sizeof(struct fadt_descriptor_rev1)) {
-		ACPI_REPORT_ERROR(("FADT is invalid, too short: 0x%X\n",
-				   acpi_gbl_FADT->length));
+		ACPI_ERROR((AE_INFO, "FADT is invalid, too short: 0x%X",
+			    acpi_gbl_FADT->length));
 		return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
 	}
 
@@ -517,7 +517,10 @@ acpi_status acpi_tb_convert_table_fadt(v
 		if (acpi_gbl_FADT->length < sizeof(struct fadt_descriptor_rev2)) {
 			/* Length is too short to be a V2.0 table */
 
-			ACPI_REPORT_WARNING(("Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table\n", acpi_gbl_FADT->length, acpi_gbl_FADT->revision));
+			ACPI_WARNING((AE_INFO,
+				      "Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table",
+				      acpi_gbl_FADT->length,
+				      acpi_gbl_FADT->revision));
 
 			acpi_tb_convert_fadt1(local_fadt,
 					      (void *)acpi_gbl_FADT);
@@ -554,7 +557,9 @@ acpi_status acpi_tb_convert_table_fadt(v
 	ACPI_DEBUG_PRINT((ACPI_DB_TABLES,
 			  "Hex dump of common internal FADT, size %d (%X)\n",
 			  acpi_gbl_FADT->length, acpi_gbl_FADT->length));
-	ACPI_DUMP_BUFFER((u8 *) (acpi_gbl_FADT), acpi_gbl_FADT->length);
+
+	ACPI_DUMP_BUFFER(ACPI_CAST_PTR(u8, acpi_gbl_FADT),
+			 acpi_gbl_FADT->length);
 
 	return_ACPI_STATUS(AE_OK);
 }
@@ -580,13 +585,15 @@ acpi_status acpi_tb_build_common_facs(st
 	/* Absolute minimum length is 24, but the ACPI spec says 64 */
 
 	if (acpi_gbl_FACS->length < 24) {
-		ACPI_REPORT_ERROR(("Invalid FACS table length: 0x%X\n",
-				   acpi_gbl_FACS->length));
+		ACPI_ERROR((AE_INFO, "Invalid FACS table length: 0x%X",
+			    acpi_gbl_FACS->length));
 		return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
 	}
 
 	if (acpi_gbl_FACS->length < 64) {
-		ACPI_REPORT_WARNING(("FACS is shorter than the ACPI specification allows: 0x%X, using anyway\n", acpi_gbl_FACS->length));
+		ACPI_WARNING((AE_INFO,
+			      "FACS is shorter than the ACPI specification allows: 0x%X, using anyway",
+			      acpi_gbl_FACS->length));
 	}
 
 	/* Copy fields to the new FACS */
diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c
index 6acd5ae..09b4ee6 100644
--- a/drivers/acpi/tables/tbget.c
+++ b/drivers/acpi/tables/tbget.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -91,9 +91,9 @@ acpi_tb_get_table(struct acpi_pointer *a
 
 	status = acpi_tb_get_table_body(address, &header, table_info);
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("Could not get ACPI table (size %X), %s\n",
-				   header.length,
-				   acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status,
+				"Could not get ACPI table (size %X)",
+				header.length));
 		return_ACPI_STATUS(status);
 	}
 
@@ -148,7 +148,6 @@ acpi_tb_get_table_header(struct acpi_poi
 					    sizeof(struct acpi_table_header),
 					    (void *)&header);
 		if (ACPI_FAILURE(status)) {
-			ACPI_REPORT_ERROR(("Could not map memory at %8.8X%8.8X for length %X\n", ACPI_FORMAT_UINT64(address->pointer.physical), sizeof(struct acpi_table_header)));
 			return_ACPI_STATUS(status);
 		}
 
@@ -161,8 +160,8 @@ acpi_tb_get_table_header(struct acpi_poi
 
 	default:
 
-		ACPI_REPORT_ERROR(("Invalid address flags %X\n",
-				   address->pointer_type));
+		ACPI_ERROR((AE_INFO, "Invalid address flags %X",
+			    address->pointer_type));
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
@@ -253,8 +252,8 @@ acpi_tb_table_override(struct acpi_table
 	if (ACPI_FAILURE(status)) {
 		/* Some severe error from the OSL, but we basically ignore it */
 
-		ACPI_REPORT_ERROR(("Could not override ACPI table, %s\n",
-				   acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status,
+				"Could not override ACPI table"));
 		return_ACPI_STATUS(status);
 	}
 
@@ -273,15 +272,14 @@ acpi_tb_table_override(struct acpi_table
 
 	status = acpi_tb_get_this_table(&address, new_table, table_info);
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("Could not copy override ACPI table, %s\n",
-				   acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status, "Could not copy ACPI table"));
 		return_ACPI_STATUS(status);
 	}
 
 	/* Copy the table info */
 
-	ACPI_REPORT_INFO(("Table [%4.4s] replaced by host OS\n",
-			  table_info->pointer->signature));
+	ACPI_INFO((AE_INFO, "Table [%4.4s] replaced by host OS",
+		   table_info->pointer->signature));
 
 	return_ACPI_STATUS(AE_OK);
 }
@@ -327,7 +325,9 @@ acpi_tb_get_this_table(struct acpi_point
 
 		full_table = ACPI_MEM_ALLOCATE(header->length);
 		if (!full_table) {
-			ACPI_REPORT_ERROR(("Could not allocate table memory for [%4.4s] length %X\n", header->signature, header->length));
+			ACPI_ERROR((AE_INFO,
+				    "Could not allocate table memory for [%4.4s] length %X",
+				    header->signature, header->length));
 			return_ACPI_STATUS(AE_NO_MEMORY);
 		}
 
@@ -351,7 +351,12 @@ acpi_tb_get_this_table(struct acpi_point
 					    (acpi_size) header->length,
 					    (void *)&full_table);
 		if (ACPI_FAILURE(status)) {
-			ACPI_REPORT_ERROR(("Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X\n", header->signature, ACPI_FORMAT_UINT64(address->pointer.physical), header->length));
+			ACPI_ERROR((AE_INFO,
+				    "Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X",
+				    header->signature,
+				    ACPI_FORMAT_UINT64(address->pointer.
+						       physical),
+				    header->length));
 			return (status);
 		}
 
@@ -362,8 +367,8 @@ acpi_tb_get_this_table(struct acpi_point
 
 	default:
 
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid address flags %X\n",
-				  address->pointer_type));
+		ACPI_ERROR((AE_INFO, "Invalid address flags %X",
+			    address->pointer_type));
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
diff --git a/drivers/acpi/tables/tbgetall.c b/drivers/acpi/tables/tbgetall.c
index 8d72343..134e5dc 100644
--- a/drivers/acpi/tables/tbgetall.c
+++ b/drivers/acpi/tables/tbgetall.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -152,7 +152,9 @@ acpi_tb_get_secondary_table(struct acpi_
 	/* Signature must match request */
 
 	if (ACPI_STRNCMP(header.signature, signature, ACPI_NAME_SIZE)) {
-		ACPI_REPORT_ERROR(("Incorrect table signature - wanted [%s] found [%4.4s]\n", signature, header.signature));
+		ACPI_ERROR((AE_INFO,
+			    "Incorrect table signature - wanted [%s] found [%4.4s]",
+			    signature, header.signature));
 		return_ACPI_STATUS(AE_BAD_SIGNATURE);
 	}
 
@@ -231,14 +233,18 @@ acpi_status acpi_tb_get_required_tables(
 		 */
 		status = acpi_tb_get_primary_table(&address, &table_info);
 		if ((status != AE_OK) && (status != AE_TABLE_NOT_SUPPORTED)) {
-			ACPI_REPORT_WARNING(("%s, while getting table at %8.8X%8.8X\n", acpi_format_exception(status), ACPI_FORMAT_UINT64(address.pointer.value)));
+			ACPI_WARNING((AE_INFO,
+				      "%s, while getting table at %8.8X%8.8X",
+				      acpi_format_exception(status),
+				      ACPI_FORMAT_UINT64(address.pointer.
+							 value)));
 		}
 	}
 
 	/* We must have a FADT to continue */
 
 	if (!acpi_gbl_FADT) {
-		ACPI_REPORT_ERROR(("No FADT present in RSDT/XSDT\n"));
+		ACPI_ERROR((AE_INFO, "No FADT present in RSDT/XSDT"));
 		return_ACPI_STATUS(AE_NO_ACPI_TABLES);
 	}
 
@@ -248,7 +254,8 @@ acpi_status acpi_tb_get_required_tables(
 	 */
 	status = acpi_tb_convert_table_fadt();
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("Could not convert FADT to internal common format\n"));
+		ACPI_ERROR((AE_INFO,
+			    "Could not convert FADT to internal common format"));
 		return_ACPI_STATUS(status);
 	}
 
@@ -258,8 +265,8 @@ acpi_status acpi_tb_get_required_tables(
 
 	status = acpi_tb_get_secondary_table(&address, FACS_SIG, &table_info);
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("Could not get/install the FACS, %s\n",
-				   acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status,
+				"Could not get/install the FACS"));
 		return_ACPI_STATUS(status);
 	}
 
@@ -278,7 +285,7 @@ acpi_status acpi_tb_get_required_tables(
 
 	status = acpi_tb_get_secondary_table(&address, DSDT_SIG, &table_info);
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("Could not get/install the DSDT\n"));
+		ACPI_ERROR((AE_INFO, "Could not get/install the DSDT"));
 		return_ACPI_STATUS(status);
 	}
 
@@ -292,7 +299,9 @@ acpi_status acpi_tb_get_required_tables(
 			  "Hex dump of entire DSDT, size %d (0x%X), Integer width = %d\n",
 			  acpi_gbl_DSDT->length, acpi_gbl_DSDT->length,
 			  acpi_gbl_integer_bit_width));
-	ACPI_DUMP_BUFFER((u8 *) acpi_gbl_DSDT, acpi_gbl_DSDT->length);
+
+	ACPI_DUMP_BUFFER(ACPI_CAST_PTR(u8, acpi_gbl_DSDT),
+			 acpi_gbl_DSDT->length);
 
 	/* Always delete the RSDP mapping, we are done with it */
 
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c
index 10db848..7ffd0fd 100644
--- a/drivers/acpi/tables/tbinstal.c
+++ b/drivers/acpi/tables/tbinstal.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -128,8 +128,8 @@ acpi_status acpi_tb_install_table(struct
 
 	status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("Could not acquire table mutex, %s\n",
-				   acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status,
+				"Could not acquire table mutex"));
 		return_ACPI_STATUS(status);
 	}
 
@@ -146,9 +146,9 @@ acpi_status acpi_tb_install_table(struct
 
 	status = acpi_tb_init_table_descriptor(table_info->type, table_info);
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("Could not install table [%4.4s], %s\n",
-				   table_info->pointer->signature,
-				   acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status,
+				"Could not install table [%4.4s]",
+				table_info->pointer->signature));
 	}
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s located at %p\n",
diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c
index ad0252c..4d30822 100644
--- a/drivers/acpi/tables/tbrsdt.c
+++ b/drivers/acpi/tables/tbrsdt.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -176,7 +176,7 @@ acpi_status acpi_tb_validate_rsdt(struct
 {
 	int no_match;
 
-	ACPI_FUNCTION_NAME("tb_validate_rsdt");
+	ACPI_FUNCTION_ENTRY();
 
 	/*
 	 * Search for appropriate signature, RSDT or XSDT
@@ -192,24 +192,24 @@ acpi_status acpi_tb_validate_rsdt(struct
 	if (no_match) {
 		/* Invalid RSDT or XSDT signature */
 
-		ACPI_REPORT_ERROR(("Invalid signature where RSDP indicates RSDT/XSDT should be located\n"));
+		ACPI_ERROR((AE_INFO,
+			    "Invalid signature where RSDP indicates RSDT/XSDT should be located. RSDP:"));
 
 		ACPI_DUMP_BUFFER(acpi_gbl_RSDP, 20);
 
-		ACPI_DEBUG_PRINT_RAW((ACPI_DB_ERROR,
-				      "RSDT/XSDT signature at %X (%p) is invalid\n",
-				      acpi_gbl_RSDP->rsdt_physical_address,
-				      (void *)(acpi_native_uint) acpi_gbl_RSDP->
-				      rsdt_physical_address));
+		ACPI_ERROR((AE_INFO,
+			    "RSDT/XSDT signature at %X (%p) is invalid",
+			    acpi_gbl_RSDP->rsdt_physical_address,
+			    (void *)(acpi_native_uint) acpi_gbl_RSDP->
+			    rsdt_physical_address));
 
 		if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
-			ACPI_REPORT_ERROR(("Looking for RSDT\n"))
+			ACPI_ERROR((AE_INFO, "Looking for RSDT"));
 		} else {
-			ACPI_REPORT_ERROR(("Looking for XSDT\n"))
+			ACPI_ERROR((AE_INFO, "Looking for XSDT"));
 		}
 
 		ACPI_DUMP_BUFFER((char *)table_ptr, 48);
-
 		return (AE_BAD_SIGNATURE);
 	}
 
@@ -243,15 +243,13 @@ acpi_status acpi_tb_get_table_rsdt(void)
 	table_info.type = ACPI_TABLE_XSDT;
 	status = acpi_tb_get_table(&address, &table_info);
 	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Could not get the RSDT/XSDT, %s\n",
-				  acpi_format_exception(status)));
-
+		ACPI_EXCEPTION((AE_INFO, status,
+				"Could not get the RSDT/XSDT"));
 		return_ACPI_STATUS(status);
 	}
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			  "RSDP located at %p, points to RSDT physical=%8.8X%8.8X \n",
+			  "RSDP located at %p, points to RSDT physical=%8.8X%8.8X\n",
 			  acpi_gbl_RSDP,
 			  ACPI_FORMAT_UINT64(address.pointer.value)));
 
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
index 4b2fbb5..bc57159 100644
--- a/drivers/acpi/tables/tbutils.c
+++ b/drivers/acpi/tables/tbutils.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -94,9 +94,8 @@ acpi_status acpi_tb_is_table_installed(s
 		     new_table_desc->pointer->length)
 		    &&
 		    (!ACPI_MEMCMP
-		     ((const char *)table_desc->pointer,
-		      (const char *)new_table_desc->pointer,
-		      (acpi_size) new_table_desc->pointer->length))) {
+		     (table_desc->pointer, new_table_desc->pointer,
+		      new_table_desc->pointer->length))) {
 			/* Match: this table is already installed */
 
 			ACPI_DEBUG_PRINT((ACPI_DB_TABLES,
@@ -145,14 +144,13 @@ acpi_tb_validate_table_header(struct acp
 {
 	acpi_name signature;
 
-	ACPI_FUNCTION_NAME("tb_validate_table_header");
+	ACPI_FUNCTION_ENTRY();
 
 	/* Verify that this is a valid address */
 
 	if (!acpi_os_readable(table_header, sizeof(struct acpi_table_header))) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Cannot read table header at %p\n",
-				  table_header));
+		ACPI_ERROR((AE_INFO,
+			    "Cannot read table header at %p", table_header));
 
 		return (AE_BAD_ADDRESS);
 	}
@@ -161,12 +159,12 @@ acpi_tb_validate_table_header(struct acp
 
 	ACPI_MOVE_32_TO_32(&signature, table_header->signature);
 	if (!acpi_ut_valid_acpi_name(signature)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Table signature at %p [%p] has invalid characters\n",
-				  table_header, &signature));
+		ACPI_ERROR((AE_INFO,
+			    "Table signature at %p [%p] has invalid characters",
+			    table_header, &signature));
 
-		ACPI_REPORT_WARNING(("Invalid table signature found: [%4.4s]\n",
-				     (char *)&signature));
+		ACPI_WARNING((AE_INFO, "Invalid table signature found: [%4.4s]",
+			      ACPI_CAST_PTR(char, &signature)));
 
 		ACPI_DUMP_BUFFER(table_header,
 				 sizeof(struct acpi_table_header));
@@ -176,11 +174,13 @@ acpi_tb_validate_table_header(struct acp
 	/* Validate the table length */
 
 	if (table_header->length < sizeof(struct acpi_table_header)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Invalid length in table header %p name %4.4s\n",
-				  table_header, (char *)&signature));
-
-		ACPI_REPORT_WARNING(("Invalid table header length (0x%X) found\n", (u32) table_header->length));
+		ACPI_ERROR((AE_INFO,
+			    "Invalid length in table header %p name %4.4s",
+			    table_header, (char *)&signature));
+
+		ACPI_WARNING((AE_INFO,
+			      "Invalid table header length (0x%X) found",
+			      (u32) table_header->length));
 
 		ACPI_DUMP_BUFFER(table_header,
 				 sizeof(struct acpi_table_header));
@@ -219,7 +219,10 @@ acpi_tb_verify_table_checksum(struct acp
 	/* Return the appropriate exception */
 
 	if (checksum) {
-		ACPI_REPORT_WARNING(("Invalid checksum in table [%4.4s] (%02X, sum %02X is not zero)\n", table_header->signature, (u32) table_header->checksum, (u32) checksum));
+		ACPI_WARNING((AE_INFO,
+			      "Invalid checksum in table [%4.4s] (%02X, sum %02X is not zero)",
+			      table_header->signature,
+			      (u32) table_header->checksum, (u32) checksum));
 
 		status = AE_BAD_CHECKSUM;
 	}
@@ -241,16 +244,16 @@ acpi_tb_verify_table_checksum(struct acp
 
 u8 acpi_tb_generate_checksum(void *buffer, u32 length)
 {
-	const u8 *limit;
-	const u8 *rover;
+	u8 *end_buffer;
+	u8 *rover;
 	u8 sum = 0;
 
 	if (buffer && length) {
 		/*  Buffer and Length are valid   */
 
-		limit = (u8 *) buffer + length;
+		end_buffer = ACPI_ADD_PTR(u8, buffer, length);
 
-		for (rover = buffer; rover < limit; rover++) {
+		for (rover = buffer; rover < end_buffer; rover++) {
 			sum = (u8) (sum + *rover);
 		}
 	}
@@ -292,8 +295,7 @@ acpi_tb_handle_to_object(u16 table_id,
 		}
 	}
 
-	ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "table_id=%X does not exist\n",
-			  table_id));
+	ACPI_ERROR((AE_INFO, "table_id=%X does not exist", table_id));
 	return (AE_BAD_PARAMETER);
 }
 #endif
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
index 3f96a49..9fe53c9 100644
--- a/drivers/acpi/tables/tbxface.c
+++ b/drivers/acpi/tables/tbxface.c
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -75,8 +75,7 @@ acpi_status acpi_load_tables(void)
 	status = acpi_os_get_root_pointer(ACPI_LOGICAL_ADDRESSING,
 					  &rsdp_address);
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("acpi_load_tables: Could not get RSDP, %s\n",
-				   acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status, "Could not get the RSDP"));
 		goto error_exit;
 	}
 
@@ -86,7 +85,7 @@ acpi_status acpi_load_tables(void)
 
 	status = acpi_tb_verify_rsdp(&rsdp_address);
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("acpi_load_tables: RSDP Failed validation: %s\n", acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status, "During RSDP validation"));
 		goto error_exit;
 	}
 
@@ -94,7 +93,7 @@ acpi_status acpi_load_tables(void)
 
 	status = acpi_tb_get_table_rsdt();
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("acpi_load_tables: Could not load RSDT: %s\n", acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status, "Could not load RSDT"));
 		goto error_exit;
 	}
 
@@ -102,7 +101,8 @@ acpi_status acpi_load_tables(void)
 
 	status = acpi_tb_get_required_tables();
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("acpi_load_tables: Error getting required tables (DSDT/FADT/FACS): %s\n", acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status,
+				"Could not get all required tables (DSDT/FADT/FACS)"));
 		goto error_exit;
 	}
 
@@ -112,16 +112,14 @@ acpi_status acpi_load_tables(void)
 
 	status = acpi_ns_load_namespace();
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("acpi_load_tables: Could not load namespace: %s\n", acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status, "Could not load namespace"));
 		goto error_exit;
 	}
 
 	return_ACPI_STATUS(AE_OK);
 
       error_exit:
-	ACPI_REPORT_ERROR(("acpi_load_tables: Could not load tables: %s\n",
-			   acpi_format_exception(status)));
-
+	ACPI_EXCEPTION((AE_INFO, status, "Could not load tables"));
 	return_ACPI_STATUS(status);
 }
 
diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c
index 3b8a7e0..a62db6a 100644
--- a/drivers/acpi/tables/tbxfroot.c
+++ b/drivers/acpi/tables/tbxfroot.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -251,7 +251,7 @@ acpi_get_firmware_table(acpi_string sign
 
 	acpi_tb_get_rsdt_address(&address);
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			  "RSDP located at %p, RSDT physical=%8.8X%8.8X \n",
+			  "RSDP located at %p, RSDT physical=%8.8X%8.8X\n",
 			  acpi_gbl_RSDP,
 			  ACPI_FORMAT_UINT64(address.pointer.value)));
 
@@ -396,9 +396,8 @@ acpi_status acpi_find_root_pointer(u32 f
 
 	status = acpi_tb_find_rsdp(&table_info, flags);
 	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "RSDP structure not found, %s Flags=%X\n",
-				  acpi_format_exception(status), flags));
+		ACPI_EXCEPTION((AE_INFO, status,
+				"RSDP structure not found - Flags=%X", flags));
 
 		return_ACPI_STATUS(AE_NO_ACPI_TABLES);
 	}
@@ -503,10 +502,10 @@ acpi_tb_find_rsdp(struct acpi_table_desc
 					    ACPI_EBDA_PTR_LENGTH,
 					    (void *)&table_ptr);
 		if (ACPI_FAILURE(status)) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Could not map memory at %8.8X for length %X\n",
-					  ACPI_EBDA_PTR_LOCATION,
-					  ACPI_EBDA_PTR_LENGTH));
+			ACPI_ERROR((AE_INFO,
+				    "Could not map memory at %8.8X for length %X",
+				    ACPI_EBDA_PTR_LOCATION,
+				    ACPI_EBDA_PTR_LENGTH));
 
 			return_ACPI_STATUS(status);
 		}
@@ -530,10 +529,10 @@ acpi_tb_find_rsdp(struct acpi_table_desc
 						    ACPI_EBDA_WINDOW_SIZE,
 						    (void *)&table_ptr);
 			if (ACPI_FAILURE(status)) {
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "Could not map memory at %8.8X for length %X\n",
-						  physical_address,
-						  ACPI_EBDA_WINDOW_SIZE));
+				ACPI_ERROR((AE_INFO,
+					    "Could not map memory at %8.8X for length %X",
+					    physical_address,
+					    ACPI_EBDA_WINDOW_SIZE));
 
 				return_ACPI_STATUS(status);
 			}
@@ -563,10 +562,10 @@ acpi_tb_find_rsdp(struct acpi_table_desc
 					    (void *)&table_ptr);
 
 		if (ACPI_FAILURE(status)) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Could not map memory at %8.8X for length %X\n",
-					  ACPI_HI_RSDP_WINDOW_BASE,
-					  ACPI_HI_RSDP_WINDOW_SIZE));
+			ACPI_ERROR((AE_INFO,
+				    "Could not map memory at %8.8X for length %X",
+				    ACPI_HI_RSDP_WINDOW_BASE,
+				    ACPI_HI_RSDP_WINDOW_SIZE));
 
 			return_ACPI_STATUS(status);
 		}
@@ -635,7 +634,7 @@ acpi_tb_find_rsdp(struct acpi_table_desc
 
 	/* A valid RSDP was not found */
 
-	ACPI_REPORT_ERROR(("No valid RSDP was found\n"));
+	ACPI_ERROR((AE_INFO, "No valid RSDP was found"));
 	return_ACPI_STATUS(AE_NOT_FOUND);
 }
 
diff --git a/drivers/acpi/utilities/Makefile b/drivers/acpi/utilities/Makefile
index e87108b..88eff14 100644
--- a/drivers/acpi/utilities/Makefile
+++ b/drivers/acpi/utilities/Makefile
@@ -2,7 +2,8 @@
 # Makefile for all Linux ACPI interpreter subdirectories
 #
 
-obj-y := utalloc.o  utdebug.o   uteval.o    utinit.o  utmisc.o    utxface.o \
-	 utcopy.o   utdelete.o  utglobal.o  utmath.o  utobject.o utstate.o utmutex.o utobject.o utcache.o
+obj-y := utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \
+		utcopy.o utdelete.o utglobal.o utmath.o utobject.o \
+		utstate.o utmutex.o utobject.o utcache.o utresrc.o
 
 EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c
index 068450b..03b0044 100644
--- a/drivers/acpi/utilities/utalloc.c
+++ b/drivers/acpi/utilities/utalloc.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -47,7 +47,7 @@
 ACPI_MODULE_NAME("utalloc")
 
 /* Local prototypes */
-#ifdef	ACPI_DBG_TRACK_ALLOCATIONS
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
 static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation);
 
 static acpi_status
@@ -58,9 +58,7 @@ acpi_ut_track_allocation(struct acpi_deb
 static acpi_status
 acpi_ut_remove_allocation(struct acpi_debug_mem_block *address,
 			  u32 component, char *module, u32 line);
-#endif				/* ACPI_DBG_TRACK_ALLOCATIONS */
 
-#ifdef ACPI_DBG_TRACK_ALLOCATIONS
 static acpi_status
 acpi_ut_create_list(char *list_name,
 		    u16 object_size, struct acpi_memory_list **return_cache);
@@ -303,8 +301,8 @@ void *acpi_ut_allocate(acpi_size size, u
 	/* Check for an inadvertent size of zero bytes */
 
 	if (!size) {
-		_ACPI_REPORT_ERROR(module, line, component,
-				   ("ut_allocate: Attempt to allocate zero bytes\n"));
+		ACPI_ERROR((module, line,
+			    "ut_allocate: Attempt to allocate zero bytes, allocating 1 byte"));
 		size = 1;
 	}
 
@@ -312,9 +310,9 @@ void *acpi_ut_allocate(acpi_size size, u
 	if (!allocation) {
 		/* Report allocation error */
 
-		_ACPI_REPORT_ERROR(module, line, component,
-				   ("ut_allocate: Could not allocate size %X\n",
-				    (u32) size));
+		ACPI_ERROR((module, line,
+			    "ut_allocate: Could not allocate size %X",
+			    (u32) size));
 
 		return_PTR(NULL);
 	}
@@ -346,18 +344,17 @@ void *acpi_ut_callocate(acpi_size size, 
 	/* Check for an inadvertent size of zero bytes */
 
 	if (!size) {
-		_ACPI_REPORT_ERROR(module, line, component,
-				   ("ut_callocate: Attempt to allocate zero bytes\n"));
-		return_PTR(NULL);
+		ACPI_ERROR((module, line,
+			    "Attempt to allocate zero bytes, allocating 1 byte"));
+		size = 1;
 	}
 
 	allocation = acpi_os_allocate(size);
 	if (!allocation) {
 		/* Report allocation error */
 
-		_ACPI_REPORT_ERROR(module, line, component,
-				   ("ut_callocate: Could not allocate size %X\n",
-				    (u32) size));
+		ACPI_ERROR((module, line,
+			    "Could not allocate size %X", (u32) size));
 		return_PTR(NULL);
 	}
 
@@ -482,9 +479,8 @@ void *acpi_ut_callocate_and_track(acpi_s
 	if (!allocation) {
 		/* Report allocation error */
 
-		_ACPI_REPORT_ERROR(module, line, component,
-				   ("ut_callocate: Could not allocate size %X\n",
-				    (u32) size));
+		ACPI_ERROR((module, line,
+			    "Could not allocate size %X", (u32) size));
 		return (NULL);
 	}
 
@@ -526,8 +522,7 @@ acpi_ut_free_and_track(void *allocation,
 	ACPI_FUNCTION_TRACE_PTR("ut_free", allocation);
 
 	if (NULL == allocation) {
-		_ACPI_REPORT_ERROR(module, line, component,
-				   ("acpi_ut_free: Attempt to delete a NULL address\n"));
+		ACPI_ERROR((module, line, "Attempt to delete a NULL address"));
 
 		return_VOID;
 	}
@@ -542,14 +537,11 @@ acpi_ut_free_and_track(void *allocation,
 	status = acpi_ut_remove_allocation(debug_block,
 					   component, module, line);
 	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Could not free memory, %s\n",
-				  acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status, "Could not free memory"));
 	}
 
 	acpi_os_free(debug_block);
-
 	ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p freed\n", allocation));
-
 	return_VOID;
 }
 
@@ -626,10 +618,12 @@ acpi_ut_track_allocation(struct acpi_deb
 	 */
 	element = acpi_ut_find_allocation(allocation);
 	if (element) {
-		ACPI_REPORT_ERROR(("ut_track_allocation: Allocation already present in list! (%p)\n", allocation));
+		ACPI_ERROR((AE_INFO,
+			    "ut_track_allocation: Allocation already present in list! (%p)",
+			    allocation));
 
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Element %p Address %p\n",
-				  element, allocation));
+		ACPI_ERROR((AE_INFO, "Element %p Address %p",
+			    element, allocation));
 
 		goto unlock_and_exit;
 	}
@@ -689,8 +683,8 @@ acpi_ut_remove_allocation(struct acpi_de
 	if (NULL == mem_list->list_head) {
 		/* No allocations! */
 
-		_ACPI_REPORT_ERROR(module, line, component,
-				   ("ut_remove_allocation: Empty allocation list, nothing to free!\n"));
+		ACPI_ERROR((module, line,
+			    "Empty allocation list, nothing to free!"));
 
 		return_ACPI_STATUS(AE_OK);
 	}
@@ -865,12 +859,11 @@ void acpi_ut_dump_allocations(u32 compon
 	/* Print summary */
 
 	if (!num_outstanding) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "No outstanding allocations.\n"));
+		ACPI_INFO((AE_INFO, "No outstanding allocations"));
 	} else {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "%d(%X) Outstanding allocations\n",
-				  num_outstanding, num_outstanding));
+		ACPI_ERROR((AE_INFO,
+			    "%d(%X) Outstanding allocations",
+			    num_outstanding, num_outstanding));
 	}
 
 	return_VOID;
diff --git a/drivers/acpi/utilities/utcache.c b/drivers/acpi/utilities/utcache.c
index 93d4868..2177cb1 100644
--- a/drivers/acpi/utilities/utcache.c
+++ b/drivers/acpi/utilities/utcache.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c
index 5442b32..df2d320 100644
--- a/drivers/acpi/utilities/utcopy.c
+++ b/drivers/acpi/utilities/utcopy.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -398,14 +398,17 @@ acpi_ut_copy_iobject_to_eobject(union ac
 		 * Build a simple object (no nested objects)
 		 */
 		status = acpi_ut_copy_isimple_to_esimple(internal_object,
-							 (union acpi_object *)
-							 ret_buffer->pointer,
-							 ((u8 *) ret_buffer->
-							  pointer +
-							  ACPI_ROUND_UP_TO_NATIVE_WORD
-							  (sizeof
-							   (union
-							    acpi_object))),
+							 ACPI_CAST_PTR(union
+								       acpi_object,
+								       ret_buffer->
+								       pointer),
+							 ACPI_ADD_PTR(u8,
+								      ret_buffer->
+								      pointer,
+								      ACPI_ROUND_UP_TO_NATIVE_WORD
+								      (sizeof
+								       (union
+									acpi_object))),
 							 &ret_buffer->length);
 		/*
 		 * build simple does not include the object size in the length
@@ -603,8 +606,8 @@ acpi_ut_copy_eobject_to_iobject(union ac
 		/*
 		 * Packages as external input to control methods are not supported,
 		 */
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Packages as parameters not implemented!\n"));
+		ACPI_ERROR((AE_INFO,
+			    "Packages as parameters not implemented!"));
 
 		return_ACPI_STATUS(AE_NOT_IMPLEMENTED);
 	}
@@ -867,7 +870,7 @@ acpi_ut_copy_ipackage_to_ipackage(union 
 							 count +
 							 1) * sizeof(void *));
 	if (!dest_obj->package.elements) {
-		ACPI_REPORT_ERROR(("aml_build_copy_internal_package_object: Package allocation failure\n"));
+		ACPI_ERROR((AE_INFO, "Package allocation failure"));
 		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
 
diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c
index d80e926..35f3d58 100644
--- a/drivers/acpi/utilities/utdebug.c
+++ b/drivers/acpi/utilities/utdebug.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
index 2bc878f..1db9695 100644
--- a/drivers/acpi/utilities/utdelete.c
+++ b/drivers/acpi/utilities/utdelete.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -363,8 +363,7 @@ acpi_ut_update_ref_count(union acpi_oper
 
 	default:
 
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown action (%X)\n",
-				  action));
+		ACPI_ERROR((AE_INFO, "Unknown action (%X)", action));
 		break;
 	}
 
@@ -374,9 +373,9 @@ acpi_ut_update_ref_count(union acpi_oper
 	 */
 	if (count > ACPI_MAX_REFERENCE_COUNT) {
 
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN,
-				  "**** Warning **** Large Reference Count (%X) in object %p\n\n",
-				  count, object));
+		ACPI_WARNING((AE_INFO,
+			      "Large Reference Count (%X) in object %p",
+			      count, object));
 	}
 
 	return;
@@ -535,8 +534,8 @@ acpi_ut_update_object_reference(union ac
 
       error_exit:
 
-	ACPI_REPORT_ERROR(("Could not update object reference count, %s\n",
-			   acpi_format_exception(status)));
+	ACPI_EXCEPTION((AE_INFO, status,
+			"Could not update object reference count"));
 
 	return_ACPI_STATUS(status);
 }
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
index 7b81d5e..106cc97 100644
--- a/drivers/acpi/utilities/uteval.c
+++ b/drivers/acpi/utilities/uteval.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -95,7 +95,9 @@ acpi_status acpi_ut_osi_implementation(s
 
 	for (i = 0; i < ACPI_NUM_OSI_STRINGS; i++) {
 		if (!ACPI_STRCMP(string_desc->string.pointer,
-				 (char *)acpi_gbl_valid_osi_strings[i])) {
+				 ACPI_CAST_PTR(char,
+					       acpi_gbl_valid_osi_strings[i])))
+		{
 			/* This string is supported */
 
 			return_desc->integer.value = 0xFFFFFFFF;
@@ -152,8 +154,8 @@ acpi_ut_evaluate_object(struct acpi_name
 					  acpi_ut_get_node_name(prefix_node),
 					  path));
 		} else {
-			ACPI_REPORT_METHOD_ERROR("Method execution failed",
-						 prefix_node, path, status);
+			ACPI_ERROR_METHOD("Method execution failed",
+					  prefix_node, path, status);
 		}
 
 		return_ACPI_STATUS(status);
@@ -163,9 +165,8 @@ acpi_ut_evaluate_object(struct acpi_name
 
 	if (!info.return_object) {
 		if (expected_return_btypes) {
-			ACPI_REPORT_METHOD_ERROR("No object was returned from",
-						 prefix_node, path,
-						 AE_NOT_EXIST);
+			ACPI_ERROR_METHOD("No object was returned from",
+					  prefix_node, path, AE_NOT_EXIST);
 
 			return_ACPI_STATUS(AE_NOT_EXIST);
 		}
@@ -210,15 +211,14 @@ acpi_ut_evaluate_object(struct acpi_name
 	/* Is the return object one of the expected types? */
 
 	if (!(expected_return_btypes & return_btype)) {
-		ACPI_REPORT_METHOD_ERROR("Return object type is incorrect",
-					 prefix_node, path, AE_TYPE);
+		ACPI_ERROR_METHOD("Return object type is incorrect",
+				  prefix_node, path, AE_TYPE);
 
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Type returned from %s was incorrect: %s, expected Btypes: %X\n",
-				  path,
-				  acpi_ut_get_object_type_name(info.
-							       return_object),
-				  expected_return_btypes));
+		ACPI_ERROR((AE_INFO,
+			    "Type returned from %s was incorrect: %s, expected Btypes: %X",
+			    path,
+			    acpi_ut_get_object_type_name(info.return_object),
+			    expected_return_btypes));
 
 		/* On error exit, we must delete the return object */
 
@@ -592,7 +592,7 @@ acpi_ut_execute_STA(struct acpi_namespac
 					  "_STA on %4.4s was not found, assuming device is present\n",
 					  acpi_ut_get_node_name(device_node)));
 
-			*flags = 0x0F;
+			*flags = ACPI_UINT32_MAX;
 			status = AE_OK;
 		}
 
@@ -637,17 +637,17 @@ acpi_ut_execute_sxds(struct acpi_namespa
 	for (i = 0; i < 4; i++) {
 		highest[i] = 0xFF;
 		status = acpi_ut_evaluate_object(device_node,
-						 (char *)
-						 acpi_gbl_highest_dstate_names
-						 [i], ACPI_BTYPE_INTEGER,
-						 &obj_desc);
+						 ACPI_CAST_PTR(char,
+							       acpi_gbl_highest_dstate_names
+							       [i]),
+						 ACPI_BTYPE_INTEGER, &obj_desc);
 		if (ACPI_FAILURE(status)) {
 			if (status != AE_NOT_FOUND) {
 				ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 						  "%s on Device %4.4s, %s\n",
-						  (char *)
-						  acpi_gbl_highest_dstate_names
-						  [i],
+						  ACPI_CAST_PTR(char,
+								acpi_gbl_highest_dstate_names
+								[i]),
 						  acpi_ut_get_node_name
 						  (device_node),
 						  acpi_format_exception
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
index 399e64b..ffd1338 100644
--- a/drivers/acpi/utilities/utglobal.c
+++ b/drivers/acpi/utilities/utglobal.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -67,8 +67,11 @@ const char *acpi_format_exception(acpi_s
 	acpi_status sub_status;
 	const char *exception = NULL;
 
-	ACPI_FUNCTION_NAME("format_exception");
+	ACPI_FUNCTION_ENTRY();
 
+	/*
+	 * Status is composed of two parts, a "type" and an actual code
+	 */
 	sub_status = (status & ~AE_CODE_MASK);
 
 	switch (status & AE_CODE_MASK) {
@@ -118,13 +121,13 @@ const char *acpi_format_exception(acpi_s
 	if (!exception) {
 		/* Exception code was not recognized */
 
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Unknown exception code: 0x%8.8X\n", status));
+		ACPI_ERROR((AE_INFO,
+			    "Unknown exception code: 0x%8.8X", status));
 
-		return ((const char *)"UNKNOWN_STATUS_CODE");
+		exception = "UNKNOWN_STATUS_CODE";
 	}
 
-	return ((const char *)exception);
+	return (ACPI_CAST_PTR(const char, exception));
 }
 
 /*******************************************************************************
@@ -217,23 +220,23 @@ const char *acpi_gbl_valid_osi_strings[A
  * 2) _TZ_ is defined to be a thermal zone in order to allow ASL code to
  *    perform a Notify() operation on it.
  */
-const struct acpi_predefined_names acpi_gbl_pre_defined_names[] =
-    { {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL},
-{"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL},
-{"_SB_", ACPI_TYPE_DEVICE, NULL},
-{"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL},
-{"_TZ_", ACPI_TYPE_THERMAL, NULL},
-{"_REV", ACPI_TYPE_INTEGER, (char *)ACPI_CA_SUPPORT_LEVEL},
-{"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME},
-{"_GL_", ACPI_TYPE_MUTEX, (char *)1},
+const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = {
+	{"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL},
+	{"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL},
+	{"_SB_", ACPI_TYPE_DEVICE, NULL},
+	{"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL},
+	{"_TZ_", ACPI_TYPE_THERMAL, NULL},
+	{"_REV", ACPI_TYPE_INTEGER, (char *)ACPI_CA_SUPPORT_LEVEL},
+	{"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME},
+	{"_GL_", ACPI_TYPE_MUTEX, (char *)1},
 
 #if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
-{"_OSI", ACPI_TYPE_METHOD, (char *)1},
+	{"_OSI", ACPI_TYPE_METHOD, (char *)1},
 #endif
 
 	/* Table terminator */
 
-{NULL, ACPI_TYPE_ANY, NULL}
+	{NULL, ACPI_TYPE_ANY, NULL}
 };
 
 /*
@@ -485,7 +488,7 @@ char *acpi_ut_get_region_name(u8 space_i
 		return ("invalid_space_id");
 	}
 
-	return ((char *)acpi_gbl_region_types[space_id]);
+	return (ACPI_CAST_PTR(char, acpi_gbl_region_types[space_id]));
 }
 
 /*******************************************************************************
@@ -503,11 +506,13 @@ char *acpi_ut_get_region_name(u8 space_i
 /* Event type decoding */
 
 static const char *acpi_gbl_event_types[ACPI_NUM_FIXED_EVENTS] = {
+/*! [Begin] no source code translation (keep these strings as-is) */
 	"PM_Timer",
-	"global_lock",
-	"power_button",
-	"sleep_button",
-	"real_time_clock",
+	"GlobalLock",
+	"PowerButton",
+	"SleepButton",
+	"RealTimeClock",
+/*! [End] no source code translation !*/
 };
 
 char *acpi_ut_get_event_name(u32 event_id)
@@ -517,7 +522,7 @@ char *acpi_ut_get_event_name(u32 event_i
 		return ("invalid_event_iD");
 	}
 
-	return ((char *)acpi_gbl_event_types[event_id]);
+	return (ACPI_CAST_PTR(char, acpi_gbl_event_types[event_id]));
 }
 
 /*******************************************************************************
@@ -545,12 +550,13 @@ static const char acpi_gbl_bad_type[] = 
 /* Printable names of the ACPI object types */
 
 static const char *acpi_gbl_ns_type_names[] = {
+/*! [Begin] no source code translation (keep these strings as-is) */
 	/* 00 */ "Untyped",
 	/* 01 */ "Integer",
 	/* 02 */ "String",
 	/* 03 */ "Buffer",
 	/* 04 */ "Package",
-	/* 05 */ "field_unit",
+	/* 05 */ "FieldUnit",
 	/* 06 */ "Device",
 	/* 07 */ "Event",
 	/* 08 */ "Method",
@@ -559,33 +565,34 @@ static const char *acpi_gbl_ns_type_name
 	/* 11 */ "Power",
 	/* 12 */ "Processor",
 	/* 13 */ "Thermal",
-	/* 14 */ "buffer_field",
-	/* 15 */ "ddb_handle",
-	/* 16 */ "debug_object",
-	/* 17 */ "region_field",
-	/* 18 */ "bank_field",
-	/* 19 */ "index_field",
+	/* 14 */ "BufferField",
+	/* 15 */ "DdbHandle",
+	/* 16 */ "DebugObject",
+	/* 17 */ "RegionField",
+	/* 18 */ "BankField",
+	/* 19 */ "IndexField",
 	/* 20 */ "Reference",
 	/* 21 */ "Alias",
-	/* 22 */ "method_alias",
+	/* 22 */ "MethodAlias",
 	/* 23 */ "Notify",
-	/* 24 */ "addr_handler",
-	/* 25 */ "resource_desc",
-	/* 26 */ "resource_fld",
+	/* 24 */ "AddrHandler",
+	/* 25 */ "ResourceDesc",
+	/* 26 */ "ResourceFld",
 	/* 27 */ "Scope",
 	/* 28 */ "Extra",
 	/* 29 */ "Data",
 	/* 30 */ "Invalid"
+/*! [End] no source code translation !*/
 };
 
 char *acpi_ut_get_type_name(acpi_object_type type)
 {
 
 	if (type > ACPI_TYPE_INVALID) {
-		return ((char *)acpi_gbl_bad_type);
+		return (ACPI_CAST_PTR(char, acpi_gbl_bad_type));
 	}
 
-	return ((char *)acpi_gbl_ns_type_names[type]);
+	return (ACPI_CAST_PTR(char, acpi_gbl_ns_type_names[type]));
 }
 
 char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc)
@@ -634,7 +641,7 @@ char *acpi_ut_get_node_name(void *object
 
 	/* Name must be a valid ACPI name */
 
-	if (!acpi_ut_valid_acpi_name(*(u32 *) node->name.ascii)) {
+	if (!acpi_ut_valid_acpi_name(node->name.integer)) {
 		return ("????");
 	}
 
@@ -658,15 +665,16 @@ char *acpi_ut_get_node_name(void *object
 /* Printable names of object descriptor types */
 
 static const char *acpi_gbl_desc_type_names[] = {
+/*! [Begin] no source code translation (keep these ASL Keywords as-is) */
 	/* 00 */ "Invalid",
 	/* 01 */ "Cached",
 	/* 02 */ "State-Generic",
 	/* 03 */ "State-Update",
 	/* 04 */ "State-Package",
 	/* 05 */ "State-Control",
-	/* 06 */ "State-root_parse_scope",
-	/* 07 */ "State-parse_scope",
-	/* 08 */ "State-walk_scope",
+	/* 06 */ "State-RootParseScope",
+	/* 07 */ "State-ParseScope",
+	/* 08 */ "State-WalkScope",
 	/* 09 */ "State-Result",
 	/* 10 */ "State-Notify",
 	/* 11 */ "State-Thread",
@@ -674,6 +682,7 @@ static const char *acpi_gbl_desc_type_na
 	/* 13 */ "Parser",
 	/* 14 */ "Operand",
 	/* 15 */ "Node"
+/*! [End] no source code translation !*/
 };
 
 char *acpi_ut_get_descriptor_name(void *object)
@@ -684,11 +693,12 @@ char *acpi_ut_get_descriptor_name(void *
 	}
 
 	if (ACPI_GET_DESCRIPTOR_TYPE(object) > ACPI_DESC_TYPE_MAX) {
-		return ((char *)acpi_gbl_bad_type);
+		return (ACPI_CAST_PTR(char, acpi_gbl_bad_type));
 	}
 
-	return ((char *)
-		acpi_gbl_desc_type_names[ACPI_GET_DESCRIPTOR_TYPE(object)]);
+	return (ACPI_CAST_PTR(char,
+			      acpi_gbl_desc_type_names[ACPI_GET_DESCRIPTOR_TYPE
+						       (object)]));
 
 }
 
@@ -787,6 +797,11 @@ void acpi_ut_init_globals(void)
 		acpi_gbl_mutex_info[i].use_count = 0;
 	}
 
+	for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) {
+		acpi_gbl_owner_id_mask[i] = 0;
+	}
+	acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000;	/* Last ID is never valid */
+
 	/* GPE support */
 
 	acpi_gbl_gpe_xrupt_list_head = NULL;
@@ -824,7 +839,11 @@ void acpi_ut_init_globals(void)
 	acpi_gbl_ns_lookup_count = 0;
 	acpi_gbl_ps_find_count = 0;
 	acpi_gbl_acpi_hardware_present = TRUE;
-	acpi_gbl_owner_id_mask = 0;
+	acpi_gbl_last_owner_id_index = 0;
+	acpi_gbl_next_owner_id_offset = 0;
+	acpi_gbl_trace_method_name = 0;
+	acpi_gbl_trace_dbg_level = 0;
+	acpi_gbl_trace_dbg_layer = 0;
 	acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
 	acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
 
@@ -836,7 +855,6 @@ void acpi_ut_init_globals(void)
 	/* Namespace */
 
 	acpi_gbl_root_node = NULL;
-
 	acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME;
 	acpi_gbl_root_node_struct.descriptor = ACPI_DESC_TYPE_NAMED;
 	acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE;
diff --git a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c
index 9dde82b..ba771b4 100644
--- a/drivers/acpi/utilities/utinit.c
+++ b/drivers/acpi/utilities/utinit.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -72,9 +72,9 @@ static void
 acpi_ut_fadt_register_error(char *register_name, u32 value, acpi_size offset)
 {
 
-	ACPI_REPORT_WARNING(("Invalid FADT value %s=%X at offset %X FADT=%p\n",
-			     register_name, value, (u32) offset,
-			     acpi_gbl_FADT));
+	ACPI_WARNING((AE_INFO,
+		      "Invalid FADT value %s=%X at offset %X FADT=%p",
+		      register_name, value, (u32) offset, acpi_gbl_FADT));
 }
 
 /******************************************************************************
@@ -221,15 +221,14 @@ void acpi_ut_subsystem_shutdown(void)
 	/* Just exit if subsystem is already shutdown */
 
 	if (acpi_gbl_shutdown) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "ACPI Subsystem is already terminated\n"));
+		ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated"));
 		return_VOID;
 	}
 
 	/* Subsystem appears active, go ahead and shut it down */
 
 	acpi_gbl_shutdown = TRUE;
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem...\n"));
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n"));
 
 	/* Close the acpi_event Handling */
 
diff --git a/drivers/acpi/utilities/utmath.c b/drivers/acpi/utilities/utmath.c
index 68a0a6f..4a33604 100644
--- a/drivers/acpi/utilities/utmath.c
+++ b/drivers/acpi/utilities/utmath.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -82,7 +82,7 @@ acpi_ut_short_divide(acpi_integer divide
 	/* Always check for a zero divisor */
 
 	if (divisor == 0) {
-		ACPI_REPORT_ERROR(("acpi_ut_short_divide: Divide by zero\n"));
+		ACPI_ERROR((AE_INFO, "Divide by zero"));
 		return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO);
 	}
 
@@ -144,7 +144,7 @@ acpi_ut_divide(acpi_integer in_dividend,
 	/* Always check for a zero divisor */
 
 	if (in_divisor == 0) {
-		ACPI_REPORT_ERROR(("acpi_ut_divide: Divide by zero\n"));
+		ACPI_ERROR((AE_INFO, "Divide by zero"));
 		return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO);
 	}
 
@@ -266,7 +266,7 @@ acpi_ut_short_divide(acpi_integer in_div
 	/* Always check for a zero divisor */
 
 	if (divisor == 0) {
-		ACPI_REPORT_ERROR(("acpi_ut_short_divide: Divide by zero\n"));
+		ACPI_ERROR((AE_INFO, "Divide by zero"));
 		return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO);
 	}
 
@@ -292,7 +292,7 @@ acpi_ut_divide(acpi_integer in_dividend,
 	/* Always check for a zero divisor */
 
 	if (in_divisor == 0) {
-		ACPI_REPORT_ERROR(("acpi_ut_divide: Divide by zero\n"));
+		ACPI_ERROR((AE_INFO, "Divide by zero"));
 		return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO);
 	}
 
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index 2ce872d..7364f5f 100644
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -63,6 +63,8 @@ ACPI_MODULE_NAME("utmisc")
 acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
 {
 	acpi_native_uint i;
+	acpi_native_uint j;
+	acpi_native_uint k;
 	acpi_status status;
 
 	ACPI_FUNCTION_TRACE("ut_allocate_owner_id");
@@ -70,8 +72,8 @@ acpi_status acpi_ut_allocate_owner_id(ac
 	/* Guard against multiple allocations of ID to the same location */
 
 	if (*owner_id) {
-		ACPI_REPORT_ERROR(("Owner ID [%2.2X] already exists\n",
-				   *owner_id));
+		ACPI_ERROR((AE_INFO, "Owner ID [%2.2X] already exists",
+			    *owner_id));
 		return_ACPI_STATUS(AE_ALREADY_EXISTS);
 	}
 
@@ -82,31 +84,67 @@ acpi_status acpi_ut_allocate_owner_id(ac
 		return_ACPI_STATUS(status);
 	}
 
-	/* Find a free owner ID */
+	/*
+	 * Find a free owner ID, cycle through all possible IDs on repeated
+	 * allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have
+	 * to be scanned twice.
+	 */
+	for (i = 0, j = acpi_gbl_last_owner_id_index;
+	     i < (ACPI_NUM_OWNERID_MASKS + 1); i++, j++) {
+		if (j >= ACPI_NUM_OWNERID_MASKS) {
+			j = 0;	/* Wraparound to start of mask array */
+		}
+
+		for (k = acpi_gbl_next_owner_id_offset; k < 32; k++) {
+			if (acpi_gbl_owner_id_mask[j] == ACPI_UINT32_MAX) {
+				/* There are no free IDs in this mask */
+
+				break;
+			}
+
+			if (!(acpi_gbl_owner_id_mask[j] & (1 << k))) {
+				/*
+				 * Found a free ID. The actual ID is the bit index plus one,
+				 * making zero an invalid Owner ID. Save this as the last ID
+				 * allocated and update the global ID mask.
+				 */
+				acpi_gbl_owner_id_mask[j] |= (1 << k);
+
+				acpi_gbl_last_owner_id_index = (u8) j;
+				acpi_gbl_next_owner_id_offset = (u8) (k + 1);
+
+				/*
+				 * Construct encoded ID from the index and bit position
+				 *
+				 * Note: Last [j].k (bit 255) is never used and is marked
+				 * permanently allocated (prevents +1 overflow)
+				 */
+				*owner_id =
+				    (acpi_owner_id) ((k + 1) + ACPI_MUL_32(j));
 
-	for (i = 0; i < 64; i++) {
-		if (!(acpi_gbl_owner_id_mask & (1ULL << i))) {
-			ACPI_DEBUG_PRINT((ACPI_DB_VALUES,
-					  "Current owner_id mask: %16.16LX New ID: %2.2X\n",
-					  acpi_gbl_owner_id_mask,
-					  (unsigned int)(i + 1)));
-
-			acpi_gbl_owner_id_mask |= (1ULL << i);
-			*owner_id = (acpi_owner_id) (i + 1);
-			goto exit;
+				ACPI_DEBUG_PRINT((ACPI_DB_VALUES,
+						  "Allocated owner_id: %2.2X\n",
+						  (unsigned int)*owner_id));
+				goto exit;
+			}
 		}
+
+		acpi_gbl_next_owner_id_offset = 0;
 	}
 
 	/*
-	 * If we are here, all owner_ids have been allocated. This probably should
+	 * All owner_ids have been allocated. This typically should
 	 * not happen since the IDs are reused after deallocation. The IDs are
 	 * allocated upon table load (one per table) and method execution, and
 	 * they are released when a table is unloaded or a method completes
 	 * execution.
+	 *
+	 * If this error happens, there may be very deep nesting of invoked control
+	 * methods, or there may be a bug where the IDs are not released.
 	 */
-	*owner_id = 0;
 	status = AE_OWNER_ID_LIMIT;
-	ACPI_REPORT_ERROR(("Could not allocate new owner_id (64 max), AE_OWNER_ID_LIMIT\n"));
+	ACPI_ERROR((AE_INFO,
+		    "Could not allocate new owner_id (255 max), AE_OWNER_ID_LIMIT"));
 
       exit:
 	(void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
@@ -123,7 +161,7 @@ acpi_status acpi_ut_allocate_owner_id(ac
  *              control method or unloading a table. Either way, we would
  *              ignore any error anyway.
  *
- * DESCRIPTION: Release a table or method owner ID.  Valid IDs are 1 - 64
+ * DESCRIPTION: Release a table or method owner ID.  Valid IDs are 1 - 255
  *
  ******************************************************************************/
 
@@ -131,6 +169,8 @@ void acpi_ut_release_owner_id(acpi_owner
 {
 	acpi_owner_id owner_id = *owner_id_ptr;
 	acpi_status status;
+	acpi_native_uint index;
+	u32 bit;
 
 	ACPI_FUNCTION_TRACE_U32("ut_release_owner_id", owner_id);
 
@@ -140,8 +180,8 @@ void acpi_ut_release_owner_id(acpi_owner
 
 	/* Zero is not a valid owner_iD */
 
-	if ((owner_id == 0) || (owner_id > 64)) {
-		ACPI_REPORT_ERROR(("Invalid owner_id: %2.2X\n", owner_id));
+	if (owner_id == 0) {
+		ACPI_ERROR((AE_INFO, "Invalid owner_id: %2.2X", owner_id));
 		return_VOID;
 	}
 
@@ -156,10 +196,19 @@ void acpi_ut_release_owner_id(acpi_owner
 
 	owner_id--;
 
+	/* Decode ID to index/offset pair */
+
+	index = ACPI_DIV_32(owner_id);
+	bit = 1 << ACPI_MOD_32(owner_id);
+
 	/* Free the owner ID only if it is valid */
 
-	if (acpi_gbl_owner_id_mask & (1ULL << owner_id)) {
-		acpi_gbl_owner_id_mask ^= (1ULL << owner_id);
+	if (acpi_gbl_owner_id_mask[index] & bit) {
+		acpi_gbl_owner_id_mask[index] ^= bit;
+	} else {
+		ACPI_ERROR((AE_INFO,
+			    "Release of non-allocated owner_id: %2.2X",
+			    owner_id + 1));
 	}
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
@@ -790,109 +839,97 @@ u8 acpi_ut_generate_checksum(u8 * buffer
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ut_get_resource_end_tag
+ * FUNCTION:    acpi_ut_error, acpi_ut_warning, acpi_ut_info
  *
- * PARAMETERS:  obj_desc        - The resource template buffer object
+ * PARAMETERS:  module_name         - Caller's module name (for error output)
+ *              line_number         - Caller's line number (for error output)
+ *              Format              - Printf format string + additional args
  *
- * RETURN:      Pointer to the end tag
+ * RETURN:      None
  *
- * DESCRIPTION: Find the END_TAG resource descriptor in a resource template
+ * DESCRIPTION: Print message with module/line/version info
  *
  ******************************************************************************/
 
-u8 *acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc)
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_error(char *module_name, u32 line_number, char *format, ...)
 {
-	u8 buffer_byte;
-	u8 *buffer;
-	u8 *end_buffer;
+	va_list args;
 
-	buffer = obj_desc->buffer.pointer;
-	end_buffer = buffer + obj_desc->buffer.length;
+	acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number);
 
-	while (buffer < end_buffer) {
-		buffer_byte = *buffer;
-		if (buffer_byte & ACPI_RDESC_TYPE_MASK) {
-			/* Large Descriptor - Length is next 2 bytes */
+	va_start(args, format);
+	acpi_os_vprintf(format, args);
+	acpi_os_printf(" [%X]\n", ACPI_CA_VERSION);
+}
 
-			buffer += ((*(buffer + 1) | (*(buffer + 2) << 8)) + 3);
-		} else {
-			/* Small Descriptor.  End Tag will be found here */
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_exception(char *module_name,
+		  u32 line_number, acpi_status status, char *format, ...)
+{
+	va_list args;
 
-			if ((buffer_byte & ACPI_RDESC_SMALL_MASK) ==
-			    ACPI_RDESC_TYPE_END_TAG) {
-				/* Found the end tag descriptor, all done. */
+	acpi_os_printf("ACPI Exception (%s-%04d): %s, ", module_name,
+		       line_number, acpi_format_exception(status));
 
-				return (buffer);
-			}
+	va_start(args, format);
+	acpi_os_vprintf(format, args);
+	acpi_os_printf(" [%X]\n", ACPI_CA_VERSION);
+}
 
-			/* Length is in the header */
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_warning(char *module_name, u32 line_number, char *format, ...)
+{
+	va_list args;
 
-			buffer += ((buffer_byte & 0x07) + 1);
-		}
-	}
+	acpi_os_printf("ACPI Warning (%s-%04d): ", module_name, line_number);
+
+	va_start(args, format);
+	acpi_os_vprintf(format, args);
+	acpi_os_printf(" [%X]\n", ACPI_CA_VERSION);
+}
+
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_info(char *module_name, u32 line_number, char *format, ...)
+{
+	va_list args;
 
-	/* End tag not found */
+	acpi_os_printf("ACPI (%s-%04d): ", module_name, line_number);
 
-	return (NULL);
+	va_start(args, format);
+	acpi_os_vprintf(format, args);
+	acpi_os_printf(" [%X]\n", ACPI_CA_VERSION);
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ut_report_error
+ * FUNCTION:    acpi_ut_report_error, Warning, Info
  *
  * PARAMETERS:  module_name         - Caller's module name (for error output)
  *              line_number         - Caller's line number (for error output)
- *              component_id        - Caller's component ID (for error output)
  *
  * RETURN:      None
  *
  * DESCRIPTION: Print error message
  *
+ * Note: Legacy only, should be removed when no longer used by drivers.
+ *
  ******************************************************************************/
 
-void acpi_ut_report_error(char *module_name, u32 line_number, u32 component_id)
+void acpi_ut_report_error(char *module_name, u32 line_number)
 {
 
-	acpi_os_printf("%8s-%04d: *** Error: ", module_name, line_number);
+	acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number);
 }
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_report_warning
- *
- * PARAMETERS:  module_name         - Caller's module name (for error output)
- *              line_number         - Caller's line number (for error output)
- *              component_id        - Caller's component ID (for error output)
- *
- * RETURN:      None
- *
- * DESCRIPTION: Print warning message
- *
- ******************************************************************************/
-
-void
-acpi_ut_report_warning(char *module_name, u32 line_number, u32 component_id)
+void acpi_ut_report_warning(char *module_name, u32 line_number)
 {
 
-	acpi_os_printf("%8s-%04d: *** Warning: ", module_name, line_number);
+	acpi_os_printf("ACPI Warning (%s-%04d): ", module_name, line_number);
 }
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_report_info
- *
- * PARAMETERS:  module_name         - Caller's module name (for error output)
- *              line_number         - Caller's line number (for error output)
- *              component_id        - Caller's component ID (for error output)
- *
- * RETURN:      None
- *
- * DESCRIPTION: Print information message
- *
- ******************************************************************************/
-
-void acpi_ut_report_info(char *module_name, u32 line_number, u32 component_id)
+void acpi_ut_report_info(char *module_name, u32 line_number)
 {
 
-	acpi_os_printf("%8s-%04d: *** Info: ", module_name, line_number);
+	acpi_os_printf("ACPI (%s-%04d): ", module_name, line_number);
 }
diff --git a/drivers/acpi/utilities/utmutex.c b/drivers/acpi/utilities/utmutex.c
index 90134c5..45a7244 100644
--- a/drivers/acpi/utilities/utmutex.c
+++ b/drivers/acpi/utilities/utmutex.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -214,23 +214,22 @@ acpi_status acpi_ut_acquire_mutex(acpi_m
 		 * the ACPI subsystem code.
 		 */
 		for (i = mutex_id; i < MAX_MUTEX; i++) {
-			if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) {
+			if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) {
 				if (i == mutex_id) {
-					ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-							  "Mutex [%s] already acquired by this thread [%X]\n",
-							  acpi_ut_get_mutex_name
-							  (mutex_id),
-							  this_thread_id));
+					ACPI_ERROR((AE_INFO,
+						    "Mutex [%s] already acquired by this thread [%X]",
+						    acpi_ut_get_mutex_name
+						    (mutex_id),
+						    this_thread_id));
 
 					return (AE_ALREADY_ACQUIRED);
 				}
 
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "Invalid acquire order: Thread %X owns [%s], wants [%s]\n",
-						  this_thread_id,
-						  acpi_ut_get_mutex_name(i),
-						  acpi_ut_get_mutex_name
-						  (mutex_id)));
+				ACPI_ERROR((AE_INFO,
+					    "Invalid acquire order: Thread %X owns [%s], wants [%s]",
+					    this_thread_id,
+					    acpi_ut_get_mutex_name(i),
+					    acpi_ut_get_mutex_name(mutex_id)));
 
 				return (AE_ACQUIRE_DEADLOCK);
 			}
@@ -253,11 +252,9 @@ acpi_status acpi_ut_acquire_mutex(acpi_m
 		acpi_gbl_mutex_info[mutex_id].use_count++;
 		acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id;
 	} else {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Thread %X could not acquire Mutex [%s] %s\n",
-				  this_thread_id,
-				  acpi_ut_get_mutex_name(mutex_id),
-				  acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status,
+				"Thread %X could not acquire Mutex [%X]",
+				this_thread_id, mutex_id));
 	}
 
 	return (status);
@@ -295,9 +292,9 @@ acpi_status acpi_ut_release_mutex(acpi_m
 	 * Mutex must be acquired in order to release it!
 	 */
 	if (acpi_gbl_mutex_info[mutex_id].thread_id == ACPI_MUTEX_NOT_ACQUIRED) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Mutex [%s] is not acquired, cannot release\n",
-				  acpi_ut_get_mutex_name(mutex_id)));
+		ACPI_ERROR((AE_INFO,
+			    "Mutex [%X] is not acquired, cannot release",
+			    mutex_id));
 
 		return (AE_NOT_ACQUIRED);
 	}
@@ -313,16 +310,15 @@ acpi_status acpi_ut_release_mutex(acpi_m
 		 * the ACPI subsystem code.
 		 */
 		for (i = mutex_id; i < MAX_MUTEX; i++) {
-			if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) {
+			if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) {
 				if (i == mutex_id) {
 					continue;
 				}
 
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "Invalid release order: owns [%s], releasing [%s]\n",
-						  acpi_ut_get_mutex_name(i),
-						  acpi_ut_get_mutex_name
-						  (mutex_id)));
+				ACPI_ERROR((AE_INFO,
+					    "Invalid release order: owns [%s], releasing [%s]",
+					    acpi_ut_get_mutex_name(i),
+					    acpi_ut_get_mutex_name(mutex_id)));
 
 				return (AE_RELEASE_DEADLOCK);
 			}
@@ -338,11 +334,9 @@ acpi_status acpi_ut_release_mutex(acpi_m
 	    acpi_os_signal_semaphore(acpi_gbl_mutex_info[mutex_id].mutex, 1);
 
 	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Thread %X could not release Mutex [%s] %s\n",
-				  this_thread_id,
-				  acpi_ut_get_mutex_name(mutex_id),
-				  acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status,
+				"Thread %X could not release Mutex [%X]",
+				this_thread_id, mutex_id));
 	} else {
 		ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
 				  "Thread %X released Mutex [%s]\n",
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c
index 3015e15..7ee2d1d 100644
--- a/drivers/acpi/utilities/utobject.c
+++ b/drivers/acpi/utilities/utobject.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -177,7 +177,8 @@ union acpi_operand_object *acpi_ut_creat
 
 		buffer = ACPI_MEM_CALLOCATE(buffer_size);
 		if (!buffer) {
-			ACPI_REPORT_ERROR(("create_buffer: could not allocate size %X\n", (u32) buffer_size));
+			ACPI_ERROR((AE_INFO, "Could not allocate size %X",
+				    (u32) buffer_size));
 			acpi_ut_remove_reference(buffer_desc);
 			return_PTR(NULL);
 		}
@@ -228,7 +229,8 @@ union acpi_operand_object *acpi_ut_creat
 	 */
 	string = ACPI_MEM_CALLOCATE(string_size + 1);
 	if (!string) {
-		ACPI_REPORT_ERROR(("create_string: could not allocate size %X\n", (u32) string_size));
+		ACPI_ERROR((AE_INFO, "Could not allocate size %X",
+			    (u32) string_size));
 		acpi_ut_remove_reference(string_desc);
 		return_PTR(NULL);
 	}
@@ -310,8 +312,8 @@ void *acpi_ut_allocate_object_desc_dbg(c
 
 	object = acpi_os_acquire_object(acpi_gbl_operand_cache);
 	if (!object) {
-		_ACPI_REPORT_ERROR(module_name, line_number, component_id,
-				   ("Could not allocate an object descriptor\n"));
+		ACPI_ERROR((module_name, line_number,
+			    "Could not allocate an object descriptor"));
 
 		return_PTR(NULL);
 	}
@@ -345,9 +347,9 @@ void acpi_ut_delete_object_desc(union ac
 	/* Object must be an union acpi_operand_object    */
 
 	if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "%p is not an ACPI Operand object [%s]\n",
-				  object, acpi_ut_get_descriptor_name(object)));
+		ACPI_ERROR((AE_INFO,
+			    "%p is not an ACPI Operand object [%s]", object,
+			    acpi_ut_get_descriptor_name(object)));
 		return_VOID;
 	}
 
@@ -449,10 +451,10 @@ acpi_ut_get_simple_object_size(union acp
 			 * Notably, Locals and Args are not supported, but this may be
 			 * required eventually.
 			 */
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "Unsupported Reference opcode=%X in object %p\n",
-					  internal_object->reference.opcode,
-					  internal_object));
+			ACPI_ERROR((AE_INFO,
+				    "Unsupported Reference opcode=%X in object %p",
+				    internal_object->reference.opcode,
+				    internal_object));
 			status = AE_TYPE;
 			break;
 		}
@@ -460,10 +462,9 @@ acpi_ut_get_simple_object_size(union acp
 
 	default:
 
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Unsupported type=%X in object %p\n",
-				  ACPI_GET_OBJECT_TYPE(internal_object),
-				  internal_object));
+		ACPI_ERROR((AE_INFO, "Unsupported type=%X in object %p",
+			    ACPI_GET_OBJECT_TYPE(internal_object),
+			    internal_object));
 		status = AE_TYPE;
 		break;
 	}
diff --git a/drivers/acpi/utilities/utresrc.c b/drivers/acpi/utilities/utresrc.c
new file mode 100644
index 0000000..1646131
--- /dev/null
+++ b/drivers/acpi/utilities/utresrc.c
@@ -0,0 +1,554 @@
+/*******************************************************************************
+ *
+ * Module Name: utresrc - Resource managment utilities
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2006, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include <acpi/amlresrc.h>
+
+#define _COMPONENT          ACPI_UTILITIES
+ACPI_MODULE_NAME("utmisc")
+
+#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER)
+/*
+ * Strings used to decode resource descriptors.
+ * Used by both the disasssembler and the debugger resource dump routines
+ */
+const char *acpi_gbl_BMdecode[2] = {
+	"not_bus_master",
+	"bus_master"
+};
+
+const char *acpi_gbl_config_decode[4] = {
+	"0 - Good Configuration",
+	"1 - Acceptable Configuration",
+	"2 - Suboptimal Configuration",
+	"3 - ***Invalid Configuration***",
+};
+
+const char *acpi_gbl_consume_decode[2] = {
+	"resource_producer",
+	"resource_consumer"
+};
+
+const char *acpi_gbl_DECdecode[2] = {
+	"pos_decode",
+	"sub_decode"
+};
+
+const char *acpi_gbl_HEdecode[2] = {
+	"Level",
+	"Edge"
+};
+
+const char *acpi_gbl_io_decode[2] = {
+	"Decode10",
+	"Decode16"
+};
+
+const char *acpi_gbl_LLdecode[2] = {
+	"active_high",
+	"active_low"
+};
+
+const char *acpi_gbl_max_decode[2] = {
+	"max_not_fixed",
+	"max_fixed"
+};
+
+const char *acpi_gbl_MEMdecode[4] = {
+	"non_cacheable",
+	"Cacheable",
+	"write_combining",
+	"Prefetchable"
+};
+
+const char *acpi_gbl_min_decode[2] = {
+	"min_not_fixed",
+	"min_fixed"
+};
+
+const char *acpi_gbl_MTPdecode[4] = {
+	"address_range_memory",
+	"address_range_reserved",
+	"address_range_aCPI",
+	"address_range_nVS"
+};
+
+const char *acpi_gbl_RNGdecode[4] = {
+	"invalid_ranges",
+	"non_iSAonly_ranges",
+	"ISAonly_ranges",
+	"entire_range"
+};
+
+const char *acpi_gbl_RWdecode[2] = {
+	"read_only",
+	"read_write"
+};
+
+const char *acpi_gbl_SHRdecode[2] = {
+	"Exclusive",
+	"Shared"
+};
+
+const char *acpi_gbl_SIZdecode[4] = {
+	"Transfer8",
+	"Transfer8_16",
+	"Transfer16",
+	"invalid_size"
+};
+
+const char *acpi_gbl_TRSdecode[2] = {
+	"dense_translation",
+	"sparse_translation"
+};
+
+const char *acpi_gbl_TTPdecode[2] = {
+	"type_static",
+	"type_translation"
+};
+
+const char *acpi_gbl_TYPdecode[4] = {
+	"Compatibility",
+	"type_a",
+	"type_b",
+	"type_f"
+};
+
+#endif
+
+/*
+ * Base sizes of the raw AML resource descriptors, indexed by resource type.
+ * Zero indicates a reserved (and therefore invalid) resource type.
+ */
+const u8 acpi_gbl_resource_aml_sizes[] = {
+	/* Small descriptors */
+
+	0,
+	0,
+	0,
+	0,
+	ACPI_AML_SIZE_SMALL(struct aml_resource_irq),
+	ACPI_AML_SIZE_SMALL(struct aml_resource_dma),
+	ACPI_AML_SIZE_SMALL(struct aml_resource_start_dependent),
+	ACPI_AML_SIZE_SMALL(struct aml_resource_end_dependent),
+	ACPI_AML_SIZE_SMALL(struct aml_resource_io),
+	ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_io),
+	0,
+	0,
+	0,
+	0,
+	ACPI_AML_SIZE_SMALL(struct aml_resource_vendor_small),
+	ACPI_AML_SIZE_SMALL(struct aml_resource_end_tag),
+
+	/* Large descriptors */
+
+	0,
+	ACPI_AML_SIZE_LARGE(struct aml_resource_memory24),
+	ACPI_AML_SIZE_LARGE(struct aml_resource_generic_register),
+	0,
+	ACPI_AML_SIZE_LARGE(struct aml_resource_vendor_large),
+	ACPI_AML_SIZE_LARGE(struct aml_resource_memory32),
+	ACPI_AML_SIZE_LARGE(struct aml_resource_fixed_memory32),
+	ACPI_AML_SIZE_LARGE(struct aml_resource_address32),
+	ACPI_AML_SIZE_LARGE(struct aml_resource_address16),
+	ACPI_AML_SIZE_LARGE(struct aml_resource_extended_irq),
+	ACPI_AML_SIZE_LARGE(struct aml_resource_address64),
+	ACPI_AML_SIZE_LARGE(struct aml_resource_extended_address64)
+};
+
+/*
+ * Resource types, used to validate the resource length field.
+ * The length of fixed-length types must match exactly, variable
+ * lengths must meet the minimum required length, etc.
+ * Zero indicates a reserved (and therefore invalid) resource type.
+ */
+static const u8 acpi_gbl_resource_types[] = {
+	/* Small descriptors */
+
+	0,
+	0,
+	0,
+	0,
+	ACPI_SMALL_VARIABLE_LENGTH,
+	ACPI_FIXED_LENGTH,
+	ACPI_SMALL_VARIABLE_LENGTH,
+	ACPI_FIXED_LENGTH,
+	ACPI_FIXED_LENGTH,
+	ACPI_FIXED_LENGTH,
+	0,
+	0,
+	0,
+	0,
+	ACPI_VARIABLE_LENGTH,
+	ACPI_FIXED_LENGTH,
+
+	/* Large descriptors */
+
+	0,
+	ACPI_FIXED_LENGTH,
+	ACPI_FIXED_LENGTH,
+	0,
+	ACPI_VARIABLE_LENGTH,
+	ACPI_FIXED_LENGTH,
+	ACPI_FIXED_LENGTH,
+	ACPI_VARIABLE_LENGTH,
+	ACPI_VARIABLE_LENGTH,
+	ACPI_VARIABLE_LENGTH,
+	ACPI_VARIABLE_LENGTH,
+	ACPI_FIXED_LENGTH
+};
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_validate_resource
+ *
+ * PARAMETERS:  Aml             - Pointer to the raw AML resource descriptor
+ *              return_index    - Where the resource index is returned. NULL
+ *                                if the index is not required.
+ *
+ * RETURN:      Status, and optionally the Index into the global resource tables
+ *
+ * DESCRIPTION: Validate an AML resource descriptor by checking the Resource
+ *              Type and Resource Length. Returns an index into the global
+ *              resource information/dispatch tables for later use.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
+{
+	u8 resource_type;
+	u8 resource_index;
+	acpi_rs_length resource_length;
+	acpi_rs_length minimum_resource_length;
+
+	ACPI_FUNCTION_ENTRY();
+
+	/*
+	 * 1) Validate the resource_type field (Byte 0)
+	 */
+	resource_type = ACPI_GET8(aml);
+
+	/*
+	 * Byte 0 contains the descriptor name (Resource Type)
+	 * Examine the large/small bit in the resource header
+	 */
+	if (resource_type & ACPI_RESOURCE_NAME_LARGE) {
+		/* Verify the large resource type (name) against the max */
+
+		if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) {
+			return (AE_AML_INVALID_RESOURCE_TYPE);
+		}
+
+		/*
+		 * Large Resource Type -- bits 6:0 contain the name
+		 * Translate range 0x80-0x8B to index range 0x10-0x1B
+		 */
+		resource_index = (u8) (resource_type - 0x70);
+	} else {
+		/*
+		 * Small Resource Type -- bits 6:3 contain the name
+		 * Shift range to index range 0x00-0x0F
+		 */
+		resource_index = (u8)
+		    ((resource_type & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3);
+	}
+
+	/* Check validity of the resource type, zero indicates name is invalid */
+
+	if (!acpi_gbl_resource_types[resource_index]) {
+		return (AE_AML_INVALID_RESOURCE_TYPE);
+	}
+
+	/*
+	 * 2) Validate the resource_length field. This ensures that the length
+	 *    is at least reasonable, and guarantees that it is non-zero.
+	 */
+	resource_length = acpi_ut_get_resource_length(aml);
+	minimum_resource_length = acpi_gbl_resource_aml_sizes[resource_index];
+
+	/* Validate based upon the type of resource - fixed length or variable */
+
+	switch (acpi_gbl_resource_types[resource_index]) {
+	case ACPI_FIXED_LENGTH:
+
+		/* Fixed length resource, length must match exactly */
+
+		if (resource_length != minimum_resource_length) {
+			return (AE_AML_BAD_RESOURCE_LENGTH);
+		}
+		break;
+
+	case ACPI_VARIABLE_LENGTH:
+
+		/* Variable length resource, length must be at least the minimum */
+
+		if (resource_length < minimum_resource_length) {
+			return (AE_AML_BAD_RESOURCE_LENGTH);
+		}
+		break;
+
+	case ACPI_SMALL_VARIABLE_LENGTH:
+
+		/* Small variable length resource, length can be (Min) or (Min-1) */
+
+		if ((resource_length > minimum_resource_length) ||
+		    (resource_length < (minimum_resource_length - 1))) {
+			return (AE_AML_BAD_RESOURCE_LENGTH);
+		}
+		break;
+
+	default:
+
+		/* Shouldn't happen (because of validation earlier), but be sure */
+
+		return (AE_AML_INVALID_RESOURCE_TYPE);
+	}
+
+	/* Optionally return the resource table index */
+
+	if (return_index) {
+		*return_index = resource_index;
+	}
+
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_get_resource_type
+ *
+ * PARAMETERS:  Aml             - Pointer to the raw AML resource descriptor
+ *
+ * RETURN:      The Resource Type with no extraneous bits (except the
+ *              Large/Small descriptor bit -- this is left alone)
+ *
+ * DESCRIPTION: Extract the Resource Type/Name from the first byte of
+ *              a resource descriptor.
+ *
+ ******************************************************************************/
+
+u8 acpi_ut_get_resource_type(void *aml)
+{
+	ACPI_FUNCTION_ENTRY();
+
+	/*
+	 * Byte 0 contains the descriptor name (Resource Type)
+	 * Examine the large/small bit in the resource header
+	 */
+	if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
+		/* Large Resource Type -- bits 6:0 contain the name */
+
+		return (ACPI_GET8(aml));
+	} else {
+		/* Small Resource Type -- bits 6:3 contain the name */
+
+		return ((u8) (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_SMALL_MASK));
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_get_resource_length
+ *
+ * PARAMETERS:  Aml             - Pointer to the raw AML resource descriptor
+ *
+ * RETURN:      Byte Length
+ *
+ * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By
+ *              definition, this does not include the size of the descriptor
+ *              header or the length field itself.
+ *
+ ******************************************************************************/
+
+u16 acpi_ut_get_resource_length(void *aml)
+{
+	acpi_rs_length resource_length;
+
+	ACPI_FUNCTION_ENTRY();
+
+	/*
+	 * Byte 0 contains the descriptor name (Resource Type)
+	 * Examine the large/small bit in the resource header
+	 */
+	if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
+		/* Large Resource type -- bytes 1-2 contain the 16-bit length */
+
+		ACPI_MOVE_16_TO_16(&resource_length, ACPI_ADD_PTR(u8, aml, 1));
+
+	} else {
+		/* Small Resource type -- bits 2:0 of byte 0 contain the length */
+
+		resource_length = (u16) (ACPI_GET8(aml) &
+					 ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK);
+	}
+
+	return (resource_length);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_get_resource_header_length
+ *
+ * PARAMETERS:  Aml             - Pointer to the raw AML resource descriptor
+ *
+ * RETURN:      Length of the AML header (depends on large/small descriptor)
+ *
+ * DESCRIPTION: Get the length of the header for this resource.
+ *
+ ******************************************************************************/
+
+u8 acpi_ut_get_resource_header_length(void *aml)
+{
+	ACPI_FUNCTION_ENTRY();
+
+	/* Examine the large/small bit in the resource header */
+
+	if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
+		return (sizeof(struct aml_resource_large_header));
+	} else {
+		return (sizeof(struct aml_resource_small_header));
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_get_descriptor_length
+ *
+ * PARAMETERS:  Aml             - Pointer to the raw AML resource descriptor
+ *
+ * RETURN:      Byte length
+ *
+ * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the
+ *              length of the descriptor header and the length field itself.
+ *              Used to walk descriptor lists.
+ *
+ ******************************************************************************/
+
+u32 acpi_ut_get_descriptor_length(void *aml)
+{
+	ACPI_FUNCTION_ENTRY();
+
+	/*
+	 * Get the Resource Length (does not include header length) and add
+	 * the header length (depends on if this is a small or large resource)
+	 */
+	return (acpi_ut_get_resource_length(aml) +
+		acpi_ut_get_resource_header_length(aml));
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_get_resource_end_tag
+ *
+ * PARAMETERS:  obj_desc        - The resource template buffer object
+ *              end_tag         - Where the pointer to the end_tag is returned
+ *
+ * RETURN:      Status, pointer to the end tag
+ *
+ * DESCRIPTION: Find the end_tag resource descriptor in an AML resource template
+ *              Note: allows a buffer length of zero.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc,
+			     u8 ** end_tag)
+{
+	acpi_status status;
+	u8 *aml;
+	u8 *end_aml;
+
+	ACPI_FUNCTION_TRACE("ut_get_resource_end_tag");
+
+	/* Get start and end pointers */
+
+	aml = obj_desc->buffer.pointer;
+	end_aml = aml + obj_desc->buffer.length;
+
+	/* Allow a buffer length of zero */
+
+	if (!obj_desc->buffer.length) {
+		*end_tag = aml;
+		return_ACPI_STATUS(AE_OK);
+	}
+
+	/* Walk the resource template, one descriptor per iteration */
+
+	while (aml < end_aml) {
+		/* Validate the Resource Type and Resource Length */
+
+		status = acpi_ut_validate_resource(aml, NULL);
+		if (ACPI_FAILURE(status)) {
+			return_ACPI_STATUS(status);
+		}
+
+		/* end_tag resource indicates the end of the resource template */
+
+		if (acpi_ut_get_resource_type(aml) ==
+		    ACPI_RESOURCE_NAME_END_TAG) {
+			/*
+			 * There must be at least one more byte in the buffer for
+			 * the 2nd byte of the end_tag
+			 */
+			if ((aml + 1) >= end_aml) {
+				return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
+			}
+
+			/* Return the pointer to the end_tag */
+
+			*end_tag = aml;
+			return_ACPI_STATUS(AE_OK);
+		}
+
+		/*
+		 * Point to the next resource descriptor in the AML buffer. The
+		 * descriptor length is guaranteed to be non-zero by resource
+		 * validation above.
+		 */
+		aml += acpi_ut_get_descriptor_length(aml);
+	}
+
+	/* Did not find an end_tag resource descriptor */
+
+	return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
+}
diff --git a/drivers/acpi/utilities/utstate.c b/drivers/acpi/utilities/utstate.c
index c1cb275..4b134a7 100644
--- a/drivers/acpi/utilities/utstate.c
+++ b/drivers/acpi/utilities/utstate.c
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -63,7 +63,7 @@ acpi_status
 acpi_ut_create_pkg_state_and_push(void *internal_object,
 				  void *external_object,
 				  u16 index,
-				  union acpi_generic_state ** state_list)
+				  union acpi_generic_state **state_list)
 {
 	union acpi_generic_state *state;
 
diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c
index f06bd5e..308a960 100644
--- a/drivers/acpi/utilities/utxface.c
+++ b/drivers/acpi/utilities/utxface.c
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -75,8 +75,7 @@ acpi_status acpi_initialize_subsystem(vo
 
 	status = acpi_os_initialize();
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("OSD failed to initialize, %s\n",
-				   acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status, "During OSL initialization"));
 		return_ACPI_STATUS(status);
 	}
 
@@ -88,8 +87,8 @@ acpi_status acpi_initialize_subsystem(vo
 
 	status = acpi_ut_mutex_initialize();
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("Global mutex creation failure, %s\n",
-				   acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status,
+				"During Global Mutex creation"));
 		return_ACPI_STATUS(status);
 	}
 
@@ -99,15 +98,14 @@ acpi_status acpi_initialize_subsystem(vo
 	 */
 	status = acpi_ns_root_initialize();
 	if (ACPI_FAILURE(status)) {
-		ACPI_REPORT_ERROR(("Namespace initialization failure, %s\n",
-				   acpi_format_exception(status)));
+		ACPI_EXCEPTION((AE_INFO, status,
+				"During Namespace initialization"));
 		return_ACPI_STATUS(status);
 	}
 
 	/* If configured, initialize the AML debugger */
 
 	ACPI_DEBUGGER_EXEC(status = acpi_db_initialize());
-
 	return_ACPI_STATUS(status);
 }
 
@@ -154,8 +152,7 @@ acpi_status acpi_enable_subsystem(u32 fl
 
 		status = acpi_enable();
 		if (ACPI_FAILURE(status)) {
-			ACPI_DEBUG_PRINT((ACPI_DB_WARN,
-					  "acpi_enable failed.\n"));
+			ACPI_WARNING((AE_INFO, "acpi_enable failed"));
 			return_ACPI_STATUS(status);
 		}
 	}
@@ -178,10 +175,14 @@ acpi_status acpi_enable_subsystem(u32 fl
 	/*
 	 * Initialize ACPI Event handling (Fixed and General Purpose)
 	 *
-	 * NOTE: We must have the hardware AND events initialized before we can
-	 * execute ANY control methods SAFELY.  Any control method can require
-	 * ACPI hardware support, so the hardware MUST be initialized before
-	 * execution!
+	 * Note1: We must have the hardware and events initialized before we can
+	 * execute any control methods safely. Any control method can require
+	 * ACPI hardware support, so the hardware must be fully initialized before
+	 * any method execution!
+	 *
+	 * Note2: Fixed events are initialized and enabled here. GPEs are
+	 * initialized, but cannot be enabled until after the hardware is
+	 * completely initialized (SCI and global_lock activated)
 	 */
 	if (!(flags & ACPI_NO_EVENT_INIT)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
@@ -193,8 +194,10 @@ acpi_status acpi_enable_subsystem(u32 fl
 		}
 	}
 
-	/* Install the SCI handler and Global Lock handler */
-
+	/*
+	 * Install the SCI handler and Global Lock handler. This completes the
+	 * hardware initialization.
+	 */
 	if (!(flags & ACPI_NO_HANDLER_INIT)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 				  "[Init] Installing SCI/GL handlers\n"));
@@ -205,6 +208,24 @@ acpi_status acpi_enable_subsystem(u32 fl
 		}
 	}
 
+	/*
+	 * Complete the GPE initialization for the GPE blocks defined in the FADT
+	 * (GPE block 0 and 1).
+	 *
+	 * Note1: This is where the _PRW methods are executed for the GPEs. These
+	 * methods can only be executed after the SCI and Global Lock handlers are
+	 * installed and initialized.
+	 *
+	 * Note2: Currently, there seems to be no need to run the _REG methods
+	 * before execution of the _PRW methods and enabling of the GPEs.
+	 */
+	if (!(flags & ACPI_NO_EVENT_INIT)) {
+		status = acpi_ev_install_fadt_gpes();
+		if (ACPI_FAILURE(status)) {
+			return (status);
+		}
+	}
+
 	return_ACPI_STATUS(status);
 }
 
@@ -230,9 +251,9 @@ acpi_status acpi_initialize_objects(u32 
 	/*
 	 * Run all _REG methods
 	 *
-	 * NOTE: Any objects accessed
-	 * by the _REG methods will be automatically initialized, even if they
-	 * contain executable AML (see call to acpi_ns_initialize_objects below).
+	 * Note: Any objects accessed by the _REG methods will be automatically
+	 * initialized, even if they contain executable AML (see the call to
+	 * acpi_ns_initialize_objects below).
 	 */
 	if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
@@ -245,9 +266,9 @@ acpi_status acpi_initialize_objects(u32 
 	}
 
 	/*
-	 * Initialize the objects that remain uninitialized.  This
-	 * runs the executable AML that may be part of the declaration of these
-	 * objects: operation_regions, buffer_fields, Buffers, and Packages.
+	 * Initialize the objects that remain uninitialized. This runs the
+	 * executable AML that may be part of the declaration of these objects:
+	 * operation_regions, buffer_fields, Buffers, and Packages.
 	 */
 	if (!(flags & ACPI_NO_OBJECT_INIT)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
@@ -260,8 +281,8 @@ acpi_status acpi_initialize_objects(u32 
 	}
 
 	/*
-	 * Initialize all device objects in the namespace
-	 * This runs the _STA and _INI methods.
+	 * Initialize all device objects in the namespace. This runs the device
+	 * _STA and _INI methods.
 	 */
 	if (!(flags & ACPI_NO_DEVICE_INIT)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index d10668f..bd48875 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -920,8 +920,8 @@ static int acpi_video_device_add_fs(stru
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 				  "Unable to create 'state' fs entry\n"));
 	else {
+		acpi_video_device_state_fops.write = acpi_video_device_write_state;
 		entry->proc_fops = &acpi_video_device_state_fops;
-		entry->proc_fops->write = acpi_video_device_write_state;
 		entry->data = acpi_driver_data(device);
 		entry->owner = THIS_MODULE;
 	}
@@ -934,8 +934,8 @@ static int acpi_video_device_add_fs(stru
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 				  "Unable to create 'brightness' fs entry\n"));
 	else {
+		acpi_video_device_brightness_fops.write = acpi_video_device_write_brightness;
 		entry->proc_fops = &acpi_video_device_brightness_fops;
-		entry->proc_fops->write = acpi_video_device_write_brightness;
 		entry->data = acpi_driver_data(device);
 		entry->owner = THIS_MODULE;
 	}
@@ -1239,8 +1239,8 @@ static int acpi_video_bus_add_fs(struct 
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 				  "Unable to create 'POST' fs entry\n"));
 	else {
+		acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST;
 		entry->proc_fops = &acpi_video_bus_POST_fops;
-		entry->proc_fops->write = acpi_video_bus_write_POST;
 		entry->data = acpi_driver_data(device);
 		entry->owner = THIS_MODULE;
 	}
@@ -1253,8 +1253,8 @@ static int acpi_video_bus_add_fs(struct 
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 				  "Unable to create 'DOS' fs entry\n"));
 	else {
+		acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS;
 		entry->proc_fops = &acpi_video_bus_DOS_fops;
-		entry->proc_fops->write = acpi_video_bus_write_DOS;
 		entry->data = acpi_driver_data(device);
 		entry->owner = THIS_MODULE;
 	}
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index a05fe58..f04d864 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -14,7 +14,6 @@
  *  -- special case some senses, e.g. 3a/0 -> no media present, reduce retries
  *  -- verify the 13 conditions and do bulk resets
  *  -- kill last_pipe and simply do two-state clearing on both pipes
- *  -- verify protocol (bulk) from USB descriptors (maybe...)
  *  -- highmem
  *  -- move top_sense and work_bcs into separate allocations (if they survive)
  *     for cache purists and esoteric architectures.
@@ -355,7 +354,7 @@ struct ub_lun {
  * The USB device instance.
  */
 struct ub_dev {
-	spinlock_t lock;
+	spinlock_t *lock;
 	atomic_t poison;		/* The USB device is disconnected */
 	int openc;			/* protected by ub_lock! */
 					/* kref is too implicit for our taste */
@@ -420,11 +419,13 @@ static void ub_state_sense(struct ub_dev
 static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
     int stalled_pipe);
 static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd);
-static void ub_reset_enter(struct ub_dev *sc);
+static void ub_reset_enter(struct ub_dev *sc, int try);
 static void ub_reset_task(void *arg);
 static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun);
 static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
     struct ub_capacity *ret);
+static int ub_sync_reset(struct ub_dev *sc);
+static int ub_probe_clear_stall(struct ub_dev *sc, int stalled_pipe);
 static int ub_probe_lun(struct ub_dev *sc, int lnum);
 
 /*
@@ -452,6 +453,10 @@ MODULE_DEVICE_TABLE(usb, ub_usb_ids);
 #define UB_MAX_HOSTS  26
 static char ub_hostv[UB_MAX_HOSTS];
 
+#define UB_QLOCK_NUM 5
+static spinlock_t ub_qlockv[UB_QLOCK_NUM];
+static int ub_qlock_next = 0;
+
 static DEFINE_SPINLOCK(ub_lock);	/* Locks globals and ->openc */
 
 /*
@@ -531,7 +536,7 @@ static ssize_t ub_diag_show(struct devic
 		return 0;
 
 	cnt = 0;
-	spin_lock_irqsave(&sc->lock, flags);
+	spin_lock_irqsave(sc->lock, flags);
 
 	cnt += sprintf(page + cnt,
 	    "poison %d reset %d\n",
@@ -579,7 +584,7 @@ static ssize_t ub_diag_show(struct devic
 		if (++nc == SCMD_TRACE_SZ) nc = 0;
 	}
 
-	spin_unlock_irqrestore(&sc->lock, flags);
+	spin_unlock_irqrestore(sc->lock, flags);
 	return cnt;
 }
 
@@ -627,6 +632,24 @@ static void ub_id_put(int id)
 }
 
 /*
+ * This is necessitated by the fact that blk_cleanup_queue does not
+ * necesserily destroy the queue. Instead, it may merely decrease q->refcnt.
+ * Since our blk_init_queue() passes a spinlock common with ub_dev,
+ * we have life time issues when ub_cleanup frees ub_dev.
+ */
+static spinlock_t *ub_next_lock(void)
+{
+	unsigned long flags;
+	spinlock_t *ret;
+
+	spin_lock_irqsave(&ub_lock, flags);
+	ret = &ub_qlockv[ub_qlock_next];
+	ub_qlock_next = (ub_qlock_next + 1) % UB_QLOCK_NUM;
+	spin_unlock_irqrestore(&ub_lock, flags);
+	return ret;
+}
+
+/*
  * Downcount for deallocation. This rides on two assumptions:
  *  - once something is poisoned, its refcount cannot grow
  *  - opens cannot happen at this time (del_gendisk was done)
@@ -961,7 +984,7 @@ static int ub_rw_cmd_retry(struct ub_dev
 	if (atomic_read(&sc->poison))
 		return -ENXIO;
 
-	ub_reset_enter(sc);
+	ub_reset_enter(sc, urq->current_try);
 
 	if (urq->current_try >= 3)
 		return -EIO;
@@ -997,8 +1020,6 @@ static int ub_rw_cmd_retry(struct ub_dev
  * No exceptions.
  *
  * Host is assumed locked.
- *
- * XXX We only support Bulk for the moment.
  */
 static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 {
@@ -1083,9 +1104,10 @@ static void ub_urb_timeout(unsigned long
 	struct ub_dev *sc = (struct ub_dev *) arg;
 	unsigned long flags;
 
-	spin_lock_irqsave(&sc->lock, flags);
-	usb_unlink_urb(&sc->work_urb);
-	spin_unlock_irqrestore(&sc->lock, flags);
+	spin_lock_irqsave(sc->lock, flags);
+	if (!ub_is_completed(&sc->work_done))
+		usb_unlink_urb(&sc->work_urb);
+	spin_unlock_irqrestore(sc->lock, flags);
 }
 
 /*
@@ -1108,10 +1130,9 @@ static void ub_scsi_action(unsigned long
 	struct ub_dev *sc = (struct ub_dev *) _dev;
 	unsigned long flags;
 
-	spin_lock_irqsave(&sc->lock, flags);
-	del_timer(&sc->work_timer);
+	spin_lock_irqsave(sc->lock, flags);
 	ub_scsi_dispatch(sc);
-	spin_unlock_irqrestore(&sc->lock, flags);
+	spin_unlock_irqrestore(sc->lock, flags);
 }
 
 static void ub_scsi_dispatch(struct ub_dev *sc)
@@ -1133,6 +1154,7 @@ static void ub_scsi_dispatch(struct ub_d
 		} else {
 			if (!ub_is_completed(&sc->work_done))
 				break;
+			del_timer(&sc->work_timer);
 			ub_scsi_urb_compl(sc, cmd);
 		}
 	}
@@ -1680,16 +1702,18 @@ static void ub_top_sense_done(struct ub_
 
 /*
  * Reset management
+ * XXX Move usb_reset_device to khubd. Hogging kevent is not a good thing.
+ * XXX Make usb_sync_reset asynchronous.
  */
 
-static void ub_reset_enter(struct ub_dev *sc)
+static void ub_reset_enter(struct ub_dev *sc, int try)
 {
 
 	if (sc->reset) {
 		/* This happens often on multi-LUN devices. */
 		return;
 	}
-	sc->reset = 1;
+	sc->reset = try + 1;
 
 #if 0 /* Not needed because the disconnect waits for us. */
 	unsigned long flags;
@@ -1727,6 +1751,11 @@ static void ub_reset_task(void *arg)
 	if (atomic_read(&sc->poison)) {
 		printk(KERN_NOTICE "%s: Not resetting disconnected device\n",
 		    sc->name); /* P3 This floods. Remove soon. XXX */
+	} else if ((sc->reset & 1) == 0) {
+		ub_sync_reset(sc);
+		msleep(700);	/* usb-storage sleeps 6s (!) */
+		ub_probe_clear_stall(sc, sc->recv_bulk_pipe);
+		ub_probe_clear_stall(sc, sc->send_bulk_pipe);
 	} else if (sc->dev->actconfig->desc.bNumInterfaces != 1) {
 		printk(KERN_NOTICE "%s: Not resetting multi-interface device\n",
 		    sc->name); /* P3 This floods. Remove soon. XXX */
@@ -1754,7 +1783,7 @@ static void ub_reset_task(void *arg)
 	 * queues of resets or anything. We do need a spinlock though,
 	 * to interact with block layer.
 	 */
-	spin_lock_irqsave(&sc->lock, flags);
+	spin_lock_irqsave(sc->lock, flags);
 	sc->reset = 0;
 	tasklet_schedule(&sc->tasklet);
 	list_for_each(p, &sc->luns) {
@@ -1762,7 +1791,7 @@ static void ub_reset_task(void *arg)
 		blk_start_queue(lun->disk->queue);
 	}
 	wake_up(&sc->reset_wait);
-	spin_unlock_irqrestore(&sc->lock, flags);
+	spin_unlock_irqrestore(sc->lock, flags);
 }
 
 /*
@@ -1990,11 +2019,11 @@ static int ub_sync_tur(struct ub_dev *sc
 	cmd->done = ub_probe_done;
 	cmd->back = &compl;
 
-	spin_lock_irqsave(&sc->lock, flags);
+	spin_lock_irqsave(sc->lock, flags);
 	cmd->tag = sc->tagcnt++;
 
 	rc = ub_submit_scsi(sc, cmd);
-	spin_unlock_irqrestore(&sc->lock, flags);
+	spin_unlock_irqrestore(sc->lock, flags);
 
 	if (rc != 0) {
 		printk("ub: testing ready: submit error (%d)\n", rc); /* P3 */
@@ -2052,11 +2081,11 @@ static int ub_sync_read_cap(struct ub_de
 	cmd->done = ub_probe_done;
 	cmd->back = &compl;
 
-	spin_lock_irqsave(&sc->lock, flags);
+	spin_lock_irqsave(sc->lock, flags);
 	cmd->tag = sc->tagcnt++;
 
 	rc = ub_submit_scsi(sc, cmd);
-	spin_unlock_irqrestore(&sc->lock, flags);
+	spin_unlock_irqrestore(sc->lock, flags);
 
 	if (rc != 0) {
 		printk("ub: reading capacity: submit error (%d)\n", rc); /* P3 */
@@ -2118,6 +2147,52 @@ static void ub_probe_timeout(unsigned lo
 }
 
 /*
+ * Reset with a Bulk reset.
+ */
+static int ub_sync_reset(struct ub_dev *sc)
+{
+	int ifnum = sc->intf->cur_altsetting->desc.bInterfaceNumber;
+	struct usb_ctrlrequest *cr;
+	struct completion compl;
+	struct timer_list timer;
+	int rc;
+
+	init_completion(&compl);
+
+	cr = &sc->work_cr;
+	cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
+	cr->bRequest = US_BULK_RESET_REQUEST;
+	cr->wValue = cpu_to_le16(0);
+	cr->wIndex = cpu_to_le16(ifnum);
+	cr->wLength = cpu_to_le16(0);
+
+	usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe,
+	    (unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl);
+	sc->work_urb.actual_length = 0;
+	sc->work_urb.error_count = 0;
+	sc->work_urb.status = 0;
+
+	if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) {
+		printk(KERN_WARNING
+		     "%s: Unable to submit a bulk reset (%d)\n", sc->name, rc);
+		return rc;
+	}
+
+	init_timer(&timer);
+	timer.function = ub_probe_timeout;
+	timer.data = (unsigned long) &compl;
+	timer.expires = jiffies + UB_CTRL_TIMEOUT;
+	add_timer(&timer);
+
+	wait_for_completion(&compl);
+
+	del_timer_sync(&timer);
+	usb_kill_urb(&sc->work_urb);
+
+	return sc->work_urb.status;
+}
+
+/*
  * Get number of LUNs by the way of Bulk GetMaxLUN command.
  */
 static int ub_sync_getmaxlun(struct ub_dev *sc)
@@ -2333,7 +2408,7 @@ static int ub_probe(struct usb_interface
 	if ((sc = kmalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL)
 		goto err_core;
 	memset(sc, 0, sizeof(struct ub_dev));
-	spin_lock_init(&sc->lock);
+	sc->lock = ub_next_lock();
 	INIT_LIST_HEAD(&sc->luns);
 	usb_init_urb(&sc->work_urb);
 	tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc);
@@ -2483,7 +2558,7 @@ static int ub_probe_lun(struct ub_dev *s
 	disk->driverfs_dev = &sc->intf->dev;
 
 	rc = -ENOMEM;
-	if ((q = blk_init_queue(ub_request_fn, &sc->lock)) == NULL)
+	if ((q = blk_init_queue(ub_request_fn, sc->lock)) == NULL)
 		goto err_blkqinit;
 
 	disk->queue = q;
@@ -2554,7 +2629,7 @@ static void ub_disconnect(struct usb_int
 	 * and the whole queue drains. So, we just use this code to
 	 * print warnings.
 	 */
-	spin_lock_irqsave(&sc->lock, flags);
+	spin_lock_irqsave(sc->lock, flags);
 	{
 		struct ub_scsi_cmd *cmd;
 		int cnt = 0;
@@ -2571,7 +2646,7 @@ static void ub_disconnect(struct usb_int
 			    "%d was queued after shutdown\n", sc->name, cnt);
 		}
 	}
-	spin_unlock_irqrestore(&sc->lock, flags);
+	spin_unlock_irqrestore(sc->lock, flags);
 
 	/*
 	 * Unregister the upper layer.
@@ -2590,19 +2665,15 @@ static void ub_disconnect(struct usb_int
 	}
 
 	/*
-	 * Taking a lock on a structure which is about to be freed
-	 * is very nonsensual. Here it is largely a way to do a debug freeze,
-	 * and a bracket which shows where the nonsensual code segment ends.
-	 *
 	 * Testing for -EINPROGRESS is always a bug, so we are bending
 	 * the rules a little.
 	 */
-	spin_lock_irqsave(&sc->lock, flags);
+	spin_lock_irqsave(sc->lock, flags);
 	if (sc->work_urb.status == -EINPROGRESS) {	/* janitors: ignore */
 		printk(KERN_WARNING "%s: "
 		    "URB is active after disconnect\n", sc->name);
 	}
-	spin_unlock_irqrestore(&sc->lock, flags);
+	spin_unlock_irqrestore(sc->lock, flags);
 
 	/*
 	 * There is virtually no chance that other CPU runs times so long
@@ -2636,6 +2707,10 @@ static struct usb_driver ub_driver = {
 static int __init ub_init(void)
 {
 	int rc;
+	int i;
+
+	for (i = 0; i < UB_QLOCK_NUM; i++)
+		spin_lock_init(&ub_qlockv[i]);
 
 	if ((rc = register_blkdev(UB_MAJOR, DRV_NAME)) != 0)
 		goto err_regblkdev;
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 4135d8c..4c67727 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -992,7 +992,7 @@ config HPET_MMAP
 
 config HANGCHECK_TIMER
 	tristate "Hangcheck timer"
-	depends on X86 || IA64 || PPC64 || S390
+	depends on X86 || IA64 || PPC64
 	help
 	  The hangcheck-timer module detects when the system has gone
 	  out to lunch past a certain margin.  It can reboot the system
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 810679d..9964c50 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -600,6 +600,26 @@ static void __devexit agp_amd64_remove(s
 	agp_put_bridge(bridge);
 }
 
+#ifdef CONFIG_PM
+
+static int agp_amd64_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	pci_save_state(pdev);
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+	return 0;
+}
+
+static int agp_amd64_resume(struct pci_dev *pdev)
+{
+	pci_set_power_state(pdev, PCI_D0);
+	pci_restore_state(pdev);
+
+	return amd_8151_configure();
+}
+
+#endif /* CONFIG_PM */
+
 static struct pci_device_id agp_amd64_pci_table[] = {
 	{
 	.class		= (PCI_CLASS_BRIDGE_HOST << 8),
@@ -718,6 +738,10 @@ static struct pci_driver agp_amd64_pci_d
 	.id_table	= agp_amd64_pci_table,
 	.probe		= agp_amd64_probe,
 	.remove		= agp_amd64_remove,
+#ifdef CONFIG_PM
+	.suspend	= agp_amd64_suspend,
+	.resume		= agp_amd64_resume,
+#endif
 };
 
 
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index 53372a8..5b74c36 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -244,6 +244,22 @@ static int ati_configure(void)
 }
 
 
+#ifdef CONFIG_PM
+static int agp_ati_resume(struct pci_dev *dev)
+{
+	pci_restore_state(dev);
+
+	return ati_configure();
+}
+
+static int agp_ati_suspend(struct pci_dev *dev, pm_message_t state)
+{
+	pci_save_state(dev);
+
+	return 0;
+}
+#endif
+
 /*
  *Since we don't need contigious memory we just try
  * to get the gatt table once
@@ -525,6 +541,10 @@ static struct pci_driver agp_ati_pci_dri
 	.id_table	= agp_ati_pci_table,
 	.probe		= agp_ati_probe,
 	.remove		= agp_ati_remove,
+#ifdef CONFIG_PM
+	.resume		= agp_ati_resume,
+	.suspend	= agp_ati_suspend,
+#endif
 };
 
 static int __init agp_ati_init(void)
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
index 17f520c..97eeb23 100644
--- a/drivers/char/agp/frontend.c
+++ b/drivers/char/agp/frontend.c
@@ -592,7 +592,7 @@ static int agp_mmap(struct file *file, s
 	struct agp_file_private *priv = file->private_data;
 	struct agp_kern_info kerninfo;
 
-	down(&(agp_fe.agp_mutex));
+	mutex_lock(&(agp_fe.agp_mutex));
 
 	if (agp_fe.backend_acquired != TRUE)
 		goto out_eperm;
@@ -627,7 +627,7 @@ static int agp_mmap(struct file *file, s
 					    size, vma->vm_page_prot)) {
 			goto out_again;
 		}
-		up(&(agp_fe.agp_mutex));
+		mutex_unlock(&(agp_fe.agp_mutex));
 		return 0;
 	}
 
@@ -643,20 +643,20 @@ static int agp_mmap(struct file *file, s
 					    size, vma->vm_page_prot)) {
 			goto out_again;
 		}
-		up(&(agp_fe.agp_mutex));
+		mutex_unlock(&(agp_fe.agp_mutex));
 		return 0;
 	}
 
 out_eperm:
-	up(&(agp_fe.agp_mutex));
+	mutex_unlock(&(agp_fe.agp_mutex));
 	return -EPERM;
 
 out_inval:
-	up(&(agp_fe.agp_mutex));
+	mutex_unlock(&(agp_fe.agp_mutex));
 	return -EINVAL;
 
 out_again:
-	up(&(agp_fe.agp_mutex));
+	mutex_unlock(&(agp_fe.agp_mutex));
 	return -EAGAIN;
 }
 
@@ -664,7 +664,7 @@ static int agp_release(struct inode *ino
 {
 	struct agp_file_private *priv = file->private_data;
 
-	down(&(agp_fe.agp_mutex));
+	mutex_lock(&(agp_fe.agp_mutex));
 
 	DBG("priv=%p", priv);
 
@@ -687,7 +687,7 @@ static int agp_release(struct inode *ino
 	agp_remove_file_private(priv);
 	kfree(priv);
 	file->private_data = NULL;
-	up(&(agp_fe.agp_mutex));
+	mutex_unlock(&(agp_fe.agp_mutex));
 	return 0;
 }
 
@@ -698,7 +698,7 @@ static int agp_open(struct inode *inode,
 	struct agp_client *client;
 	int rc = -ENXIO;
 
-	down(&(agp_fe.agp_mutex));
+	mutex_lock(&(agp_fe.agp_mutex));
 
 	if (minor != AGPGART_MINOR)
 		goto err_out;
@@ -723,13 +723,13 @@ static int agp_open(struct inode *inode,
 	file->private_data = (void *) priv;
 	agp_insert_file_private(priv);
 	DBG("private=%p, client=%p", priv, client);
-	up(&(agp_fe.agp_mutex));
+	mutex_unlock(&(agp_fe.agp_mutex));
 	return 0;
 
 err_out_nomem:
 	rc = -ENOMEM;
 err_out:
-	up(&(agp_fe.agp_mutex));
+	mutex_unlock(&(agp_fe.agp_mutex));
 	return rc;
 }
 
@@ -985,7 +985,7 @@ static int agp_ioctl(struct inode *inode
 	int ret_val = -ENOTTY;
 
 	DBG("priv=%p, cmd=%x", curr_priv, cmd);
-	down(&(agp_fe.agp_mutex));
+	mutex_lock(&(agp_fe.agp_mutex));
 
 	if ((agp_fe.current_controller == NULL) &&
 	    (cmd != AGPIOC_ACQUIRE)) {
@@ -1055,7 +1055,7 @@ static int agp_ioctl(struct inode *inode
 
 ioctl_out:
 	DBG("ioctl returns %d\n", ret_val);
-	up(&(agp_fe.agp_mutex));
+	mutex_unlock(&(agp_fe.agp_mutex));
 	return ret_val;
 }
 
@@ -1081,7 +1081,7 @@ static struct miscdevice agp_miscdev =
 int agp_frontend_initialize(void)
 {
 	memset(&agp_fe, 0, sizeof(struct agp_front_data));
-	sema_init(&(agp_fe.agp_mutex), 1);
+	mutex_init(&(agp_fe.agp_mutex));
 
 	if (misc_register(&agp_miscdev)) {
 		printk(KERN_ERR PFX "unable to get minor: %d\n", AGPGART_MINOR);
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index e7bed50..631531f 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -422,7 +422,8 @@ static void intel_i830_init_gtt_entries(
 			/* Check it's really I915G */
 			if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
 			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
-			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB)
+			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
+			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB)
 				gtt_entries = MB(48) - KB(size);
 			else
 				gtt_entries = 0;
@@ -431,7 +432,8 @@ static void intel_i830_init_gtt_entries(
 			/* Check it's really I915G */
 			if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
 			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
-			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB)
+			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
+			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB)
 				gtt_entries = MB(64) - KB(size);
 			else
 				gtt_entries = 0;
@@ -1681,6 +1683,14 @@ static int __devinit agp_intel_probe(str
 		}
 		name = "945G";
 		break;
+	case PCI_DEVICE_ID_INTEL_82945GM_HB:
+		if (find_i830(PCI_DEVICE_ID_INTEL_82945GM_IG)) {
+			bridge->driver = &intel_915_driver;
+		} else {
+			bridge->driver = &intel_845_driver;
+		}
+		name = "945GM";
+		break;
 	case PCI_DEVICE_ID_INTEL_7505_0:
 		bridge->driver = &intel_7505_driver;
 		name = "E7505";
@@ -1821,6 +1831,7 @@ static struct pci_device_id agp_intel_pc
 	ID(PCI_DEVICE_ID_INTEL_82915G_HB),
 	ID(PCI_DEVICE_ID_INTEL_82915GM_HB),
 	ID(PCI_DEVICE_ID_INTEL_82945G_HB),
+	ID(PCI_DEVICE_ID_INTEL_82945GM_HB),
 	{ }
 };
 
diff --git a/drivers/char/agp/isoch.c b/drivers/char/agp/isoch.c
index 4008324..7c14a09 100644
--- a/drivers/char/agp/isoch.c
+++ b/drivers/char/agp/isoch.c
@@ -218,10 +218,8 @@ static int agp_3_5_isochronous_node_enab
 			master[cdev].rq *= (1 << (master[cdev].y - 1));
 
 		tot_rq += master[cdev].rq;
-
-		if (cdev == ndevs-1)
-			master[cdev].n += rem;
 	}
+	master[ndevs-1].n += rem;
 
 	/* Figure the number of isochronous and asynchronous RQ slots the
 	 * target is providing. */
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c
index 40a67c8..ac62641 100644
--- a/drivers/char/hangcheck-timer.c
+++ b/drivers/char/hangcheck-timer.c
@@ -117,12 +117,9 @@ __setup("hcheck_reboot", hangcheck_parse
 __setup("hcheck_dump_tasks", hangcheck_parse_dump_tasks);
 #endif /* not MODULE */
 
-#if defined(CONFIG_X86)
+#if defined(CONFIG_X86) || defined(CONFIG_S390)
 # define HAVE_MONOTONIC
 # define TIMER_FREQ 1000000000ULL
-#elif defined(CONFIG_S390)
-/* FA240000 is 1 Second in the IBM time universe (Page 4-38 Principles of Op for zSeries */
-# define TIMER_FREQ 0xFA240000ULL
 #elif defined(CONFIG_IA64)
 # define TIMER_FREQ ((unsigned long long)local_cpu_data->itc_freq)
 #elif defined(CONFIG_PPC64)
@@ -134,12 +131,7 @@ extern unsigned long long monotonic_cloc
 #else
 static inline unsigned long long monotonic_clock(void)
 {
-# ifdef __s390__
-	/* returns the TOD.  see 4-38 Principles of Op of zSeries */
-	return get_clock();
-# else
 	return get_cycles();
-# endif  /* __s390__ */
 }
 #endif  /* HAVE_MONOTONIC */
 
@@ -188,8 +180,6 @@ static int __init hangcheck_init(void)
 	       VERSION_STR, hangcheck_tick, hangcheck_margin);
 #if defined (HAVE_MONOTONIC)
 	printk("Hangcheck: Using monotonic_clock().\n");
-#elif defined(__s390__)
-	printk("Hangcheck: Using TOD.\n");
 #else
 	printk("Hangcheck: Using get_cycles().\n");
 #endif  /* HAVE_MONOTONIC */
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 3808d95..66a2fee 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -927,9 +927,9 @@ static acpi_status hpet_resources(struct
 	if (ACPI_SUCCESS(status)) {
 		unsigned long size;
 
-		size = addr.max_address_range - addr.min_address_range + 1;
-		hdp->hd_phys_address = addr.min_address_range;
-		hdp->hd_address = ioremap(addr.min_address_range, size);
+		size = addr.maximum - addr.minimum + 1;
+		hdp->hd_phys_address = addr.minimum;
+		hdp->hd_address = ioremap(addr.minimum, size);
 
 		if (hpet_is_known(hdp)) {
 			printk(KERN_DEBUG "%s: 0x%lx is busy\n",
@@ -937,15 +937,15 @@ static acpi_status hpet_resources(struct
 			iounmap(hdp->hd_address);
 			return -EBUSY;
 		}
-	} else if (res->id == ACPI_RSTYPE_FIXED_MEM32) {
-		struct acpi_resource_fixed_mem32 *fixmem32;
+	} else if (res->type == ACPI_RESOURCE_TYPE_FIXED_MEMORY32) {
+		struct acpi_resource_fixed_memory32 *fixmem32;
 
 		fixmem32 = &res->data.fixed_memory32;
 		if (!fixmem32)
 			return -EINVAL;
 
-		hdp->hd_phys_address = fixmem32->range_base_address;
-		hdp->hd_address = ioremap(fixmem32->range_base_address,
+		hdp->hd_phys_address = fixmem32->address;
+		hdp->hd_address = ioremap(fixmem32->address,
 						HPET_RANGE_SIZE);
 
 		if (hpet_is_known(hdp)) {
@@ -954,20 +954,20 @@ static acpi_status hpet_resources(struct
 			iounmap(hdp->hd_address);
 			return -EBUSY;
 		}
-	} else if (res->id == ACPI_RSTYPE_EXT_IRQ) {
-		struct acpi_resource_ext_irq *irqp;
+	} else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) {
+		struct acpi_resource_extended_irq *irqp;
 		int i;
 
 		irqp = &res->data.extended_irq;
 
-		if (irqp->number_of_interrupts > 0) {
-			hdp->hd_nirqs = irqp->number_of_interrupts;
+		if (irqp->interrupt_count > 0) {
+			hdp->hd_nirqs = irqp->interrupt_count;
 
 			for (i = 0; i < hdp->hd_nirqs; i++) {
 				int rc =
 				    acpi_register_gsi(irqp->interrupts[i],
-						      irqp->edge_level,
-						      irqp->active_high_low);
+						      irqp->triggering,
+						      irqp->polarity);
 				if (rc < 0)
 					return AE_ERROR;
 				hdp->hd_irq[i] = rc;
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index c67ef3e..6ed213b 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -1580,11 +1580,6 @@ static int try_init_acpi(int intf_num, s
 	if (! is_new_interface(-1, addr_space, spmi->addr.address))
 		return -ENODEV;
 
-	if (! spmi->addr.register_bit_width) {
-		acpi_failure = 1;
-		return -ENODEV;
-	}
-
 	/* Figure out the interface type. */
 	switch (spmi->InterfaceType)
 	{
@@ -1634,9 +1629,6 @@ static int try_init_acpi(int intf_num, s
 		regspacings[intf_num] = spmi->addr.register_bit_width / 8;
 		info->io.regspacing = spmi->addr.register_bit_width / 8;
 	} else {
-		/* Some broken systems get this wrong and set the value
-		 * to zero.  Assume it is the default spacing.  If that
-		 * is wrong, too bad, the vendor should fix the tables. */
 		regspacings[intf_num] = DEFAULT_REGSPACING;
 		info->io.regspacing = DEFAULT_REGSPACING;
 	}
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 07c9be6..a85a60a 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -2630,7 +2630,7 @@ static int get_interface(struct slgt_inf
 static int set_interface(struct slgt_info *info, int if_mode)
 {
  	unsigned long flags;
-	unsigned char val;
+	unsigned short val;
 
 	DBGINFO(("%s set_interface=%x)\n", info->device_name, if_mode));
 	spin_lock_irqsave(&info->lock,flags);
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c
index bc56df8..4c27218 100644
--- a/drivers/char/tlclk.c
+++ b/drivers/char/tlclk.c
@@ -34,7 +34,6 @@
 #include <linux/kernel.h>	/* printk() */
 #include <linux/fs.h>		/* everything... */
 #include <linux/errno.h>	/* error codes */
-#include <linux/delay.h>	/* udelay */
 #include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
@@ -156,6 +155,8 @@ This directory exports the following int
 documented in the MCPBL0010 TPS under the Telecom Clock API section, 11.4.
 alarms				:
 current_ref			:
+received_ref_clk3a		:
+received_ref_clk3b		:
 enable_clk3a_output		:
 enable_clk3b_output		:
 enable_clka0_output		:
@@ -165,7 +166,7 @@ enable_clkb1_output		:
 filter_select			:
 hardware_switching		:
 hardware_switching_mode		:
-interrupt_switch		:
+telclock_version		:
 mode_select			:
 refalign			:
 reset				:
@@ -173,7 +174,6 @@ select_amcb1_transmit_clock	:
 select_amcb2_transmit_clock	:
 select_redundant_clock		:
 select_ref_frequency		:
-test_mode			:
 
 All sysfs interfaces are integers in hex format, i.e echo 99 > refalign
 has the same effect as echo 0x99 > refalign.
@@ -226,7 +226,7 @@ static int tlclk_release(struct inode *i
 	return 0;
 }
 
-ssize_t tlclk_read(struct file *filp, char __user *buf, size_t count,
+static ssize_t tlclk_read(struct file *filp, char __user *buf, size_t count,
 		loff_t *f_pos)
 {
 	if (count < sizeof(struct tlclk_alarms))
@@ -242,7 +242,7 @@ ssize_t tlclk_read(struct file *filp, ch
 	return  sizeof(struct tlclk_alarms);
 }
 
-ssize_t tlclk_write(struct file *filp, const char __user *buf, size_t count,
+static ssize_t tlclk_write(struct file *filp, const char __user *buf, size_t count,
 	    loff_t *f_pos)
 {
 	return 0;
@@ -278,21 +278,21 @@ static ssize_t show_current_ref(struct d
 static DEVICE_ATTR(current_ref, S_IRUGO, show_current_ref, NULL);
 
 
-static ssize_t show_interrupt_switch(struct device *d,
+static ssize_t show_telclock_version(struct device *d,
 		struct device_attribute *attr, char *buf)
 {
 	unsigned long ret_val;
 	unsigned long flags;
 
 	spin_lock_irqsave(&event_lock, flags);
-	ret_val = inb(TLCLK_REG6);
+	ret_val = inb(TLCLK_REG5);
 	spin_unlock_irqrestore(&event_lock, flags);
 
 	return sprintf(buf, "0x%lX\n", ret_val);
 }
 
-static DEVICE_ATTR(interrupt_switch, S_IRUGO,
-		show_interrupt_switch, NULL);
+static DEVICE_ATTR(telclock_version, S_IRUGO,
+		show_telclock_version, NULL);
 
 static ssize_t show_alarms(struct device *d,
 		struct device_attribute *attr,  char *buf)
@@ -309,6 +309,50 @@ static ssize_t show_alarms(struct device
 
 static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
 
+static ssize_t store_received_ref_clk3a(struct device *d,
+		 struct device_attribute *attr, const char *buf, size_t count)
+{
+	unsigned long tmp;
+	unsigned char val;
+	unsigned long flags;
+
+	sscanf(buf, "%lX", &tmp);
+	dev_dbg(d, ": tmp = 0x%lX\n", tmp);
+
+	val = (unsigned char)tmp;
+	spin_lock_irqsave(&event_lock, flags);
+	SET_PORT_BITS(TLCLK_REG1, 0xef, val);
+	spin_unlock_irqrestore(&event_lock, flags);
+
+	return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(received_ref_clk3a, S_IWUGO, NULL,
+		store_received_ref_clk3a);
+
+
+static ssize_t store_received_ref_clk3b(struct device *d,
+		 struct device_attribute *attr, const char *buf, size_t count)
+{
+	unsigned long tmp;
+	unsigned char val;
+	unsigned long flags;
+
+	sscanf(buf, "%lX", &tmp);
+	dev_dbg(d, ": tmp = 0x%lX\n", tmp);
+
+	val = (unsigned char)tmp;
+	spin_lock_irqsave(&event_lock, flags);
+	SET_PORT_BITS(TLCLK_REG1, 0xef, val << 1);
+	spin_unlock_irqrestore(&event_lock, flags);
+
+	return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(received_ref_clk3b, S_IWUGO, NULL,
+		store_received_ref_clk3b);
+
+
 static ssize_t store_enable_clk3b_output(struct device *d,
 		 struct device_attribute *attr, const char *buf, size_t count)
 {
@@ -436,26 +480,6 @@ static ssize_t store_enable_clka0_output
 static DEVICE_ATTR(enable_clka0_output, S_IWUGO, NULL,
 		store_enable_clka0_output);
 
-static ssize_t store_test_mode(struct device *d,
-		struct device_attribute *attr,  const char *buf, size_t count)
-{
-	unsigned long flags;
-	unsigned long tmp;
-	unsigned char val;
-
-	sscanf(buf, "%lX", &tmp);
-	dev_dbg(d, "tmp = 0x%lX\n", tmp);
-
-	val = (unsigned char)tmp;
-	spin_lock_irqsave(&event_lock, flags);
-	SET_PORT_BITS(TLCLK_REG4, 0xfd, 2);
-	spin_unlock_irqrestore(&event_lock, flags);
-
-	return strnlen(buf, count);
-}
-
-static DEVICE_ATTR(test_mode, S_IWUGO, NULL, store_test_mode);
-
 static ssize_t store_select_amcb2_transmit_clock(struct device *d,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
@@ -475,7 +499,7 @@ static ssize_t store_select_amcb2_transm
 			SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x38);
 			switch (val) {
 			case CLK_8_592MHz:
-				SET_PORT_BITS(TLCLK_REG0, 0xfc, 1);
+				SET_PORT_BITS(TLCLK_REG0, 0xfc, 2);
 				break;
 			case CLK_11_184MHz:
 				SET_PORT_BITS(TLCLK_REG0, 0xfc, 0);
@@ -484,7 +508,7 @@ static ssize_t store_select_amcb2_transm
 				SET_PORT_BITS(TLCLK_REG0, 0xfc, 3);
 				break;
 			case CLK_44_736MHz:
-				SET_PORT_BITS(TLCLK_REG0, 0xfc, 2);
+				SET_PORT_BITS(TLCLK_REG0, 0xfc, 1);
 				break;
 			}
 		} else
@@ -653,9 +677,7 @@ static ssize_t store_refalign (struct de
 	dev_dbg(d, "tmp = 0x%lX\n", tmp);
 	spin_lock_irqsave(&event_lock, flags);
 	SET_PORT_BITS(TLCLK_REG0, 0xf7, 0);
-	udelay(2);
 	SET_PORT_BITS(TLCLK_REG0, 0xf7, 0x08);
-	udelay(2);
 	SET_PORT_BITS(TLCLK_REG0, 0xf7, 0);
 	spin_unlock_irqrestore(&event_lock, flags);
 
@@ -706,15 +728,16 @@ static DEVICE_ATTR(reset, S_IWUGO, NULL,
 
 static struct attribute *tlclk_sysfs_entries[] = {
 	&dev_attr_current_ref.attr,
-	&dev_attr_interrupt_switch.attr,
+	&dev_attr_telclock_version.attr,
 	&dev_attr_alarms.attr,
+	&dev_attr_received_ref_clk3a.attr,
+	&dev_attr_received_ref_clk3b.attr,
 	&dev_attr_enable_clk3a_output.attr,
 	&dev_attr_enable_clk3b_output.attr,
 	&dev_attr_enable_clkb1_output.attr,
 	&dev_attr_enable_clka1_output.attr,
 	&dev_attr_enable_clkb0_output.attr,
 	&dev_attr_enable_clka0_output.attr,
-	&dev_attr_test_mode.attr,
 	&dev_attr_select_amcb1_transmit_clock.attr,
 	&dev_attr_select_amcb2_transmit_clock.attr,
 	&dev_attr_select_redundant_clock.attr,
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c
index aedf7a8..537aa45 100644
--- a/drivers/char/tpm/tpm_bios.c
+++ b/drivers/char/tpm/tpm_bios.c
@@ -191,7 +191,7 @@ static int get_event_name(char *dest, st
 	const char *name = "";
 	char data[40] = "";
 	int i, n_len = 0, d_len = 0;
-	u32 event_id, event_data_size;
+	u32 event_id;
 
 	switch(event->event_type) {
 	case PREBOOT:
@@ -220,8 +220,7 @@ static int get_event_name(char *dest, st
 		}
 		break;
 	case EVENT_TAG:
-		event_id = be32_to_cpu(event_entry);
-		event_data_size = be32_to_cpu(&event_entry[4]);
+		event_id = be32_to_cpu(*((u32 *)event_entry));
 
 		/* ToDo Row data -> Base64 */
 
@@ -376,7 +375,7 @@ static int read_log(struct tpm_bios_log 
 {
 	struct acpi_tcpa *buff;
 	acpi_status status;
-	void *virt;
+	struct acpi_table_header *virt;
 
 	if (log->bios_event_log != NULL) {
 		printk(KERN_ERR
@@ -413,7 +412,7 @@ static int read_log(struct tpm_bios_log 
 
 	log->bios_event_log_end = log->bios_event_log + buff->log_max_len;
 
-	acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, &virt);
+	acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, (void *) &virt);
 
 	memcpy(log->bios_event_log, virt, buff->log_max_len);
 
@@ -487,26 +486,35 @@ struct file_operations tpm_binary_bios_m
 	.release = tpm_bios_measurements_release,
 };
 
+static int is_bad(void *p)
+{
+	if (!p)
+		return 1;
+	if (IS_ERR(p) && (PTR_ERR(p) != -ENODEV))
+		return 1;
+	return 0;
+}
+
 struct dentry **tpm_bios_log_setup(char *name)
 {
 	struct dentry **ret = NULL, *tpm_dir, *bin_file, *ascii_file;
 
 	tpm_dir = securityfs_create_dir(name, NULL);
-	if (!tpm_dir)
+	if (is_bad(tpm_dir))
 		goto out;
 
 	bin_file =
 	    securityfs_create_file("binary_bios_measurements",
 				   S_IRUSR | S_IRGRP, tpm_dir, NULL,
 				   &tpm_binary_bios_measurements_ops);
-	if (!bin_file)
+	if (is_bad(bin_file))
 		goto out_tpm;
 
 	ascii_file =
 	    securityfs_create_file("ascii_bios_measurements",
 				   S_IRUSR | S_IRGRP, tpm_dir, NULL,
 				   &tpm_ascii_bios_measurements_ops);
-	if (!ascii_file)
+	if (is_bad(ascii_file))
 		goto out_bin;
 
 	ret = kmalloc(3 * sizeof(struct dentry *), GFP_KERNEL);
@@ -538,3 +546,4 @@ void tpm_bios_log_teardown(struct dentry
 		securityfs_remove(lst[i]);
 }
 EXPORT_SYMBOL_GPL(tpm_bios_log_teardown);
+MODULE_LICENSE("GPL");
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
index 8198dbb..ec75909 100644
--- a/drivers/char/tpm/tpm_infineon.c
+++ b/drivers/char/tpm/tpm_infineon.c
@@ -441,7 +441,7 @@ static int __devinit tpm_inf_pnp_probe(s
 
 		if ((ioh << 8 | iol) != tpm_inf.base) {
 			dev_err(&dev->dev,
-				"Could not set IO-ports to %04x\n",
+				"Could not set IO-ports to 0x%lx\n",
 				tpm_inf.base);
 			release_region(tpm_inf.base, TPM_INF_PORT_LEN);
 			return -EIO;
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index f1d9cb7..0900d1d 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -3213,6 +3213,7 @@ void getconsxy(struct vc_data *vc, unsig
 
 void putconsxy(struct vc_data *vc, unsigned char *p)
 {
+	hide_cursor(vc);
 	gotoxy(vc, p[0], p[1]);
 	set_cursor(vc);
 }
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 277a843..7a51147 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -26,6 +26,7 @@
 #include <linux/slab.h>
 #include <linux/cpu.h>
 #include <linux/completion.h>
+#include <linux/mutex.h>
 
 #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, "cpufreq-core", msg)
 
@@ -55,7 +56,7 @@ static DECLARE_RWSEM		(cpufreq_notifier_
 
 
 static LIST_HEAD(cpufreq_governor_list);
-static DECLARE_MUTEX		(cpufreq_governor_sem);
+static DEFINE_MUTEX		(cpufreq_governor_mutex);
 
 struct cpufreq_policy * cpufreq_cpu_get(unsigned int cpu)
 {
@@ -297,18 +298,18 @@ static int cpufreq_parse_governor (char 
 		return -EINVAL;
 	} else {
 		struct cpufreq_governor *t;
-		down(&cpufreq_governor_sem);
+		mutex_lock(&cpufreq_governor_mutex);
 		if (!cpufreq_driver || !cpufreq_driver->target)
 			goto out;
 		list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
 			if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN)) {
 				*governor = t;
-				up(&cpufreq_governor_sem);
+				mutex_unlock(&cpufreq_governor_mutex);
 				return 0;
 			}
 		}
 	out:
-		up(&cpufreq_governor_sem);
+		mutex_unlock(&cpufreq_governor_mutex);
 	}
 	return -EINVAL;
 }
@@ -600,7 +601,8 @@ static int cpufreq_add_dev (struct sys_d
 	policy->cpu = cpu;
 	policy->cpus = cpumask_of_cpu(cpu);
 
-	init_MUTEX_LOCKED(&policy->lock);
+	mutex_init(&policy->lock);
+	mutex_lock(&policy->lock);
 	init_completion(&policy->kobj_unregister);
 	INIT_WORK(&policy->update, handle_update, (void *)(long)cpu);
 
@@ -610,6 +612,7 @@ static int cpufreq_add_dev (struct sys_d
 	ret = cpufreq_driver->init(policy);
 	if (ret) {
 		dprintk("initialization failed\n");
+		mutex_unlock(&policy->lock);
 		goto err_out;
 	}
 
@@ -621,9 +624,10 @@ static int cpufreq_add_dev (struct sys_d
 	strlcpy(policy->kobj.name, "cpufreq", KOBJ_NAME_LEN);
 
 	ret = kobject_register(&policy->kobj);
-	if (ret)
+	if (ret) {
+		mutex_unlock(&policy->lock);
 		goto err_out_driver_exit;
-
+	}
 	/* set up files for this cpu device */
 	drv_attr = cpufreq_driver->attr;
 	while ((drv_attr) && (*drv_attr)) {
@@ -641,7 +645,7 @@ static int cpufreq_add_dev (struct sys_d
 	spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
 	policy->governor = NULL; /* to assure that the starting sequence is
 				  * run in cpufreq_set_policy */
-	up(&policy->lock);
+	mutex_unlock(&policy->lock);
 	
 	/* set default policy */
 	
@@ -762,10 +766,10 @@ static int cpufreq_remove_dev (struct sy
 	spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
 #endif
 
-	down(&data->lock);
+	mutex_lock(&data->lock);
 	if (cpufreq_driver->target)
 		__cpufreq_governor(data, CPUFREQ_GOV_STOP);
-	up(&data->lock);
+	mutex_unlock(&data->lock);
 
 	kobject_unregister(&data->kobj);
 
@@ -834,9 +838,9 @@ unsigned int cpufreq_quick_get(unsigned 
 	unsigned int ret = 0;
 
 	if (policy) {
-		down(&policy->lock);
+		mutex_lock(&policy->lock);
 		ret = policy->cur;
-		up(&policy->lock);
+		mutex_unlock(&policy->lock);
 		cpufreq_cpu_put(policy);
 	}
 
@@ -862,7 +866,7 @@ unsigned int cpufreq_get(unsigned int cp
 	if (!cpufreq_driver->get)
 		goto out;
 
-	down(&policy->lock);
+	mutex_lock(&policy->lock);
 
 	ret = cpufreq_driver->get(cpu);
 
@@ -875,7 +879,7 @@ unsigned int cpufreq_get(unsigned int cp
 		}
 	}
 
-	up(&policy->lock);
+	mutex_unlock(&policy->lock);
 
  out:
 	cpufreq_cpu_put(policy);
@@ -1158,11 +1162,11 @@ int cpufreq_driver_target(struct cpufreq
 	if (!policy)
 		return -EINVAL;
 
-	down(&policy->lock);
+	mutex_lock(&policy->lock);
 
 	ret = __cpufreq_driver_target(policy, target_freq, relation);
 
-	up(&policy->lock);
+	mutex_unlock(&policy->lock);
 
 	cpufreq_cpu_put(policy);
 
@@ -1199,9 +1203,9 @@ int cpufreq_governor(unsigned int cpu, u
 	if (!policy)
 		return -EINVAL;
 
-	down(&policy->lock);
+	mutex_lock(&policy->lock);
 	ret = __cpufreq_governor(policy, event);
-	up(&policy->lock);
+	mutex_unlock(&policy->lock);
 
 	cpufreq_cpu_put(policy);
 
@@ -1217,17 +1221,17 @@ int cpufreq_register_governor(struct cpu
 	if (!governor)
 		return -EINVAL;
 
-	down(&cpufreq_governor_sem);
+	mutex_lock(&cpufreq_governor_mutex);
 	
 	list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
 		if (!strnicmp(governor->name,t->name,CPUFREQ_NAME_LEN)) {
-			up(&cpufreq_governor_sem);
+			mutex_unlock(&cpufreq_governor_mutex);
 			return -EBUSY;
 		}
 	}
 	list_add(&governor->governor_list, &cpufreq_governor_list);
 
- 	up(&cpufreq_governor_sem);
+ 	mutex_unlock(&cpufreq_governor_mutex);
 
 	return 0;
 }
@@ -1239,9 +1243,9 @@ void cpufreq_unregister_governor(struct 
 	if (!governor)
 		return;
 
-	down(&cpufreq_governor_sem);
+	mutex_lock(&cpufreq_governor_mutex);
 	list_del(&governor->governor_list);
-	up(&cpufreq_governor_sem);
+	mutex_unlock(&cpufreq_governor_mutex);
 	return;
 }
 EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
@@ -1268,9 +1272,9 @@ int cpufreq_get_policy(struct cpufreq_po
 	if (!cpu_policy)
 		return -EINVAL;
 
-	down(&cpu_policy->lock);
+	mutex_lock(&cpu_policy->lock);
 	memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
-	up(&cpu_policy->lock);
+	mutex_unlock(&cpu_policy->lock);
 
 	cpufreq_cpu_put(cpu_policy);
 
@@ -1382,7 +1386,7 @@ int cpufreq_set_policy(struct cpufreq_po
 		return -EINVAL;
 
 	/* lock this CPU */
-	down(&data->lock);
+	mutex_lock(&data->lock);
 
 	ret = __cpufreq_set_policy(data, policy);
 	data->user_policy.min = data->min;
@@ -1390,7 +1394,7 @@ int cpufreq_set_policy(struct cpufreq_po
 	data->user_policy.policy = data->policy;
 	data->user_policy.governor = data->governor;
 
-	up(&data->lock);
+	mutex_unlock(&data->lock);
 	cpufreq_cpu_put(data);
 
 	return ret;
@@ -1414,7 +1418,7 @@ int cpufreq_update_policy(unsigned int c
 	if (!data)
 		return -ENODEV;
 
-	down(&data->lock);
+	mutex_lock(&data->lock);
 
 	dprintk("updating policy for CPU %u\n", cpu);
 	memcpy(&policy, 
@@ -1425,9 +1429,17 @@ int cpufreq_update_policy(unsigned int c
 	policy.policy = data->user_policy.policy;
 	policy.governor = data->user_policy.governor;
 
+	/* BIOS might change freq behind our back
+	  -> ask driver for current freq and notify governors about a change */
+	if (cpufreq_driver->get) {
+		policy.cur = cpufreq_driver->get(cpu);
+		if (data->cur != policy.cur)
+			cpufreq_out_of_sync(cpu, data->cur, policy.cur);
+	}
+
 	ret = __cpufreq_set_policy(data, &policy);
 
-	up(&data->lock);
+	mutex_unlock(&data->lock);
 
 	cpufreq_cpu_put(data);
 	return ret;
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index 39543a2..ac38766 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -28,7 +28,7 @@
 #include <linux/jiffies.h>
 #include <linux/kernel_stat.h>
 #include <linux/percpu.h>
-
+#include <linux/mutex.h>
 /*
  * dbs is used in this file as a shortform for demandbased switching
  * It helps to keep variable names smaller, simpler
@@ -71,7 +71,7 @@ static DEFINE_PER_CPU(struct cpu_dbs_inf
 
 static unsigned int dbs_enable;	/* number of CPUs using this policy */
 
-static DECLARE_MUTEX 	(dbs_sem);
+static DEFINE_MUTEX 	(dbs_mutex);
 static DECLARE_WORK	(dbs_work, do_dbs_timer, NULL);
 
 struct dbs_tuners {
@@ -139,9 +139,9 @@ static ssize_t store_sampling_down_facto
 	if (ret != 1 )
 		return -EINVAL;
 
-	down(&dbs_sem);
+	mutex_lock(&dbs_mutex);
 	dbs_tuners_ins.sampling_down_factor = input;
-	up(&dbs_sem);
+	mutex_unlock(&dbs_mutex);
 
 	return count;
 }
@@ -153,14 +153,14 @@ static ssize_t store_sampling_rate(struc
 	int ret;
 	ret = sscanf (buf, "%u", &input);
 
-	down(&dbs_sem);
+	mutex_lock(&dbs_mutex);
 	if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE) {
-		up(&dbs_sem);
+		mutex_unlock(&dbs_mutex);
 		return -EINVAL;
 	}
 
 	dbs_tuners_ins.sampling_rate = input;
-	up(&dbs_sem);
+	mutex_unlock(&dbs_mutex);
 
 	return count;
 }
@@ -172,16 +172,16 @@ static ssize_t store_up_threshold(struct
 	int ret;
 	ret = sscanf (buf, "%u", &input);
 
-	down(&dbs_sem);
+	mutex_lock(&dbs_mutex);
 	if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || 
 			input < MIN_FREQUENCY_UP_THRESHOLD ||
 			input <= dbs_tuners_ins.down_threshold) {
-		up(&dbs_sem);
+		mutex_unlock(&dbs_mutex);
 		return -EINVAL;
 	}
 
 	dbs_tuners_ins.up_threshold = input;
-	up(&dbs_sem);
+	mutex_unlock(&dbs_mutex);
 
 	return count;
 }
@@ -193,16 +193,16 @@ static ssize_t store_down_threshold(stru
 	int ret;
 	ret = sscanf (buf, "%u", &input);
 
-	down(&dbs_sem);
+	mutex_lock(&dbs_mutex);
 	if (ret != 1 || input > MAX_FREQUENCY_DOWN_THRESHOLD || 
 			input < MIN_FREQUENCY_DOWN_THRESHOLD ||
 			input >= dbs_tuners_ins.up_threshold) {
-		up(&dbs_sem);
+		mutex_unlock(&dbs_mutex);
 		return -EINVAL;
 	}
 
 	dbs_tuners_ins.down_threshold = input;
-	up(&dbs_sem);
+	mutex_unlock(&dbs_mutex);
 
 	return count;
 }
@@ -222,9 +222,9 @@ static ssize_t store_ignore_nice_load(st
 	if ( input > 1 )
 		input = 1;
 	
-	down(&dbs_sem);
+	mutex_lock(&dbs_mutex);
 	if ( input == dbs_tuners_ins.ignore_nice ) { /* nothing to do */
-		up(&dbs_sem);
+		mutex_unlock(&dbs_mutex);
 		return count;
 	}
 	dbs_tuners_ins.ignore_nice = input;
@@ -236,7 +236,7 @@ static ssize_t store_ignore_nice_load(st
 		j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j);
 		j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up;
 	}
-	up(&dbs_sem);
+	mutex_unlock(&dbs_mutex);
 
 	return count;
 }
@@ -257,9 +257,9 @@ static ssize_t store_freq_step(struct cp
 	
 	/* no need to test here if freq_step is zero as the user might actually
 	 * want this, they would be crazy though :) */
-	down(&dbs_sem);
+	mutex_lock(&dbs_mutex);
 	dbs_tuners_ins.freq_step = input;
-	up(&dbs_sem);
+	mutex_unlock(&dbs_mutex);
 
 	return count;
 }
@@ -444,12 +444,12 @@ static void dbs_check_cpu(int cpu)
 static void do_dbs_timer(void *data)
 { 
 	int i;
-	down(&dbs_sem);
+	mutex_lock(&dbs_mutex);
 	for_each_online_cpu(i)
 		dbs_check_cpu(i);
 	schedule_delayed_work(&dbs_work, 
 			usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
-	up(&dbs_sem);
+	mutex_unlock(&dbs_mutex);
 } 
 
 static inline void dbs_timer_init(void)
@@ -487,7 +487,7 @@ static int cpufreq_governor_dbs(struct c
 		if (this_dbs_info->enable) /* Already enabled */
 			break;
 		 
-		down(&dbs_sem);
+		mutex_lock(&dbs_mutex);
 		for_each_cpu_mask(j, policy->cpus) {
 			struct cpu_dbs_info_s *j_dbs_info;
 			j_dbs_info = &per_cpu(cpu_dbs_info, j);
@@ -521,11 +521,11 @@ static int cpufreq_governor_dbs(struct c
 			dbs_timer_init();
 		}
 		
-		up(&dbs_sem);
+		mutex_unlock(&dbs_mutex);
 		break;
 
 	case CPUFREQ_GOV_STOP:
-		down(&dbs_sem);
+		mutex_lock(&dbs_mutex);
 		this_dbs_info->enable = 0;
 		sysfs_remove_group(&policy->kobj, &dbs_attr_group);
 		dbs_enable--;
@@ -536,12 +536,12 @@ static int cpufreq_governor_dbs(struct c
 		if (dbs_enable == 0) 
 			dbs_timer_exit();
 		
-		up(&dbs_sem);
+		mutex_unlock(&dbs_mutex);
 
 		break;
 
 	case CPUFREQ_GOV_LIMITS:
-		down(&dbs_sem);
+		mutex_lock(&dbs_mutex);
 		if (policy->max < this_dbs_info->cur_policy->cur)
 			__cpufreq_driver_target(
 					this_dbs_info->cur_policy,
@@ -550,7 +550,7 @@ static int cpufreq_governor_dbs(struct c
 			__cpufreq_driver_target(
 					this_dbs_info->cur_policy,
 				       	policy->min, CPUFREQ_RELATION_L);
-		up(&dbs_sem);
+		mutex_unlock(&dbs_mutex);
 		break;
 	}
 	return 0;
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index e69fd8d..9ee9411 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -27,6 +27,7 @@
 #include <linux/jiffies.h>
 #include <linux/kernel_stat.h>
 #include <linux/percpu.h>
+#include <linux/mutex.h>
 
 /*
  * dbs is used in this file as a shortform for demandbased switching
@@ -70,7 +71,7 @@ static DEFINE_PER_CPU(struct cpu_dbs_inf
 
 static unsigned int dbs_enable;	/* number of CPUs using this policy */
 
-static DECLARE_MUTEX 	(dbs_sem);
+static DEFINE_MUTEX 	(dbs_mutex);
 static DECLARE_WORK	(dbs_work, do_dbs_timer, NULL);
 
 struct dbs_tuners {
@@ -136,9 +137,9 @@ static ssize_t store_sampling_down_facto
 	if (input > MAX_SAMPLING_DOWN_FACTOR || input < 1)
 		return -EINVAL;
 
-	down(&dbs_sem);
+	mutex_lock(&dbs_mutex);
 	dbs_tuners_ins.sampling_down_factor = input;
-	up(&dbs_sem);
+	mutex_unlock(&dbs_mutex);
 
 	return count;
 }
@@ -150,14 +151,14 @@ static ssize_t store_sampling_rate(struc
 	int ret;
 	ret = sscanf (buf, "%u", &input);
 
-	down(&dbs_sem);
+	mutex_lock(&dbs_mutex);
 	if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE) {
-		up(&dbs_sem);
+		mutex_unlock(&dbs_mutex);
 		return -EINVAL;
 	}
 
 	dbs_tuners_ins.sampling_rate = input;
-	up(&dbs_sem);
+	mutex_unlock(&dbs_mutex);
 
 	return count;
 }
@@ -169,15 +170,15 @@ static ssize_t store_up_threshold(struct
 	int ret;
 	ret = sscanf (buf, "%u", &input);
 
-	down(&dbs_sem);
+	mutex_lock(&dbs_mutex);
 	if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || 
 			input < MIN_FREQUENCY_UP_THRESHOLD) {
-		up(&dbs_sem);
+		mutex_unlock(&dbs_mutex);
 		return -EINVAL;
 	}
 
 	dbs_tuners_ins.up_threshold = input;
-	up(&dbs_sem);
+	mutex_unlock(&dbs_mutex);
 
 	return count;
 }
@@ -197,9 +198,9 @@ static ssize_t store_ignore_nice_load(st
 	if ( input > 1 )
 		input = 1;
 	
-	down(&dbs_sem);
+	mutex_lock(&dbs_mutex);
 	if ( input == dbs_tuners_ins.ignore_nice ) { /* nothing to do */
-		up(&dbs_sem);
+		mutex_unlock(&dbs_mutex);
 		return count;
 	}
 	dbs_tuners_ins.ignore_nice = input;
@@ -211,7 +212,7 @@ static ssize_t store_ignore_nice_load(st
 		j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j);
 		j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up;
 	}
-	up(&dbs_sem);
+	mutex_unlock(&dbs_mutex);
 
 	return count;
 }
@@ -356,12 +357,12 @@ static void dbs_check_cpu(int cpu)
 static void do_dbs_timer(void *data)
 { 
 	int i;
-	down(&dbs_sem);
+	mutex_lock(&dbs_mutex);
 	for_each_online_cpu(i)
 		dbs_check_cpu(i);
 	schedule_delayed_work(&dbs_work, 
 			usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
-	up(&dbs_sem);
+	mutex_unlock(&dbs_mutex);
 } 
 
 static inline void dbs_timer_init(void)
@@ -399,7 +400,7 @@ static int cpufreq_governor_dbs(struct c
 		if (this_dbs_info->enable) /* Already enabled */
 			break;
 		 
-		down(&dbs_sem);
+		mutex_lock(&dbs_mutex);
 		for_each_cpu_mask(j, policy->cpus) {
 			struct cpu_dbs_info_s *j_dbs_info;
 			j_dbs_info = &per_cpu(cpu_dbs_info, j);
@@ -435,11 +436,11 @@ static int cpufreq_governor_dbs(struct c
 			dbs_timer_init();
 		}
 		
-		up(&dbs_sem);
+		mutex_unlock(&dbs_mutex);
 		break;
 
 	case CPUFREQ_GOV_STOP:
-		down(&dbs_sem);
+		mutex_lock(&dbs_mutex);
 		this_dbs_info->enable = 0;
 		sysfs_remove_group(&policy->kobj, &dbs_attr_group);
 		dbs_enable--;
@@ -450,12 +451,12 @@ static int cpufreq_governor_dbs(struct c
 		if (dbs_enable == 0) 
 			dbs_timer_exit();
 		
-		up(&dbs_sem);
+		mutex_unlock(&dbs_mutex);
 
 		break;
 
 	case CPUFREQ_GOV_LIMITS:
-		down(&dbs_sem);
+		mutex_lock(&dbs_mutex);
 		if (policy->max < this_dbs_info->cur_policy->cur)
 			__cpufreq_driver_target(
 					this_dbs_info->cur_policy,
@@ -464,7 +465,7 @@ static int cpufreq_governor_dbs(struct c
 			__cpufreq_driver_target(
 					this_dbs_info->cur_policy,
 				       	policy->min, CPUFREQ_RELATION_L);
-		up(&dbs_sem);
+		mutex_unlock(&dbs_mutex);
 		break;
 	}
 	return 0;
diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c
index d32bf35..92a0be2 100644
--- a/drivers/cpufreq/cpufreq_userspace.c
+++ b/drivers/cpufreq/cpufreq_userspace.c
@@ -1,3 +1,4 @@
+
 /*
  *  linux/drivers/cpufreq/cpufreq_userspace.c
  *
@@ -21,6 +22,7 @@
 #include <linux/types.h>
 #include <linux/fs.h>
 #include <linux/sysfs.h>
+#include <linux/mutex.h>
 
 #include <asm/uaccess.h>
 
@@ -33,9 +35,8 @@ static unsigned int	cpu_min_freq[NR_CPUS
 static unsigned int	cpu_cur_freq[NR_CPUS]; /* current CPU freq */
 static unsigned int	cpu_set_freq[NR_CPUS]; /* CPU freq desired by userspace */
 static unsigned int	cpu_is_managed[NR_CPUS];
-static struct cpufreq_policy current_policy[NR_CPUS];
 
-static DECLARE_MUTEX	(userspace_sem); 
+static DEFINE_MUTEX	(userspace_mutex);
 
 #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_GOVERNOR, "userspace", msg)
 
@@ -64,35 +65,34 @@ static struct notifier_block userspace_c
  *
  * Sets the CPU frequency to freq.
  */
-static int cpufreq_set(unsigned int freq, unsigned int cpu)
+static int cpufreq_set(unsigned int freq, struct cpufreq_policy *policy)
 {
 	int ret = -EINVAL;
 
-	dprintk("cpufreq_set for cpu %u, freq %u kHz\n", cpu, freq);
+	dprintk("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq);
 
-	down(&userspace_sem);
-	if (!cpu_is_managed[cpu])
+	mutex_lock(&userspace_mutex);
+	if (!cpu_is_managed[policy->cpu])
 		goto err;
 
-	cpu_set_freq[cpu] = freq;
+	cpu_set_freq[policy->cpu] = freq;
 
-	if (freq < cpu_min_freq[cpu])
-		freq = cpu_min_freq[cpu];
-	if (freq > cpu_max_freq[cpu])
-		freq = cpu_max_freq[cpu];
+	if (freq < cpu_min_freq[policy->cpu])
+		freq = cpu_min_freq[policy->cpu];
+	if (freq > cpu_max_freq[policy->cpu])
+		freq = cpu_max_freq[policy->cpu];
 
 	/*
 	 * We're safe from concurrent calls to ->target() here
-	 * as we hold the userspace_sem lock. If we were calling
+	 * as we hold the userspace_mutex lock. If we were calling
 	 * cpufreq_driver_target, a deadlock situation might occur:
-	 * A: cpufreq_set (lock userspace_sem) -> cpufreq_driver_target(lock policy->lock)
-	 * B: cpufreq_set_policy(lock policy->lock) -> __cpufreq_governor -> cpufreq_governor_userspace (lock userspace_sem)
+	 * A: cpufreq_set (lock userspace_mutex) -> cpufreq_driver_target(lock policy->lock)
+	 * B: cpufreq_set_policy(lock policy->lock) -> __cpufreq_governor -> cpufreq_governor_userspace (lock userspace_mutex)
 	 */
-	ret = __cpufreq_driver_target(&current_policy[cpu], freq, 
-	      CPUFREQ_RELATION_L);
+	ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L);
 
  err:
-	up(&userspace_sem);
+	mutex_unlock(&userspace_mutex);
 	return ret;
 }
 
@@ -113,7 +113,7 @@ store_speed (struct cpufreq_policy *poli
 	if (ret != 1)
 		return -EINVAL;
 
-	cpufreq_set(freq, policy->cpu);
+	cpufreq_set(freq, policy);
 
 	return count;
 }
@@ -134,44 +134,48 @@ static int cpufreq_governor_userspace(st
 		if (!cpu_online(cpu))
 			return -EINVAL;
 		BUG_ON(!policy->cur);
-		down(&userspace_sem);
+		mutex_lock(&userspace_mutex);
 		cpu_is_managed[cpu] = 1;		
 		cpu_min_freq[cpu] = policy->min;
 		cpu_max_freq[cpu] = policy->max;
 		cpu_cur_freq[cpu] = policy->cur;
 		cpu_set_freq[cpu] = policy->cur;
 		sysfs_create_file (&policy->kobj, &freq_attr_scaling_setspeed.attr);
-		memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy));
 		dprintk("managing cpu %u started (%u - %u kHz, currently %u kHz)\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu]);
-		up(&userspace_sem);
+		mutex_unlock(&userspace_mutex);
 		break;
 	case CPUFREQ_GOV_STOP:
-		down(&userspace_sem);
+		mutex_lock(&userspace_mutex);
 		cpu_is_managed[cpu] = 0;
 		cpu_min_freq[cpu] = 0;
 		cpu_max_freq[cpu] = 0;
 		cpu_set_freq[cpu] = 0;
 		sysfs_remove_file (&policy->kobj, &freq_attr_scaling_setspeed.attr);
 		dprintk("managing cpu %u stopped\n", cpu);
-		up(&userspace_sem);
+		mutex_unlock(&userspace_mutex);
 		break;
 	case CPUFREQ_GOV_LIMITS:
-		down(&userspace_sem);
-		cpu_min_freq[cpu] = policy->min;
-		cpu_max_freq[cpu] = policy->max;
-		dprintk("limit event for cpu %u: %u - %u kHz, currently %u kHz, last set to %u kHz\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu], cpu_set_freq[cpu]);
+		mutex_lock(&userspace_mutex);
+		dprintk("limit event for cpu %u: %u - %u kHz,"
+			"currently %u kHz, last set to %u kHz\n",
+			cpu, policy->min, policy->max,
+			cpu_cur_freq[cpu], cpu_set_freq[cpu]);
 		if (policy->max < cpu_set_freq[cpu]) {
-			__cpufreq_driver_target(&current_policy[cpu], policy->max, 
-			      CPUFREQ_RELATION_H);
-		} else if (policy->min > cpu_set_freq[cpu]) {
-			__cpufreq_driver_target(&current_policy[cpu], policy->min, 
-			      CPUFREQ_RELATION_L);
-		} else {
-			__cpufreq_driver_target(&current_policy[cpu], cpu_set_freq[cpu],
-			      CPUFREQ_RELATION_L);
+			__cpufreq_driver_target(policy, policy->max,
+						CPUFREQ_RELATION_H);
+		}
+		else if (policy->min > cpu_set_freq[cpu]) {
+			__cpufreq_driver_target(policy, policy->min,
+						CPUFREQ_RELATION_L);
 		}
-		memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy));
-		up(&userspace_sem);
+		else {
+			__cpufreq_driver_target(policy, cpu_set_freq[cpu],
+						CPUFREQ_RELATION_L);
+		}
+		cpu_min_freq[cpu] = policy->min;
+		cpu_max_freq[cpu] = policy->max;
+		cpu_cur_freq[cpu] = policy->cur;
+		mutex_unlock(&userspace_mutex);
 		break;
 	}
 	return 0;
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
new file mode 100644
index 0000000..4819e7f
--- /dev/null
+++ b/drivers/edac/Kconfig
@@ -0,0 +1,102 @@
+#
+#	EDAC Kconfig
+#	Copyright (c) 2003 Linux Networx
+#	Licensed and distributed under the GPL
+#
+# $Id: Kconfig,v 1.4.2.7 2005/07/08 22:05:38 dsp_llnl Exp $
+#
+
+menu 'EDAC - error detection and reporting (RAS)'
+
+config EDAC
+	tristate "EDAC core system error reporting"
+	depends on X86
+	default y
+	help
+	  EDAC is designed to report errors in the core system.
+	  These are low-level errors that are reported in the CPU or
+	  supporting chipset: memory errors, cache errors, PCI errors,
+	  thermal throttling, etc..  If unsure, select 'Y'.
+
+
+comment "Reporting subsystems"
+	depends on EDAC
+
+config EDAC_DEBUG
+	bool "Debugging"
+	depends on EDAC
+	help
+	  This turns on debugging information for the entire EDAC
+	  sub-system. You can insert module with "debug_level=x", current
+	  there're four debug levels (x=0,1,2,3 from low to high).
+	  Usually you should select 'N'.
+
+config EDAC_MM_EDAC
+	tristate "Main Memory EDAC (Error Detection And Correction) reporting"
+	depends on EDAC
+	default y
+	help
+	  Some systems are able to detect and correct errors in main
+	  memory.  EDAC can report statistics on memory error
+	  detection and correction (EDAC - or commonly referred to ECC
+	  errors).  EDAC will also try to decode where these errors
+	  occurred so that a particular failing memory module can be
+	  replaced.  If unsure, select 'Y'.
+
+
+config EDAC_AMD76X
+	tristate "AMD 76x (760, 762, 768)"
+	depends on EDAC_MM_EDAC  && PCI
+	help
+	  Support for error detection and correction on the AMD 76x
+	  series of chipsets used with the Athlon processor.
+
+config EDAC_E7XXX
+	tristate "Intel e7xxx (e7205, e7500, e7501, e7505)"
+	depends on EDAC_MM_EDAC && PCI
+	help
+	  Support for error detection and correction on the Intel
+	  E7205, E7500, E7501 and E7505 server chipsets.
+
+config EDAC_E752X
+	tristate "Intel e752x (e7520, e7525, e7320)"
+	depends on EDAC_MM_EDAC && PCI
+	help
+	  Support for error detection and correction on the Intel
+	  E7520, E7525, E7320 server chipsets.
+
+config EDAC_I82875P
+	tristate "Intel 82875p (D82875P, E7210)"
+	depends on EDAC_MM_EDAC && PCI
+	help
+	  Support for error detection and correction on the Intel
+	  DP82785P and E7210 server chipsets.
+
+config EDAC_I82860
+	tristate "Intel 82860"
+	depends on EDAC_MM_EDAC && PCI
+	help
+	  Support for error detection and correction on the Intel
+	  82860 chipset.
+
+config EDAC_R82600
+	tristate "Radisys 82600 embedded chipset"
+	depends on EDAC_MM_EDAC
+	help
+	  Support for error detection and correction on the Radisys
+	  82600 embedded chipset.
+
+choice
+	prompt "Error detecting method"
+	depends on EDAC
+	default EDAC_POLL
+
+config EDAC_POLL
+	bool "Poll for errors"
+	depends on EDAC
+	help
+	  Poll the chipset periodically to detect errors.
+
+endchoice
+
+endmenu
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
new file mode 100644
index 0000000..93137fd
--- /dev/null
+++ b/drivers/edac/Makefile
@@ -0,0 +1,18 @@
+#
+# Makefile for the Linux kernel EDAC drivers.
+#
+# Copyright 02 Jul 2003, Linux Networx (http://lnxi.com)
+# This file may be distributed under the terms of the
+# GNU General Public License.
+#
+# $Id: Makefile,v 1.4.2.3 2005/07/08 22:05:38 dsp_llnl Exp $
+
+
+obj-$(CONFIG_EDAC_MM_EDAC)		+= edac_mc.o
+obj-$(CONFIG_EDAC_AMD76X)		+= amd76x_edac.o
+obj-$(CONFIG_EDAC_E7XXX)		+= e7xxx_edac.o
+obj-$(CONFIG_EDAC_E752X)		+= e752x_edac.o
+obj-$(CONFIG_EDAC_I82875P)		+= i82875p_edac.o
+obj-$(CONFIG_EDAC_I82860)		+= i82860_edac.o
+obj-$(CONFIG_EDAC_R82600)		+= r82600_edac.o
+
diff --git a/drivers/edac/amd76x_edac.c b/drivers/edac/amd76x_edac.c
new file mode 100644
index 0000000..2fcc812
--- /dev/null
+++ b/drivers/edac/amd76x_edac.c
@@ -0,0 +1,356 @@
+/*
+ * AMD 76x Memory Controller kernel module
+ * (C) 2003 Linux Networx (http://lnxi.com)
+ * This file may be distributed under the terms of the
+ * GNU General Public License.
+ *
+ * Written by Thayne Harbaugh
+ * Based on work by Dan Hollis <goemon at anime dot net> and others.
+ *	http://www.anime.net/~goemon/linux-ecc/
+ *
+ * $Id: edac_amd76x.c,v 1.4.2.5 2005/10/05 00:43:44 dsp_llnl Exp $
+ *
+ */
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+
+#include <linux/slab.h>
+
+#include "edac_mc.h"
+
+
+#define AMD76X_NR_CSROWS 8
+#define AMD76X_NR_CHANS  1
+#define AMD76X_NR_DIMMS  4
+
+
+/* AMD 76x register addresses - device 0 function 0 - PCI bridge */
+#define AMD76X_ECC_MODE_STATUS	0x48	/* Mode and status of ECC (32b)
+					 *
+					 * 31:16 reserved
+					 * 15:14 SERR enabled: x1=ue 1x=ce
+					 * 13    reserved
+					 * 12    diag: disabled, enabled
+					 * 11:10 mode: dis, EC, ECC, ECC+scrub
+					 *  9:8  status: x1=ue 1x=ce
+					 *  7:4  UE cs row
+					 *  3:0  CE cs row
+					 */
+#define AMD76X_DRAM_MODE_STATUS	0x58	/* DRAM Mode and status (32b)
+					 *
+					 * 31:26 clock disable 5 - 0
+					 * 25    SDRAM init
+					 * 24    reserved
+					 * 23    mode register service
+					 * 22:21 suspend to RAM
+					 * 20    burst refresh enable
+					 * 19    refresh disable
+					 * 18    reserved
+					 * 17:16 cycles-per-refresh
+					 * 15:8  reserved
+					 *  7:0  x4 mode enable 7 - 0
+					 */
+#define AMD76X_MEM_BASE_ADDR	0xC0	/* Memory base address (8 x 32b)
+					 *
+					 * 31:23 chip-select base
+					 * 22:16 reserved
+					 * 15:7  chip-select mask
+					 *  6:3  reserved
+					 *  2:1  address mode
+					 *  0    chip-select enable
+					 */
+
+
+struct amd76x_error_info {
+	u32 ecc_mode_status;
+};
+
+
+enum amd76x_chips {
+	AMD761 = 0,
+	AMD762
+};
+
+
+struct amd76x_dev_info {
+	const char *ctl_name;
+};
+
+
+static const struct amd76x_dev_info amd76x_devs[] = {
+	[AMD761] = {.ctl_name = "AMD761"},
+	[AMD762] = {.ctl_name = "AMD762"},
+};
+
+
+/**
+ *	amd76x_get_error_info	-	fetch error information
+ *	@mci: Memory controller
+ *	@info: Info to fill in
+ *
+ *	Fetch and store the AMD76x ECC status. Clear pending status
+ *	on the chip so that further errors will be reported
+ */
+
+static void amd76x_get_error_info (struct mem_ctl_info *mci,
+				   struct amd76x_error_info *info)
+{
+	pci_read_config_dword(mci->pdev, AMD76X_ECC_MODE_STATUS,
+				&info->ecc_mode_status);
+
+	if (info->ecc_mode_status & BIT(8))
+		pci_write_bits32(mci->pdev, AMD76X_ECC_MODE_STATUS,
+				   (u32) BIT(8), (u32) BIT(8));
+
+	if (info->ecc_mode_status & BIT(9))
+		pci_write_bits32(mci->pdev, AMD76X_ECC_MODE_STATUS,
+				   (u32) BIT(9), (u32) BIT(9));
+}
+
+
+/**
+ *	amd76x_process_error_info	-	Error check
+ *	@mci: Memory controller
+ *	@info: Previously fetched information from chip
+ *	@handle_errors: 1 if we should do recovery
+ *
+ *	Process the chip state and decide if an error has occurred.
+ *	A return of 1 indicates an error. Also if handle_errors is true
+ *	then attempt to handle and clean up after the error
+ */
+
+static int amd76x_process_error_info (struct mem_ctl_info *mci,
+		struct amd76x_error_info *info, int handle_errors)
+{
+	int error_found;
+	u32 row;
+
+	error_found = 0;
+
+	/*
+	 *	Check for an uncorrectable error
+	 */
+	if (info->ecc_mode_status & BIT(8)) {
+		error_found = 1;
+
+		if (handle_errors) {
+			row = (info->ecc_mode_status >> 4) & 0xf;
+			edac_mc_handle_ue(mci,
+			    mci->csrows[row].first_page, 0, row,
+			    mci->ctl_name);
+		}
+	}
+
+	/*
+	 *	Check for a correctable error
+	 */
+	if (info->ecc_mode_status & BIT(9)) {
+		error_found = 1;
+
+		if (handle_errors) {
+			row = info->ecc_mode_status & 0xf;
+			edac_mc_handle_ce(mci,
+			    mci->csrows[row].first_page, 0, 0, row, 0,
+			    mci->ctl_name);
+		}
+	}
+	return error_found;
+}
+
+/**
+ *	amd76x_check	-	Poll the controller
+ *	@mci: Memory controller
+ *
+ *	Called by the poll handlers this function reads the status
+ *	from the controller and checks for errors.
+ */
+
+static void amd76x_check(struct mem_ctl_info *mci)
+{
+	struct amd76x_error_info info;
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+	amd76x_get_error_info(mci, &info);
+	amd76x_process_error_info(mci, &info, 1);
+}
+
+
+/**
+ *	amd76x_probe1	-	Perform set up for detected device
+ *	@pdev; PCI device detected
+ *	@dev_idx: Device type index
+ *
+ *	We have found an AMD76x and now need to set up the memory
+ *	controller status reporting. We configure and set up the
+ *	memory controller reporting and claim the device.
+ */
+
+static int amd76x_probe1(struct pci_dev *pdev, int dev_idx)
+{
+	int rc = -ENODEV;
+	int index;
+	struct mem_ctl_info *mci = NULL;
+	enum edac_type ems_modes[] = {
+		EDAC_NONE,
+		EDAC_EC,
+		EDAC_SECDED,
+		EDAC_SECDED
+	};
+	u32 ems;
+	u32 ems_mode;
+
+	debugf0("MC: " __FILE__ ": %s()\n", __func__);
+
+	pci_read_config_dword(pdev, AMD76X_ECC_MODE_STATUS, &ems);
+	ems_mode = (ems >> 10) & 0x3;
+
+	mci = edac_mc_alloc(0, AMD76X_NR_CSROWS, AMD76X_NR_CHANS);
+
+	if (mci == NULL) {
+		rc = -ENOMEM;
+		goto fail;
+	}
+
+	debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci);
+
+	mci->pdev = pci_dev_get(pdev);
+	mci->mtype_cap = MEM_FLAG_RDDR;
+
+	mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED;
+	mci->edac_cap = ems_mode ?
+	    (EDAC_FLAG_EC | EDAC_FLAG_SECDED) : EDAC_FLAG_NONE;
+
+	mci->mod_name = BS_MOD_STR;
+	mci->mod_ver = "$Revision: 1.4.2.5 $";
+	mci->ctl_name = amd76x_devs[dev_idx].ctl_name;
+	mci->edac_check = amd76x_check;
+	mci->ctl_page_to_phys = NULL;
+
+	for (index = 0; index < mci->nr_csrows; index++) {
+		struct csrow_info *csrow = &mci->csrows[index];
+		u32 mba;
+		u32 mba_base;
+		u32 mba_mask;
+		u32 dms;
+
+		/* find the DRAM Chip Select Base address and mask */
+		pci_read_config_dword(mci->pdev,
+				      AMD76X_MEM_BASE_ADDR + (index * 4),
+				      &mba);
+
+		if (!(mba & BIT(0)))
+			continue;
+
+		mba_base = mba & 0xff800000UL;
+		mba_mask = ((mba & 0xff80) << 16) | 0x7fffffUL;
+
+		pci_read_config_dword(mci->pdev, AMD76X_DRAM_MODE_STATUS,
+				      &dms);
+
+		csrow->first_page = mba_base >> PAGE_SHIFT;
+		csrow->nr_pages = (mba_mask + 1) >> PAGE_SHIFT;
+		csrow->last_page = csrow->first_page + csrow->nr_pages - 1;
+		csrow->page_mask = mba_mask >> PAGE_SHIFT;
+		csrow->grain = csrow->nr_pages << PAGE_SHIFT;
+		csrow->mtype = MEM_RDDR;
+		csrow->dtype = ((dms >> index) & 0x1) ? DEV_X4 : DEV_UNKNOWN;
+		csrow->edac_mode = ems_modes[ems_mode];
+	}
+
+	/* clear counters */
+	pci_write_bits32(mci->pdev, AMD76X_ECC_MODE_STATUS, (u32) (0x3 << 8),
+			 (u32) (0x3 << 8));
+
+	if (edac_mc_add_mc(mci)) {
+		debugf3("MC: " __FILE__
+			": %s(): failed edac_mc_add_mc()\n", __func__);
+		goto fail;
+	}
+
+	/* get this far and it's successful */
+	debugf3("MC: " __FILE__ ": %s(): success\n", __func__);
+	return 0;
+
+fail:
+	if (mci) {
+		if(mci->pdev)
+			pci_dev_put(mci->pdev);
+		edac_mc_free(mci);
+	}
+	return rc;
+}
+
+/* returns count (>= 0), or negative on error */
+static int __devinit amd76x_init_one(struct pci_dev *pdev,
+				     const struct pci_device_id *ent)
+{
+	debugf0("MC: " __FILE__ ": %s()\n", __func__);
+
+	/* don't need to call pci_device_enable() */
+	return amd76x_probe1(pdev, ent->driver_data);
+}
+
+
+/**
+ *	amd76x_remove_one	-	driver shutdown
+ *	@pdev: PCI device being handed back
+ *
+ *	Called when the driver is unloaded. Find the matching mci
+ *	structure for the device then delete the mci and free the
+ *	resources.
+ */
+
+static void __devexit amd76x_remove_one(struct pci_dev *pdev)
+{
+	struct mem_ctl_info *mci;
+
+	debugf0(__FILE__ ": %s()\n", __func__);
+
+	if ((mci = edac_mc_find_mci_by_pdev(pdev)) == NULL)
+		return;
+	if (edac_mc_del_mc(mci))
+		return;
+	pci_dev_put(mci->pdev);
+	edac_mc_free(mci);
+}
+
+
+static const struct pci_device_id amd76x_pci_tbl[] __devinitdata = {
+	{PCI_VEND_DEV(AMD, FE_GATE_700C), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	 AMD762},
+	{PCI_VEND_DEV(AMD, FE_GATE_700E), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	 AMD761},
+	{0,}			/* 0 terminated list. */
+};
+
+MODULE_DEVICE_TABLE(pci, amd76x_pci_tbl);
+
+
+static struct pci_driver amd76x_driver = {
+	.name = BS_MOD_STR,
+	.probe = amd76x_init_one,
+	.remove = __devexit_p(amd76x_remove_one),
+	.id_table = amd76x_pci_tbl,
+};
+
+static int __init amd76x_init(void)
+{
+	return pci_register_driver(&amd76x_driver);
+}
+
+static void __exit amd76x_exit(void)
+{
+	pci_unregister_driver(&amd76x_driver);
+}
+
+module_init(amd76x_init);
+module_exit(amd76x_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Linux Networx (http://lnxi.com) Thayne Harbaugh");
+MODULE_DESCRIPTION("MC support for AMD 76x memory controllers");
diff --git a/drivers/edac/e752x_edac.c b/drivers/edac/e752x_edac.c
new file mode 100644
index 0000000..770a5a6
--- /dev/null
+++ b/drivers/edac/e752x_edac.c
@@ -0,0 +1,1071 @@
+/*
+ * Intel e752x Memory Controller kernel module
+ * (C) 2004 Linux Networx (http://lnxi.com)
+ * This file may be distributed under the terms of the
+ * GNU General Public License.
+ *
+ * See "enum e752x_chips" below for supported chipsets
+ *
+ * Written by Tom Zimmerman
+ *
+ * Contributors:
+ * 	Thayne Harbaugh at realmsys.com (?)
+ * 	Wang Zhenyu at intel.com
+ * 	Dave Jiang at mvista.com
+ *
+ * $Id: edac_e752x.c,v 1.5.2.11 2005/10/05 00:43:44 dsp_llnl Exp $
+ *
+ */
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+
+#include <linux/slab.h>
+
+#include "edac_mc.h"
+
+
+#ifndef PCI_DEVICE_ID_INTEL_7520_0
+#define PCI_DEVICE_ID_INTEL_7520_0      0x3590
+#endif				/* PCI_DEVICE_ID_INTEL_7520_0      */
+
+#ifndef PCI_DEVICE_ID_INTEL_7520_1_ERR
+#define PCI_DEVICE_ID_INTEL_7520_1_ERR  0x3591
+#endif				/* PCI_DEVICE_ID_INTEL_7520_1_ERR  */
+
+#ifndef PCI_DEVICE_ID_INTEL_7525_0
+#define PCI_DEVICE_ID_INTEL_7525_0      0x359E
+#endif				/* PCI_DEVICE_ID_INTEL_7525_0      */
+
+#ifndef PCI_DEVICE_ID_INTEL_7525_1_ERR
+#define PCI_DEVICE_ID_INTEL_7525_1_ERR  0x3593
+#endif				/* PCI_DEVICE_ID_INTEL_7525_1_ERR  */
+
+#ifndef PCI_DEVICE_ID_INTEL_7320_0
+#define PCI_DEVICE_ID_INTEL_7320_0	0x3592
+#endif				/* PCI_DEVICE_ID_INTEL_7320_0 */
+
+#ifndef PCI_DEVICE_ID_INTEL_7320_1_ERR
+#define PCI_DEVICE_ID_INTEL_7320_1_ERR	0x3593
+#endif				/* PCI_DEVICE_ID_INTEL_7320_1_ERR */
+
+#define E752X_NR_CSROWS		8	/* number of csrows */
+
+
+/* E752X register addresses - device 0 function 0 */
+#define E752X_DRB		0x60	/* DRAM row boundary register (8b) */
+#define E752X_DRA		0x70	/* DRAM row attribute register (8b) */
+					/*
+					 * 31:30   Device width row 7
+					 *      01=x8 10=x4 11=x8 DDR2
+					 * 27:26   Device width row 6
+					 * 23:22   Device width row 5
+					 * 19:20   Device width row 4
+					 * 15:14   Device width row 3
+					 * 11:10   Device width row 2
+					 *  7:6    Device width row 1
+					 *  3:2    Device width row 0
+					 */
+#define E752X_DRC		0x7C	/* DRAM controller mode reg (32b) */
+					/* FIXME:IS THIS RIGHT? */
+					/*
+					 * 22    Number channels 0=1,1=2
+					 * 19:18 DRB Granularity 32/64MB
+					 */
+#define E752X_DRM		0x80	/* Dimm mapping register */
+#define E752X_DDRCSR		0x9A	/* DDR control and status reg (16b) */
+					/*
+					 * 14:12 1 single A, 2 single B, 3 dual
+					 */
+#define E752X_TOLM		0xC4	/* DRAM top of low memory reg (16b) */
+#define E752X_REMAPBASE		0xC6	/* DRAM remap base address reg (16b) */
+#define E752X_REMAPLIMIT	0xC8	/* DRAM remap limit address reg (16b) */
+#define E752X_REMAPOFFSET	0xCA	/* DRAM remap limit offset reg (16b) */
+
+/* E752X register addresses - device 0 function 1 */
+#define E752X_FERR_GLOBAL	0x40	/* Global first error register (32b) */
+#define E752X_NERR_GLOBAL	0x44	/* Global next error register (32b) */
+#define E752X_HI_FERR		0x50	/* Hub interface first error reg (8b) */
+#define E752X_HI_NERR		0x52	/* Hub interface next error reg (8b) */
+#define E752X_HI_ERRMASK	0x54	/* Hub interface error mask reg (8b) */
+#define E752X_HI_SMICMD		0x5A	/* Hub interface SMI command reg (8b) */
+#define E752X_SYSBUS_FERR	0x60	/* System buss first error reg (16b) */
+#define E752X_SYSBUS_NERR	0x62	/* System buss next error reg (16b) */
+#define E752X_SYSBUS_ERRMASK	0x64	/* System buss error mask reg (16b) */
+#define E752X_SYSBUS_SMICMD	0x6A	/* System buss SMI command reg (16b) */
+#define E752X_BUF_FERR		0x70	/* Memory buffer first error reg (8b) */
+#define E752X_BUF_NERR		0x72	/* Memory buffer next error reg (8b) */
+#define E752X_BUF_ERRMASK	0x74	/* Memory buffer error mask reg (8b) */
+#define E752X_BUF_SMICMD	0x7A	/* Memory buffer SMI command reg (8b) */
+#define E752X_DRAM_FERR		0x80	/* DRAM first error register (16b) */
+#define E752X_DRAM_NERR		0x82	/* DRAM next error register (16b) */
+#define E752X_DRAM_ERRMASK	0x84	/* DRAM error mask register (8b) */
+#define E752X_DRAM_SMICMD	0x8A	/* DRAM SMI command register (8b) */
+#define E752X_DRAM_RETR_ADD	0xAC	/* DRAM Retry address register (32b) */
+#define E752X_DRAM_SEC1_ADD	0xA0	/* DRAM first correctable memory */
+					/*     error address register (32b) */
+					/*
+					 * 31    Reserved
+					 * 30:2  CE address (64 byte block 34:6)
+					 * 1     Reserved
+					 * 0     HiLoCS
+					 */
+#define E752X_DRAM_SEC2_ADD	0xC8	/* DRAM first correctable memory */
+					/*     error address register (32b) */
+					/*
+					 * 31    Reserved
+					 * 30:2  CE address (64 byte block 34:6)
+					 * 1     Reserved
+					 * 0     HiLoCS
+					 */
+#define E752X_DRAM_DED_ADD	0xA4	/* DRAM first uncorrectable memory */
+					/*     error address register (32b) */
+					/*
+					 * 31    Reserved
+					 * 30:2  CE address (64 byte block 34:6)
+					 * 1     Reserved
+					 * 0     HiLoCS
+					 */
+#define E752X_DRAM_SCRB_ADD	0xA8	/* DRAM first uncorrectable scrub memory */
+					/*     error address register (32b) */
+					/*
+					 * 31    Reserved
+					 * 30:2  CE address (64 byte block 34:6)
+					 * 1     Reserved
+					 * 0     HiLoCS
+					 */
+#define E752X_DRAM_SEC1_SYNDROME 0xC4	/* DRAM first correctable memory */
+					/*     error syndrome register (16b) */
+#define E752X_DRAM_SEC2_SYNDROME 0xC6	/* DRAM second correctable memory */
+					/*     error syndrome register (16b) */
+#define E752X_DEVPRES1		0xF4	/* Device Present 1 register (8b) */
+
+/* ICH5R register addresses - device 30 function 0 */
+#define ICH5R_PCI_STAT		0x06	/* PCI status register (16b) */
+#define ICH5R_PCI_2ND_STAT	0x1E	/* PCI status secondary reg (16b) */
+#define ICH5R_PCI_BRIDGE_CTL	0x3E	/* PCI bridge control register (16b) */
+
+enum e752x_chips {
+	E7520 = 0,
+	E7525 = 1,
+	E7320 = 2
+};
+
+
+struct e752x_pvt {
+	struct pci_dev *bridge_ck;
+	struct pci_dev *dev_d0f0;
+	struct pci_dev *dev_d0f1;
+	u32 tolm;
+	u32 remapbase;
+	u32 remaplimit;
+	int mc_symmetric;
+	u8 map[8];
+	int map_type;
+	const struct e752x_dev_info *dev_info;
+};
+
+
+struct e752x_dev_info {
+	u16 err_dev;
+	const char *ctl_name;
+};
+
+struct e752x_error_info {
+	u32 ferr_global;
+	u32 nerr_global;
+	u8 hi_ferr;
+	u8 hi_nerr;
+	u16 sysbus_ferr;
+	u16 sysbus_nerr;
+	u8 buf_ferr;
+	u8 buf_nerr;
+	u16 dram_ferr;
+	u16 dram_nerr;
+	u32 dram_sec1_add;
+	u32 dram_sec2_add;
+	u16 dram_sec1_syndrome;
+	u16 dram_sec2_syndrome;
+	u32 dram_ded_add;
+	u32 dram_scrb_add;
+	u32 dram_retr_add;
+};
+
+static const struct e752x_dev_info e752x_devs[] = {
+	[E7520] = {
+		   .err_dev = PCI_DEVICE_ID_INTEL_7520_1_ERR,
+		   .ctl_name = "E7520"},
+	[E7525] = {
+		   .err_dev = PCI_DEVICE_ID_INTEL_7525_1_ERR,
+		   .ctl_name = "E7525"},
+	[E7320] = {
+		   .err_dev = PCI_DEVICE_ID_INTEL_7320_1_ERR,
+		   .ctl_name = "E7320"},
+};
+
+
+static unsigned long ctl_page_to_phys(struct mem_ctl_info *mci,
+				      unsigned long page)
+{
+	u32 remap;
+	struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info;
+
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+
+	if (page < pvt->tolm)
+		return page;
+	if ((page >= 0x100000) && (page < pvt->remapbase))
+		return page;
+	remap = (page - pvt->tolm) + pvt->remapbase;
+	if (remap < pvt->remaplimit)
+		return remap;
+	printk(KERN_ERR "Invalid page %lx - out of range\n", page);
+	return pvt->tolm - 1;
+}
+
+static void do_process_ce(struct mem_ctl_info *mci, u16 error_one,
+		       u32 sec1_add, u16 sec1_syndrome)
+{
+	u32 page;
+	int row;
+	int channel;
+	int i;
+	struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info;
+
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+
+	/* convert the addr to 4k page */
+	page = sec1_add >> (PAGE_SHIFT - 4);
+
+	/* FIXME - check for -1 */
+	if (pvt->mc_symmetric) {
+		/* chip select are bits 14 & 13 */
+		row = ((page >> 1) & 3);
+		printk(KERN_WARNING
+		       "Test row %d Table %d %d %d %d %d %d %d %d\n",
+		       row, pvt->map[0], pvt->map[1], pvt->map[2],
+		       pvt->map[3], pvt->map[4], pvt->map[5],
+		       pvt->map[6], pvt->map[7]);
+
+		/* test for channel remapping */
+		for (i = 0; i < 8; i++) {
+			if (pvt->map[i] == row)
+				break;
+		}
+		printk(KERN_WARNING "Test computed row %d\n", i);
+		if (i < 8)
+			row = i;
+		else
+			printk(KERN_WARNING
+			       "MC%d: row %d not found in remap table\n",
+			       mci->mc_idx, row);
+	} else
+		row = edac_mc_find_csrow_by_page(mci, page);
+	/* 0 = channel A, 1 = channel B */
+	channel = !(error_one & 1);
+
+	if (!pvt->map_type)
+		row = 7 - row;
+	edac_mc_handle_ce(mci, page, 0, sec1_syndrome, row, channel,
+	    "e752x CE");
+}
+
+
+static inline void process_ce(struct mem_ctl_info *mci, u16 error_one,
+		u32 sec1_add, u16 sec1_syndrome, int *error_found,
+		int handle_error)
+{
+	*error_found = 1;
+
+	if (handle_error)
+		do_process_ce(mci, error_one, sec1_add, sec1_syndrome);
+}
+
+static void do_process_ue(struct mem_ctl_info *mci, u16 error_one, u32 ded_add,
+		u32 scrb_add)
+{
+	u32 error_2b, block_page;
+	int row;
+	struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info;
+
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+
+	if (error_one & 0x0202) {
+		error_2b = ded_add;
+		/* convert to 4k address */
+		block_page = error_2b >> (PAGE_SHIFT - 4);
+		row = pvt->mc_symmetric ?
+		    /* chip select are bits 14 & 13 */
+		    ((block_page >> 1) & 3) :
+		    edac_mc_find_csrow_by_page(mci, block_page);
+		edac_mc_handle_ue(mci, block_page, 0, row,
+				       "e752x UE from Read");
+	}
+	if (error_one & 0x0404) {
+		error_2b = scrb_add;
+		/* convert to 4k address */
+		block_page = error_2b >> (PAGE_SHIFT - 4);
+		row = pvt->mc_symmetric ?
+		    /* chip select are bits 14 & 13 */
+		    ((block_page >> 1) & 3) :
+		    edac_mc_find_csrow_by_page(mci, block_page);
+		edac_mc_handle_ue(mci, block_page, 0, row,
+				       "e752x UE from Scruber");
+	}
+}
+
+static inline void process_ue(struct mem_ctl_info *mci, u16 error_one,
+		u32 ded_add, u32 scrb_add, int *error_found, int handle_error)
+{
+	*error_found = 1;
+
+	if (handle_error)
+		do_process_ue(mci, error_one, ded_add, scrb_add);
+}
+
+static inline void process_ue_no_info_wr(struct mem_ctl_info *mci,
+		int *error_found, int handle_error)
+{
+	*error_found = 1;
+
+	if (!handle_error)
+		return;
+
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+	edac_mc_handle_ue_no_info(mci, "e752x UE log memory write");
+}
+
+static void do_process_ded_retry(struct mem_ctl_info *mci, u16 error,
+		u32 retry_add)
+{
+	u32 error_1b, page;
+	int row;
+	struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info;
+
+	error_1b = retry_add;
+	page = error_1b >> (PAGE_SHIFT - 4);	/* convert the addr to 4k page */
+	row = pvt->mc_symmetric ?
+	    ((page >> 1) & 3) :	/* chip select are bits 14 & 13 */
+	    edac_mc_find_csrow_by_page(mci, page);
+	printk(KERN_WARNING
+	       "MC%d: CE page 0x%lx, row %d : Memory read retry\n",
+	       mci->mc_idx, (long unsigned int) page, row);
+}
+
+static inline void process_ded_retry(struct mem_ctl_info *mci, u16 error,
+		u32 retry_add, int *error_found, int handle_error)
+{
+	*error_found = 1;
+
+	if (handle_error)
+		do_process_ded_retry(mci, error, retry_add);
+}
+
+static inline void process_threshold_ce(struct mem_ctl_info *mci, u16 error,
+		int *error_found, int handle_error)
+{
+	*error_found = 1;
+
+	if (handle_error)
+		printk(KERN_WARNING "MC%d: Memory threshold CE\n",
+		       mci->mc_idx);
+}
+
+static char *global_message[11] = {
+	"PCI Express C1", "PCI Express C", "PCI Express B1",
+	"PCI Express B", "PCI Express A1", "PCI Express A",
+	"DMA Controler", "HUB Interface", "System Bus",
+	"DRAM Controler", "Internal Buffer"
+};
+
+static char *fatal_message[2] = { "Non-Fatal ", "Fatal " };
+
+static void do_global_error(int fatal, u32 errors)
+{
+	int i;
+
+	for (i = 0; i < 11; i++) {
+		if (errors & (1 << i))
+			printk(KERN_WARNING "%sError %s\n",
+			       fatal_message[fatal], global_message[i]);
+	}
+}
+
+static inline void global_error(int fatal, u32 errors, int *error_found,
+		int handle_error)
+{
+	*error_found = 1;
+
+	if (handle_error)
+		do_global_error(fatal, errors);
+}
+
+static char *hub_message[7] = {
+	"HI Address or Command Parity", "HI Illegal Access",
+	"HI Internal Parity", "Out of Range Access",
+	"HI Data Parity", "Enhanced Config Access",
+	"Hub Interface Target Abort"
+};
+
+static void do_hub_error(int fatal, u8 errors)
+{
+	int i;
+
+	for (i = 0; i < 7; i++) {
+		if (errors & (1 << i))
+			printk(KERN_WARNING "%sError %s\n",
+			       fatal_message[fatal], hub_message[i]);
+	}
+}
+
+static inline void hub_error(int fatal, u8 errors, int *error_found,
+		int handle_error)
+{
+	*error_found = 1;
+
+	if (handle_error)
+		do_hub_error(fatal, errors);
+}
+
+static char *membuf_message[4] = {
+	"Internal PMWB to DRAM parity",
+	"Internal PMWB to System Bus Parity",
+	"Internal System Bus or IO to PMWB Parity",
+	"Internal DRAM to PMWB Parity"
+};
+
+static void do_membuf_error(u8 errors)
+{
+	int i;
+
+	for (i = 0; i < 4; i++) {
+		if (errors & (1 << i))
+			printk(KERN_WARNING "Non-Fatal Error %s\n",
+			       membuf_message[i]);
+	}
+}
+
+static inline void membuf_error(u8 errors, int *error_found, int handle_error)
+{
+	*error_found = 1;
+
+	if (handle_error)
+		do_membuf_error(errors);
+}
+
+#if 0
+char *sysbus_message[10] = {
+	"Addr or Request Parity",
+	"Data Strobe Glitch",
+	"Addr Strobe Glitch",
+	"Data Parity",
+	"Addr Above TOM",
+	"Non DRAM Lock Error",
+	"MCERR", "BINIT",
+	"Memory Parity",
+	"IO Subsystem Parity"
+};
+#endif  /*  0  */
+
+static void do_sysbus_error(int fatal, u32 errors)
+{
+	int i;
+
+	for (i = 0; i < 10; i++) {
+		if (errors & (1 << i))
+			printk(KERN_WARNING "%sError System Bus %s\n",
+			       fatal_message[fatal], global_message[i]);
+	}
+}
+
+static inline void sysbus_error(int fatal, u32 errors, int *error_found,
+		int handle_error)
+{
+	*error_found = 1;
+
+	if (handle_error)
+		do_sysbus_error(fatal, errors);
+}
+
+static void e752x_check_hub_interface (struct e752x_error_info *info,
+		int *error_found, int handle_error)
+{
+	u8 stat8;
+
+	//pci_read_config_byte(dev,E752X_HI_FERR,&stat8);
+	stat8 = info->hi_ferr;
+	if(stat8 & 0x7f) { /* Error, so process */
+		stat8 &= 0x7f;
+		if(stat8 & 0x2b)
+			hub_error(1, stat8 & 0x2b, error_found, handle_error);
+		if(stat8 & 0x54)
+			hub_error(0, stat8 & 0x54, error_found, handle_error);
+	}
+	//pci_read_config_byte(dev,E752X_HI_NERR,&stat8);
+	stat8 = info->hi_nerr;
+	if(stat8 & 0x7f) { /* Error, so process */
+		stat8 &= 0x7f;
+		if (stat8 & 0x2b)
+			hub_error(1, stat8 & 0x2b, error_found, handle_error);
+		if(stat8 & 0x54)
+			hub_error(0, stat8 & 0x54, error_found, handle_error);
+	}
+}
+
+static void e752x_check_sysbus (struct e752x_error_info *info, int *error_found,
+		int handle_error)
+{
+	u32 stat32, error32;
+
+	//pci_read_config_dword(dev,E752X_SYSBUS_FERR,&stat32);
+	stat32 = info->sysbus_ferr + (info->sysbus_nerr << 16);
+
+	if (stat32 == 0)
+		return;  /* no errors */
+
+	error32 = (stat32 >> 16) & 0x3ff;
+	stat32 = stat32 & 0x3ff;
+	if(stat32 & 0x083)
+		sysbus_error(1, stat32 & 0x083, error_found, handle_error);
+	if(stat32 & 0x37c)
+		sysbus_error(0, stat32 & 0x37c, error_found, handle_error);
+	if(error32 & 0x083)
+		sysbus_error(1, error32 & 0x083, error_found, handle_error);
+	if(error32 & 0x37c)
+		sysbus_error(0, error32 & 0x37c, error_found, handle_error);
+}
+
+static void e752x_check_membuf (struct e752x_error_info *info, int *error_found,
+		int handle_error)
+{
+	u8 stat8;
+
+	stat8 = info->buf_ferr;
+	if (stat8 & 0x0f) { /* Error, so process */
+		stat8 &= 0x0f;
+		membuf_error(stat8, error_found, handle_error);
+	}
+	stat8 = info->buf_nerr;
+	if (stat8 & 0x0f) { /* Error, so process */
+		stat8 &= 0x0f;
+		membuf_error(stat8, error_found, handle_error);
+	}
+}
+
+static void e752x_check_dram (struct mem_ctl_info *mci,
+		struct e752x_error_info *info, int *error_found, int handle_error)
+{
+	u16 error_one, error_next;
+
+	error_one = info->dram_ferr;
+	error_next = info->dram_nerr;
+
+	/* decode and report errors */
+	if(error_one & 0x0101)  /* check first error correctable */
+		process_ce(mci, error_one, info->dram_sec1_add,
+			   info->dram_sec1_syndrome, error_found,
+			   handle_error);
+
+	if(error_next & 0x0101)  /* check next error correctable */
+		process_ce(mci, error_next, info->dram_sec2_add,
+			   info->dram_sec2_syndrome, error_found,
+			   handle_error);
+
+	if(error_one & 0x4040)
+		process_ue_no_info_wr(mci, error_found, handle_error);
+
+	if(error_next & 0x4040)
+		process_ue_no_info_wr(mci, error_found, handle_error);
+
+	if(error_one & 0x2020)
+		process_ded_retry(mci, error_one, info->dram_retr_add,
+				  error_found, handle_error);
+
+	if(error_next & 0x2020)
+		process_ded_retry(mci, error_next, info->dram_retr_add,
+				  error_found, handle_error);
+
+	if(error_one & 0x0808)
+		process_threshold_ce(mci, error_one, error_found,
+				     handle_error);
+
+	if(error_next & 0x0808)
+		process_threshold_ce(mci, error_next, error_found,
+				     handle_error);
+
+	if(error_one & 0x0606)
+		process_ue(mci, error_one, info->dram_ded_add,
+			   info->dram_scrb_add, error_found, handle_error);
+
+	if(error_next & 0x0606)
+		process_ue(mci, error_next, info->dram_ded_add,
+			   info->dram_scrb_add, error_found, handle_error);
+}
+
+static void e752x_get_error_info (struct mem_ctl_info *mci,
+				  struct e752x_error_info *info)
+{
+	struct pci_dev *dev;
+	struct e752x_pvt *pvt;
+
+	memset(info, 0, sizeof(*info));
+	pvt = (struct e752x_pvt *) mci->pvt_info;
+	dev = pvt->dev_d0f1;
+
+	pci_read_config_dword(dev, E752X_FERR_GLOBAL, &info->ferr_global);
+
+	if (info->ferr_global) {
+		pci_read_config_byte(dev, E752X_HI_FERR, &info->hi_ferr);
+		pci_read_config_word(dev, E752X_SYSBUS_FERR,
+				&info->sysbus_ferr);
+		pci_read_config_byte(dev, E752X_BUF_FERR, &info->buf_ferr);
+		pci_read_config_word(dev, E752X_DRAM_FERR,
+				&info->dram_ferr);
+		pci_read_config_dword(dev, E752X_DRAM_SEC1_ADD,
+				&info->dram_sec1_add);
+		pci_read_config_word(dev, E752X_DRAM_SEC1_SYNDROME,
+				&info->dram_sec1_syndrome);
+		pci_read_config_dword(dev, E752X_DRAM_DED_ADD,
+				&info->dram_ded_add);
+		pci_read_config_dword(dev, E752X_DRAM_SCRB_ADD,
+				&info->dram_scrb_add);
+		pci_read_config_dword(dev, E752X_DRAM_RETR_ADD,
+				&info->dram_retr_add);
+
+		if (info->hi_ferr & 0x7f)
+			pci_write_config_byte(dev, E752X_HI_FERR,
+					info->hi_ferr);
+
+		if (info->sysbus_ferr)
+			pci_write_config_word(dev, E752X_SYSBUS_FERR,
+					info->sysbus_ferr);
+
+		if (info->buf_ferr & 0x0f)
+			pci_write_config_byte(dev, E752X_BUF_FERR,
+					info->buf_ferr);
+
+		if (info->dram_ferr)
+			pci_write_bits16(pvt->bridge_ck, E752X_DRAM_FERR,
+					info->dram_ferr, info->dram_ferr);
+
+		pci_write_config_dword(dev, E752X_FERR_GLOBAL,
+				info->ferr_global);
+	}
+
+	pci_read_config_dword(dev, E752X_NERR_GLOBAL, &info->nerr_global);
+
+	if (info->nerr_global) {
+		pci_read_config_byte(dev, E752X_HI_NERR, &info->hi_nerr);
+		pci_read_config_word(dev, E752X_SYSBUS_NERR,
+				&info->sysbus_nerr);
+		pci_read_config_byte(dev, E752X_BUF_NERR, &info->buf_nerr);
+		pci_read_config_word(dev, E752X_DRAM_NERR,
+				&info->dram_nerr);
+		pci_read_config_dword(dev, E752X_DRAM_SEC2_ADD,
+				&info->dram_sec2_add);
+		pci_read_config_word(dev, E752X_DRAM_SEC2_SYNDROME,
+				&info->dram_sec2_syndrome);
+
+		if (info->hi_nerr & 0x7f)
+			pci_write_config_byte(dev, E752X_HI_NERR,
+					info->hi_nerr);
+
+		if (info->sysbus_nerr)
+			pci_write_config_word(dev, E752X_SYSBUS_NERR,
+					info->sysbus_nerr);
+
+		if (info->buf_nerr & 0x0f)
+			pci_write_config_byte(dev, E752X_BUF_NERR,
+					info->buf_nerr);
+
+		if (info->dram_nerr)
+			pci_write_bits16(pvt->bridge_ck, E752X_DRAM_NERR,
+					info->dram_nerr, info->dram_nerr);
+
+		pci_write_config_dword(dev, E752X_NERR_GLOBAL,
+				info->nerr_global);
+	}
+}
+
+static int e752x_process_error_info (struct mem_ctl_info *mci,
+		struct e752x_error_info *info, int handle_errors)
+{
+	u32 error32, stat32;
+	int error_found;
+
+	error_found = 0;
+	error32 = (info->ferr_global >> 18) & 0x3ff;
+	stat32 = (info->ferr_global >> 4) & 0x7ff;
+
+	if (error32)
+		global_error(1, error32, &error_found, handle_errors);
+
+	if (stat32)
+		global_error(0, stat32, &error_found, handle_errors);
+
+	error32 = (info->nerr_global >> 18) & 0x3ff;
+	stat32 = (info->nerr_global >> 4) & 0x7ff;
+
+	if (error32)
+		global_error(1, error32, &error_found, handle_errors);
+
+	if (stat32)
+		global_error(0, stat32, &error_found, handle_errors);
+
+	e752x_check_hub_interface(info, &error_found, handle_errors);
+	e752x_check_sysbus(info, &error_found, handle_errors);
+	e752x_check_membuf(info, &error_found, handle_errors);
+	e752x_check_dram(mci, info, &error_found, handle_errors);
+	return error_found;
+}
+
+static void e752x_check(struct mem_ctl_info *mci)
+{
+	struct e752x_error_info info;
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+	e752x_get_error_info(mci, &info);
+	e752x_process_error_info(mci, &info, 1);
+}
+
+static int e752x_probe1(struct pci_dev *pdev, int dev_idx)
+{
+	int rc = -ENODEV;
+	int index;
+	u16 pci_data, stat;
+	u32 stat32;
+	u16 stat16;
+	u8 stat8;
+	struct mem_ctl_info *mci = NULL;
+	struct e752x_pvt *pvt = NULL;
+	u16 ddrcsr;
+	u32 drc;
+	int drc_chan;		/* Number of channels 0=1chan,1=2chan */
+	int drc_drbg;		/* DRB granularity 0=64mb,1=128mb */
+	int drc_ddim;		/* DRAM Data Integrity Mode 0=none,2=edac */
+	u32 dra;
+	unsigned long last_cumul_size;
+	struct pci_dev *pres_dev;
+	struct pci_dev *dev = NULL;
+
+	debugf0("MC: " __FILE__ ": %s(): mci\n", __func__);
+	debugf0("Starting Probe1\n");
+
+	/* enable device 0 function 1 */
+	pci_read_config_byte(pdev, E752X_DEVPRES1, &stat8);
+	stat8 |= (1 << 5);
+	pci_write_config_byte(pdev, E752X_DEVPRES1, stat8);
+
+	/* need to find out the number of channels */
+	pci_read_config_dword(pdev, E752X_DRC, &drc);
+	pci_read_config_word(pdev, E752X_DDRCSR, &ddrcsr);
+	/* FIXME: should check >>12 or 0xf, true for all? */
+	/* Dual channel = 1, Single channel = 0 */
+	drc_chan = (((ddrcsr >> 12) & 3) == 3);
+	drc_drbg = drc_chan + 1;	/* 128 in dual mode, 64 in single */
+	drc_ddim = (drc >> 20) & 0x3;
+
+	mci = edac_mc_alloc(sizeof(*pvt), E752X_NR_CSROWS, drc_chan + 1);
+
+	if (mci == NULL) {
+		rc = -ENOMEM;
+		goto fail;
+	}
+
+	debugf3("MC: " __FILE__ ": %s(): init mci\n", __func__);
+
+	mci->mtype_cap = MEM_FLAG_RDDR;
+	mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED |
+	    EDAC_FLAG_S4ECD4ED;
+	/* FIXME - what if different memory types are in different csrows? */
+	mci->mod_name = BS_MOD_STR;
+	mci->mod_ver = "$Revision: 1.5.2.11 $";
+	mci->pdev = pdev;
+
+	debugf3("MC: " __FILE__ ": %s(): init pvt\n", __func__);
+	pvt = (struct e752x_pvt *) mci->pvt_info;
+	pvt->dev_info = &e752x_devs[dev_idx];
+	pvt->bridge_ck = pci_get_device(PCI_VENDOR_ID_INTEL,
+					 pvt->dev_info->err_dev,
+					 pvt->bridge_ck);
+	if (pvt->bridge_ck == NULL)
+		pvt->bridge_ck = pci_scan_single_device(pdev->bus,
+							PCI_DEVFN(0, 1));
+	if (pvt->bridge_ck == NULL) {
+		printk(KERN_ERR "MC: error reporting device not found:"
+		       "vendor %x device 0x%x (broken BIOS?)\n",
+		       PCI_VENDOR_ID_INTEL, e752x_devs[dev_idx].err_dev);
+		goto fail;
+	}
+	pvt->mc_symmetric = ((ddrcsr & 0x10) != 0);
+
+	debugf3("MC: " __FILE__ ": %s(): more mci init\n", __func__);
+	mci->ctl_name = pvt->dev_info->ctl_name;
+	mci->edac_check = e752x_check;
+	mci->ctl_page_to_phys = ctl_page_to_phys;
+
+	/* find out the device types */
+	pci_read_config_dword(pdev, E752X_DRA, &dra);
+
+	/*
+	 * The dram row boundary (DRB) reg values are boundary address for
+	 * each DRAM row with a granularity of 64 or 128MB (single/dual
+	 * channel operation).  DRB regs are cumulative; therefore DRB7 will
+	 * contain the total memory contained in all eight rows.
+	 */
+	for (last_cumul_size = index = 0; index < mci->nr_csrows; index++) {
+		u8 value;
+		u32 cumul_size;
+		/* mem_dev 0=x8, 1=x4 */
+		int mem_dev = (dra >> (index * 4 + 2)) & 0x3;
+		struct csrow_info *csrow = &mci->csrows[index];
+
+		mem_dev = (mem_dev == 2);
+		pci_read_config_byte(mci->pdev, E752X_DRB + index, &value);
+		/* convert a 128 or 64 MiB DRB to a page size. */
+		cumul_size = value << (25 + drc_drbg - PAGE_SHIFT);
+		debugf3("MC: " __FILE__ ": %s(): (%d) cumul_size 0x%x\n",
+			__func__, index, cumul_size);
+		if (cumul_size == last_cumul_size)
+			continue;	/* not populated */
+
+		csrow->first_page = last_cumul_size;
+		csrow->last_page = cumul_size - 1;
+		csrow->nr_pages = cumul_size - last_cumul_size;
+		last_cumul_size = cumul_size;
+		csrow->grain = 1 << 12;	/* 4KiB - resolution of CELOG */
+		csrow->mtype = MEM_RDDR;	/* only one type supported */
+		csrow->dtype = mem_dev ? DEV_X4 : DEV_X8;
+
+		/*
+		 * if single channel or x8 devices then SECDED
+		 * if dual channel and x4 then S4ECD4ED
+		 */
+		if (drc_ddim) {
+			if (drc_chan && mem_dev) {
+				csrow->edac_mode = EDAC_S4ECD4ED;
+				mci->edac_cap |= EDAC_FLAG_S4ECD4ED;
+			} else {
+				csrow->edac_mode = EDAC_SECDED;
+				mci->edac_cap |= EDAC_FLAG_SECDED;
+			}
+		} else
+			csrow->edac_mode = EDAC_NONE;
+	}
+
+	/* Fill in the memory map table */
+	{
+		u8 value;
+		u8 last = 0;
+		u8 row = 0;
+		for (index = 0; index < 8; index += 2) {
+
+			pci_read_config_byte(mci->pdev, E752X_DRB + index,
+					     &value);
+			/* test if there is a dimm in this slot */
+			if (value == last) {
+				/* no dimm in the slot, so flag it as empty */
+				pvt->map[index] = 0xff;
+				pvt->map[index + 1] = 0xff;
+			} else {	/* there is a dimm in the slot */
+				pvt->map[index] = row;
+				row++;
+				last = value;
+				/* test the next value to see if the dimm is
+				   double sided */
+				pci_read_config_byte(mci->pdev,
+						     E752X_DRB + index + 1,
+						     &value);
+				pvt->map[index + 1] = (value == last) ?
+				    0xff :	/* the dimm is single sided,
+						   so flag as empty */
+				    row;	/* this is a double sided dimm
+						   to save the next row # */
+				row++;
+				last = value;
+			}
+		}
+	}
+
+	/* set the map type.  1 = normal, 0 = reversed */
+	pci_read_config_byte(mci->pdev, E752X_DRM, &stat8);
+	pvt->map_type = ((stat8 & 0x0f) > ((stat8 >> 4) & 0x0f));
+
+	mci->edac_cap |= EDAC_FLAG_NONE;
+
+	debugf3("MC: " __FILE__ ": %s(): tolm, remapbase, remaplimit\n",
+		__func__);
+	/* load the top of low memory, remap base, and remap limit vars */
+	pci_read_config_word(mci->pdev, E752X_TOLM, &pci_data);
+	pvt->tolm = ((u32) pci_data) << 4;
+	pci_read_config_word(mci->pdev, E752X_REMAPBASE, &pci_data);
+	pvt->remapbase = ((u32) pci_data) << 14;
+	pci_read_config_word(mci->pdev, E752X_REMAPLIMIT, &pci_data);
+	pvt->remaplimit = ((u32) pci_data) << 14;
+	printk("tolm = %x, remapbase = %x, remaplimit = %x\n", pvt->tolm,
+	       pvt->remapbase, pvt->remaplimit);
+
+	if (edac_mc_add_mc(mci)) {
+		debugf3("MC: " __FILE__
+			": %s(): failed edac_mc_add_mc()\n",
+			__func__);
+		goto fail;
+	}
+
+	/* Walk through the PCI table and clear errors */
+	switch (dev_idx) {
+	case E7520:
+		dev = pci_get_device(PCI_VENDOR_ID_INTEL,
+				      PCI_DEVICE_ID_INTEL_7520_0, NULL);
+		break;
+	case E7525:
+		dev = pci_get_device(PCI_VENDOR_ID_INTEL,
+				      PCI_DEVICE_ID_INTEL_7525_0, NULL);
+		break;
+	case E7320:
+		dev = pci_get_device(PCI_VENDOR_ID_INTEL,
+				      PCI_DEVICE_ID_INTEL_7320_0, NULL);
+		break;
+	}
+
+
+	pvt->dev_d0f0 = dev;
+	for (pres_dev = dev;
+	     ((struct pci_dev *) pres_dev->global_list.next != dev);
+	     pres_dev = (struct pci_dev *) pres_dev->global_list.next) {
+		pci_read_config_dword(pres_dev, PCI_COMMAND, &stat32);
+		stat = (u16) (stat32 >> 16);
+		/* clear any error bits */
+		if (stat32 & ((1 << 6) + (1 << 8)))
+			pci_write_config_word(pres_dev, PCI_STATUS, stat);
+	}
+	/* find the error reporting device and clear errors */
+	dev = pvt->dev_d0f1 = pci_dev_get(pvt->bridge_ck);
+	/* Turn off error disable & SMI in case the BIOS turned it on */
+	pci_write_config_byte(dev, E752X_HI_ERRMASK, 0x00);
+	pci_write_config_byte(dev, E752X_HI_SMICMD, 0x00);
+	pci_write_config_word(dev, E752X_SYSBUS_ERRMASK, 0x00);
+	pci_write_config_word(dev, E752X_SYSBUS_SMICMD, 0x00);
+	pci_write_config_byte(dev, E752X_BUF_ERRMASK, 0x00);
+	pci_write_config_byte(dev, E752X_BUF_SMICMD, 0x00);
+	pci_write_config_byte(dev, E752X_DRAM_ERRMASK, 0x00);
+	pci_write_config_byte(dev, E752X_DRAM_SMICMD, 0x00);
+	/* clear other MCH errors */
+	pci_read_config_dword(dev, E752X_FERR_GLOBAL, &stat32);
+	pci_write_config_dword(dev, E752X_FERR_GLOBAL, stat32);
+	pci_read_config_dword(dev, E752X_NERR_GLOBAL, &stat32);
+	pci_write_config_dword(dev, E752X_NERR_GLOBAL, stat32);
+	pci_read_config_byte(dev, E752X_HI_FERR, &stat8);
+	pci_write_config_byte(dev, E752X_HI_FERR, stat8);
+	pci_read_config_byte(dev, E752X_HI_NERR, &stat8);
+	pci_write_config_byte(dev, E752X_HI_NERR, stat8);
+	pci_read_config_dword(dev, E752X_SYSBUS_FERR, &stat32);
+	pci_write_config_dword(dev, E752X_SYSBUS_FERR, stat32);
+	pci_read_config_byte(dev, E752X_BUF_FERR, &stat8);
+	pci_write_config_byte(dev, E752X_BUF_FERR, stat8);
+	pci_read_config_byte(dev, E752X_BUF_NERR, &stat8);
+	pci_write_config_byte(dev, E752X_BUF_NERR, stat8);
+	pci_read_config_word(dev, E752X_DRAM_FERR, &stat16);
+	pci_write_config_word(dev, E752X_DRAM_FERR, stat16);
+	pci_read_config_word(dev, E752X_DRAM_NERR, &stat16);
+	pci_write_config_word(dev, E752X_DRAM_NERR, stat16);
+
+	/* get this far and it's successful */
+	debugf3("MC: " __FILE__ ": %s(): success\n", __func__);
+	return 0;
+
+fail:
+	if (mci) {
+		if (pvt->dev_d0f0)
+			pci_dev_put(pvt->dev_d0f0);
+		if (pvt->dev_d0f1)
+			pci_dev_put(pvt->dev_d0f1);
+		if (pvt->bridge_ck)
+			pci_dev_put(pvt->bridge_ck);
+		edac_mc_free(mci);
+	}
+	return rc;
+}
+
+/* returns count (>= 0), or negative on error */
+static int __devinit e752x_init_one(struct pci_dev *pdev,
+				    const struct pci_device_id *ent)
+{
+	debugf0("MC: " __FILE__ ": %s()\n", __func__);
+
+	/* wake up and enable device */
+	if(pci_enable_device(pdev) < 0)
+		return -EIO;
+	return e752x_probe1(pdev, ent->driver_data);
+}
+
+
+static void __devexit e752x_remove_one(struct pci_dev *pdev)
+{
+	struct mem_ctl_info *mci;
+	struct e752x_pvt *pvt;
+
+	debugf0(__FILE__ ": %s()\n", __func__);
+
+	if ((mci = edac_mc_find_mci_by_pdev(pdev)) == NULL)
+		return;
+
+	if (edac_mc_del_mc(mci))
+		return;
+
+	pvt = (struct e752x_pvt *) mci->pvt_info;
+	pci_dev_put(pvt->dev_d0f0);
+	pci_dev_put(pvt->dev_d0f1);
+	pci_dev_put(pvt->bridge_ck);
+	edac_mc_free(mci);
+}
+
+
+static const struct pci_device_id e752x_pci_tbl[] __devinitdata = {
+	{PCI_VEND_DEV(INTEL, 7520_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	 E7520},
+	{PCI_VEND_DEV(INTEL, 7525_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	 E7525},
+	{PCI_VEND_DEV(INTEL, 7320_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	 E7320},
+	{0,}			/* 0 terminated list. */
+};
+
+MODULE_DEVICE_TABLE(pci, e752x_pci_tbl);
+
+
+static struct pci_driver e752x_driver = {
+      name: BS_MOD_STR,
+      probe: e752x_init_one,
+      remove: __devexit_p(e752x_remove_one),
+      id_table: e752x_pci_tbl,
+};
+
+
+static int __init e752x_init(void)
+{
+	int pci_rc;
+
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+	pci_rc = pci_register_driver(&e752x_driver);
+	return (pci_rc < 0) ? pci_rc : 0;
+}
+
+
+static void __exit e752x_exit(void)
+{
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+	pci_unregister_driver(&e752x_driver);
+}
+
+
+module_init(e752x_init);
+module_exit(e752x_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Linux Networx (http://lnxi.com) Tom Zimmerman\n");
+MODULE_DESCRIPTION("MC support for Intel e752x memory controllers");
diff --git a/drivers/edac/e7xxx_edac.c b/drivers/edac/e7xxx_edac.c
new file mode 100644
index 0000000..d5e320d
--- /dev/null
+++ b/drivers/edac/e7xxx_edac.c
@@ -0,0 +1,558 @@
+/*
+ * Intel e7xxx Memory Controller kernel module
+ * (C) 2003 Linux Networx (http://lnxi.com)
+ * This file may be distributed under the terms of the
+ * GNU General Public License.
+ *
+ * See "enum e7xxx_chips" below for supported chipsets
+ *
+ * Written by Thayne Harbaugh
+ * Based on work by Dan Hollis <goemon at anime dot net> and others.
+ *	http://www.anime.net/~goemon/linux-ecc/
+ *
+ * Contributors:
+ * 	Eric Biederman (Linux Networx)
+ * 	Tom Zimmerman (Linux Networx)
+ * 	Jim Garlick (Lawrence Livermore National Labs)
+ *	Dave Peterson (Lawrence Livermore National Labs)
+ *	That One Guy (Some other place)
+ *	Wang Zhenyu (intel.com)
+ *
+ * $Id: edac_e7xxx.c,v 1.5.2.9 2005/10/05 00:43:44 dsp_llnl Exp $
+ *
+ */
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/slab.h>
+#include "edac_mc.h"
+
+
+#ifndef PCI_DEVICE_ID_INTEL_7205_0
+#define PCI_DEVICE_ID_INTEL_7205_0	0x255d
+#endif				/* PCI_DEVICE_ID_INTEL_7205_0 */
+
+#ifndef PCI_DEVICE_ID_INTEL_7205_1_ERR
+#define PCI_DEVICE_ID_INTEL_7205_1_ERR	0x2551
+#endif				/* PCI_DEVICE_ID_INTEL_7205_1_ERR */
+
+#ifndef PCI_DEVICE_ID_INTEL_7500_0
+#define PCI_DEVICE_ID_INTEL_7500_0	0x2540
+#endif				/* PCI_DEVICE_ID_INTEL_7500_0 */
+
+#ifndef PCI_DEVICE_ID_INTEL_7500_1_ERR
+#define PCI_DEVICE_ID_INTEL_7500_1_ERR	0x2541
+#endif				/* PCI_DEVICE_ID_INTEL_7500_1_ERR */
+
+#ifndef PCI_DEVICE_ID_INTEL_7501_0
+#define PCI_DEVICE_ID_INTEL_7501_0	0x254c
+#endif				/* PCI_DEVICE_ID_INTEL_7501_0 */
+
+#ifndef PCI_DEVICE_ID_INTEL_7501_1_ERR
+#define PCI_DEVICE_ID_INTEL_7501_1_ERR	0x2541
+#endif				/* PCI_DEVICE_ID_INTEL_7501_1_ERR */
+
+#ifndef PCI_DEVICE_ID_INTEL_7505_0
+#define PCI_DEVICE_ID_INTEL_7505_0	0x2550
+#endif				/* PCI_DEVICE_ID_INTEL_7505_0 */
+
+#ifndef PCI_DEVICE_ID_INTEL_7505_1_ERR
+#define PCI_DEVICE_ID_INTEL_7505_1_ERR	0x2551
+#endif				/* PCI_DEVICE_ID_INTEL_7505_1_ERR */
+
+
+#define E7XXX_NR_CSROWS		8	/* number of csrows */
+#define E7XXX_NR_DIMMS		8	/* FIXME - is this correct? */
+
+
+/* E7XXX register addresses - device 0 function 0 */
+#define E7XXX_DRB		0x60	/* DRAM row boundary register (8b) */
+#define E7XXX_DRA		0x70	/* DRAM row attribute register (8b) */
+					/*
+					 * 31   Device width row 7 0=x8 1=x4
+					 * 27   Device width row 6
+					 * 23   Device width row 5
+					 * 19   Device width row 4
+					 * 15   Device width row 3
+					 * 11   Device width row 2
+					 *  7   Device width row 1
+					 *  3   Device width row 0
+					 */
+#define E7XXX_DRC		0x7C	/* DRAM controller mode reg (32b) */
+					/*
+					 * 22    Number channels 0=1,1=2
+					 * 19:18 DRB Granularity 32/64MB
+					 */
+#define E7XXX_TOLM		0xC4	/* DRAM top of low memory reg (16b) */
+#define E7XXX_REMAPBASE		0xC6	/* DRAM remap base address reg (16b) */
+#define E7XXX_REMAPLIMIT	0xC8	/* DRAM remap limit address reg (16b) */
+
+/* E7XXX register addresses - device 0 function 1 */
+#define E7XXX_DRAM_FERR		0x80	/* DRAM first error register (8b) */
+#define E7XXX_DRAM_NERR		0x82	/* DRAM next error register (8b) */
+#define E7XXX_DRAM_CELOG_ADD	0xA0	/* DRAM first correctable memory */
+					/*     error address register (32b) */
+					/*
+					 * 31:28 Reserved
+					 * 27:6  CE address (4k block 33:12)
+					 *  5:0  Reserved
+					 */
+#define E7XXX_DRAM_UELOG_ADD	0xB0	/* DRAM first uncorrectable memory */
+					/*     error address register (32b) */
+					/*
+					 * 31:28 Reserved
+					 * 27:6  CE address (4k block 33:12)
+					 *  5:0  Reserved
+					 */
+#define E7XXX_DRAM_CELOG_SYNDROME 0xD0	/* DRAM first correctable memory */
+					/*     error syndrome register (16b) */
+
+enum e7xxx_chips {
+	E7500 = 0,
+	E7501,
+	E7505,
+	E7205,
+};
+
+
+struct e7xxx_pvt {
+	struct pci_dev *bridge_ck;
+	u32 tolm;
+	u32 remapbase;
+	u32 remaplimit;
+	const struct e7xxx_dev_info *dev_info;
+};
+
+
+struct e7xxx_dev_info {
+	u16 err_dev;
+	const char *ctl_name;
+};
+
+
+struct e7xxx_error_info {
+	u8 dram_ferr;
+	u8 dram_nerr;
+	u32 dram_celog_add;
+	u16 dram_celog_syndrome;
+	u32 dram_uelog_add;
+};
+
+static const struct e7xxx_dev_info e7xxx_devs[] = {
+	[E7500] = {
+		   .err_dev = PCI_DEVICE_ID_INTEL_7500_1_ERR,
+		   .ctl_name = "E7500"},
+	[E7501] = {
+		   .err_dev = PCI_DEVICE_ID_INTEL_7501_1_ERR,
+		   .ctl_name = "E7501"},
+	[E7505] = {
+		   .err_dev = PCI_DEVICE_ID_INTEL_7505_1_ERR,
+		   .ctl_name = "E7505"},
+	[E7205] = {
+		   .err_dev = PCI_DEVICE_ID_INTEL_7205_1_ERR,
+		   .ctl_name = "E7205"},
+};
+
+
+/* FIXME - is this valid for both SECDED and S4ECD4ED? */
+static inline int e7xxx_find_channel(u16 syndrome)
+{
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+
+	if ((syndrome & 0xff00) == 0)
+		return 0;
+	if ((syndrome & 0x00ff) == 0)
+		return 1;
+	if ((syndrome & 0xf000) == 0 || (syndrome & 0x0f00) == 0)
+		return 0;
+	return 1;
+}
+
+
+static unsigned long
+ctl_page_to_phys(struct mem_ctl_info *mci, unsigned long page)
+{
+	u32 remap;
+	struct e7xxx_pvt *pvt = (struct e7xxx_pvt *) mci->pvt_info;
+
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+
+	if ((page < pvt->tolm) ||
+	    ((page >= 0x100000) && (page < pvt->remapbase)))
+		return page;
+	remap = (page - pvt->tolm) + pvt->remapbase;
+	if (remap < pvt->remaplimit)
+		return remap;
+	printk(KERN_ERR "Invalid page %lx - out of range\n", page);
+	return pvt->tolm - 1;
+}
+
+
+static void process_ce(struct mem_ctl_info *mci, struct e7xxx_error_info *info)
+{
+	u32 error_1b, page;
+	u16 syndrome;
+	int row;
+	int channel;
+
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+
+	/* read the error address */
+	error_1b = info->dram_celog_add;
+	/* FIXME - should use PAGE_SHIFT */
+	page = error_1b >> 6;	/* convert the address to 4k page */
+	/* read the syndrome */
+	syndrome = info->dram_celog_syndrome;
+	/* FIXME - check for -1 */
+	row = edac_mc_find_csrow_by_page(mci, page);
+	/* convert syndrome to channel */
+	channel = e7xxx_find_channel(syndrome);
+	edac_mc_handle_ce(mci, page, 0, syndrome, row, channel,
+			       "e7xxx CE");
+}
+
+
+static void process_ce_no_info(struct mem_ctl_info *mci)
+{
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+	edac_mc_handle_ce_no_info(mci, "e7xxx CE log register overflow");
+}
+
+
+static void process_ue(struct mem_ctl_info *mci, struct e7xxx_error_info *info)
+{
+	u32 error_2b, block_page;
+	int row;
+
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+
+	/* read the error address */
+	error_2b = info->dram_uelog_add;
+	/* FIXME - should use PAGE_SHIFT */
+	block_page = error_2b >> 6;	/* convert to 4k address */
+	row = edac_mc_find_csrow_by_page(mci, block_page);
+	edac_mc_handle_ue(mci, block_page, 0, row, "e7xxx UE");
+}
+
+
+static void process_ue_no_info(struct mem_ctl_info *mci)
+{
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+	edac_mc_handle_ue_no_info(mci, "e7xxx UE log register overflow");
+}
+
+
+static void e7xxx_get_error_info (struct mem_ctl_info *mci,
+		struct e7xxx_error_info *info)
+{
+	struct e7xxx_pvt *pvt;
+
+	pvt = (struct e7xxx_pvt *) mci->pvt_info;
+	pci_read_config_byte(pvt->bridge_ck, E7XXX_DRAM_FERR,
+	    &info->dram_ferr);
+	pci_read_config_byte(pvt->bridge_ck, E7XXX_DRAM_NERR,
+	    &info->dram_nerr);
+
+	if ((info->dram_ferr & 1) || (info->dram_nerr & 1)) {
+		pci_read_config_dword(pvt->bridge_ck, E7XXX_DRAM_CELOG_ADD,
+		    &info->dram_celog_add);
+		pci_read_config_word(pvt->bridge_ck,
+		    E7XXX_DRAM_CELOG_SYNDROME, &info->dram_celog_syndrome);
+	}
+
+	if ((info->dram_ferr & 2) || (info->dram_nerr & 2))
+		pci_read_config_dword(pvt->bridge_ck, E7XXX_DRAM_UELOG_ADD,
+		    &info->dram_uelog_add);
+
+	if (info->dram_ferr & 3)
+		pci_write_bits8(pvt->bridge_ck, E7XXX_DRAM_FERR, 0x03,
+		    0x03);
+
+	if (info->dram_nerr & 3)
+		pci_write_bits8(pvt->bridge_ck, E7XXX_DRAM_NERR, 0x03,
+		    0x03);
+}
+
+
+static int e7xxx_process_error_info (struct mem_ctl_info *mci,
+		struct e7xxx_error_info *info, int handle_errors)
+{
+	int error_found;
+
+	error_found = 0;
+
+	/* decode and report errors */
+	if (info->dram_ferr & 1) {	/* check first error correctable */
+		error_found = 1;
+
+		if (handle_errors)
+			process_ce(mci, info);
+	}
+
+	if (info->dram_ferr & 2) {	/* check first error uncorrectable */
+		error_found = 1;
+
+		if (handle_errors)
+			process_ue(mci, info);
+	}
+
+	if (info->dram_nerr & 1) {	/* check next error correctable */
+		error_found = 1;
+
+		if (handle_errors) {
+			if (info->dram_ferr & 1)
+				process_ce_no_info(mci);
+			else
+				process_ce(mci, info);
+		}
+	}
+
+	if (info->dram_nerr & 2) {	/* check next error uncorrectable */
+		error_found = 1;
+
+		if (handle_errors) {
+			if (info->dram_ferr & 2)
+				process_ue_no_info(mci);
+			else
+				process_ue(mci, info);
+		}
+	}
+
+	return error_found;
+}
+
+
+static void e7xxx_check(struct mem_ctl_info *mci)
+{
+	struct e7xxx_error_info info;
+
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+	e7xxx_get_error_info(mci, &info);
+	e7xxx_process_error_info(mci, &info, 1);
+}
+
+
+static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx)
+{
+	int rc = -ENODEV;
+	int index;
+	u16 pci_data;
+	struct mem_ctl_info *mci = NULL;
+	struct e7xxx_pvt *pvt = NULL;
+	u32 drc;
+	int drc_chan = 1;	/* Number of channels 0=1chan,1=2chan */
+	int drc_drbg = 1;	/* DRB granularity 0=32mb,1=64mb */
+	int drc_ddim;		/* DRAM Data Integrity Mode 0=none,2=edac */
+	u32 dra;
+	unsigned long last_cumul_size;
+
+
+	debugf0("MC: " __FILE__ ": %s(): mci\n", __func__);
+
+	/* need to find out the number of channels */
+	pci_read_config_dword(pdev, E7XXX_DRC, &drc);
+	/* only e7501 can be single channel */
+	if (dev_idx == E7501) {
+		drc_chan = ((drc >> 22) & 0x1);
+		drc_drbg = (drc >> 18) & 0x3;
+	}
+	drc_ddim = (drc >> 20) & 0x3;
+
+	mci = edac_mc_alloc(sizeof(*pvt), E7XXX_NR_CSROWS, drc_chan + 1);
+
+	if (mci == NULL) {
+		rc = -ENOMEM;
+		goto fail;
+	}
+
+	debugf3("MC: " __FILE__ ": %s(): init mci\n", __func__);
+
+	mci->mtype_cap = MEM_FLAG_RDDR;
+	mci->edac_ctl_cap =
+	    EDAC_FLAG_NONE | EDAC_FLAG_SECDED | EDAC_FLAG_S4ECD4ED;
+	/* FIXME - what if different memory types are in different csrows? */
+	mci->mod_name = BS_MOD_STR;
+	mci->mod_ver = "$Revision: 1.5.2.9 $";
+	mci->pdev = pdev;
+
+	debugf3("MC: " __FILE__ ": %s(): init pvt\n", __func__);
+	pvt = (struct e7xxx_pvt *) mci->pvt_info;
+	pvt->dev_info = &e7xxx_devs[dev_idx];
+	pvt->bridge_ck = pci_get_device(PCI_VENDOR_ID_INTEL,
+					 pvt->dev_info->err_dev,
+					 pvt->bridge_ck);
+	if (!pvt->bridge_ck) {
+		printk(KERN_ERR
+		       "MC: error reporting device not found:"
+		       "vendor %x device 0x%x (broken BIOS?)\n",
+		       PCI_VENDOR_ID_INTEL, e7xxx_devs[dev_idx].err_dev);
+		goto fail;
+	}
+
+	debugf3("MC: " __FILE__ ": %s(): more mci init\n", __func__);
+	mci->ctl_name = pvt->dev_info->ctl_name;
+
+	mci->edac_check = e7xxx_check;
+	mci->ctl_page_to_phys = ctl_page_to_phys;
+
+	/* find out the device types */
+	pci_read_config_dword(pdev, E7XXX_DRA, &dra);
+
+	/*
+	 * The dram row boundary (DRB) reg values are boundary address
+	 * for each DRAM row with a granularity of 32 or 64MB (single/dual
+	 * channel operation).  DRB regs are cumulative; therefore DRB7 will
+	 * contain the total memory contained in all eight rows.
+	 */
+	for (last_cumul_size = index = 0; index < mci->nr_csrows; index++) {
+		u8 value;
+		u32 cumul_size;
+		/* mem_dev 0=x8, 1=x4 */
+		int mem_dev = (dra >> (index * 4 + 3)) & 0x1;
+		struct csrow_info *csrow = &mci->csrows[index];
+
+		pci_read_config_byte(mci->pdev, E7XXX_DRB + index, &value);
+		/* convert a 64 or 32 MiB DRB to a page size. */
+		cumul_size = value << (25 + drc_drbg - PAGE_SHIFT);
+		debugf3("MC: " __FILE__ ": %s(): (%d) cumul_size 0x%x\n",
+			__func__, index, cumul_size);
+		if (cumul_size == last_cumul_size)
+			continue;	/* not populated */
+
+		csrow->first_page = last_cumul_size;
+		csrow->last_page = cumul_size - 1;
+		csrow->nr_pages = cumul_size - last_cumul_size;
+		last_cumul_size = cumul_size;
+		csrow->grain = 1 << 12;	/* 4KiB - resolution of CELOG */
+		csrow->mtype = MEM_RDDR;	/* only one type supported */
+		csrow->dtype = mem_dev ? DEV_X4 : DEV_X8;
+
+		/*
+		 * if single channel or x8 devices then SECDED
+		 * if dual channel and x4 then S4ECD4ED
+		 */
+		if (drc_ddim) {
+			if (drc_chan && mem_dev) {
+				csrow->edac_mode = EDAC_S4ECD4ED;
+				mci->edac_cap |= EDAC_FLAG_S4ECD4ED;
+			} else {
+				csrow->edac_mode = EDAC_SECDED;
+				mci->edac_cap |= EDAC_FLAG_SECDED;
+			}
+		} else
+			csrow->edac_mode = EDAC_NONE;
+	}
+
+	mci->edac_cap |= EDAC_FLAG_NONE;
+
+	debugf3("MC: " __FILE__ ": %s(): tolm, remapbase, remaplimit\n",
+		__func__);
+	/* load the top of low memory, remap base, and remap limit vars */
+	pci_read_config_word(mci->pdev, E7XXX_TOLM, &pci_data);
+	pvt->tolm = ((u32) pci_data) << 4;
+	pci_read_config_word(mci->pdev, E7XXX_REMAPBASE, &pci_data);
+	pvt->remapbase = ((u32) pci_data) << 14;
+	pci_read_config_word(mci->pdev, E7XXX_REMAPLIMIT, &pci_data);
+	pvt->remaplimit = ((u32) pci_data) << 14;
+	printk("tolm = %x, remapbase = %x, remaplimit = %x\n", pvt->tolm,
+	       pvt->remapbase, pvt->remaplimit);
+
+	/* clear any pending errors, or initial state bits */
+	pci_write_bits8(pvt->bridge_ck, E7XXX_DRAM_FERR, 0x03, 0x03);
+	pci_write_bits8(pvt->bridge_ck, E7XXX_DRAM_NERR, 0x03, 0x03);
+
+	if (edac_mc_add_mc(mci) != 0) {
+		debugf3("MC: " __FILE__
+			": %s(): failed edac_mc_add_mc()\n",
+			__func__);
+		goto fail;
+	}
+
+	/* get this far and it's successful */
+	debugf3("MC: " __FILE__ ": %s(): success\n", __func__);
+	return 0;
+
+fail:
+	if (mci != NULL) {
+		if(pvt != NULL && pvt->bridge_ck)
+			pci_dev_put(pvt->bridge_ck);
+		edac_mc_free(mci);
+	}
+
+	return rc;
+}
+
+/* returns count (>= 0), or negative on error */
+static int __devinit
+e7xxx_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	debugf0("MC: " __FILE__ ": %s()\n", __func__);
+
+	/* wake up and enable device */
+	return pci_enable_device(pdev) ?
+	    -EIO : e7xxx_probe1(pdev, ent->driver_data);
+}
+
+
+static void __devexit e7xxx_remove_one(struct pci_dev *pdev)
+{
+	struct mem_ctl_info *mci;
+	struct e7xxx_pvt *pvt;
+
+	debugf0(__FILE__ ": %s()\n", __func__);
+
+	if (((mci = edac_mc_find_mci_by_pdev(pdev)) != 0) &&
+	    edac_mc_del_mc(mci)) {
+		pvt = (struct e7xxx_pvt *) mci->pvt_info;
+		pci_dev_put(pvt->bridge_ck);
+		edac_mc_free(mci);
+	}
+}
+
+
+static const struct pci_device_id e7xxx_pci_tbl[] __devinitdata = {
+	{PCI_VEND_DEV(INTEL, 7205_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	 E7205},
+	{PCI_VEND_DEV(INTEL, 7500_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	 E7500},
+	{PCI_VEND_DEV(INTEL, 7501_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	 E7501},
+	{PCI_VEND_DEV(INTEL, 7505_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	 E7505},
+	{0,}			/* 0 terminated list. */
+};
+
+MODULE_DEVICE_TABLE(pci, e7xxx_pci_tbl);
+
+
+static struct pci_driver e7xxx_driver = {
+	.name = BS_MOD_STR,
+	.probe = e7xxx_init_one,
+	.remove = __devexit_p(e7xxx_remove_one),
+	.id_table = e7xxx_pci_tbl,
+};
+
+
+static int __init e7xxx_init(void)
+{
+	return pci_register_driver(&e7xxx_driver);
+}
+
+
+static void __exit e7xxx_exit(void)
+{
+	pci_unregister_driver(&e7xxx_driver);
+}
+
+module_init(e7xxx_init);
+module_exit(e7xxx_exit);
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Linux Networx (http://lnxi.com) Thayne Harbaugh et al\n"
+	      "Based on.work by Dan Hollis et al");
+MODULE_DESCRIPTION("MC support for Intel e7xxx memory controllers");
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
new file mode 100644
index 0000000..4be9bd0
--- /dev/null
+++ b/drivers/edac/edac_mc.c
@@ -0,0 +1,2209 @@
+/*
+ * edac_mc kernel module
+ * (C) 2005 Linux Networx (http://lnxi.com)
+ * This file may be distributed under the terms of the
+ * GNU General Public License.
+ *
+ * Written by Thayne Harbaugh
+ * Based on work by Dan Hollis <goemon at anime dot net> and others.
+ *	http://www.anime.net/~goemon/linux-ecc/
+ *
+ * Modified by Dave Peterson and Doug Thompson
+ *
+ */
+
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <linux/sysctl.h>
+#include <linux/highmem.h>
+#include <linux/timer.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/sysdev.h>
+#include <linux/ctype.h>
+
+#include <asm/uaccess.h>
+#include <asm/page.h>
+#include <asm/edac.h>
+
+#include "edac_mc.h"
+
+#define	EDAC_MC_VERSION	"edac_mc  Ver: 2.0.0 " __DATE__
+
+#ifdef CONFIG_EDAC_DEBUG
+/* Values of 0 to 4 will generate output */
+int edac_debug_level = 1;
+EXPORT_SYMBOL(edac_debug_level);
+#endif
+
+/* EDAC Controls, setable by module parameter, and sysfs */
+static int log_ue = 1;
+static int log_ce = 1;
+static int panic_on_ue = 1;
+static int poll_msec = 1000;
+
+static int check_pci_parity = 0;	/* default YES check PCI parity */
+static int panic_on_pci_parity;		/* default no panic on PCI Parity */
+static atomic_t pci_parity_count = ATOMIC_INIT(0);
+
+/* lock to memory controller's control array */
+static DECLARE_MUTEX(mem_ctls_mutex);
+static struct list_head mc_devices = LIST_HEAD_INIT(mc_devices);
+
+/* Structure of the whitelist and blacklist arrays */
+struct edac_pci_device_list {
+	unsigned int  vendor;		/* Vendor ID */
+	unsigned int  device;		/* Deviice ID */
+};
+
+
+#define MAX_LISTED_PCI_DEVICES		32
+
+/* List of PCI devices (vendor-id:device-id) that should be skipped */
+static struct edac_pci_device_list pci_blacklist[MAX_LISTED_PCI_DEVICES];
+static int pci_blacklist_count;
+
+/* List of PCI devices (vendor-id:device-id) that should be scanned */
+static struct edac_pci_device_list pci_whitelist[MAX_LISTED_PCI_DEVICES];
+static int pci_whitelist_count ;
+
+/*  START sysfs data and methods */
+
+static const char *mem_types[] = {
+	[MEM_EMPTY] = "Empty",
+	[MEM_RESERVED] = "Reserved",
+	[MEM_UNKNOWN] = "Unknown",
+	[MEM_FPM] = "FPM",
+	[MEM_EDO] = "EDO",
+	[MEM_BEDO] = "BEDO",
+	[MEM_SDR] = "Unbuffered-SDR",
+	[MEM_RDR] = "Registered-SDR",
+	[MEM_DDR] = "Unbuffered-DDR",
+	[MEM_RDDR] = "Registered-DDR",
+	[MEM_RMBS] = "RMBS"
+};
+
+static const char *dev_types[] = {
+	[DEV_UNKNOWN] = "Unknown",
+	[DEV_X1] = "x1",
+	[DEV_X2] = "x2",
+	[DEV_X4] = "x4",
+	[DEV_X8] = "x8",
+	[DEV_X16] = "x16",
+	[DEV_X32] = "x32",
+	[DEV_X64] = "x64"
+};
+
+static const char *edac_caps[] = {
+	[EDAC_UNKNOWN] = "Unknown",
+	[EDAC_NONE] = "None",
+	[EDAC_RESERVED] = "Reserved",
+	[EDAC_PARITY] = "PARITY",
+	[EDAC_EC] = "EC",
+	[EDAC_SECDED] = "SECDED",
+	[EDAC_S2ECD2ED] = "S2ECD2ED",
+	[EDAC_S4ECD4ED] = "S4ECD4ED",
+	[EDAC_S8ECD8ED] = "S8ECD8ED",
+	[EDAC_S16ECD16ED] = "S16ECD16ED"
+};
+
+
+/* sysfs object: /sys/devices/system/edac */
+static struct sysdev_class edac_class = {
+	set_kset_name("edac"),
+};
+
+/* sysfs objects:
+ *	/sys/devices/system/edac/mc
+ *	/sys/devices/system/edac/pci
+ */
+static struct kobject edac_memctrl_kobj;
+static struct kobject edac_pci_kobj;
+
+/*
+ * /sys/devices/system/edac/mc;
+ * 	data structures and methods
+ */
+static ssize_t memctrl_string_show(void *ptr, char *buffer)
+{
+	char *value = (char*) ptr;
+	return sprintf(buffer, "%s\n", value);
+}
+
+static ssize_t memctrl_int_show(void *ptr, char *buffer)
+{
+	int *value = (int*) ptr;
+	return sprintf(buffer, "%d\n", *value);
+}
+
+static ssize_t memctrl_int_store(void *ptr, const char *buffer, size_t count)
+{
+	int *value = (int*) ptr;
+
+	if (isdigit(*buffer))
+		*value = simple_strtoul(buffer, NULL, 0);
+
+	return count;
+}
+
+struct memctrl_dev_attribute {
+	struct attribute	attr;
+	void	*value;
+	ssize_t (*show)(void *,char *);
+	ssize_t (*store)(void *, const char *, size_t);
+};
+
+/* Set of show/store abstract level functions for memory control object */
+static ssize_t
+memctrl_dev_show(struct kobject *kobj, struct attribute *attr, char *buffer)
+{
+	struct memctrl_dev_attribute *memctrl_dev;
+	memctrl_dev = (struct memctrl_dev_attribute*)attr;
+
+	if (memctrl_dev->show)
+		return memctrl_dev->show(memctrl_dev->value, buffer);
+	return -EIO;
+}
+
+static ssize_t
+memctrl_dev_store(struct kobject *kobj, struct attribute *attr,
+			const char *buffer, size_t count)
+{
+	struct memctrl_dev_attribute *memctrl_dev;
+	memctrl_dev = (struct memctrl_dev_attribute*)attr;
+
+	if (memctrl_dev->store)
+		return memctrl_dev->store(memctrl_dev->value, buffer, count);
+	return -EIO;
+}
+
+static struct sysfs_ops memctrlfs_ops = {
+	.show   = memctrl_dev_show,
+	.store  = memctrl_dev_store
+};
+
+#define MEMCTRL_ATTR(_name,_mode,_show,_store)			\
+struct memctrl_dev_attribute attr_##_name = {			\
+	.attr = {.name = __stringify(_name), .mode = _mode },	\
+	.value  = &_name,					\
+	.show   = _show,					\
+	.store  = _store,					\
+};
+
+#define MEMCTRL_STRING_ATTR(_name,_data,_mode,_show,_store)	\
+struct memctrl_dev_attribute attr_##_name = {			\
+	.attr = {.name = __stringify(_name), .mode = _mode },	\
+	.value  = _data,					\
+	.show   = _show,					\
+	.store  = _store,					\
+};
+
+/* cwrow<id> attribute f*/
+MEMCTRL_STRING_ATTR(mc_version,EDAC_MC_VERSION,S_IRUGO,memctrl_string_show,NULL);
+
+/* csrow<id> control files */
+MEMCTRL_ATTR(panic_on_ue,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store);
+MEMCTRL_ATTR(log_ue,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store);
+MEMCTRL_ATTR(log_ce,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store);
+MEMCTRL_ATTR(poll_msec,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store);
+
+
+/* Base Attributes of the memory ECC object */
+static struct memctrl_dev_attribute *memctrl_attr[] = {
+	&attr_panic_on_ue,
+	&attr_log_ue,
+	&attr_log_ce,
+	&attr_poll_msec,
+	&attr_mc_version,
+	NULL,
+};
+
+/* Main MC kobject release() function */
+static void edac_memctrl_master_release(struct kobject *kobj)
+{
+	debugf1("EDAC MC: " __FILE__ ": %s()\n", __func__);
+}
+
+static struct kobj_type ktype_memctrl = {
+	.release	= edac_memctrl_master_release,
+	.sysfs_ops	= &memctrlfs_ops,
+	.default_attrs	= (struct attribute **) memctrl_attr,
+};
+
+
+/* Initialize the main sysfs entries for edac:
+ *   /sys/devices/system/edac
+ *
+ * and children
+ *
+ * Return:  0 SUCCESS
+ *         !0 FAILURE
+ */
+static int edac_sysfs_memctrl_setup(void)
+{
+	int err=0;
+
+	debugf1("MC: " __FILE__ ": %s()\n", __func__);
+
+	/* create the /sys/devices/system/edac directory */
+	err = sysdev_class_register(&edac_class);
+	if (!err) {
+		/* Init the MC's kobject */
+		memset(&edac_memctrl_kobj, 0, sizeof (edac_memctrl_kobj));
+		kobject_init(&edac_memctrl_kobj);
+
+		edac_memctrl_kobj.parent = &edac_class.kset.kobj;
+		edac_memctrl_kobj.ktype = &ktype_memctrl;
+
+		/* generate sysfs "..../edac/mc"   */
+		err = kobject_set_name(&edac_memctrl_kobj,"mc");
+		if (!err) {
+			/* FIXME: maybe new sysdev_create_subdir() */
+			err = kobject_register(&edac_memctrl_kobj);
+			if (err) {
+				debugf1("Failed to register '.../edac/mc'\n");
+			} else {
+				debugf1("Registered '.../edac/mc' kobject\n");
+			}
+		}
+	} else {
+		debugf1(KERN_WARNING "__FILE__ %s() error=%d\n", __func__,err);
+	}
+
+	return err;
+}
+
+/*
+ * MC teardown:
+ *	the '..../edac/mc' kobject followed by '..../edac' itself
+ */
+static void edac_sysfs_memctrl_teardown(void)
+{
+	debugf0("MC: " __FILE__ ": %s()\n", __func__);
+
+	/* Unregister the MC's kobject */
+	kobject_unregister(&edac_memctrl_kobj);
+
+	/* release the master edac mc kobject */
+	kobject_put(&edac_memctrl_kobj);
+
+	/* Unregister the 'edac' object */
+	sysdev_class_unregister(&edac_class);
+}
+
+/*
+ * /sys/devices/system/edac/pci;
+ * 	data structures and methods
+ */
+
+struct list_control {
+	struct edac_pci_device_list *list;
+	int *count;
+};
+
+/* Output the list as:  vendor_id:device:id<,vendor_id:device_id> */
+static ssize_t edac_pci_list_string_show(void *ptr, char *buffer)
+{
+	struct list_control *listctl;
+	struct edac_pci_device_list *list;
+	char *p = buffer;
+	int len=0;
+	int i;
+
+	listctl = ptr;
+	list = listctl->list;
+
+	for (i = 0; i < *(listctl->count); i++, list++ ) {
+		if (len > 0)
+			len += snprintf(p + len, (PAGE_SIZE-len), ",");
+
+		len += snprintf(p + len,
+				(PAGE_SIZE-len),
+				"%x:%x",
+				list->vendor,list->device);
+	}
+
+	len += snprintf(p + len,(PAGE_SIZE-len), "\n");
+
+	return (ssize_t) len;
+}
+
+/**
+ *
+ * Scan string from **s to **e looking for one 'vendor:device' tuple
+ * where each field is a hex value
+ *
+ * return 0 if an entry is NOT found
+ * return 1 if an entry is found
+ *	fill in *vendor_id and *device_id with values found
+ *
+ * In both cases, make sure *s has been moved forward toward *e
+ */
+static int parse_one_device(const char **s,const char **e,
+	unsigned int *vendor_id, unsigned int *device_id)
+{
+	const char *runner, *p;
+
+	/* if null byte, we are done */
+	if (!**s) {
+		(*s)++;	/* keep *s moving */
+		return 0;
+	}
+
+	/* skip over newlines & whitespace */
+	if ((**s == '\n') || isspace(**s)) {
+		(*s)++;
+		return 0;
+	}
+
+	if (!isxdigit(**s)) {
+		(*s)++;
+		return 0;
+	}
+
+	/* parse vendor_id */
+	runner = *s;
+	while (runner < *e) {
+		/* scan for vendor:device delimiter */
+		if (*runner == ':') {
+			*vendor_id = simple_strtol((char*) *s, (char**) &p, 16);
+			runner = p + 1;
+			break;
+		}
+		runner++;
+	}
+
+	if (!isxdigit(*runner)) {
+		*s = ++runner;
+		return 0;
+	}
+
+	/* parse device_id */
+	if (runner < *e) {
+		*device_id = simple_strtol((char*)runner, (char**)&p, 16);
+		runner = p;
+	}
+
+	*s = runner;
+
+	return 1;
+}
+
+static ssize_t edac_pci_list_string_store(void *ptr, const char *buffer,
+					size_t count)
+{
+	struct list_control *listctl;
+	struct edac_pci_device_list *list;
+	unsigned int vendor_id, device_id;
+	const char *s, *e;
+	int *index;
+
+	s = (char*)buffer;
+	e = s + count;
+
+	listctl = ptr;
+	list = listctl->list;
+	index = listctl->count;
+
+	*index = 0;
+	while (*index < MAX_LISTED_PCI_DEVICES) {
+
+		if (parse_one_device(&s,&e,&vendor_id,&device_id)) {
+			list[ *index ].vendor = vendor_id;
+			list[ *index ].device = device_id;
+			(*index)++;
+		}
+
+		/* check for all data consume */
+		if (s >= e)
+			break;
+	}
+
+	return count;
+}
+
+static ssize_t edac_pci_int_show(void *ptr, char *buffer)
+{
+	int *value = ptr;
+	return sprintf(buffer,"%d\n",*value);
+}
+
+static ssize_t edac_pci_int_store(void *ptr, const char *buffer, size_t count)
+{
+	int *value = ptr;
+
+	if (isdigit(*buffer))
+		*value = simple_strtoul(buffer,NULL,0);
+
+	return count;
+}
+
+struct edac_pci_dev_attribute {
+	struct attribute	attr;
+	void	*value;
+	ssize_t (*show)(void *,char *);
+	ssize_t (*store)(void *, const char *,size_t);
+};
+
+/* Set of show/store abstract level functions for PCI Parity object */
+static ssize_t edac_pci_dev_show(struct kobject *kobj, struct attribute *attr,
+				char *buffer)
+{
+	struct edac_pci_dev_attribute *edac_pci_dev;
+	edac_pci_dev= (struct edac_pci_dev_attribute*)attr;
+
+	if (edac_pci_dev->show)
+		return edac_pci_dev->show(edac_pci_dev->value, buffer);
+	return -EIO;
+}
+
+static ssize_t edac_pci_dev_store(struct kobject *kobj, struct attribute *attr,
+				const char *buffer, size_t count)
+{
+	struct edac_pci_dev_attribute *edac_pci_dev;
+	edac_pci_dev= (struct edac_pci_dev_attribute*)attr;
+
+	if (edac_pci_dev->show)
+		return edac_pci_dev->store(edac_pci_dev->value, buffer, count);
+	return -EIO;
+}
+
+static struct sysfs_ops edac_pci_sysfs_ops = {
+	.show   = edac_pci_dev_show,
+	.store  = edac_pci_dev_store
+};
+
+
+#define EDAC_PCI_ATTR(_name,_mode,_show,_store)			\
+struct edac_pci_dev_attribute edac_pci_attr_##_name = {		\
+	.attr = {.name = __stringify(_name), .mode = _mode },	\
+	.value  = &_name,					\
+	.show   = _show,					\
+	.store  = _store,					\
+};
+
+#define EDAC_PCI_STRING_ATTR(_name,_data,_mode,_show,_store)	\
+struct edac_pci_dev_attribute edac_pci_attr_##_name = {		\
+	.attr = {.name = __stringify(_name), .mode = _mode },	\
+	.value  = _data,					\
+	.show   = _show,					\
+	.store  = _store,					\
+};
+
+static struct list_control pci_whitelist_control = {
+	.list = pci_whitelist,
+	.count = &pci_whitelist_count
+};
+
+static struct list_control pci_blacklist_control = {
+	.list = pci_blacklist,
+	.count = &pci_blacklist_count
+};
+
+/* whitelist attribute */
+EDAC_PCI_STRING_ATTR(pci_parity_whitelist,
+	&pci_whitelist_control,
+	S_IRUGO|S_IWUSR,
+	edac_pci_list_string_show,
+	edac_pci_list_string_store);
+
+EDAC_PCI_STRING_ATTR(pci_parity_blacklist,
+	&pci_blacklist_control,
+	S_IRUGO|S_IWUSR,
+	edac_pci_list_string_show,
+	edac_pci_list_string_store);
+
+/* PCI Parity control files */
+EDAC_PCI_ATTR(check_pci_parity,S_IRUGO|S_IWUSR,edac_pci_int_show,edac_pci_int_store);
+EDAC_PCI_ATTR(panic_on_pci_parity,S_IRUGO|S_IWUSR,edac_pci_int_show,edac_pci_int_store);
+EDAC_PCI_ATTR(pci_parity_count,S_IRUGO,edac_pci_int_show,NULL);
+
+/* Base Attributes of the memory ECC object */
+static struct edac_pci_dev_attribute *edac_pci_attr[] = {
+	&edac_pci_attr_check_pci_parity,
+	&edac_pci_attr_panic_on_pci_parity,
+	&edac_pci_attr_pci_parity_count,
+	&edac_pci_attr_pci_parity_whitelist,
+	&edac_pci_attr_pci_parity_blacklist,
+	NULL,
+};
+
+/* No memory to release */
+static void edac_pci_release(struct kobject *kobj)
+{
+	debugf1("EDAC PCI: " __FILE__ ": %s()\n", __func__);
+}
+
+static struct kobj_type ktype_edac_pci = {
+	.release	= edac_pci_release,
+	.sysfs_ops	= &edac_pci_sysfs_ops,
+	.default_attrs	= (struct attribute **) edac_pci_attr,
+};
+
+/**
+ * edac_sysfs_pci_setup()
+ *
+ */
+static int edac_sysfs_pci_setup(void)
+{
+	int err;
+
+	debugf1("MC: " __FILE__ ": %s()\n", __func__);
+
+	memset(&edac_pci_kobj, 0, sizeof(edac_pci_kobj));
+
+	kobject_init(&edac_pci_kobj);
+	edac_pci_kobj.parent = &edac_class.kset.kobj;
+	edac_pci_kobj.ktype = &ktype_edac_pci;
+
+	err = kobject_set_name(&edac_pci_kobj, "pci");
+	if (!err) {
+		/* Instanstiate the csrow object */
+		/* FIXME: maybe new sysdev_create_subdir() */
+		err = kobject_register(&edac_pci_kobj);
+		if (err)
+			debugf1("Failed to register '.../edac/pci'\n");
+		else
+			debugf1("Registered '.../edac/pci' kobject\n");
+	}
+	return err;
+}
+
+
+static void edac_sysfs_pci_teardown(void)
+{
+	debugf0("MC: " __FILE__ ": %s()\n", __func__);
+
+	kobject_unregister(&edac_pci_kobj);
+	kobject_put(&edac_pci_kobj);
+}
+
+/* EDAC sysfs CSROW data structures and methods */
+
+/* Set of more detailed csrow<id> attribute show/store functions */
+static ssize_t csrow_ch0_dimm_label_show(struct csrow_info *csrow, char *data)
+{
+	ssize_t size = 0;
+
+	if (csrow->nr_channels > 0) {
+		size = snprintf(data, EDAC_MC_LABEL_LEN,"%s\n",
+			csrow->channels[0].label);
+	}
+	return size;
+}
+
+static ssize_t csrow_ch1_dimm_label_show(struct csrow_info *csrow, char *data)
+{
+	ssize_t size = 0;
+
+	if (csrow->nr_channels > 0) {
+		size = snprintf(data, EDAC_MC_LABEL_LEN, "%s\n",
+			csrow->channels[1].label);
+	}
+	return size;
+}
+
+static ssize_t csrow_ch0_dimm_label_store(struct csrow_info *csrow,
+			const char *data, size_t size)
+{
+	ssize_t max_size = 0;
+
+	if (csrow->nr_channels > 0) {
+		max_size = min((ssize_t)size,(ssize_t)EDAC_MC_LABEL_LEN-1);
+		strncpy(csrow->channels[0].label, data, max_size);
+		csrow->channels[0].label[max_size] = '\0';
+	}
+	return size;
+}
+
+static ssize_t csrow_ch1_dimm_label_store(struct csrow_info *csrow,
+			const char *data, size_t size)
+{
+	ssize_t max_size = 0;
+
+	if (csrow->nr_channels > 1) {
+		max_size = min((ssize_t)size,(ssize_t)EDAC_MC_LABEL_LEN-1);
+		strncpy(csrow->channels[1].label, data, max_size);
+		csrow->channels[1].label[max_size] = '\0';
+	}
+	return max_size;
+}
+
+static ssize_t csrow_ue_count_show(struct csrow_info *csrow, char *data)
+{
+	return sprintf(data,"%u\n", csrow->ue_count);
+}
+
+static ssize_t csrow_ce_count_show(struct csrow_info *csrow, char *data)
+{
+	return sprintf(data,"%u\n", csrow->ce_count);
+}
+
+static ssize_t csrow_ch0_ce_count_show(struct csrow_info *csrow, char *data)
+{
+	ssize_t size = 0;
+
+	if (csrow->nr_channels > 0) {
+		size = sprintf(data,"%u\n", csrow->channels[0].ce_count);
+	}
+	return size;
+}
+
+static ssize_t csrow_ch1_ce_count_show(struct csrow_info *csrow, char *data)
+{
+	ssize_t size = 0;
+
+	if (csrow->nr_channels > 1) {
+		size = sprintf(data,"%u\n", csrow->channels[1].ce_count);
+	}
+	return size;
+}
+
+static ssize_t csrow_size_show(struct csrow_info *csrow, char *data)
+{
+	return sprintf(data,"%u\n", PAGES_TO_MiB(csrow->nr_pages));
+}
+
+static ssize_t csrow_mem_type_show(struct csrow_info *csrow, char *data)
+{
+	return sprintf(data,"%s\n", mem_types[csrow->mtype]);
+}
+
+static ssize_t csrow_dev_type_show(struct csrow_info *csrow, char *data)
+{
+	return sprintf(data,"%s\n", dev_types[csrow->dtype]);
+}
+
+static ssize_t csrow_edac_mode_show(struct csrow_info *csrow, char *data)
+{
+	return sprintf(data,"%s\n", edac_caps[csrow->edac_mode]);
+}
+
+struct csrowdev_attribute {
+	struct attribute	attr;
+	ssize_t (*show)(struct csrow_info *,char *);
+	ssize_t (*store)(struct csrow_info *, const char *,size_t);
+};
+
+#define to_csrow(k) container_of(k, struct csrow_info, kobj)
+#define to_csrowdev_attr(a) container_of(a, struct csrowdev_attribute, attr)
+
+/* Set of show/store higher level functions for csrow objects */
+static ssize_t csrowdev_show(struct kobject *kobj, struct attribute *attr,
+				char *buffer)
+{
+	struct csrow_info *csrow = to_csrow(kobj);
+	struct csrowdev_attribute *csrowdev_attr = to_csrowdev_attr(attr);
+
+	if (csrowdev_attr->show)
+		return csrowdev_attr->show(csrow, buffer);
+	return -EIO;
+}
+
+static ssize_t csrowdev_store(struct kobject *kobj, struct attribute *attr,
+				const char *buffer, size_t count)
+{
+	struct csrow_info *csrow = to_csrow(kobj);
+	struct csrowdev_attribute * csrowdev_attr = to_csrowdev_attr(attr);
+
+	if (csrowdev_attr->store)
+		return csrowdev_attr->store(csrow, buffer, count);
+	return -EIO;
+}
+
+static struct sysfs_ops csrowfs_ops = {
+	.show   = csrowdev_show,
+	.store  = csrowdev_store
+};
+
+#define CSROWDEV_ATTR(_name,_mode,_show,_store)			\
+struct csrowdev_attribute attr_##_name = {			\
+	.attr = {.name = __stringify(_name), .mode = _mode },	\
+	.show   = _show,					\
+	.store  = _store,					\
+};
+
+/* cwrow<id>/attribute files */
+CSROWDEV_ATTR(size_mb,S_IRUGO,csrow_size_show,NULL);
+CSROWDEV_ATTR(dev_type,S_IRUGO,csrow_dev_type_show,NULL);
+CSROWDEV_ATTR(mem_type,S_IRUGO,csrow_mem_type_show,NULL);
+CSROWDEV_ATTR(edac_mode,S_IRUGO,csrow_edac_mode_show,NULL);
+CSROWDEV_ATTR(ue_count,S_IRUGO,csrow_ue_count_show,NULL);
+CSROWDEV_ATTR(ce_count,S_IRUGO,csrow_ce_count_show,NULL);
+CSROWDEV_ATTR(ch0_ce_count,S_IRUGO,csrow_ch0_ce_count_show,NULL);
+CSROWDEV_ATTR(ch1_ce_count,S_IRUGO,csrow_ch1_ce_count_show,NULL);
+
+/* control/attribute files */
+CSROWDEV_ATTR(ch0_dimm_label,S_IRUGO|S_IWUSR,
+		csrow_ch0_dimm_label_show,
+		csrow_ch0_dimm_label_store);
+CSROWDEV_ATTR(ch1_dimm_label,S_IRUGO|S_IWUSR,
+		csrow_ch1_dimm_label_show,
+		csrow_ch1_dimm_label_store);
+
+
+/* Attributes of the CSROW<id> object */
+static struct csrowdev_attribute *csrow_attr[] = {
+	&attr_dev_type,
+	&attr_mem_type,
+	&attr_edac_mode,
+	&attr_size_mb,
+	&attr_ue_count,
+	&attr_ce_count,
+	&attr_ch0_ce_count,
+	&attr_ch1_ce_count,
+	&attr_ch0_dimm_label,
+	&attr_ch1_dimm_label,
+	NULL,
+};
+
+
+/* No memory to release */
+static void edac_csrow_instance_release(struct kobject *kobj)
+{
+	debugf1("EDAC MC: " __FILE__ ": %s()\n", __func__);
+}
+
+static struct kobj_type ktype_csrow = {
+	.release	= edac_csrow_instance_release,
+	.sysfs_ops	= &csrowfs_ops,
+	.default_attrs	= (struct attribute **) csrow_attr,
+};
+
+/* Create a CSROW object under specifed edac_mc_device */
+static int edac_create_csrow_object(struct kobject *edac_mci_kobj,
+				struct csrow_info *csrow, int index )
+{
+	int err = 0;
+
+	debugf0("MC: " __FILE__ ": %s()\n", __func__);
+
+	memset(&csrow->kobj, 0, sizeof(csrow->kobj));
+
+	/* generate ..../edac/mc/mc<id>/csrow<index>   */
+
+	kobject_init(&csrow->kobj);
+	csrow->kobj.parent = edac_mci_kobj;
+	csrow->kobj.ktype = &ktype_csrow;
+
+	/* name this instance of csrow<id> */
+	err = kobject_set_name(&csrow->kobj,"csrow%d",index);
+	if (!err) {
+		/* Instanstiate the csrow object */
+		err = kobject_register(&csrow->kobj);
+		if (err)
+			debugf0("Failed to register CSROW%d\n",index);
+		else
+			debugf0("Registered CSROW%d\n",index);
+	}
+
+	return err;
+}
+
+/* sysfs data structures and methods for the MCI kobjects */
+
+static ssize_t mci_reset_counters_store(struct mem_ctl_info  *mci,
+					const char *data, size_t count )
+{
+	int row, chan;
+
+	mci->ue_noinfo_count = 0;
+	mci->ce_noinfo_count = 0;
+	mci->ue_count = 0;
+	mci->ce_count = 0;
+	for (row = 0; row < mci->nr_csrows; row++) {
+		struct csrow_info *ri = &mci->csrows[row];
+
+		ri->ue_count = 0;
+		ri->ce_count = 0;
+		for (chan = 0; chan < ri->nr_channels; chan++)
+			ri->channels[chan].ce_count = 0;
+	}
+	mci->start_time = jiffies;
+
+	return count;
+}
+
+static ssize_t mci_ue_count_show(struct mem_ctl_info *mci, char *data)
+{
+	return sprintf(data,"%d\n", mci->ue_count);
+}
+
+static ssize_t mci_ce_count_show(struct mem_ctl_info *mci, char *data)
+{
+	return sprintf(data,"%d\n", mci->ce_count);
+}
+
+static ssize_t mci_ce_noinfo_show(struct mem_ctl_info *mci, char *data)
+{
+	return sprintf(data,"%d\n", mci->ce_noinfo_count);
+}
+
+static ssize_t mci_ue_noinfo_show(struct mem_ctl_info *mci, char *data)
+{
+	return sprintf(data,"%d\n", mci->ue_noinfo_count);
+}
+
+static ssize_t mci_seconds_show(struct mem_ctl_info *mci, char *data)
+{
+	return sprintf(data,"%ld\n", (jiffies - mci->start_time) / HZ);
+}
+
+static ssize_t mci_mod_name_show(struct mem_ctl_info *mci, char *data)
+{
+	return sprintf(data,"%s %s\n", mci->mod_name, mci->mod_ver);
+}
+
+static ssize_t mci_ctl_name_show(struct mem_ctl_info *mci, char *data)
+{
+	return sprintf(data,"%s\n", mci->ctl_name);
+}
+
+static int mci_output_edac_cap(char *buf, unsigned long edac_cap)
+{
+	char *p = buf;
+	int bit_idx;
+
+	for (bit_idx = 0; bit_idx < 8 * sizeof(edac_cap); bit_idx++) {
+		if ((edac_cap >> bit_idx) & 0x1)
+			p += sprintf(p, "%s ", edac_caps[bit_idx]);
+	}
+
+	return p - buf;
+}
+
+static ssize_t mci_edac_capability_show(struct mem_ctl_info *mci, char *data)
+{
+	char *p = data;
+
+	p += mci_output_edac_cap(p,mci->edac_ctl_cap);
+	p += sprintf(p, "\n");
+
+	return p - data;
+}
+
+static ssize_t mci_edac_current_capability_show(struct mem_ctl_info *mci,
+						char *data)
+{
+	char *p = data;
+
+	p += mci_output_edac_cap(p,mci->edac_cap);
+	p += sprintf(p, "\n");
+
+	return p - data;
+}
+
+static int mci_output_mtype_cap(char *buf, unsigned long mtype_cap)
+{
+	char *p = buf;
+	int bit_idx;
+
+	for (bit_idx = 0; bit_idx < 8 * sizeof(mtype_cap); bit_idx++) {
+		if ((mtype_cap >> bit_idx) & 0x1)
+			p += sprintf(p, "%s ", mem_types[bit_idx]);
+	}
+
+	return p - buf;
+}
+
+static ssize_t mci_supported_mem_type_show(struct mem_ctl_info *mci, char *data)
+{
+	char *p = data;
+
+	p += mci_output_mtype_cap(p,mci->mtype_cap);
+	p += sprintf(p, "\n");
+
+	return p - data;
+}
+
+static ssize_t mci_size_mb_show(struct mem_ctl_info *mci, char *data)
+{
+	int total_pages, csrow_idx;
+
+	for (total_pages = csrow_idx = 0; csrow_idx < mci->nr_csrows;
+			csrow_idx++) {
+		struct csrow_info *csrow = &mci->csrows[csrow_idx];
+
+		if (!csrow->nr_pages)
+			continue;
+		total_pages += csrow->nr_pages;
+	}
+
+	return sprintf(data,"%u\n", PAGES_TO_MiB(total_pages));
+}
+
+struct mcidev_attribute {
+	struct attribute	attr;
+	ssize_t (*show)(struct mem_ctl_info *,char *);
+	ssize_t (*store)(struct mem_ctl_info *, const char *,size_t);
+};
+
+#define to_mci(k) container_of(k, struct mem_ctl_info, edac_mci_kobj)
+#define to_mcidev_attr(a) container_of(a, struct mcidev_attribute, attr)
+
+static ssize_t mcidev_show(struct kobject *kobj, struct attribute *attr,
+			char *buffer)
+{
+	struct mem_ctl_info *mem_ctl_info = to_mci(kobj);
+	struct mcidev_attribute * mcidev_attr = to_mcidev_attr(attr);
+
+	if (mcidev_attr->show)
+		return mcidev_attr->show(mem_ctl_info, buffer);
+	return -EIO;
+}
+
+static ssize_t mcidev_store(struct kobject *kobj, struct attribute *attr,
+				const char *buffer, size_t count)
+{
+	struct mem_ctl_info *mem_ctl_info = to_mci(kobj);
+	struct mcidev_attribute * mcidev_attr = to_mcidev_attr(attr);
+
+	if (mcidev_attr->store)
+		return mcidev_attr->store(mem_ctl_info, buffer, count);
+	return -EIO;
+}
+
+static struct sysfs_ops mci_ops = {
+	.show   = mcidev_show,
+	.store  = mcidev_store
+};
+
+#define MCIDEV_ATTR(_name,_mode,_show,_store)			\
+struct mcidev_attribute mci_attr_##_name = {			\
+	.attr = {.name = __stringify(_name), .mode = _mode },	\
+	.show   = _show,					\
+	.store  = _store,					\
+};
+
+/* Control file */
+MCIDEV_ATTR(reset_counters,S_IWUSR,NULL,mci_reset_counters_store);
+
+/* Attribute files */
+MCIDEV_ATTR(mc_name,S_IRUGO,mci_ctl_name_show,NULL);
+MCIDEV_ATTR(module_name,S_IRUGO,mci_mod_name_show,NULL);
+MCIDEV_ATTR(edac_capability,S_IRUGO,mci_edac_capability_show,NULL);
+MCIDEV_ATTR(size_mb,S_IRUGO,mci_size_mb_show,NULL);
+MCIDEV_ATTR(seconds_since_reset,S_IRUGO,mci_seconds_show,NULL);
+MCIDEV_ATTR(ue_noinfo_count,S_IRUGO,mci_ue_noinfo_show,NULL);
+MCIDEV_ATTR(ce_noinfo_count,S_IRUGO,mci_ce_noinfo_show,NULL);
+MCIDEV_ATTR(ue_count,S_IRUGO,mci_ue_count_show,NULL);
+MCIDEV_ATTR(ce_count,S_IRUGO,mci_ce_count_show,NULL);
+MCIDEV_ATTR(edac_current_capability,S_IRUGO,
+	mci_edac_current_capability_show,NULL);
+MCIDEV_ATTR(supported_mem_type,S_IRUGO,
+	mci_supported_mem_type_show,NULL);
+
+
+static struct mcidev_attribute *mci_attr[] = {
+	&mci_attr_reset_counters,
+	&mci_attr_module_name,
+	&mci_attr_mc_name,
+	&mci_attr_edac_capability,
+	&mci_attr_edac_current_capability,
+	&mci_attr_supported_mem_type,
+	&mci_attr_size_mb,
+	&mci_attr_seconds_since_reset,
+	&mci_attr_ue_noinfo_count,
+	&mci_attr_ce_noinfo_count,
+	&mci_attr_ue_count,
+	&mci_attr_ce_count,
+	NULL
+};
+
+
+/*
+ * Release of a MC controlling instance
+ */
+static void edac_mci_instance_release(struct kobject *kobj)
+{
+	struct mem_ctl_info *mci;
+	mci = container_of(kobj,struct mem_ctl_info,edac_mci_kobj);
+
+	debugf0("MC: " __FILE__ ": %s() idx=%d calling kfree\n",
+		__func__, mci->mc_idx);
+
+	kfree(mci);
+}
+
+static struct kobj_type ktype_mci = {
+	.release	= edac_mci_instance_release,
+	.sysfs_ops	= &mci_ops,
+	.default_attrs	= (struct attribute **) mci_attr,
+};
+
+#define EDAC_DEVICE_SYMLINK	"device"
+
+/*
+ * Create a new Memory Controller kobject instance,
+ *	mc<id> under the 'mc' directory
+ *
+ * Return:
+ *	0	Success
+ *	!0	Failure
+ */
+static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
+{
+	int i;
+	int err;
+	struct csrow_info *csrow;
+	struct kobject *edac_mci_kobj=&mci->edac_mci_kobj;
+
+	debugf0("MC: " __FILE__ ": %s() idx=%d\n", __func__, mci->mc_idx);
+
+	memset(edac_mci_kobj, 0, sizeof(*edac_mci_kobj));
+	kobject_init(edac_mci_kobj);
+
+	/* set the name of the mc<id> object */
+	err = kobject_set_name(edac_mci_kobj,"mc%d",mci->mc_idx);
+	if (err)
+		return err;
+
+	/* link to our parent the '..../edac/mc' object */
+	edac_mci_kobj->parent = &edac_memctrl_kobj;
+	edac_mci_kobj->ktype = &ktype_mci;
+
+	/* register the mc<id> kobject */
+	err = kobject_register(edac_mci_kobj);
+	if (err)
+		return err;
+
+	/* create a symlink for the device */
+	err = sysfs_create_link(edac_mci_kobj, &mci->pdev->dev.kobj,
+				EDAC_DEVICE_SYMLINK);
+	if (err) {
+		kobject_unregister(edac_mci_kobj);
+		return err;
+	}
+
+	/* Make directories for each CSROW object
+	 * under the mc<id> kobject
+	 */
+	for (i = 0; i < mci->nr_csrows; i++) {
+
+		csrow = &mci->csrows[i];
+
+		/* Only expose populated CSROWs */
+		if (csrow->nr_pages > 0) {
+			err = edac_create_csrow_object(edac_mci_kobj,csrow,i);
+			if (err)
+				goto fail;
+		}
+	}
+
+	/* Mark this MCI instance as having sysfs entries */
+	mci->sysfs_active = MCI_SYSFS_ACTIVE;
+
+	return 0;
+
+
+	/* CSROW error: backout what has already been registered,  */
+fail:
+	for ( i--; i >= 0; i--) {
+		if (csrow->nr_pages > 0) {
+			kobject_unregister(&mci->csrows[i].kobj);
+			kobject_put(&mci->csrows[i].kobj);
+		}
+	}
+
+	kobject_unregister(edac_mci_kobj);
+	kobject_put(edac_mci_kobj);
+
+	return err;
+}
+
+/*
+ * remove a Memory Controller instance
+ */
+static void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
+{
+	int i;
+
+	debugf0("MC: " __FILE__ ": %s()\n", __func__);
+
+	/* remove all csrow kobjects */
+	for (i = 0; i < mci->nr_csrows; i++) {
+		if (mci->csrows[i].nr_pages > 0)  {
+			kobject_unregister(&mci->csrows[i].kobj);
+			kobject_put(&mci->csrows[i].kobj);
+		}
+	}
+
+	sysfs_remove_link(&mci->edac_mci_kobj, EDAC_DEVICE_SYMLINK);
+
+	kobject_unregister(&mci->edac_mci_kobj);
+	kobject_put(&mci->edac_mci_kobj);
+}
+
+/* END OF sysfs data and methods */
+
+#ifdef CONFIG_EDAC_DEBUG
+
+EXPORT_SYMBOL(edac_mc_dump_channel);
+
+void edac_mc_dump_channel(struct channel_info *chan)
+{
+	debugf4("\tchannel = %p\n", chan);
+	debugf4("\tchannel->chan_idx = %d\n", chan->chan_idx);
+	debugf4("\tchannel->ce_count = %d\n", chan->ce_count);
+	debugf4("\tchannel->label = '%s'\n", chan->label);
+	debugf4("\tchannel->csrow = %p\n\n", chan->csrow);
+}
+
+
+EXPORT_SYMBOL(edac_mc_dump_csrow);
+
+void edac_mc_dump_csrow(struct csrow_info *csrow)
+{
+	debugf4("\tcsrow = %p\n", csrow);
+	debugf4("\tcsrow->csrow_idx = %d\n", csrow->csrow_idx);
+	debugf4("\tcsrow->first_page = 0x%lx\n",
+		csrow->first_page);
+	debugf4("\tcsrow->last_page = 0x%lx\n", csrow->last_page);
+	debugf4("\tcsrow->page_mask = 0x%lx\n", csrow->page_mask);
+	debugf4("\tcsrow->nr_pages = 0x%x\n", csrow->nr_pages);
+	debugf4("\tcsrow->nr_channels = %d\n",
+		csrow->nr_channels);
+	debugf4("\tcsrow->channels = %p\n", csrow->channels);
+	debugf4("\tcsrow->mci = %p\n\n", csrow->mci);
+}
+
+
+EXPORT_SYMBOL(edac_mc_dump_mci);
+
+void edac_mc_dump_mci(struct mem_ctl_info *mci)
+{
+	debugf3("\tmci = %p\n", mci);
+	debugf3("\tmci->mtype_cap = %lx\n", mci->mtype_cap);
+	debugf3("\tmci->edac_ctl_cap = %lx\n", mci->edac_ctl_cap);
+	debugf3("\tmci->edac_cap = %lx\n", mci->edac_cap);
+	debugf4("\tmci->edac_check = %p\n", mci->edac_check);
+	debugf3("\tmci->nr_csrows = %d, csrows = %p\n",
+		mci->nr_csrows, mci->csrows);
+	debugf3("\tpdev = %p\n", mci->pdev);
+	debugf3("\tmod_name:ctl_name = %s:%s\n",
+		mci->mod_name, mci->ctl_name);
+	debugf3("\tpvt_info = %p\n\n", mci->pvt_info);
+}
+
+
+#endif				/* CONFIG_EDAC_DEBUG */
+
+/* 'ptr' points to a possibly unaligned item X such that sizeof(X) is 'size'.
+ * Adjust 'ptr' so that its alignment is at least as stringent as what the
+ * compiler would provide for X and return the aligned result.
+ *
+ * If 'size' is a constant, the compiler will optimize this whole function
+ * down to either a no-op or the addition of a constant to the value of 'ptr'.
+ */
+static inline char * align_ptr (void *ptr, unsigned size)
+{
+	unsigned align, r;
+
+	/* Here we assume that the alignment of a "long long" is the most
+	 * stringent alignment that the compiler will ever provide by default.
+	 * As far as I know, this is a reasonable assumption.
+	 */
+	if (size > sizeof(long))
+		align = sizeof(long long);
+	else if (size > sizeof(int))
+		align = sizeof(long);
+	else if (size > sizeof(short))
+		align = sizeof(int);
+	else if (size > sizeof(char))
+		align = sizeof(short);
+	else
+		return (char *) ptr;
+
+	r = size % align;
+
+	if (r == 0)
+		return (char *) ptr;
+
+	return (char *) (((unsigned long) ptr) + align - r);
+}
+
+
+EXPORT_SYMBOL(edac_mc_alloc);
+
+/**
+ * edac_mc_alloc: Allocate a struct mem_ctl_info structure
+ * @size_pvt:	size of private storage needed
+ * @nr_csrows:	Number of CWROWS needed for this MC
+ * @nr_chans:	Number of channels for the MC
+ *
+ * Everything is kmalloc'ed as one big chunk - more efficient.
+ * Only can be used if all structures have the same lifetime - otherwise
+ * you have to allocate and initialize your own structures.
+ *
+ * Use edac_mc_free() to free mc structures allocated by this function.
+ *
+ * Returns:
+ *	NULL allocation failed
+ *	struct mem_ctl_info pointer
+ */
+struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
+					unsigned nr_chans)
+{
+	struct mem_ctl_info *mci;
+	struct csrow_info *csi, *csrow;
+	struct channel_info *chi, *chp, *chan;
+	void *pvt;
+	unsigned size;
+	int row, chn;
+
+	/* Figure out the offsets of the various items from the start of an mc
+	 * structure.  We want the alignment of each item to be at least as
+	 * stringent as what the compiler would provide if we could simply
+	 * hardcode everything into a single struct.
+	 */
+	mci = (struct mem_ctl_info *) 0;
+	csi = (struct csrow_info *)align_ptr(&mci[1], sizeof(*csi));
+	chi = (struct channel_info *)
+			align_ptr(&csi[nr_csrows], sizeof(*chi));
+	pvt = align_ptr(&chi[nr_chans * nr_csrows], sz_pvt);
+	size = ((unsigned long) pvt) + sz_pvt;
+
+	if ((mci = kmalloc(size, GFP_KERNEL)) == NULL)
+		return NULL;
+
+	/* Adjust pointers so they point within the memory we just allocated
+	 * rather than an imaginary chunk of memory located at address 0.
+	 */
+	csi = (struct csrow_info *) (((char *) mci) + ((unsigned long) csi));
+	chi = (struct channel_info *) (((char *) mci) + ((unsigned long) chi));
+	pvt = sz_pvt ? (((char *) mci) + ((unsigned long) pvt)) : NULL;
+
+	memset(mci, 0, size);	/* clear all fields */
+
+	mci->csrows = csi;
+	mci->pvt_info = pvt;
+	mci->nr_csrows = nr_csrows;
+
+	for (row = 0; row < nr_csrows; row++) {
+		csrow = &csi[row];
+		csrow->csrow_idx = row;
+		csrow->mci = mci;
+		csrow->nr_channels = nr_chans;
+		chp = &chi[row * nr_chans];
+		csrow->channels = chp;
+
+		for (chn = 0; chn < nr_chans; chn++) {
+			chan = &chp[chn];
+			chan->chan_idx = chn;
+			chan->csrow = csrow;
+		}
+	}
+
+	return mci;
+}
+
+
+EXPORT_SYMBOL(edac_mc_free);
+
+/**
+ * edac_mc_free:  Free a previously allocated 'mci' structure
+ * @mci: pointer to a struct mem_ctl_info structure
+ *
+ * Free up a previously allocated mci structure
+ * A MCI structure can be in 2 states after being allocated
+ * by edac_mc_alloc().
+ *	1) Allocated in a MC driver's probe, but not yet committed
+ *	2) Allocated and committed, by a call to  edac_mc_add_mc()
+ * edac_mc_add_mc() is the function that adds the sysfs entries
+ * thus, this free function must determine which state the 'mci'
+ * structure is in, then either free it directly or
+ * perform kobject cleanup by calling edac_remove_sysfs_mci_device().
+ *
+ * VOID Return
+ */
+void edac_mc_free(struct mem_ctl_info *mci)
+{
+	/* only if sysfs entries for this mci instance exist
+	 * do we remove them and defer the actual kfree via
+	 * the kobject 'release()' callback.
+ 	 *
+	 * Otherwise, do a straight kfree now.
+	 */
+	if (mci->sysfs_active == MCI_SYSFS_ACTIVE)
+		edac_remove_sysfs_mci_device(mci);
+	else
+		kfree(mci);
+}
+
+
+
+EXPORT_SYMBOL(edac_mc_find_mci_by_pdev);
+
+struct mem_ctl_info *edac_mc_find_mci_by_pdev(struct pci_dev *pdev)
+{
+	struct mem_ctl_info *mci;
+	struct list_head *item;
+
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+
+	list_for_each(item, &mc_devices) {
+		mci = list_entry(item, struct mem_ctl_info, link);
+
+		if (mci->pdev == pdev)
+			return mci;
+	}
+
+	return NULL;
+}
+
+static int add_mc_to_global_list (struct mem_ctl_info *mci)
+{
+	struct list_head *item, *insert_before;
+	struct mem_ctl_info *p;
+	int i;
+
+	if (list_empty(&mc_devices)) {
+		mci->mc_idx = 0;
+		insert_before = &mc_devices;
+	} else {
+		if (edac_mc_find_mci_by_pdev(mci->pdev)) {
+			printk(KERN_WARNING
+				"EDAC MC: %s (%s) %s %s already assigned %d\n",
+				mci->pdev->dev.bus_id, pci_name(mci->pdev),
+				mci->mod_name, mci->ctl_name, mci->mc_idx);
+			return 1;
+		}
+
+		insert_before = NULL;
+		i = 0;
+
+		list_for_each(item, &mc_devices) {
+			p = list_entry(item, struct mem_ctl_info, link);
+
+			if (p->mc_idx != i) {
+				insert_before = item;
+				break;
+			}
+
+			i++;
+		}
+
+		mci->mc_idx = i;
+
+		if (insert_before == NULL)
+			insert_before = &mc_devices;
+	}
+
+	list_add_tail_rcu(&mci->link, insert_before);
+	return 0;
+}
+
+
+
+EXPORT_SYMBOL(edac_mc_add_mc);
+
+/**
+ * edac_mc_add_mc: Insert the 'mci' structure into the mci global list
+ * @mci: pointer to the mci structure to be added to the list
+ *
+ * Return:
+ *	0	Success
+ *	!0	Failure
+ */
+
+/* FIXME - should a warning be printed if no error detection? correction? */
+int edac_mc_add_mc(struct mem_ctl_info *mci)
+{
+	int rc = 1;
+
+	debugf0("MC: " __FILE__ ": %s()\n", __func__);
+#ifdef CONFIG_EDAC_DEBUG
+	if (edac_debug_level >= 3)
+		edac_mc_dump_mci(mci);
+	if (edac_debug_level >= 4) {
+		int i;
+
+		for (i = 0; i < mci->nr_csrows; i++) {
+			int j;
+			edac_mc_dump_csrow(&mci->csrows[i]);
+			for (j = 0; j < mci->csrows[i].nr_channels; j++)
+				edac_mc_dump_channel(&mci->csrows[i].
+							  channels[j]);
+		}
+	}
+#endif
+	down(&mem_ctls_mutex);
+
+	if (add_mc_to_global_list(mci))
+		goto finish;
+
+	/* set load time so that error rate can be tracked */
+	mci->start_time = jiffies;
+
+        if (edac_create_sysfs_mci_device(mci)) {
+                printk(KERN_WARNING
+                       "EDAC MC%d: failed to create sysfs device\n",
+                       mci->mc_idx);
+		/* FIXME - should there be an error code and unwind? */
+                goto finish;
+        }
+
+	/* Report action taken */
+	printk(KERN_INFO
+	       "EDAC MC%d: Giving out device to %s %s: PCI %s\n",
+	       mci->mc_idx, mci->mod_name, mci->ctl_name,
+	       pci_name(mci->pdev));
+
+
+	rc = 0;
+
+finish:
+	up(&mem_ctls_mutex);
+	return rc;
+}
+
+
+
+static void complete_mc_list_del (struct rcu_head *head)
+{
+	struct mem_ctl_info *mci;
+
+	mci = container_of(head, struct mem_ctl_info, rcu);
+	INIT_LIST_HEAD(&mci->link);
+	complete(&mci->complete);
+}
+
+static void del_mc_from_global_list (struct mem_ctl_info *mci)
+{
+	list_del_rcu(&mci->link);
+	init_completion(&mci->complete);
+	call_rcu(&mci->rcu, complete_mc_list_del);
+	wait_for_completion(&mci->complete);
+}
+
+EXPORT_SYMBOL(edac_mc_del_mc);
+
+/**
+ * edac_mc_del_mc:  Remove the specified mci structure from global list
+ * @mci:	Pointer to struct mem_ctl_info structure
+ *
+ * Returns:
+ *	0	Success
+ *	1 	Failure
+ */
+int edac_mc_del_mc(struct mem_ctl_info *mci)
+{
+	int rc = 1;
+
+	debugf0("MC%d: " __FILE__ ": %s()\n", mci->mc_idx, __func__);
+	down(&mem_ctls_mutex);
+	del_mc_from_global_list(mci);
+	printk(KERN_INFO
+	       "EDAC MC%d: Removed device %d for %s %s: PCI %s\n",
+	       mci->mc_idx, mci->mc_idx, mci->mod_name, mci->ctl_name,
+	       pci_name(mci->pdev));
+	rc = 0;
+	up(&mem_ctls_mutex);
+
+	return rc;
+}
+
+
+EXPORT_SYMBOL(edac_mc_scrub_block);
+
+void edac_mc_scrub_block(unsigned long page, unsigned long offset,
+			      u32 size)
+{
+	struct page *pg;
+	void *virt_addr;
+	unsigned long flags = 0;
+
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+
+	/* ECC error page was not in our memory. Ignore it. */
+	if(!pfn_valid(page))
+		return;
+
+	/* Find the actual page structure then map it and fix */
+	pg = pfn_to_page(page);
+
+	if (PageHighMem(pg))
+		local_irq_save(flags);
+
+	virt_addr = kmap_atomic(pg, KM_BOUNCE_READ);
+
+	/* Perform architecture specific atomic scrub operation */
+	atomic_scrub(virt_addr + offset, size);
+
+	/* Unmap and complete */
+	kunmap_atomic(virt_addr, KM_BOUNCE_READ);
+
+	if (PageHighMem(pg))
+		local_irq_restore(flags);
+}
+
+
+/* FIXME - should return -1 */
+EXPORT_SYMBOL(edac_mc_find_csrow_by_page);
+
+int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci,
+				    unsigned long page)
+{
+	struct csrow_info *csrows = mci->csrows;
+	int row, i;
+
+	debugf1("MC%d: " __FILE__ ": %s(): 0x%lx\n", mci->mc_idx, __func__,
+		page);
+	row = -1;
+
+	for (i = 0; i < mci->nr_csrows; i++) {
+		struct csrow_info *csrow = &csrows[i];
+
+		if (csrow->nr_pages == 0)
+			continue;
+
+		debugf3("MC%d: " __FILE__
+			": %s(): first(0x%lx) page(0x%lx)"
+			" last(0x%lx) mask(0x%lx)\n", mci->mc_idx,
+			__func__, csrow->first_page, page,
+			csrow->last_page, csrow->page_mask);
+
+		if ((page >= csrow->first_page) &&
+		    (page <= csrow->last_page) &&
+		    ((page & csrow->page_mask) ==
+		     (csrow->first_page & csrow->page_mask))) {
+			row = i;
+			break;
+		}
+	}
+
+	if (row == -1)
+		printk(KERN_ERR
+		       "EDAC MC%d: could not look up page error address %lx\n",
+		       mci->mc_idx, (unsigned long) page);
+
+	return row;
+}
+
+
+EXPORT_SYMBOL(edac_mc_handle_ce);
+
+/* FIXME - setable log (warning/emerg) levels */
+/* FIXME - integrate with evlog: http://evlog.sourceforge.net/ */
+void edac_mc_handle_ce(struct mem_ctl_info *mci,
+			    unsigned long page_frame_number,
+			    unsigned long offset_in_page,
+			    unsigned long syndrome, int row, int channel,
+			    const char *msg)
+{
+	unsigned long remapped_page;
+
+	debugf3("MC%d: " __FILE__ ": %s()\n", mci->mc_idx, __func__);
+
+	/* FIXME - maybe make panic on INTERNAL ERROR an option */
+	if (row >= mci->nr_csrows || row < 0) {
+		/* something is wrong */
+		printk(KERN_ERR
+		       "EDAC MC%d: INTERNAL ERROR: row out of range (%d >= %d)\n",
+		       mci->mc_idx, row, mci->nr_csrows);
+		edac_mc_handle_ce_no_info(mci, "INTERNAL ERROR");
+		return;
+	}
+	if (channel >= mci->csrows[row].nr_channels || channel < 0) {
+		/* something is wrong */
+		printk(KERN_ERR
+		       "EDAC MC%d: INTERNAL ERROR: channel out of range "
+		       "(%d >= %d)\n",
+		       mci->mc_idx, channel, mci->csrows[row].nr_channels);
+		edac_mc_handle_ce_no_info(mci, "INTERNAL ERROR");
+		return;
+	}
+
+	if (log_ce)
+		/* FIXME - put in DIMM location */
+		printk(KERN_WARNING
+		       "EDAC MC%d: CE page 0x%lx, offset 0x%lx,"
+		       " grain %d, syndrome 0x%lx, row %d, channel %d,"
+		       " label \"%s\": %s\n", mci->mc_idx,
+		       page_frame_number, offset_in_page,
+		       mci->csrows[row].grain, syndrome, row, channel,
+		       mci->csrows[row].channels[channel].label, msg);
+
+	mci->ce_count++;
+	mci->csrows[row].ce_count++;
+	mci->csrows[row].channels[channel].ce_count++;
+
+	if (mci->scrub_mode & SCRUB_SW_SRC) {
+		/*
+		 * Some MC's can remap memory so that it is still available
+		 * at a different address when PCI devices map into memory.
+		 * MC's that can't do this lose the memory where PCI devices
+		 * are mapped.  This mapping is MC dependant and so we call
+		 * back into the MC driver for it to map the MC page to
+		 * a physical (CPU) page which can then be mapped to a virtual
+		 * page - which can then be scrubbed.
+		 */
+		remapped_page = mci->ctl_page_to_phys ?
+		    mci->ctl_page_to_phys(mci, page_frame_number) :
+		    page_frame_number;
+
+		edac_mc_scrub_block(remapped_page, offset_in_page,
+					 mci->csrows[row].grain);
+	}
+}
+
+
+EXPORT_SYMBOL(edac_mc_handle_ce_no_info);
+
+void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci,
+				    const char *msg)
+{
+	if (log_ce)
+		printk(KERN_WARNING
+		       "EDAC MC%d: CE - no information available: %s\n",
+		       mci->mc_idx, msg);
+	mci->ce_noinfo_count++;
+	mci->ce_count++;
+}
+
+
+EXPORT_SYMBOL(edac_mc_handle_ue);
+
+void edac_mc_handle_ue(struct mem_ctl_info *mci,
+			    unsigned long page_frame_number,
+			    unsigned long offset_in_page, int row,
+			    const char *msg)
+{
+	int len = EDAC_MC_LABEL_LEN * 4;
+	char labels[len + 1];
+	char *pos = labels;
+	int chan;
+	int chars;
+
+	debugf3("MC%d: " __FILE__ ": %s()\n", mci->mc_idx, __func__);
+
+	/* FIXME - maybe make panic on INTERNAL ERROR an option */
+	if (row >= mci->nr_csrows || row < 0) {
+		/* something is wrong */
+		printk(KERN_ERR
+		       "EDAC MC%d: INTERNAL ERROR: row out of range (%d >= %d)\n",
+		       mci->mc_idx, row, mci->nr_csrows);
+		edac_mc_handle_ue_no_info(mci, "INTERNAL ERROR");
+		return;
+	}
+
+	chars = snprintf(pos, len + 1, "%s",
+			 mci->csrows[row].channels[0].label);
+	len -= chars;
+	pos += chars;
+	for (chan = 1; (chan < mci->csrows[row].nr_channels) && (len > 0);
+	     chan++) {
+		chars = snprintf(pos, len + 1, ":%s",
+				 mci->csrows[row].channels[chan].label);
+		len -= chars;
+		pos += chars;
+	}
+
+	if (log_ue)
+		printk(KERN_EMERG
+		       "EDAC MC%d: UE page 0x%lx, offset 0x%lx, grain %d, row %d,"
+		       " labels \"%s\": %s\n", mci->mc_idx,
+		       page_frame_number, offset_in_page,
+		       mci->csrows[row].grain, row, labels, msg);
+
+	if (panic_on_ue)
+		panic
+		    ("EDAC MC%d: UE page 0x%lx, offset 0x%lx, grain %d, row %d,"
+		     " labels \"%s\": %s\n", mci->mc_idx,
+		     page_frame_number, offset_in_page,
+		     mci->csrows[row].grain, row, labels, msg);
+
+	mci->ue_count++;
+	mci->csrows[row].ue_count++;
+}
+
+
+EXPORT_SYMBOL(edac_mc_handle_ue_no_info);
+
+void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci,
+				    const char *msg)
+{
+	if (panic_on_ue)
+		panic("EDAC MC%d: Uncorrected Error", mci->mc_idx);
+
+	if (log_ue)
+		printk(KERN_WARNING
+		       "EDAC MC%d: UE - no information available: %s\n",
+		       mci->mc_idx, msg);
+	mci->ue_noinfo_count++;
+	mci->ue_count++;
+}
+
+
+#ifdef CONFIG_PCI
+
+static u16 get_pci_parity_status(struct pci_dev *dev, int secondary)
+{
+	int where;
+	u16 status;
+
+	where = secondary ? PCI_SEC_STATUS : PCI_STATUS;
+	pci_read_config_word(dev, where, &status);
+
+	/* If we get back 0xFFFF then we must suspect that the card has been pulled but
+	   the Linux PCI layer has not yet finished cleaning up. We don't want to report
+	   on such devices */
+
+	if (status == 0xFFFF) {
+		u32 sanity;
+		pci_read_config_dword(dev, 0, &sanity);
+		if (sanity == 0xFFFFFFFF)
+			return 0;
+	}
+	status &= PCI_STATUS_DETECTED_PARITY | PCI_STATUS_SIG_SYSTEM_ERROR |
+		  PCI_STATUS_PARITY;
+
+	if (status)
+		/* reset only the bits we are interested in */
+		pci_write_config_word(dev, where, status);
+
+	return status;
+}
+
+typedef void (*pci_parity_check_fn_t) (struct pci_dev *dev);
+
+/* Clear any PCI parity errors logged by this device. */
+static void edac_pci_dev_parity_clear( struct pci_dev *dev )
+{
+	u8 header_type;
+
+	get_pci_parity_status(dev, 0);
+
+	/* read the device TYPE, looking for bridges */
+	pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type);
+
+	if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE)
+		get_pci_parity_status(dev, 1);
+}
+
+/*
+ *  PCI Parity polling
+ *
+ */
+static void edac_pci_dev_parity_test(struct pci_dev *dev)
+{
+	u16 status;
+	u8  header_type;
+
+	/* read the STATUS register on this device
+	 */
+	status = get_pci_parity_status(dev, 0);
+
+	debugf2("PCI STATUS= 0x%04x %s\n", status, dev->dev.bus_id );
+
+	/* check the status reg for errors */
+	if (status) {
+		if (status & (PCI_STATUS_SIG_SYSTEM_ERROR))
+			printk(KERN_CRIT
+			   	"EDAC PCI- "
+				"Signaled System Error on %s\n",
+				pci_name (dev));
+
+		if (status & (PCI_STATUS_PARITY)) {
+			printk(KERN_CRIT
+			   	"EDAC PCI- "
+				"Master Data Parity Error on %s\n",
+				pci_name (dev));
+
+			atomic_inc(&pci_parity_count);
+		}
+
+		if (status & (PCI_STATUS_DETECTED_PARITY)) {
+			printk(KERN_CRIT
+			   	"EDAC PCI- "
+				"Detected Parity Error on %s\n",
+				pci_name (dev));
+
+			atomic_inc(&pci_parity_count);
+		}
+	}
+
+	/* read the device TYPE, looking for bridges */
+	pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type);
+
+	debugf2("PCI HEADER TYPE= 0x%02x %s\n", header_type, dev->dev.bus_id );
+
+	if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
+		/* On bridges, need to examine secondary status register  */
+		status = get_pci_parity_status(dev, 1);
+
+		debugf2("PCI SEC_STATUS= 0x%04x %s\n",
+				status, dev->dev.bus_id );
+
+		/* check the secondary status reg for errors */
+		if (status) {
+			if (status & (PCI_STATUS_SIG_SYSTEM_ERROR))
+				printk(KERN_CRIT
+					"EDAC PCI-Bridge- "
+					"Signaled System Error on %s\n",
+					pci_name (dev));
+
+			if (status & (PCI_STATUS_PARITY)) {
+				printk(KERN_CRIT
+					"EDAC PCI-Bridge- "
+					"Master Data Parity Error on %s\n",
+					pci_name (dev));
+
+				atomic_inc(&pci_parity_count);
+			}
+
+			if (status & (PCI_STATUS_DETECTED_PARITY)) {
+				printk(KERN_CRIT
+					"EDAC PCI-Bridge- "
+					"Detected Parity Error on %s\n",
+					pci_name (dev));
+
+				atomic_inc(&pci_parity_count);
+			}
+		}
+	}
+}
+
+/*
+ * check_dev_on_list: Scan for a PCI device on a white/black list
+ * @list:	an EDAC  &edac_pci_device_list  white/black list pointer
+ * @free_index:	index of next free entry on the list
+ * @pci_dev:	PCI Device pointer
+ *
+ * see if list contains the device.
+ *
+ * Returns:  	0 not found
+ *		1 found on list
+ */
+static int check_dev_on_list(struct edac_pci_device_list *list, int free_index,
+				struct pci_dev *dev)
+{
+        int i;
+        int rc = 0;     /* Assume not found */
+        unsigned short vendor=dev->vendor;
+        unsigned short device=dev->device;
+
+        /* Scan the list, looking for a vendor/device match
+         */
+        for (i = 0; i < free_index; i++, list++ ) {
+                if (    (list->vendor == vendor ) &&
+                        (list->device == device )) {
+                        rc = 1;
+                        break;
+                }
+        }
+
+        return rc;
+}
+
+/*
+ * pci_dev parity list iterator
+ * 	Scan the PCI device list for one iteration, looking for SERRORs
+ *	Master Parity ERRORS or Parity ERRORs on primary or secondary devices
+ */
+static inline void edac_pci_dev_parity_iterator(pci_parity_check_fn_t fn)
+{
+	struct pci_dev *dev=NULL;
+
+	/* request for kernel access to the next PCI device, if any,
+	 * and while we are looking at it have its reference count
+	 * bumped until we are done with it
+	 */
+	while((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+
+                /* if whitelist exists then it has priority, so only scan those
+                 * devices on the whitelist
+                 */
+                if (pci_whitelist_count > 0 ) {
+                        if (check_dev_on_list(pci_whitelist,
+					pci_whitelist_count, dev))
+				fn(dev);
+                } else {
+			/*
+			 * if no whitelist, then check if this devices is
+			 * blacklisted
+			 */
+                        if (!check_dev_on_list(pci_blacklist,
+					pci_blacklist_count, dev))
+				fn(dev);
+                }
+	}
+}
+
+static void do_pci_parity_check(void)
+{
+	unsigned long flags;
+	int before_count;
+
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+
+	if (!check_pci_parity)
+		return;
+
+	before_count = atomic_read(&pci_parity_count);
+
+	/* scan all PCI devices looking for a Parity Error on devices and
+	 * bridges
+	 */
+	local_irq_save(flags);
+	edac_pci_dev_parity_iterator(edac_pci_dev_parity_test);
+	local_irq_restore(flags);
+
+	/* Only if operator has selected panic on PCI Error */
+	if (panic_on_pci_parity) {
+		/* If the count is different 'after' from 'before' */
+		if (before_count != atomic_read(&pci_parity_count))
+			panic("EDAC: PCI Parity Error");
+	}
+}
+
+
+static inline void clear_pci_parity_errors(void)
+{
+	/* Clear any PCI bus parity errors that devices initially have logged
+	 * in their registers.
+	 */
+	edac_pci_dev_parity_iterator(edac_pci_dev_parity_clear);
+}
+
+
+#else  /* CONFIG_PCI */
+
+
+static inline void do_pci_parity_check(void)
+{
+	/* no-op */
+}
+
+
+static inline void clear_pci_parity_errors(void)
+{
+	/* no-op */
+}
+
+
+#endif  /* CONFIG_PCI */
+
+/*
+ * Iterate over all MC instances and check for ECC, et al, errors
+ */
+static inline void check_mc_devices (void)
+{
+	unsigned long flags;
+	struct list_head *item;
+	struct mem_ctl_info *mci;
+
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+
+	/* during poll, have interrupts off */
+	local_irq_save(flags);
+
+	list_for_each(item, &mc_devices) {
+		mci = list_entry(item, struct mem_ctl_info, link);
+
+		if (mci->edac_check != NULL)
+			mci->edac_check(mci);
+	}
+
+	local_irq_restore(flags);
+}
+
+
+/*
+ * Check MC status every poll_msec.
+ * Check PCI status every poll_msec as well.
+ *
+ * This where the work gets done for edac.
+ *
+ * SMP safe, doesn't use NMI, and auto-rate-limits.
+ */
+static void do_edac_check(void)
+{
+
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+
+	check_mc_devices();
+
+	do_pci_parity_check();
+}
+
+
+/*
+ * EDAC thread state information
+ */
+struct bs_thread_info
+{
+	struct task_struct *task;
+	struct completion *event;
+	char *name;
+	void (*run)(void);
+};
+
+static struct bs_thread_info bs_thread;
+
+/*
+ *  edac_kernel_thread
+ *      This the kernel thread that processes edac operations
+ *      in a normal thread environment
+ */
+static int edac_kernel_thread(void *arg)
+{
+	struct bs_thread_info *thread = (struct bs_thread_info *) arg;
+
+	/* detach thread */
+	daemonize(thread->name);
+
+	current->exit_signal = SIGCHLD;
+	allow_signal(SIGKILL);
+	thread->task = current;
+
+	/* indicate to starting task we have started */
+	complete(thread->event);
+
+	/* loop forever, until we are told to stop */
+	while(thread->run != NULL) {
+		void (*run)(void);
+
+		/* call the function to check the memory controllers */
+		run = thread->run;
+		if (run)
+			run();
+
+		if (signal_pending(current))
+			flush_signals(current);
+
+		/* ensure we are interruptable */
+		set_current_state(TASK_INTERRUPTIBLE);
+
+		/* goto sleep for the interval */
+		schedule_timeout((HZ * poll_msec) / 1000);
+		try_to_freeze();
+	}
+
+	/* notify waiter that we are exiting */
+	complete(thread->event);
+
+	return 0;
+}
+
+/*
+ * edac_mc_init
+ *      module initialization entry point
+ */
+static int __init edac_mc_init(void)
+{
+	int ret;
+	struct completion event;
+
+	printk(KERN_INFO "MC: " __FILE__ " version " EDAC_MC_VERSION "\n");
+
+	/*
+	 * Harvest and clear any boot/initialization PCI parity errors
+	 *
+	 * FIXME: This only clears errors logged by devices present at time of
+	 * 	module initialization.  We should also do an initial clear
+	 *	of each newly hotplugged device.
+	 */
+	clear_pci_parity_errors();
+
+	/* perform check for first time to harvest boot leftovers */
+	do_edac_check();
+
+	/* Create the MC sysfs entires */
+	if (edac_sysfs_memctrl_setup()) {
+		printk(KERN_ERR "EDAC MC: Error initializing sysfs code\n");
+		return -ENODEV;
+	}
+
+	/* Create the PCI parity sysfs entries */
+	if (edac_sysfs_pci_setup()) {
+		edac_sysfs_memctrl_teardown();
+		printk(KERN_ERR "EDAC PCI: Error initializing sysfs code\n");
+		return -ENODEV;
+	}
+
+	/* Create our kernel thread */
+	init_completion(&event);
+	bs_thread.event = &event;
+	bs_thread.name = "kedac";
+	bs_thread.run = do_edac_check;
+
+	/* create our kernel thread */
+	ret = kernel_thread(edac_kernel_thread, &bs_thread, CLONE_KERNEL);
+	if (ret < 0) {
+		/* remove the sysfs entries */
+		edac_sysfs_memctrl_teardown();
+		edac_sysfs_pci_teardown();
+		return -ENOMEM;
+	}
+
+	/* wait for our kernel theard ack that it is up and running */
+	wait_for_completion(&event);
+
+	return 0;
+}
+
+
+/*
+ * edac_mc_exit()
+ *      module exit/termination functioni
+ */
+static void __exit edac_mc_exit(void)
+{
+	struct completion event;
+
+	debugf0("MC: " __FILE__ ": %s()\n", __func__);
+
+	init_completion(&event);
+	bs_thread.event = &event;
+
+	/* As soon as ->run is set to NULL, the task could disappear,
+	 * so we need to hold tasklist_lock until we have sent the signal
+	 */
+	read_lock(&tasklist_lock);
+	bs_thread.run = NULL;
+	send_sig(SIGKILL, bs_thread.task, 1);
+	read_unlock(&tasklist_lock);
+	wait_for_completion(&event);
+
+        /* tear down the sysfs device */
+	edac_sysfs_memctrl_teardown();
+	edac_sysfs_pci_teardown();
+}
+
+
+
+
+module_init(edac_mc_init);
+module_exit(edac_mc_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Linux Networx (http://lnxi.com) Thayne Harbaugh et al\n"
+	      "Based on.work by Dan Hollis et al");
+MODULE_DESCRIPTION("Core library routines for MC reporting");
+
+module_param(panic_on_ue, int, 0644);
+MODULE_PARM_DESC(panic_on_ue, "Panic on uncorrected error: 0=off 1=on");
+module_param(check_pci_parity, int, 0644);
+MODULE_PARM_DESC(check_pci_parity, "Check for PCI bus parity errors: 0=off 1=on");
+module_param(panic_on_pci_parity, int, 0644);
+MODULE_PARM_DESC(panic_on_pci_parity, "Panic on PCI Bus Parity error: 0=off 1=on");
+module_param(log_ue, int, 0644);
+MODULE_PARM_DESC(log_ue, "Log uncorrectable error to console: 0=off 1=on");
+module_param(log_ce, int, 0644);
+MODULE_PARM_DESC(log_ce, "Log correctable error to console: 0=off 1=on");
+module_param(poll_msec, int, 0644);
+MODULE_PARM_DESC(poll_msec, "Polling period in milliseconds");
+#ifdef CONFIG_EDAC_DEBUG
+module_param(edac_debug_level, int, 0644);
+MODULE_PARM_DESC(edac_debug_level, "Debug level");
+#endif
diff --git a/drivers/edac/edac_mc.h b/drivers/edac/edac_mc.h
new file mode 100644
index 0000000..75ecf48
--- /dev/null
+++ b/drivers/edac/edac_mc.h
@@ -0,0 +1,448 @@
+/*
+ * MC kernel module
+ * (C) 2003 Linux Networx (http://lnxi.com)
+ * This file may be distributed under the terms of the
+ * GNU General Public License.
+ *
+ * Written by Thayne Harbaugh
+ * Based on work by Dan Hollis <goemon at anime dot net> and others.
+ *	http://www.anime.net/~goemon/linux-ecc/
+ *
+ * NMI handling support added by
+ *     Dave Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>
+ *
+ * $Id: edac_mc.h,v 1.4.2.10 2005/10/05 00:43:44 dsp_llnl Exp $
+ *
+ */
+
+
+#ifndef _EDAC_MC_H_
+#define _EDAC_MC_H_
+
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+#include <linux/pci.h>
+#include <linux/time.h>
+#include <linux/nmi.h>
+#include <linux/rcupdate.h>
+#include <linux/completion.h>
+#include <linux/kobject.h>
+
+
+#define EDAC_MC_LABEL_LEN	31
+#define MC_PROC_NAME_MAX_LEN 7
+
+#if PAGE_SHIFT < 20
+#define PAGES_TO_MiB( pages )	( ( pages ) >> ( 20 - PAGE_SHIFT ) )
+#else				/* PAGE_SHIFT > 20 */
+#define PAGES_TO_MiB( pages )	( ( pages ) << ( PAGE_SHIFT - 20 ) )
+#endif
+
+#ifdef CONFIG_EDAC_DEBUG
+extern int edac_debug_level;
+#define edac_debug_printk(level, fmt, args...) \
+do { if (level <= edac_debug_level) printk(KERN_DEBUG fmt, ##args); } while(0)
+#define debugf0( ... ) edac_debug_printk(0, __VA_ARGS__ )
+#define debugf1( ... ) edac_debug_printk(1, __VA_ARGS__ )
+#define debugf2( ... ) edac_debug_printk(2, __VA_ARGS__ )
+#define debugf3( ... ) edac_debug_printk(3, __VA_ARGS__ )
+#define debugf4( ... ) edac_debug_printk(4, __VA_ARGS__ )
+#else				/* !CONFIG_EDAC_DEBUG */
+#define debugf0( ... )
+#define debugf1( ... )
+#define debugf2( ... )
+#define debugf3( ... )
+#define debugf4( ... )
+#endif				/* !CONFIG_EDAC_DEBUG */
+
+
+#define bs_xstr(s) bs_str(s)
+#define bs_str(s) #s
+#define BS_MOD_STR bs_xstr(KBUILD_BASENAME)
+
+#define BIT(x) (1 << (x))
+
+#define PCI_VEND_DEV(vend, dev) PCI_VENDOR_ID_ ## vend, PCI_DEVICE_ID_ ## vend ## _ ## dev
+
+/* memory devices */
+enum dev_type {
+	DEV_UNKNOWN = 0,
+	DEV_X1,
+	DEV_X2,
+	DEV_X4,
+	DEV_X8,
+	DEV_X16,
+	DEV_X32,		/* Do these parts exist? */
+	DEV_X64			/* Do these parts exist? */
+};
+
+#define DEV_FLAG_UNKNOWN	BIT(DEV_UNKNOWN)
+#define DEV_FLAG_X1		BIT(DEV_X1)
+#define DEV_FLAG_X2		BIT(DEV_X2)
+#define DEV_FLAG_X4		BIT(DEV_X4)
+#define DEV_FLAG_X8		BIT(DEV_X8)
+#define DEV_FLAG_X16		BIT(DEV_X16)
+#define DEV_FLAG_X32		BIT(DEV_X32)
+#define DEV_FLAG_X64		BIT(DEV_X64)
+
+/* memory types */
+enum mem_type {
+	MEM_EMPTY = 0,		/* Empty csrow */
+	MEM_RESERVED,		/* Reserved csrow type */
+	MEM_UNKNOWN,		/* Unknown csrow type */
+	MEM_FPM,		/* Fast page mode */
+	MEM_EDO,		/* Extended data out */
+	MEM_BEDO,		/* Burst Extended data out */
+	MEM_SDR,		/* Single data rate SDRAM */
+	MEM_RDR,		/* Registered single data rate SDRAM */
+	MEM_DDR,		/* Double data rate SDRAM */
+	MEM_RDDR,		/* Registered Double data rate SDRAM */
+	MEM_RMBS		/* Rambus DRAM */
+};
+
+#define MEM_FLAG_EMPTY		BIT(MEM_EMPTY)
+#define MEM_FLAG_RESERVED	BIT(MEM_RESERVED)
+#define MEM_FLAG_UNKNOWN	BIT(MEM_UNKNOWN)
+#define MEM_FLAG_FPM		BIT(MEM_FPM)
+#define MEM_FLAG_EDO		BIT(MEM_EDO)
+#define MEM_FLAG_BEDO		BIT(MEM_BEDO)
+#define MEM_FLAG_SDR		BIT(MEM_SDR)
+#define MEM_FLAG_RDR		BIT(MEM_RDR)
+#define MEM_FLAG_DDR		BIT(MEM_DDR)
+#define MEM_FLAG_RDDR		BIT(MEM_RDDR)
+#define MEM_FLAG_RMBS		BIT(MEM_RMBS)
+
+
+/* chipset Error Detection and Correction capabilities and mode */
+enum edac_type {
+	EDAC_UNKNOWN = 0,	/* Unknown if ECC is available */
+	EDAC_NONE,		/* Doesnt support ECC */
+	EDAC_RESERVED,		/* Reserved ECC type */
+	EDAC_PARITY,		/* Detects parity errors */
+	EDAC_EC,		/* Error Checking - no correction */
+	EDAC_SECDED,		/* Single bit error correction, Double detection */
+	EDAC_S2ECD2ED,		/* Chipkill x2 devices - do these exist? */
+	EDAC_S4ECD4ED,		/* Chipkill x4 devices */
+	EDAC_S8ECD8ED,		/* Chipkill x8 devices */
+	EDAC_S16ECD16ED,	/* Chipkill x16 devices */
+};
+
+#define EDAC_FLAG_UNKNOWN	BIT(EDAC_UNKNOWN)
+#define EDAC_FLAG_NONE		BIT(EDAC_NONE)
+#define EDAC_FLAG_PARITY	BIT(EDAC_PARITY)
+#define EDAC_FLAG_EC		BIT(EDAC_EC)
+#define EDAC_FLAG_SECDED	BIT(EDAC_SECDED)
+#define EDAC_FLAG_S2ECD2ED	BIT(EDAC_S2ECD2ED)
+#define EDAC_FLAG_S4ECD4ED	BIT(EDAC_S4ECD4ED)
+#define EDAC_FLAG_S8ECD8ED	BIT(EDAC_S8ECD8ED)
+#define EDAC_FLAG_S16ECD16ED	BIT(EDAC_S16ECD16ED)
+
+
+/* scrubbing capabilities */
+enum scrub_type {
+	SCRUB_UNKNOWN = 0,	/* Unknown if scrubber is available */
+	SCRUB_NONE,		/* No scrubber */
+	SCRUB_SW_PROG,		/* SW progressive (sequential) scrubbing */
+	SCRUB_SW_SRC,		/* Software scrub only errors */
+	SCRUB_SW_PROG_SRC,	/* Progressive software scrub from an error */
+	SCRUB_SW_TUNABLE,	/* Software scrub frequency is tunable */
+	SCRUB_HW_PROG,		/* HW progressive (sequential) scrubbing */
+	SCRUB_HW_SRC,		/* Hardware scrub only errors */
+	SCRUB_HW_PROG_SRC,	/* Progressive hardware scrub from an error */
+	SCRUB_HW_TUNABLE	/* Hardware scrub frequency is tunable */
+};
+
+#define SCRUB_FLAG_SW_PROG	BIT(SCRUB_SW_PROG)
+#define SCRUB_FLAG_SW_SRC	BIT(SCRUB_SW_SRC_CORR)
+#define SCRUB_FLAG_SW_PROG_SRC	BIT(SCRUB_SW_PROG_SRC_CORR)
+#define SCRUB_FLAG_SW_TUN	BIT(SCRUB_SW_SCRUB_TUNABLE)
+#define SCRUB_FLAG_HW_PROG	BIT(SCRUB_HW_PROG)
+#define SCRUB_FLAG_HW_SRC	BIT(SCRUB_HW_SRC_CORR)
+#define SCRUB_FLAG_HW_PROG_SRC	BIT(SCRUB_HW_PROG_SRC_CORR)
+#define SCRUB_FLAG_HW_TUN	BIT(SCRUB_HW_TUNABLE)
+
+enum mci_sysfs_status {
+	MCI_SYSFS_INACTIVE = 0,	/* sysfs entries NOT registered */
+	MCI_SYSFS_ACTIVE	/* sysfs entries ARE registered */
+};
+
+/* FIXME - should have notify capabilities: NMI, LOG, PROC, etc */
+
+/*
+ * There are several things to be aware of that aren't at all obvious:
+ *
+ *
+ * SOCKETS, SOCKET SETS, BANKS, ROWS, CHIP-SELECT ROWS, CHANNELS, etc..
+ *
+ * These are some of the many terms that are thrown about that don't always
+ * mean what people think they mean (Inconceivable!).  In the interest of
+ * creating a common ground for discussion, terms and their definitions
+ * will be established.
+ *
+ * Memory devices:	The individual chip on a memory stick.  These devices
+ *			commonly output 4 and 8 bits each.  Grouping several
+ *			of these in parallel provides 64 bits which is common
+ *			for a memory stick.
+ *
+ * Memory Stick:	A printed circuit board that agregates multiple
+ *			memory devices in parallel.  This is the atomic
+ *			memory component that is purchaseable by Joe consumer
+ *			and loaded into a memory socket.
+ *
+ * Socket:		A physical connector on the motherboard that accepts
+ *			a single memory stick.
+ *
+ * Channel:		Set of memory devices on a memory stick that must be
+ *			grouped in parallel with one or more additional
+ *			channels from other memory sticks.  This parallel
+ *			grouping of the output from multiple channels are
+ *			necessary for the smallest granularity of memory access.
+ *			Some memory controllers are capable of single channel -
+ *			which means that memory sticks can be loaded
+ *			individually.  Other memory controllers are only
+ *			capable of dual channel - which means that memory
+ *			sticks must be loaded as pairs (see "socket set").
+ *
+ * Chip-select row:	All of the memory devices that are selected together.
+ *			for a single, minimum grain of memory access.
+ *			This selects all of the parallel memory devices across
+ *			all of the parallel channels.  Common chip-select rows
+ *			for single channel are 64 bits, for dual channel 128
+ *			bits.
+ *
+ * Single-Ranked stick:	A Single-ranked stick has 1 chip-select row of memmory.
+ *			Motherboards commonly drive two chip-select pins to
+ *			a memory stick. A single-ranked stick, will occupy
+ *			only one of those rows. The other will be unused.
+ *
+ * Double-Ranked stick:	A double-ranked stick has two chip-select rows which
+ *			access different sets of memory devices.  The two
+ *			rows cannot be accessed concurrently.
+ *
+ * Double-sided stick:	DEPRECATED TERM, see Double-Ranked stick.
+ *			A double-sided stick has two chip-select rows which
+ *			access different sets of memory devices.  The two
+ *			rows cannot be accessed concurrently.  "Double-sided"
+ *			is irrespective of the memory devices being mounted
+ *			on both sides of the memory stick.
+ *
+ * Socket set:		All of the memory sticks that are required for for
+ *			a single memory access or all of the memory sticks
+ *			spanned by a chip-select row.  A single socket set
+ *			has two chip-select rows and if double-sided sticks
+ *			are used these will occupy those chip-select rows.
+ *
+ * Bank:		This term is avoided because it is unclear when
+ *			needing to distinguish between chip-select rows and
+ *			socket sets.
+ *
+ * Controller pages:
+ *
+ * Physical pages:
+ *
+ * Virtual pages:
+ *
+ *
+ * STRUCTURE ORGANIZATION AND CHOICES
+ *
+ *
+ *
+ * PS - I enjoyed writing all that about as much as you enjoyed reading it.
+ */
+
+
+struct channel_info {
+	int chan_idx;		/* channel index */
+	u32 ce_count;		/* Correctable Errors for this CHANNEL */
+	char label[EDAC_MC_LABEL_LEN + 1];	/* DIMM label on motherboard */
+	struct csrow_info *csrow;	/* the parent */
+};
+
+
+struct csrow_info {
+	unsigned long first_page;	/* first page number in dimm */
+	unsigned long last_page;	/* last page number in dimm */
+	unsigned long page_mask;	/* used for interleaving -
+					   0UL for non intlv */
+	u32 nr_pages;		/* number of pages in csrow */
+	u32 grain;		/* granularity of reported error in bytes */
+	int csrow_idx;		/* the chip-select row */
+	enum dev_type dtype;	/* memory device type */
+	u32 ue_count;		/* Uncorrectable Errors for this csrow */
+	u32 ce_count;		/* Correctable Errors for this csrow */
+	enum mem_type mtype;	/* memory csrow type */
+	enum edac_type edac_mode;	/* EDAC mode for this csrow */
+	struct mem_ctl_info *mci;	/* the parent */
+
+	struct kobject kobj;	/* sysfs kobject for this csrow */
+
+	/* FIXME the number of CHANNELs might need to become dynamic */
+	u32 nr_channels;
+	struct channel_info *channels;
+};
+
+
+struct mem_ctl_info {
+	struct list_head link;  /* for global list of mem_ctl_info structs */
+	unsigned long mtype_cap;	/* memory types supported by mc */
+	unsigned long edac_ctl_cap;	/* Mem controller EDAC capabilities */
+	unsigned long edac_cap;	/* configuration capabilities - this is
+				   closely related to edac_ctl_cap.  The
+				   difference is that the controller
+				   may be capable of s4ecd4ed which would
+				   be listed in edac_ctl_cap, but if
+				   channels aren't capable of s4ecd4ed then the
+				   edac_cap would not have that capability. */
+	unsigned long scrub_cap;	/* chipset scrub capabilities */
+	enum scrub_type scrub_mode;	/* current scrub mode */
+
+	enum mci_sysfs_status sysfs_active;	/* status of sysfs */
+
+	/* pointer to edac checking routine */
+	void (*edac_check) (struct mem_ctl_info * mci);
+	/*
+	 * Remaps memory pages: controller pages to physical pages.
+	 * For most MC's, this will be NULL.
+	 */
+	/* FIXME - why not send the phys page to begin with? */
+	unsigned long (*ctl_page_to_phys) (struct mem_ctl_info * mci,
+					   unsigned long page);
+	int mc_idx;
+	int nr_csrows;
+	struct csrow_info *csrows;
+	/*
+	 * FIXME - what about controllers on other busses? - IDs must be
+	 * unique.  pdev pointer should be sufficiently unique, but
+	 * BUS:SLOT.FUNC numbers may not be unique.
+	 */
+	struct pci_dev *pdev;
+	const char *mod_name;
+	const char *mod_ver;
+	const char *ctl_name;
+	char proc_name[MC_PROC_NAME_MAX_LEN + 1];
+	void *pvt_info;
+	u32 ue_noinfo_count;	/* Uncorrectable Errors w/o info */
+	u32 ce_noinfo_count;	/* Correctable Errors w/o info */
+	u32 ue_count;		/* Total Uncorrectable Errors for this MC */
+	u32 ce_count;		/* Total Correctable Errors for this MC */
+	unsigned long start_time;	/* mci load start time (in jiffies) */
+
+	/* this stuff is for safe removal of mc devices from global list while
+	 * NMI handlers may be traversing list
+	 */
+	struct rcu_head rcu;
+	struct completion complete;
+
+	/* edac sysfs device control */
+	struct kobject edac_mci_kobj;
+};
+
+
+
+/* write all or some bits in a byte-register*/
+static inline void pci_write_bits8(struct pci_dev *pdev, int offset,
+				   u8 value, u8 mask)
+{
+	if (mask != 0xff) {
+		u8 buf;
+		pci_read_config_byte(pdev, offset, &buf);
+		value &= mask;
+		buf &= ~mask;
+		value |= buf;
+	}
+	pci_write_config_byte(pdev, offset, value);
+}
+
+
+/* write all or some bits in a word-register*/
+static inline void pci_write_bits16(struct pci_dev *pdev, int offset,
+				    u16 value, u16 mask)
+{
+	if (mask != 0xffff) {
+		u16 buf;
+		pci_read_config_word(pdev, offset, &buf);
+		value &= mask;
+		buf &= ~mask;
+		value |= buf;
+	}
+	pci_write_config_word(pdev, offset, value);
+}
+
+
+/* write all or some bits in a dword-register*/
+static inline void pci_write_bits32(struct pci_dev *pdev, int offset,
+				    u32 value, u32 mask)
+{
+	if (mask != 0xffff) {
+		u32 buf;
+		pci_read_config_dword(pdev, offset, &buf);
+		value &= mask;
+		buf &= ~mask;
+		value |= buf;
+	}
+	pci_write_config_dword(pdev, offset, value);
+}
+
+
+#ifdef CONFIG_EDAC_DEBUG
+void edac_mc_dump_channel(struct channel_info *chan);
+void edac_mc_dump_mci(struct mem_ctl_info *mci);
+void edac_mc_dump_csrow(struct csrow_info *csrow);
+#endif				/* CONFIG_EDAC_DEBUG */
+
+extern int edac_mc_add_mc(struct mem_ctl_info *mci);
+extern int edac_mc_del_mc(struct mem_ctl_info *mci);
+
+extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci,
+					   unsigned long page);
+
+extern struct mem_ctl_info *edac_mc_find_mci_by_pdev(struct pci_dev
+							  *pdev);
+
+extern void edac_mc_scrub_block(unsigned long page,
+				     unsigned long offset, u32 size);
+
+/*
+ * The no info errors are used when error overflows are reported.
+ * There are a limited number of error logging registers that can
+ * be exausted.  When all registers are exhausted and an additional
+ * error occurs then an error overflow register records that an
+ * error occured and the type of error, but doesn't have any
+ * further information.  The ce/ue versions make for cleaner
+ * reporting logic and function interface - reduces conditional
+ * statement clutter and extra function arguments.
+ */
+extern void edac_mc_handle_ce(struct mem_ctl_info *mci,
+				   unsigned long page_frame_number,
+				   unsigned long offset_in_page,
+				   unsigned long syndrome,
+				   int row, int channel, const char *msg);
+
+extern void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci,
+					   const char *msg);
+
+extern void edac_mc_handle_ue(struct mem_ctl_info *mci,
+				   unsigned long page_frame_number,
+				   unsigned long offset_in_page,
+				   int row, const char *msg);
+
+extern void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci,
+					   const char *msg);
+
+/*
+ * This kmalloc's and initializes all the structures.
+ * Can't be used if all structures don't have the same lifetime.
+ */
+extern struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt,
+		unsigned nr_csrows, unsigned nr_chans);
+
+/* Free an mc previously allocated by edac_mc_alloc() */
+extern void edac_mc_free(struct mem_ctl_info *mci);
+
+
+#endif				/* _EDAC_MC_H_ */
diff --git a/drivers/edac/i82860_edac.c b/drivers/edac/i82860_edac.c
new file mode 100644
index 0000000..52596e7
--- /dev/null
+++ b/drivers/edac/i82860_edac.c
@@ -0,0 +1,299 @@
+/*
+ * Intel 82860 Memory Controller kernel module
+ * (C) 2005 Red Hat (http://www.redhat.com)
+ * This file may be distributed under the terms of the
+ * GNU General Public License.
+ *
+ * Written by Ben Woodard <woodard@redhat.com>
+ * shamelessly copied from and based upon the edac_i82875 driver
+ * by Thayne Harbaugh of Linux Networx. (http://lnxi.com)
+ */
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/slab.h>
+#include "edac_mc.h"
+
+
+#ifndef PCI_DEVICE_ID_INTEL_82860_0
+#define PCI_DEVICE_ID_INTEL_82860_0	0x2531
+#endif				/* PCI_DEVICE_ID_INTEL_82860_0 */
+
+#define I82860_MCHCFG 0x50
+#define I82860_GBA 0x60
+#define I82860_GBA_MASK 0x7FF
+#define I82860_GBA_SHIFT 24
+#define I82860_ERRSTS 0xC8
+#define I82860_EAP 0xE4
+#define I82860_DERRCTL_STS 0xE2
+
+enum i82860_chips {
+	I82860 = 0,
+};
+
+struct i82860_dev_info {
+	const char *ctl_name;
+};
+
+struct i82860_error_info {
+	u16 errsts;
+	u32 eap;
+	u16 derrsyn;
+	u16 errsts2;
+};
+
+static const struct i82860_dev_info i82860_devs[] = {
+	[I82860] = {
+		    .ctl_name = "i82860"},
+};
+
+static struct pci_dev *mci_pdev = NULL;	/* init dev: in case that AGP code
+					   has already registered driver */
+
+static int i82860_registered = 1;
+
+static void i82860_get_error_info (struct mem_ctl_info *mci,
+		struct i82860_error_info *info)
+{
+	/*
+	 * This is a mess because there is no atomic way to read all the
+	 * registers at once and the registers can transition from CE being
+	 * overwritten by UE.
+	 */
+	pci_read_config_word(mci->pdev, I82860_ERRSTS, &info->errsts);
+	pci_read_config_dword(mci->pdev, I82860_EAP, &info->eap);
+	pci_read_config_word(mci->pdev, I82860_DERRCTL_STS, &info->derrsyn);
+	pci_read_config_word(mci->pdev, I82860_ERRSTS, &info->errsts2);
+
+	pci_write_bits16(mci->pdev, I82860_ERRSTS, 0x0003, 0x0003);
+
+	/*
+	 * If the error is the same for both reads then the first set of reads
+	 * is valid.  If there is a change then there is a CE no info and the
+	 * second set of reads is valid and should be UE info.
+	 */
+	if (!(info->errsts2 & 0x0003))
+		return;
+	if ((info->errsts ^ info->errsts2) & 0x0003) {
+		pci_read_config_dword(mci->pdev, I82860_EAP, &info->eap);
+		pci_read_config_word(mci->pdev, I82860_DERRCTL_STS,
+		    &info->derrsyn);
+	}
+}
+
+static int i82860_process_error_info (struct mem_ctl_info *mci,
+		struct i82860_error_info *info, int handle_errors)
+{
+	int row;
+
+	if (!(info->errsts2 & 0x0003))
+		return 0;
+
+	if (!handle_errors)
+		return 1;
+
+	if ((info->errsts ^ info->errsts2) & 0x0003) {
+		edac_mc_handle_ce_no_info(mci, "UE overwrote CE");
+		info->errsts = info->errsts2;
+	}
+
+	info->eap >>= PAGE_SHIFT;
+	row = edac_mc_find_csrow_by_page(mci, info->eap);
+
+	if (info->errsts & 0x0002)
+		edac_mc_handle_ue(mci, info->eap, 0, row, "i82860 UE");
+	else
+		edac_mc_handle_ce(mci, info->eap, 0, info->derrsyn, row,
+				       0, "i82860 UE");
+
+	return 1;
+}
+
+static void i82860_check(struct mem_ctl_info *mci)
+{
+	struct i82860_error_info info;
+
+	debugf1("MC%d: " __FILE__ ": %s()\n", mci->mc_idx, __func__);
+	i82860_get_error_info(mci, &info);
+	i82860_process_error_info(mci, &info, 1);
+}
+
+static int i82860_probe1(struct pci_dev *pdev, int dev_idx)
+{
+	int rc = -ENODEV;
+	int index;
+	struct mem_ctl_info *mci = NULL;
+	unsigned long last_cumul_size;
+
+	u16 mchcfg_ddim;	/* DRAM Data Integrity Mode 0=none,2=edac */
+
+	/* RDRAM has channels but these don't map onto the abstractions that
+	   edac uses.
+	   The device groups from the GRA registers seem to map reasonably
+	   well onto the notion of a chip select row.
+	   There are 16 GRA registers and since the name is associated with
+	   the channel and the GRA registers map to physical devices so we are
+	   going to make 1 channel for group.
+	 */
+	mci = edac_mc_alloc(0, 16, 1);
+	if (!mci)
+		return -ENOMEM;
+
+	debugf3("MC: " __FILE__ ": %s(): init mci\n", __func__);
+
+	mci->pdev = pdev;
+	mci->mtype_cap = MEM_FLAG_DDR;
+
+
+	mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
+	/* I"m not sure about this but I think that all RDRAM is SECDED */
+	mci->edac_cap = EDAC_FLAG_SECDED;
+	/* adjust FLAGS */
+
+	mci->mod_name = BS_MOD_STR;
+	mci->mod_ver = "$Revision: 1.1.2.6 $";
+	mci->ctl_name = i82860_devs[dev_idx].ctl_name;
+	mci->edac_check = i82860_check;
+	mci->ctl_page_to_phys = NULL;
+
+	pci_read_config_word(mci->pdev, I82860_MCHCFG, &mchcfg_ddim);
+	mchcfg_ddim = mchcfg_ddim & 0x180;
+
+	/*
+	 * The group row boundary (GRA) reg values are boundary address
+	 * for each DRAM row with a granularity of 16MB.  GRA regs are
+	 * cumulative; therefore GRA15 will contain the total memory contained
+	 * in all eight rows.
+	 */
+	for (last_cumul_size = index = 0; index < mci->nr_csrows; index++) {
+		u16 value;
+		u32 cumul_size;
+		struct csrow_info *csrow = &mci->csrows[index];
+
+		pci_read_config_word(mci->pdev, I82860_GBA + index * 2,
+				     &value);
+
+		cumul_size = (value & I82860_GBA_MASK) <<
+		    (I82860_GBA_SHIFT - PAGE_SHIFT);
+		debugf3("MC: " __FILE__ ": %s(): (%d) cumul_size 0x%x\n",
+			__func__, index, cumul_size);
+		if (cumul_size == last_cumul_size)
+			continue;	/* not populated */
+
+		csrow->first_page = last_cumul_size;
+		csrow->last_page = cumul_size - 1;
+		csrow->nr_pages = cumul_size - last_cumul_size;
+		last_cumul_size = cumul_size;
+		csrow->grain = 1 << 12;	/* I82860_EAP has 4KiB reolution */
+		csrow->mtype = MEM_RMBS;
+		csrow->dtype = DEV_UNKNOWN;
+		csrow->edac_mode = mchcfg_ddim ? EDAC_SECDED : EDAC_NONE;
+	}
+
+	/* clear counters */
+	pci_write_bits16(mci->pdev, I82860_ERRSTS, 0x0003, 0x0003);
+
+	if (edac_mc_add_mc(mci)) {
+		debugf3("MC: " __FILE__
+			": %s(): failed edac_mc_add_mc()\n",
+			__func__);
+		edac_mc_free(mci);
+	} else {
+		/* get this far and it's successful */
+		debugf3("MC: " __FILE__ ": %s(): success\n", __func__);
+		rc = 0;
+	}
+	return rc;
+}
+
+/* returns count (>= 0), or negative on error */
+static int __devinit i82860_init_one(struct pci_dev *pdev,
+				     const struct pci_device_id *ent)
+{
+	int rc;
+
+	debugf0("MC: " __FILE__ ": %s()\n", __func__);
+
+	printk(KERN_INFO "i82860 init one\n");
+	if(pci_enable_device(pdev) < 0)
+		return -EIO;
+	rc = i82860_probe1(pdev, ent->driver_data);
+	if(rc == 0)
+		mci_pdev = pci_dev_get(pdev);
+	return rc;
+}
+
+static void __devexit i82860_remove_one(struct pci_dev *pdev)
+{
+	struct mem_ctl_info *mci;
+
+	debugf0(__FILE__ ": %s()\n", __func__);
+
+	mci = edac_mc_find_mci_by_pdev(pdev);
+	if ((mci != NULL) && (edac_mc_del_mc(mci) == 0))
+		edac_mc_free(mci);
+}
+
+static const struct pci_device_id i82860_pci_tbl[] __devinitdata = {
+	{PCI_VEND_DEV(INTEL, 82860_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	 I82860},
+	{0,}			/* 0 terminated list. */
+};
+
+MODULE_DEVICE_TABLE(pci, i82860_pci_tbl);
+
+static struct pci_driver i82860_driver = {
+	.name = BS_MOD_STR,
+	.probe = i82860_init_one,
+	.remove = __devexit_p(i82860_remove_one),
+	.id_table = i82860_pci_tbl,
+};
+
+static int __init i82860_init(void)
+{
+	int pci_rc;
+
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+	if ((pci_rc = pci_register_driver(&i82860_driver)) < 0)
+		return pci_rc;
+
+	if (!mci_pdev) {
+		i82860_registered = 0;
+		mci_pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
+					  PCI_DEVICE_ID_INTEL_82860_0, NULL);
+		if (mci_pdev == NULL) {
+			debugf0("860 pci_get_device fail\n");
+			return -ENODEV;
+		}
+		pci_rc = i82860_init_one(mci_pdev, i82860_pci_tbl);
+		if (pci_rc < 0) {
+			debugf0("860 init fail\n");
+			pci_dev_put(mci_pdev);
+			return -ENODEV;
+		}
+	}
+	return 0;
+}
+
+static void __exit i82860_exit(void)
+{
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+
+	pci_unregister_driver(&i82860_driver);
+	if (!i82860_registered) {
+		i82860_remove_one(mci_pdev);
+		pci_dev_put(mci_pdev);
+	}
+}
+
+module_init(i82860_init);
+module_exit(i82860_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR
+    ("Red Hat Inc. (http://www.redhat.com.com) Ben Woodard <woodard@redhat.com>");
+MODULE_DESCRIPTION("ECC support for Intel 82860 memory hub controllers");
diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c
new file mode 100644
index 0000000..009c08f
--- /dev/null
+++ b/drivers/edac/i82875p_edac.c
@@ -0,0 +1,532 @@
+/*
+ * Intel D82875P Memory Controller kernel module
+ * (C) 2003 Linux Networx (http://lnxi.com)
+ * This file may be distributed under the terms of the
+ * GNU General Public License.
+ *
+ * Written by Thayne Harbaugh
+ * Contributors:
+ *	Wang Zhenyu at intel.com
+ *
+ * $Id: edac_i82875p.c,v 1.5.2.11 2005/10/05 00:43:44 dsp_llnl Exp $
+ *
+ * Note: E7210 appears same as D82875P - zhenyu.z.wang at intel.com
+ */
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+
+#include <linux/slab.h>
+
+#include "edac_mc.h"
+
+
+#ifndef PCI_DEVICE_ID_INTEL_82875_0
+#define PCI_DEVICE_ID_INTEL_82875_0	0x2578
+#endif				/* PCI_DEVICE_ID_INTEL_82875_0 */
+
+#ifndef PCI_DEVICE_ID_INTEL_82875_6
+#define PCI_DEVICE_ID_INTEL_82875_6	0x257e
+#endif				/* PCI_DEVICE_ID_INTEL_82875_6 */
+
+
+/* four csrows in dual channel, eight in single channel */
+#define I82875P_NR_CSROWS(nr_chans) (8/(nr_chans))
+
+
+/* Intel 82875p register addresses - device 0 function 0 - DRAM Controller */
+#define I82875P_EAP		0x58	/* Error Address Pointer (32b)
+					 *
+					 * 31:12 block address
+					 * 11:0  reserved
+					 */
+
+#define I82875P_DERRSYN		0x5c	/* DRAM Error Syndrome (8b)
+					 *
+					 *  7:0  DRAM ECC Syndrome
+					 */
+
+#define I82875P_DES		0x5d	/* DRAM Error Status (8b)
+					 *
+					 *  7:1  reserved
+					 *  0    Error channel 0/1
+					 */
+
+#define I82875P_ERRSTS		0xc8	/* Error Status Register (16b)
+					 *
+					 * 15:10 reserved
+					 *  9    non-DRAM lock error (ndlock)
+					 *  8    Sftwr Generated SMI
+					 *  7    ECC UE
+					 *  6    reserved
+					 *  5    MCH detects unimplemented cycle
+					 *  4    AGP access outside GA
+					 *  3    Invalid AGP access
+					 *  2    Invalid GA translation table
+					 *  1    Unsupported AGP command
+					 *  0    ECC CE
+					 */
+
+#define I82875P_ERRCMD		0xca	/* Error Command (16b)
+					 *
+					 * 15:10 reserved
+					 *  9    SERR on non-DRAM lock
+					 *  8    SERR on ECC UE
+					 *  7    SERR on ECC CE
+					 *  6    target abort on high exception
+					 *  5    detect unimplemented cyc
+					 *  4    AGP access outside of GA
+					 *  3    SERR on invalid AGP access
+					 *  2    invalid translation table
+					 *  1    SERR on unsupported AGP command
+					 *  0    reserved
+					 */
+
+
+/* Intel 82875p register addresses - device 6 function 0 - DRAM Controller */
+#define I82875P_PCICMD6		0x04	/* PCI Command Register (16b)
+					 *
+					 * 15:10 reserved
+					 *  9    fast back-to-back - ro 0
+					 *  8    SERR enable - ro 0
+					 *  7    addr/data stepping - ro 0
+					 *  6    parity err enable - ro 0
+					 *  5    VGA palette snoop - ro 0
+					 *  4    mem wr & invalidate - ro 0
+					 *  3    special cycle - ro 0
+					 *  2    bus master - ro 0
+					 *  1    mem access dev6 - 0(dis),1(en)
+					 *  0    IO access dev3 - 0(dis),1(en)
+					 */
+
+#define I82875P_BAR6		0x10	/* Mem Delays Base ADDR Reg (32b)
+					 *
+					 * 31:12 mem base addr [31:12]
+					 * 11:4  address mask - ro 0
+					 *  3    prefetchable - ro 0(non),1(pre)
+					 *  2:1  mem type - ro 0
+					 *  0    mem space - ro 0
+					 */
+
+/* Intel 82875p MMIO register space - device 0 function 0 - MMR space */
+
+#define I82875P_DRB_SHIFT 26	/* 64MiB grain */
+#define I82875P_DRB		0x00	/* DRAM Row Boundary (8b x 8)
+					 *
+					 *  7    reserved
+					 *  6:0  64MiB row boundary addr
+					 */
+
+#define I82875P_DRA		0x10	/* DRAM Row Attribute (4b x 8)
+					 *
+					 *  7    reserved
+					 *  6:4  row attr row 1
+					 *  3    reserved
+					 *  2:0  row attr row 0
+					 *
+					 * 000 =  4KiB
+					 * 001 =  8KiB
+					 * 010 = 16KiB
+					 * 011 = 32KiB
+					 */
+
+#define I82875P_DRC		0x68	/* DRAM Controller Mode (32b)
+					 *
+					 * 31:30 reserved
+					 * 29    init complete
+					 * 28:23 reserved
+					 * 22:21 nr chan 00=1,01=2
+					 * 20    reserved
+					 * 19:18 Data Integ Mode 00=none,01=ecc
+					 * 17:11 reserved
+					 * 10:8  refresh mode
+					 *  7    reserved
+					 *  6:4  mode select
+					 *  3:2  reserved
+					 *  1:0  DRAM type 01=DDR
+					 */
+
+
+enum i82875p_chips {
+	I82875P = 0,
+};
+
+
+struct i82875p_pvt {
+	struct pci_dev *ovrfl_pdev;
+	void *ovrfl_window;
+};
+
+
+struct i82875p_dev_info {
+	const char *ctl_name;
+};
+
+
+struct i82875p_error_info {
+	u16 errsts;
+	u32 eap;
+	u8 des;
+	u8 derrsyn;
+	u16 errsts2;
+};
+
+
+static const struct i82875p_dev_info i82875p_devs[] = {
+	[I82875P] = {
+		     .ctl_name = "i82875p"},
+};
+
+static struct pci_dev *mci_pdev = NULL;	/* init dev: in case that AGP code
+					   has already registered driver */
+static int i82875p_registered = 1;
+
+static void i82875p_get_error_info (struct mem_ctl_info *mci,
+		struct i82875p_error_info *info)
+{
+	/*
+	 * This is a mess because there is no atomic way to read all the
+	 * registers at once and the registers can transition from CE being
+	 * overwritten by UE.
+	 */
+	pci_read_config_word(mci->pdev, I82875P_ERRSTS, &info->errsts);
+	pci_read_config_dword(mci->pdev, I82875P_EAP, &info->eap);
+	pci_read_config_byte(mci->pdev, I82875P_DES, &info->des);
+	pci_read_config_byte(mci->pdev, I82875P_DERRSYN, &info->derrsyn);
+	pci_read_config_word(mci->pdev, I82875P_ERRSTS, &info->errsts2);
+
+	pci_write_bits16(mci->pdev, I82875P_ERRSTS, 0x0081, 0x0081);
+
+	/*
+	 * If the error is the same then we can for both reads then
+	 * the first set of reads is valid.  If there is a change then
+	 * there is a CE no info and the second set of reads is valid
+	 * and should be UE info.
+	 */
+	if (!(info->errsts2 & 0x0081))
+		return;
+	if ((info->errsts ^ info->errsts2) & 0x0081) {
+		pci_read_config_dword(mci->pdev, I82875P_EAP, &info->eap);
+		pci_read_config_byte(mci->pdev, I82875P_DES, &info->des);
+		pci_read_config_byte(mci->pdev, I82875P_DERRSYN,
+		    &info->derrsyn);
+	}
+}
+
+static int i82875p_process_error_info (struct mem_ctl_info *mci,
+		struct i82875p_error_info *info, int handle_errors)
+{
+	int row, multi_chan;
+
+	multi_chan = mci->csrows[0].nr_channels - 1;
+
+	if (!(info->errsts2 & 0x0081))
+		return 0;
+
+	if (!handle_errors)
+		return 1;
+
+	if ((info->errsts ^ info->errsts2) & 0x0081) {
+		edac_mc_handle_ce_no_info(mci, "UE overwrote CE");
+		info->errsts = info->errsts2;
+	}
+
+	info->eap >>= PAGE_SHIFT;
+	row = edac_mc_find_csrow_by_page(mci, info->eap);
+
+	if (info->errsts & 0x0080)
+		edac_mc_handle_ue(mci, info->eap, 0, row, "i82875p UE");
+	else
+		edac_mc_handle_ce(mci, info->eap, 0, info->derrsyn, row,
+				       multi_chan ? (info->des & 0x1) : 0,
+				       "i82875p CE");
+
+	return 1;
+}
+
+
+static void i82875p_check(struct mem_ctl_info *mci)
+{
+	struct i82875p_error_info info;
+
+	debugf1("MC%d: " __FILE__ ": %s()\n", mci->mc_idx, __func__);
+	i82875p_get_error_info(mci, &info);
+	i82875p_process_error_info(mci, &info, 1);
+}
+
+
+#ifdef CONFIG_PROC_FS
+extern int pci_proc_attach_device(struct pci_dev *);
+#endif
+
+static int i82875p_probe1(struct pci_dev *pdev, int dev_idx)
+{
+	int rc = -ENODEV;
+	int index;
+	struct mem_ctl_info *mci = NULL;
+	struct i82875p_pvt *pvt = NULL;
+	unsigned long last_cumul_size;
+	struct pci_dev *ovrfl_pdev;
+	void __iomem *ovrfl_window = NULL;
+
+	u32 drc;
+	u32 drc_chan;		/* Number of channels 0=1chan,1=2chan */
+	u32 nr_chans;
+	u32 drc_ddim;		/* DRAM Data Integrity Mode 0=none,2=edac */
+
+	debugf0("MC: " __FILE__ ": %s()\n", __func__);
+
+	ovrfl_pdev = pci_find_device(PCI_VEND_DEV(INTEL, 82875_6), NULL);
+
+	if (!ovrfl_pdev) {
+		/*
+		 * Intel tells BIOS developers to hide device 6 which
+		 * configures the overflow device access containing
+		 * the DRBs - this is where we expose device 6.
+		 * http://www.x86-secret.com/articles/tweak/pat/patsecrets-2.htm
+		 */
+		pci_write_bits8(pdev, 0xf4, 0x2, 0x2);
+		ovrfl_pdev =
+		    pci_scan_single_device(pdev->bus, PCI_DEVFN(6, 0));
+		if (!ovrfl_pdev)
+			goto fail;
+	}
+#ifdef CONFIG_PROC_FS
+	if (!ovrfl_pdev->procent && pci_proc_attach_device(ovrfl_pdev)) {
+		printk(KERN_ERR "MC: " __FILE__
+		       ": %s(): Failed to attach overflow device\n",
+		       __func__);
+		goto fail;
+	}
+#endif				/* CONFIG_PROC_FS */
+	if (pci_enable_device(ovrfl_pdev)) {
+		printk(KERN_ERR "MC: " __FILE__
+		       ": %s(): Failed to enable overflow device\n",
+		       __func__);
+		goto fail;
+	}
+
+	if (pci_request_regions(ovrfl_pdev, pci_name(ovrfl_pdev))) {
+#ifdef CORRECT_BIOS
+		goto fail;
+#endif
+	}
+	/* cache is irrelevant for PCI bus reads/writes */
+	ovrfl_window = ioremap_nocache(pci_resource_start(ovrfl_pdev, 0),
+				       pci_resource_len(ovrfl_pdev, 0));
+
+	if (!ovrfl_window) {
+		printk(KERN_ERR "MC: " __FILE__
+		       ": %s(): Failed to ioremap bar6\n", __func__);
+		goto fail;
+	}
+
+	/* need to find out the number of channels */
+	drc = readl(ovrfl_window + I82875P_DRC);
+	drc_chan = ((drc >> 21) & 0x1);
+	nr_chans = drc_chan + 1;
+	drc_ddim = (drc >> 18) & 0x1;
+
+	mci = edac_mc_alloc(sizeof(*pvt), I82875P_NR_CSROWS(nr_chans),
+				 nr_chans);
+
+	if (!mci) {
+		rc = -ENOMEM;
+		goto fail;
+	}
+
+	debugf3("MC: " __FILE__ ": %s(): init mci\n", __func__);
+
+	mci->pdev = pdev;
+	mci->mtype_cap = MEM_FLAG_DDR;
+
+	mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
+	mci->edac_cap = EDAC_FLAG_UNKNOWN;
+	/* adjust FLAGS */
+
+	mci->mod_name = BS_MOD_STR;
+	mci->mod_ver = "$Revision: 1.5.2.11 $";
+	mci->ctl_name = i82875p_devs[dev_idx].ctl_name;
+	mci->edac_check = i82875p_check;
+	mci->ctl_page_to_phys = NULL;
+
+	debugf3("MC: " __FILE__ ": %s(): init pvt\n", __func__);
+
+	pvt = (struct i82875p_pvt *) mci->pvt_info;
+	pvt->ovrfl_pdev = ovrfl_pdev;
+	pvt->ovrfl_window = ovrfl_window;
+
+	/*
+	 * The dram row boundary (DRB) reg values are boundary address
+	 * for each DRAM row with a granularity of 32 or 64MB (single/dual
+	 * channel operation).  DRB regs are cumulative; therefore DRB7 will
+	 * contain the total memory contained in all eight rows.
+	 */
+	for (last_cumul_size = index = 0; index < mci->nr_csrows; index++) {
+		u8 value;
+		u32 cumul_size;
+		struct csrow_info *csrow = &mci->csrows[index];
+
+		value = readb(ovrfl_window + I82875P_DRB + index);
+		cumul_size = value << (I82875P_DRB_SHIFT - PAGE_SHIFT);
+		debugf3("MC: " __FILE__ ": %s(): (%d) cumul_size 0x%x\n",
+			__func__, index, cumul_size);
+		if (cumul_size == last_cumul_size)
+			continue;	/* not populated */
+
+		csrow->first_page = last_cumul_size;
+		csrow->last_page = cumul_size - 1;
+		csrow->nr_pages = cumul_size - last_cumul_size;
+		last_cumul_size = cumul_size;
+		csrow->grain = 1 << 12;	/* I82875P_EAP has 4KiB reolution */
+		csrow->mtype = MEM_DDR;
+		csrow->dtype = DEV_UNKNOWN;
+		csrow->edac_mode = drc_ddim ? EDAC_SECDED : EDAC_NONE;
+	}
+
+	/* clear counters */
+	pci_write_bits16(mci->pdev, I82875P_ERRSTS, 0x0081, 0x0081);
+
+	if (edac_mc_add_mc(mci)) {
+		debugf3("MC: " __FILE__
+			": %s(): failed edac_mc_add_mc()\n", __func__);
+		goto fail;
+	}
+
+	/* get this far and it's successful */
+	debugf3("MC: " __FILE__ ": %s(): success\n", __func__);
+	return 0;
+
+      fail:
+	if (mci)
+		edac_mc_free(mci);
+
+	if (ovrfl_window)
+		iounmap(ovrfl_window);
+
+	if (ovrfl_pdev) {
+		pci_release_regions(ovrfl_pdev);
+		pci_disable_device(ovrfl_pdev);
+	}
+
+	/* NOTE: the ovrfl proc entry and pci_dev are intentionally left */
+	return rc;
+}
+
+
+/* returns count (>= 0), or negative on error */
+static int __devinit i82875p_init_one(struct pci_dev *pdev,
+				      const struct pci_device_id *ent)
+{
+	int rc;
+
+	debugf0("MC: " __FILE__ ": %s()\n", __func__);
+
+	printk(KERN_INFO "i82875p init one\n");
+	if(pci_enable_device(pdev) < 0)
+		return -EIO;
+	rc = i82875p_probe1(pdev, ent->driver_data);
+	if (mci_pdev == NULL)
+		mci_pdev = pci_dev_get(pdev);
+	return rc;
+}
+
+
+static void __devexit i82875p_remove_one(struct pci_dev *pdev)
+{
+	struct mem_ctl_info *mci;
+	struct i82875p_pvt *pvt = NULL;
+
+	debugf0(__FILE__ ": %s()\n", __func__);
+
+	if ((mci = edac_mc_find_mci_by_pdev(pdev)) == NULL)
+		return;
+
+	pvt = (struct i82875p_pvt *) mci->pvt_info;
+	if (pvt->ovrfl_window)
+		iounmap(pvt->ovrfl_window);
+
+	if (pvt->ovrfl_pdev) {
+#ifdef CORRECT_BIOS
+		pci_release_regions(pvt->ovrfl_pdev);
+#endif				/*CORRECT_BIOS */
+		pci_disable_device(pvt->ovrfl_pdev);
+		pci_dev_put(pvt->ovrfl_pdev);
+	}
+
+	if (edac_mc_del_mc(mci))
+		return;
+
+	edac_mc_free(mci);
+}
+
+
+static const struct pci_device_id i82875p_pci_tbl[] __devinitdata = {
+	{PCI_VEND_DEV(INTEL, 82875_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	 I82875P},
+	{0,}			/* 0 terminated list. */
+};
+
+MODULE_DEVICE_TABLE(pci, i82875p_pci_tbl);
+
+
+static struct pci_driver i82875p_driver = {
+	.name = BS_MOD_STR,
+	.probe = i82875p_init_one,
+	.remove = __devexit_p(i82875p_remove_one),
+	.id_table = i82875p_pci_tbl,
+};
+
+
+static int __init i82875p_init(void)
+{
+	int pci_rc;
+
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+	pci_rc = pci_register_driver(&i82875p_driver);
+	if (pci_rc < 0)
+		return pci_rc;
+	if (mci_pdev == NULL) {
+		i82875p_registered = 0;
+		mci_pdev =
+		    pci_get_device(PCI_VENDOR_ID_INTEL,
+				   PCI_DEVICE_ID_INTEL_82875_0, NULL);
+		if (!mci_pdev) {
+			debugf0("875p pci_get_device fail\n");
+			return -ENODEV;
+		}
+		pci_rc = i82875p_init_one(mci_pdev, i82875p_pci_tbl);
+		if (pci_rc < 0) {
+			debugf0("875p init fail\n");
+			pci_dev_put(mci_pdev);
+			return -ENODEV;
+		}
+	}
+	return 0;
+}
+
+
+static void __exit i82875p_exit(void)
+{
+	debugf3("MC: " __FILE__ ": %s()\n", __func__);
+
+	pci_unregister_driver(&i82875p_driver);
+	if (!i82875p_registered) {
+		i82875p_remove_one(mci_pdev);
+		pci_dev_put(mci_pdev);
+	}
+}
+
+
+module_init(i82875p_init);
+module_exit(i82875p_exit);
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Linux Networx (http://lnxi.com) Thayne Harbaugh");
+MODULE_DESCRIPTION("MC support for Intel 82875 memory hub controllers");
diff --git a/drivers/edac/r82600_edac.c b/drivers/edac/r82600_edac.c
new file mode 100644
index 0000000..e908928
--- /dev/null
+++ b/drivers/edac/r82600_edac.c
@@ -0,0 +1,407 @@
+/*
+ * Radisys 82600 Embedded chipset Memory Controller kernel module
+ * (C) 2005 EADS Astrium
+ * This file may be distributed under the terms of the
+ * GNU General Public License.
+ *
+ * Written by Tim Small <tim@buttersideup.com>, based on work by Thayne
+ * Harbaugh, Dan Hollis <goemon at anime dot net> and others.
+ *
+ * $Id: edac_r82600.c,v 1.1.2.6 2005/10/05 00:43:44 dsp_llnl Exp $
+ *
+ * Written with reference to 82600 High Integration Dual PCI System
+ * Controller Data Book:
+ * http://www.radisys.com/files/support_downloads/007-01277-0002.82600DataBook.pdf
+ * references to this document given in []
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+
+#include <linux/slab.h>
+
+#include "edac_mc.h"
+
+/* Radisys say "The 82600 integrates a main memory SDRAM controller that
+ * supports up to four banks of memory. The four banks can support a mix of
+ * sizes of 64 bit wide (72 bits with ECC) Synchronous DRAM (SDRAM) DIMMs,
+ * each of which can be any size from 16MB to 512MB. Both registered (control
+ * signals buffered) and unbuffered DIMM types are supported. Mixing of
+ * registered and unbuffered DIMMs as well as mixing of ECC and non-ECC DIMMs
+ * is not allowed. The 82600 SDRAM interface operates at the same frequency as
+ * the CPU bus, 66MHz, 100MHz or 133MHz."
+ */
+
+#define R82600_NR_CSROWS 4
+#define R82600_NR_CHANS  1
+#define R82600_NR_DIMMS  4
+
+#define R82600_BRIDGE_ID  0x8200
+
+/* Radisys 82600 register addresses - device 0 function 0 - PCI bridge */
+#define R82600_DRAMC	0x57	/* Various SDRAM related control bits
+				 * all bits are R/W
+				 *
+				 * 7    SDRAM ISA Hole Enable
+				 * 6    Flash Page Mode Enable
+				 * 5    ECC Enable: 1=ECC 0=noECC
+				 * 4    DRAM DIMM Type: 1=
+				 * 3    BIOS Alias Disable
+				 * 2    SDRAM BIOS Flash Write Enable
+				 * 1:0  SDRAM Refresh Rate: 00=Disabled
+				 *          01=7.8usec (256Mbit SDRAMs)
+				 *          10=15.6us 11=125usec
+				 */
+
+#define R82600_SDRAMC	0x76	/* "SDRAM Control Register"
+				 * More SDRAM related control bits
+				 * all bits are R/W
+				 *
+				 * 15:8 Reserved.
+				 *
+				 * 7:5  Special SDRAM Mode Select
+				 *
+				 * 4    Force ECC
+				 *
+				 *        1=Drive ECC bits to 0 during
+				 *          write cycles (i.e. ECC test mode)
+				 *
+				 *        0=Normal ECC functioning
+				 *
+				 * 3    Enhanced Paging Enable
+				 *
+				 * 2    CAS# Latency 0=3clks 1=2clks
+				 *
+				 * 1    RAS# to CAS# Delay 0=3 1=2
+				 *
+				 * 0    RAS# Precharge     0=3 1=2
+				 */
+
+#define R82600_EAP	0x80	/* ECC Error Address Pointer Register
+				 *
+				 * 31    Disable Hardware Scrubbing (RW)
+				 *        0=Scrub on corrected read
+				 *        1=Don't scrub on corrected read
+				 *
+				 * 30:12 Error Address Pointer (RO)
+				 *        Upper 19 bits of error address
+				 *
+				 * 11:4  Syndrome Bits (RO)
+				 *
+				 * 3     BSERR# on multibit error (RW)
+				 *        1=enable 0=disable
+				 *
+				 * 2     NMI on Single Bit Eror (RW)
+				 *        1=NMI triggered by SBE n.b. other
+				 *          prerequeists
+				 *        0=NMI not triggered
+				 *
+				 * 1     MBE (R/WC)
+				 *        read 1=MBE at EAP (see above)
+				 *        read 0=no MBE, or SBE occurred first
+				 *        write 1=Clear MBE status (must also
+				 *          clear SBE)
+				 *        write 0=NOP
+				 *
+				 * 1     SBE (R/WC)
+				 *        read 1=SBE at EAP (see above)
+				 *        read 0=no SBE, or MBE occurred first
+				 *        write 1=Clear SBE status (must also
+				 *          clear MBE)
+				 *        write 0=NOP
+				 */
+
+#define R82600_DRBA	0x60	/* + 0x60..0x63 SDRAM Row Boundry Address
+				 *  Registers
+				 *
+				 * 7:0  Address lines 30:24 - upper limit of
+				 * each row [p57]
+				 */
+
+struct r82600_error_info {
+	u32 eapr;
+};
+
+
+static unsigned int disable_hardware_scrub = 0;
+
+
+static void r82600_get_error_info (struct mem_ctl_info *mci,
+		struct r82600_error_info *info)
+{
+	pci_read_config_dword(mci->pdev, R82600_EAP, &info->eapr);
+
+	if (info->eapr & BIT(0))
+		/* Clear error to allow next error to be reported [p.62] */
+		pci_write_bits32(mci->pdev, R82600_EAP,
+				   ((u32) BIT(0) & (u32) BIT(1)),
+				   ((u32) BIT(0) & (u32) BIT(1)));
+
+	if (info->eapr & BIT(1))
+		/* Clear error to allow next error to be reported [p.62] */
+		pci_write_bits32(mci->pdev, R82600_EAP,
+				   ((u32) BIT(0) & (u32) BIT(1)),
+				   ((u32) BIT(0) & (u32) BIT(1)));
+}
+
+
+static int r82600_process_error_info (struct mem_ctl_info *mci,
+		struct r82600_error_info *info, int handle_errors)
+{
+	int error_found;
+	u32 eapaddr, page;
+	u32 syndrome;
+
+	error_found = 0;
+
+	/* bits 30:12 store the upper 19 bits of the 32 bit error address */
+	eapaddr = ((info->eapr >> 12) & 0x7FFF) << 13;
+	/* Syndrome in bits 11:4 [p.62]       */
+	syndrome = (info->eapr >> 4) & 0xFF;
+
+	/* the R82600 reports at less than page *
+	 * granularity (upper 19 bits only)     */
+	page = eapaddr >> PAGE_SHIFT;
+
+	if (info->eapr & BIT(0)) { 	/* CE? */
+		error_found = 1;
+
+		if (handle_errors)
+			edac_mc_handle_ce(
+			    mci, page, 0,	/* not avail */
+			    syndrome,
+			    edac_mc_find_csrow_by_page(mci, page),
+			    0,	/* channel */
+			    mci->ctl_name);
+	}
+
+	if (info->eapr & BIT(1)) { 	/* UE? */
+		error_found = 1;
+
+		if (handle_errors)
+			/* 82600 doesn't give enough info */
+			edac_mc_handle_ue(mci, page, 0,
+			    edac_mc_find_csrow_by_page(mci, page),
+			    mci->ctl_name);
+	}
+
+	return error_found;
+}
+
+static void r82600_check(struct mem_ctl_info *mci)
+{
+	struct r82600_error_info info;
+
+	debugf1("MC%d: " __FILE__ ": %s()\n", mci->mc_idx, __func__);
+	r82600_get_error_info(mci, &info);
+	r82600_process_error_info(mci, &info, 1);
+}
+
+static int r82600_probe1(struct pci_dev *pdev, int dev_idx)
+{
+	int rc = -ENODEV;
+	int index;
+	struct mem_ctl_info *mci = NULL;
+	u8 dramcr;
+	u32 ecc_on;
+	u32 reg_sdram;
+	u32 eapr;
+	u32 scrub_disabled;
+	u32 sdram_refresh_rate;
+	u32 row_high_limit_last = 0;
+	u32 eap_init_bits;
+
+	debugf0("MC: " __FILE__ ": %s()\n", __func__);
+
+
+	pci_read_config_byte(pdev, R82600_DRAMC, &dramcr);
+	pci_read_config_dword(pdev, R82600_EAP, &eapr);
+
+	ecc_on = dramcr & BIT(5);
+	reg_sdram = dramcr & BIT(4);
+	scrub_disabled = eapr & BIT(31);
+	sdram_refresh_rate = dramcr & (BIT(0) | BIT(1));
+
+	debugf2("MC: " __FILE__ ": %s(): sdram refresh rate = %#0x\n",
+		__func__, sdram_refresh_rate);
+
+	debugf2("MC: " __FILE__ ": %s(): DRAMC register = %#0x\n", __func__,
+		dramcr);
+
+	mci = edac_mc_alloc(0, R82600_NR_CSROWS, R82600_NR_CHANS);
+
+	if (mci == NULL) {
+		rc = -ENOMEM;
+		goto fail;
+	}
+
+	debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci);
+
+	mci->pdev = pdev;
+	mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_DDR;
+
+	mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED;
+	/* FIXME try to work out if the chip leads have been                 *
+	 * used for COM2 instead on this board? [MA6?]       MAYBE:          */
+
+	/* On the R82600, the pins for memory bits 72:65 - i.e. the   *
+	 * EC bits are shared with the pins for COM2 (!), so if COM2  *
+	 * is enabled, we assume COM2 is wired up, and thus no EDAC   *
+	 * is possible.                                               */
+	mci->edac_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED;
+	if (ecc_on) {
+		if (scrub_disabled)
+			debugf3("MC: " __FILE__ ": %s(): mci = %p - "
+				"Scrubbing disabled! EAP: %#0x\n", __func__,
+				mci, eapr);
+	} else
+		mci->edac_cap = EDAC_FLAG_NONE;
+
+	mci->mod_name = BS_MOD_STR;
+	mci->mod_ver = "$Revision: 1.1.2.6 $";
+	mci->ctl_name = "R82600";
+	mci->edac_check = r82600_check;
+	mci->ctl_page_to_phys = NULL;
+
+	for (index = 0; index < mci->nr_csrows; index++) {
+		struct csrow_info *csrow = &mci->csrows[index];
+		u8 drbar;	/* sDram Row Boundry Address Register */
+		u32 row_high_limit;
+		u32 row_base;
+
+		/* find the DRAM Chip Select Base address and mask */
+		pci_read_config_byte(mci->pdev, R82600_DRBA + index, &drbar);
+
+		debugf1("MC%d: " __FILE__ ": %s() Row=%d DRBA = %#0x\n",
+			mci->mc_idx, __func__, index, drbar);
+
+		row_high_limit = ((u32) drbar << 24);
+/*		row_high_limit = ((u32)drbar << 24) | 0xffffffUL; */
+
+		debugf1("MC%d: " __FILE__ ": %s() Row=%d, "
+			"Boundry Address=%#0x, Last = %#0x \n",
+			mci->mc_idx, __func__, index, row_high_limit,
+			row_high_limit_last);
+
+		/* Empty row [p.57] */
+		if (row_high_limit == row_high_limit_last)
+			continue;
+
+		row_base = row_high_limit_last;
+
+		csrow->first_page = row_base >> PAGE_SHIFT;
+		csrow->last_page = (row_high_limit >> PAGE_SHIFT) - 1;
+		csrow->nr_pages = csrow->last_page - csrow->first_page + 1;
+		/* Error address is top 19 bits - so granularity is      *
+		 * 14 bits                                               */
+		csrow->grain = 1 << 14;
+		csrow->mtype = reg_sdram ? MEM_RDDR : MEM_DDR;
+		/* FIXME - check that this is unknowable with this chipset */
+		csrow->dtype = DEV_UNKNOWN;
+
+		/* Mode is global on 82600 */
+		csrow->edac_mode = ecc_on ? EDAC_SECDED : EDAC_NONE;
+		row_high_limit_last = row_high_limit;
+	}
+
+	/* clear counters */
+	/* FIXME should we? */
+
+	if (edac_mc_add_mc(mci)) {
+		debugf3("MC: " __FILE__
+			": %s(): failed edac_mc_add_mc()\n", __func__);
+		goto fail;
+	}
+
+	/* get this far and it's successful */
+
+	/* Clear error flags to allow next error to be reported [p.62] */
+	/* Test systems seem to always have the UE flag raised on boot */
+
+	eap_init_bits = BIT(0) & BIT(1);
+	if (disable_hardware_scrub) {
+		eap_init_bits |= BIT(31);
+		debugf3("MC: " __FILE__ ": %s(): Disabling Hardware Scrub "
+			"(scrub on error)\n", __func__);
+	}
+
+	pci_write_bits32(mci->pdev, R82600_EAP, eap_init_bits,
+			 eap_init_bits);
+
+	debugf3("MC: " __FILE__ ": %s(): success\n", __func__);
+	return 0;
+
+fail:
+	if (mci)
+		edac_mc_free(mci);
+
+	return rc;
+}
+
+/* returns count (>= 0), or negative on error */
+static int __devinit r82600_init_one(struct pci_dev *pdev,
+				     const struct pci_device_id *ent)
+{
+	debugf0("MC: " __FILE__ ": %s()\n", __func__);
+
+	/* don't need to call pci_device_enable() */
+	return r82600_probe1(pdev, ent->driver_data);
+}
+
+
+static void __devexit r82600_remove_one(struct pci_dev *pdev)
+{
+	struct mem_ctl_info *mci;
+
+	debugf0(__FILE__ ": %s()\n", __func__);
+
+	if (((mci = edac_mc_find_mci_by_pdev(pdev)) != NULL) &&
+	    !edac_mc_del_mc(mci))
+		edac_mc_free(mci);
+}
+
+
+static const struct pci_device_id r82600_pci_tbl[] __devinitdata = {
+	{PCI_DEVICE(PCI_VENDOR_ID_RADISYS, R82600_BRIDGE_ID)},
+	{0,}			/* 0 terminated list. */
+};
+
+MODULE_DEVICE_TABLE(pci, r82600_pci_tbl);
+
+
+static struct pci_driver r82600_driver = {
+	.name = BS_MOD_STR,
+	.probe = r82600_init_one,
+	.remove = __devexit_p(r82600_remove_one),
+	.id_table = r82600_pci_tbl,
+};
+
+
+static int __init r82600_init(void)
+{
+	return pci_register_driver(&r82600_driver);
+}
+
+
+static void __exit r82600_exit(void)
+{
+	pci_unregister_driver(&r82600_driver);
+}
+
+
+module_init(r82600_init);
+module_exit(r82600_exit);
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tim Small <tim@buttersideup.com> - WPAD Ltd. "
+	      "on behalf of EADS Astrium");
+MODULE_DESCRIPTION("MC support for Radisys 82600 memory controllers");
+
+module_param(disable_hardware_scrub, bool, 0644);
+MODULE_PARM_DESC(disable_hardware_scrub,
+		 "If set, disable the chipset's automatic scrub for CEs");
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index acda7d6..501cc05 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -956,6 +956,8 @@ static void ib_sa_remove_one(struct ib_d
 
 	ib_unregister_event_handler(&sa_dev->event_handler);
 
+	flush_scheduled_work();
+
 	for (i = 0; i <= sa_dev->end_port - sa_dev->start_port; ++i) {
 		ib_unregister_mad_agent(sa_dev->port[i].agent);
 		kref_put(&sa_dev->port[i].sm_ah->ref, free_sm_ah);
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 96ea79b..903f85a 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -902,6 +902,7 @@ static void __exit ib_uverbs_cleanup(voi
 	unregister_filesystem(&uverbs_event_fs);
 	class_destroy(uverbs_class);
 	unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES);
+	flush_scheduled_work();
 	idr_destroy(&ib_uverbs_pd_idr);
 	idr_destroy(&ib_uverbs_mr_idr);
 	idr_destroy(&ib_uverbs_mw_idr);
diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c
index a14eed0..a19e0ed 100644
--- a/drivers/infiniband/hw/mthca/mthca_av.c
+++ b/drivers/infiniband/hw/mthca/mthca_av.c
@@ -184,7 +184,7 @@ int mthca_read_ah(struct mthca_dev *dev,
 			ah->av->sl_tclass_flowlabel & cpu_to_be32(0xfffff);
 		ib_get_cached_gid(&dev->ib_dev,
 				  be32_to_cpu(ah->av->port_pd) >> 24,
-				  ah->av->gid_index,
+				  ah->av->gid_index % dev->limits.gid_table_len,
 				  &header->grh.source_gid);
 		memcpy(header->grh.destination_gid.raw,
 		       ah->av->dgid, 16);
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index be1791b..f9b9b93 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -199,8 +199,7 @@ static int mthca_cmd_post(struct mthca_d
 {
 	int err = 0;
 
-	if (down_interruptible(&dev->cmd.hcr_sem))
-		return -EINTR;
+	mutex_lock(&dev->cmd.hcr_mutex);
 
 	if (event) {
 		unsigned long end = jiffies + GO_BIT_TIMEOUT;
@@ -238,7 +237,7 @@ static int mthca_cmd_post(struct mthca_d
 					       op),                       dev->hcr + 6 * 4);
 
 out:
-	up(&dev->cmd.hcr_sem);
+	mutex_unlock(&dev->cmd.hcr_mutex);
 	return err;
 }
 
@@ -255,8 +254,7 @@ static int mthca_cmd_poll(struct mthca_d
 	int err = 0;
 	unsigned long end;
 
-	if (down_interruptible(&dev->cmd.poll_sem))
-		return -EINTR;
+	down(&dev->cmd.poll_sem);
 
 	err = mthca_cmd_post(dev, in_param,
 			     out_param ? *out_param : 0,
@@ -333,8 +331,7 @@ static int mthca_cmd_wait(struct mthca_d
 	int err = 0;
 	struct mthca_cmd_context *context;
 
-	if (down_interruptible(&dev->cmd.event_sem))
-		return -EINTR;
+	down(&dev->cmd.event_sem);
 
 	spin_lock(&dev->cmd.context_lock);
 	BUG_ON(dev->cmd.free_head < 0);
@@ -438,7 +435,7 @@ static int mthca_cmd_imm(struct mthca_de
 
 int mthca_cmd_init(struct mthca_dev *dev)
 {
-	sema_init(&dev->cmd.hcr_sem, 1);
+	mutex_init(&dev->cmd.hcr_mutex);
 	sema_init(&dev->cmd.poll_sem, 1);
 	dev->cmd.use_events = 0;
 
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index a104ab0..2a165fd 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -44,6 +44,8 @@
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <linux/timer.h>
+#include <linux/mutex.h>
+
 #include <asm/semaphore.h>
 
 #include "mthca_provider.h"
@@ -111,7 +113,7 @@ enum {
 struct mthca_cmd {
 	struct pci_pool          *pool;
 	int                       use_events;
-	struct semaphore          hcr_sem;
+	struct mutex              hcr_mutex;
 	struct semaphore 	  poll_sem;
 	struct semaphore 	  event_sem;
 	int              	  max_cmds;
@@ -256,7 +258,7 @@ struct mthca_av_table {
 };
 
 struct mthca_mcg_table {
-	struct semaphore   	sem;
+	struct mutex		mutex;
 	struct mthca_alloc 	alloc;
 	struct mthca_icm_table *table;
 };
@@ -301,7 +303,7 @@ struct mthca_dev {
 	u64              ddr_end;
 
 	MTHCA_DECLARE_DOORBELL_LOCK(doorbell_lock)
-	struct semaphore cap_mask_mutex;
+	struct mutex cap_mask_mutex;
 
 	void __iomem    *hcr;
 	void __iomem    *kar;
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 8b00d9a..9c849d2 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -155,6 +155,13 @@ static int __devinit mthca_dev_lim(struc
 		return -ENODEV;
 	}
 
+	if (dev_lim->uar_size > pci_resource_len(mdev->pdev, 2)) {
+		mthca_err(mdev, "HCA reported UAR size of 0x%x bigger than "
+			  "PCI resource 2 size of 0x%lx, aborting.\n",
+			  dev_lim->uar_size, pci_resource_len(mdev->pdev, 2));
+		return -ENODEV;
+	}
+
 	mdev->limits.num_ports      	= dev_lim->num_ports;
 	mdev->limits.vl_cap             = dev_lim->max_vl;
 	mdev->limits.mtu_cap            = dev_lim->max_mtu;
@@ -976,8 +983,7 @@ static int __devinit mthca_init_one(stru
 		err = -ENODEV;
 		goto err_disable_pdev;
 	}
-	if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM) ||
-	    pci_resource_len(pdev, 2) != 1 << 23) {
+	if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) {
 		dev_err(&pdev->dev, "Missing UAR, aborting.\n");
 		err = -ENODEV;
 		goto err_disable_pdev;
diff --git a/drivers/infiniband/hw/mthca/mthca_mcg.c b/drivers/infiniband/hw/mthca/mthca_mcg.c
index 77bc6c7..321f11e 100644
--- a/drivers/infiniband/hw/mthca/mthca_mcg.c
+++ b/drivers/infiniband/hw/mthca/mthca_mcg.c
@@ -154,10 +154,7 @@ int mthca_multicast_attach(struct ib_qp 
 		return PTR_ERR(mailbox);
 	mgm = mailbox->buf;
 
-	if (down_interruptible(&dev->mcg_table.sem)) {
-		err = -EINTR;
-		goto err_sem;
-	}
+	mutex_lock(&dev->mcg_table.mutex);
 
 	err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index);
 	if (err)
@@ -241,8 +238,8 @@ int mthca_multicast_attach(struct ib_qp 
 		BUG_ON(index < dev->limits.num_mgms);
 		mthca_free(&dev->mcg_table.alloc, index);
 	}
-	up(&dev->mcg_table.sem);
- err_sem:
+	mutex_unlock(&dev->mcg_table.mutex);
+
 	mthca_free_mailbox(dev, mailbox);
 	return err;
 }
@@ -263,10 +260,7 @@ int mthca_multicast_detach(struct ib_qp 
 		return PTR_ERR(mailbox);
 	mgm = mailbox->buf;
 
-	if (down_interruptible(&dev->mcg_table.sem)) {
-		err = -EINTR;
-		goto err_sem;
-	}
+	mutex_lock(&dev->mcg_table.mutex);
 
 	err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index);
 	if (err)
@@ -371,8 +365,8 @@ int mthca_multicast_detach(struct ib_qp 
 	}
 
  out:
-	up(&dev->mcg_table.sem);
- err_sem:
+	mutex_unlock(&dev->mcg_table.mutex);
+
 	mthca_free_mailbox(dev, mailbox);
 	return err;
 }
@@ -389,7 +383,7 @@ int __devinit mthca_init_mcg_table(struc
 	if (err)
 		return err;
 
-	init_MUTEX(&dev->mcg_table.sem);
+	mutex_init(&dev->mcg_table.mutex);
 
 	return 0;
 }
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index 9fb985a..d709cb1 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -50,7 +50,7 @@ enum {
 };
 
 struct mthca_user_db_table {
-	struct semaphore mutex;
+	struct mutex mutex;
 	struct {
 		u64                uvirt;
 		struct scatterlist mem;
@@ -158,7 +158,7 @@ int mthca_table_get(struct mthca_dev *de
 	int ret = 0;
 	u8 status;
 
-	down(&table->mutex);
+	mutex_lock(&table->mutex);
 
 	if (table->icm[i]) {
 		++table->icm[i]->refcount;
@@ -184,7 +184,7 @@ int mthca_table_get(struct mthca_dev *de
 	++table->icm[i]->refcount;
 
 out:
-	up(&table->mutex);
+	mutex_unlock(&table->mutex);
 	return ret;
 }
 
@@ -198,7 +198,7 @@ void mthca_table_put(struct mthca_dev *d
 
 	i = (obj & (table->num_obj - 1)) * table->obj_size / MTHCA_TABLE_CHUNK_SIZE;
 
-	down(&table->mutex);
+	mutex_lock(&table->mutex);
 
 	if (--table->icm[i]->refcount == 0) {
 		mthca_UNMAP_ICM(dev, table->virt + i * MTHCA_TABLE_CHUNK_SIZE,
@@ -207,7 +207,7 @@ void mthca_table_put(struct mthca_dev *d
 		table->icm[i] = NULL;
 	}
 
-	up(&table->mutex);
+	mutex_unlock(&table->mutex);
 }
 
 void *mthca_table_find(struct mthca_icm_table *table, int obj)
@@ -220,7 +220,7 @@ void *mthca_table_find(struct mthca_icm_
 	if (!table->lowmem)
 		return NULL;
 
-	down(&table->mutex);
+	mutex_lock(&table->mutex);
 
 	idx = (obj & (table->num_obj - 1)) * table->obj_size;
 	icm = table->icm[idx / MTHCA_TABLE_CHUNK_SIZE];
@@ -240,7 +240,7 @@ void *mthca_table_find(struct mthca_icm_
 	}
 
 out:
-	up(&table->mutex);
+	mutex_unlock(&table->mutex);
 	return page ? lowmem_page_address(page) + offset : NULL;
 }
 
@@ -301,7 +301,7 @@ struct mthca_icm_table *mthca_alloc_icm_
 	table->num_obj  = nobj;
 	table->obj_size = obj_size;
 	table->lowmem   = use_lowmem;
-	init_MUTEX(&table->mutex);
+	mutex_init(&table->mutex);
 
 	for (i = 0; i < num_icm; ++i)
 		table->icm[i] = NULL;
@@ -380,7 +380,7 @@ int mthca_map_user_db(struct mthca_dev *
 	if (index < 0 || index > dev->uar_table.uarc_size / 8)
 		return -EINVAL;
 
-	down(&db_tab->mutex);
+	mutex_lock(&db_tab->mutex);
 
 	i = index / MTHCA_DB_REC_PER_PAGE;
 
@@ -424,7 +424,7 @@ int mthca_map_user_db(struct mthca_dev *
 	db_tab->page[i].refcount = 1;
 
 out:
-	up(&db_tab->mutex);
+	mutex_unlock(&db_tab->mutex);
 	return ret;
 }
 
@@ -439,11 +439,11 @@ void mthca_unmap_user_db(struct mthca_de
 	 * pages until we clean up the whole db table.
 	 */
 
-	down(&db_tab->mutex);
+	mutex_lock(&db_tab->mutex);
 
 	--db_tab->page[index / MTHCA_DB_REC_PER_PAGE].refcount;
 
-	up(&db_tab->mutex);
+	mutex_unlock(&db_tab->mutex);
 }
 
 struct mthca_user_db_table *mthca_init_user_db_tab(struct mthca_dev *dev)
@@ -460,7 +460,7 @@ struct mthca_user_db_table *mthca_init_u
 	if (!db_tab)
 		return ERR_PTR(-ENOMEM);
 
-	init_MUTEX(&db_tab->mutex);
+	mutex_init(&db_tab->mutex);
 	for (i = 0; i < npages; ++i) {
 		db_tab->page[i].refcount = 0;
 		db_tab->page[i].uvirt    = 0;
@@ -499,7 +499,7 @@ int mthca_alloc_db(struct mthca_dev *dev
 	int ret = 0;
 	u8 status;
 
-	down(&dev->db_tab->mutex);
+	mutex_lock(&dev->db_tab->mutex);
 
 	switch (type) {
 	case MTHCA_DB_TYPE_CQ_ARM:
@@ -585,7 +585,7 @@ found:
 	*db = (__be32 *) &page->db_rec[j];
 
 out:
-	up(&dev->db_tab->mutex);
+	mutex_unlock(&dev->db_tab->mutex);
 
 	return ret;
 }
@@ -601,7 +601,7 @@ void mthca_free_db(struct mthca_dev *dev
 
 	page = dev->db_tab->page + i;
 
-	down(&dev->db_tab->mutex);
+	mutex_lock(&dev->db_tab->mutex);
 
 	page->db_rec[j] = 0;
 	if (i >= dev->db_tab->min_group2)
@@ -624,7 +624,7 @@ void mthca_free_db(struct mthca_dev *dev
 			++dev->db_tab->min_group2;
 	}
 
-	up(&dev->db_tab->mutex);
+	mutex_unlock(&dev->db_tab->mutex);
 }
 
 int mthca_init_db_tab(struct mthca_dev *dev)
@@ -638,7 +638,7 @@ int mthca_init_db_tab(struct mthca_dev *
 	if (!dev->db_tab)
 		return -ENOMEM;
 
-	init_MUTEX(&dev->db_tab->mutex);
+	mutex_init(&dev->db_tab->mutex);
 
 	dev->db_tab->npages     = dev->uar_table.uarc_size / 4096;
 	dev->db_tab->max_group1 = 0;
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.h b/drivers/infiniband/hw/mthca/mthca_memfree.h
index 4fdca26..36f1141 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.h
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.h
@@ -39,8 +39,7 @@
 
 #include <linux/list.h>
 #include <linux/pci.h>
-
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 
 #define MTHCA_ICM_CHUNK_LEN \
 	((256 - sizeof (struct list_head) - 2 * sizeof (int)) /		\
@@ -64,7 +63,7 @@ struct mthca_icm_table {
 	int               num_obj;
 	int               obj_size;
 	int               lowmem;
-	struct semaphore  mutex;
+	struct mutex      mutex;
 	struct mthca_icm *icm[0];
 };
 
@@ -147,7 +146,7 @@ struct mthca_db_table {
 	int 	       	      max_group1;
 	int 	       	      min_group2;
 	struct mthca_db_page *page;
-	struct semaphore      mutex;
+	struct mutex          mutex;
 };
 
 enum mthca_db_type {
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 484a7e6..e88e39a 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -185,7 +185,7 @@ static int mthca_modify_port(struct ib_d
 	int err;
 	u8 status;
 
-	if (down_interruptible(&to_mdev(ibdev)->cap_mask_mutex))
+	if (mutex_lock_interruptible(&to_mdev(ibdev)->cap_mask_mutex))
 		return -ERESTARTSYS;
 
 	err = mthca_query_port(ibdev, port, &attr);
@@ -207,7 +207,7 @@ static int mthca_modify_port(struct ib_d
 	}
 
 out:
-	up(&to_mdev(ibdev)->cap_mask_mutex);
+	mutex_unlock(&to_mdev(ibdev)->cap_mask_mutex);
 	return err;
 }
 
@@ -1185,7 +1185,7 @@ int mthca_register_device(struct mthca_d
 		dev->ib_dev.post_recv     = mthca_tavor_post_receive;
 	}
 
-	init_MUTEX(&dev->cap_mask_mutex);
+	mutex_init(&dev->cap_mask_mutex);
 
 	ret = ib_register_device(&dev->ib_dev);
 	if (ret)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index fd3f5c8..c3b5f79 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -505,7 +505,7 @@ static void neigh_add_path(struct sk_buf
 
 	list_add_tail(&neigh->list, &path->neigh_list);
 
-	if (path->pathrec.dlid) {
+	if (path->ah) {
 		kref_get(&path->ah->ref);
 		neigh->ah = path->ah;
 
@@ -591,7 +591,7 @@ static void unicast_arp_send(struct sk_b
 		return;
 	}
 
-	if (path->pathrec.dlid) {
+	if (path->ah) {
 		ipoib_dbg(priv, "Send unicast ARP to %04x\n",
 			  be16_to_cpu(path->pathrec.dlid));
 
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 98039da..ccaa0c3 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -97,6 +97,7 @@ static void ipoib_mcast_free(struct ipoi
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 	struct ipoib_neigh *neigh, *tmp;
 	unsigned long flags;
+	int tx_dropped = 0;
 
 	ipoib_dbg_mcast(netdev_priv(dev),
 			"deleting multicast group " IPOIB_GID_FMT "\n",
@@ -123,8 +124,14 @@ static void ipoib_mcast_free(struct ipoi
 	if (mcast->ah)
 		ipoib_put_ah(mcast->ah);
 
-	while (!skb_queue_empty(&mcast->pkt_queue))
+	while (!skb_queue_empty(&mcast->pkt_queue)) {
+		++tx_dropped;
 		dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));
+	}
+
+	spin_lock_irqsave(&priv->tx_lock, flags);
+	priv->stats.tx_dropped += tx_dropped;
+	spin_unlock_irqrestore(&priv->tx_lock, flags);
 
 	kfree(mcast);
 }
@@ -276,8 +283,10 @@ static int ipoib_mcast_join_finish(struc
 	}
 
 	/* actually send any queued packets */
+	spin_lock_irq(&priv->tx_lock);
 	while (!skb_queue_empty(&mcast->pkt_queue)) {
 		struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue);
+		spin_unlock_irq(&priv->tx_lock);
 
 		skb->dev = dev;
 
@@ -288,7 +297,9 @@ static int ipoib_mcast_join_finish(struc
 
 		if (dev_queue_xmit(skb))
 			ipoib_warn(priv, "dev_queue_xmit failed to requeue packet\n");
+		spin_lock_irq(&priv->tx_lock);
 	}
+	spin_unlock_irq(&priv->tx_lock);
 
 	return 0;
 }
@@ -300,6 +311,7 @@ ipoib_mcast_sendonly_join_complete(int s
 {
 	struct ipoib_mcast *mcast = mcast_ptr;
 	struct net_device *dev = mcast->dev;
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
 
 	if (!status)
 		ipoib_mcast_join_finish(mcast, mcmember);
@@ -310,8 +322,12 @@ ipoib_mcast_sendonly_join_complete(int s
 					IPOIB_GID_ARG(mcast->mcmember.mgid), status);
 
 		/* Flush out any queued packets */
-		while (!skb_queue_empty(&mcast->pkt_queue))
+		spin_lock_irq(&priv->tx_lock);
+		while (!skb_queue_empty(&mcast->pkt_queue)) {
+			++priv->stats.tx_dropped;
 			dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));
+		}
+		spin_unlock_irq(&priv->tx_lock);
 
 		/* Clear the busy flag so we try again */
 		clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
@@ -687,6 +703,7 @@ void ipoib_mcast_send(struct net_device 
 		if (!mcast) {
 			ipoib_warn(priv, "unable to allocate memory for "
 				   "multicast structure\n");
+			++priv->stats.tx_dropped;
 			dev_kfree_skb_any(skb);
 			goto out;
 		}
@@ -700,8 +717,10 @@ void ipoib_mcast_send(struct net_device 
 	if (!mcast->ah) {
 		if (skb_queue_len(&mcast->pkt_queue) < IPOIB_MAX_MCAST_QUEUE)
 			skb_queue_tail(&mcast->pkt_queue, skb);
-		else
+		else {
+			++priv->stats.tx_dropped;
 			dev_kfree_skb_any(skb);
+		}
 
 		if (mcast->query)
 			ipoib_dbg_mcast(priv, "no address vector, "
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 31207e6..2d2d4ac 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -357,9 +357,9 @@ static void srp_remove_work(void *target
 	target->state = SRP_TARGET_REMOVED;
 	spin_unlock_irq(target->scsi_host->host_lock);
 
-	down(&target->srp_host->target_mutex);
+	mutex_lock(&target->srp_host->target_mutex);
 	list_del(&target->list);
-	up(&target->srp_host->target_mutex);
+	mutex_unlock(&target->srp_host->target_mutex);
 
 	scsi_remove_host(target->scsi_host);
 	ib_destroy_cm_id(target->cm_id);
@@ -1254,9 +1254,9 @@ static int srp_add_target(struct srp_hos
 	if (scsi_add_host(target->scsi_host, host->dev->dma_device))
 		return -ENODEV;
 
-	down(&host->target_mutex);
+	mutex_lock(&host->target_mutex);
 	list_add_tail(&target->list, &host->target_list);
-	up(&host->target_mutex);
+	mutex_unlock(&host->target_mutex);
 
 	target->state = SRP_TARGET_LIVE;
 
@@ -1525,7 +1525,7 @@ static struct srp_host *srp_add_port(str
 		return NULL;
 
 	INIT_LIST_HEAD(&host->target_list);
-	init_MUTEX(&host->target_mutex);
+	mutex_init(&host->target_mutex);
 	init_completion(&host->released);
 	host->dev  = device;
 	host->port = port;
@@ -1626,7 +1626,7 @@ static void srp_remove_one(struct ib_dev
 		 * Mark all target ports as removed, so we stop queueing
 		 * commands and don't try to reconnect.
 		 */
-		down(&host->target_mutex);
+		mutex_lock(&host->target_mutex);
 		list_for_each_entry_safe(target, tmp_target,
 					 &host->target_list, list) {
 			spin_lock_irqsave(target->scsi_host->host_lock, flags);
@@ -1634,7 +1634,7 @@ static void srp_remove_one(struct ib_dev
 				target->state = SRP_TARGET_REMOVED;
 			spin_unlock_irqrestore(target->scsi_host->host_lock, flags);
 		}
-		up(&host->target_mutex);
+		mutex_unlock(&host->target_mutex);
 
 		/*
 		 * Wait for any reconnection tasks that may have
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h
index b564f18..4e7727d 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.h
+++ b/drivers/infiniband/ulp/srp/ib_srp.h
@@ -37,8 +37,7 @@
 
 #include <linux/types.h>
 #include <linux/list.h>
-
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_cmnd.h>
@@ -85,7 +84,7 @@ struct srp_host {
 	struct ib_mr	       *mr;
 	struct class_device	class_dev;
 	struct list_head	target_list;
-	struct semaphore        target_mutex;
+	struct mutex            target_mutex;
 	struct completion	released;
 	struct list_head	list;
 };
diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c
index 4571ea3..4612d13 100644
--- a/drivers/input/joystick/a3d.c
+++ b/drivers/input/joystick/a3d.c
@@ -57,7 +57,7 @@ static char *a3d_names[] = { NULL, "FP-G
 struct a3d {
 	struct gameport *gameport;
 	struct gameport *adc;
-	struct input_dev dev;
+	struct input_dev *dev;
 	int axes[4];
 	int buttons;
 	int mode;
@@ -115,7 +115,7 @@ static int a3d_csum(char *data, int coun
 
 static void a3d_read(struct a3d *a3d, unsigned char *data)
 {
-	struct input_dev *dev = &a3d->dev;
+	struct input_dev *dev = a3d->dev;
 
 	switch (a3d->mode) {
 
@@ -265,14 +265,20 @@ static void a3d_close(struct input_dev *
 static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv)
 {
 	struct a3d *a3d;
+	struct input_dev *input_dev;
 	struct gameport *adc;
 	unsigned char data[A3D_MAX_LENGTH];
 	int i;
 	int err;
 
-	if (!(a3d = kzalloc(sizeof(struct a3d), GFP_KERNEL)))
-		return -ENOMEM;
+	a3d = kzalloc(sizeof(struct a3d), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!a3d || !input_dev) {
+		err = -ENOMEM;
+		goto fail1;
+	}
 
+	a3d->dev = input_dev;
 	a3d->gameport = gameport;
 
 	gameport_set_drvdata(gameport, a3d);
@@ -302,42 +308,48 @@ static int a3d_connect(struct gameport *
 
 	sprintf(a3d->phys, "%s/input0", gameport->phys);
 
+	input_dev->name = a3d_names[a3d->mode];
+	input_dev->phys = a3d->phys;
+	input_dev->id.bustype = BUS_GAMEPORT;
+	input_dev->id.vendor = GAMEPORT_ID_VENDOR_MADCATZ;
+	input_dev->id.product = a3d->mode;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &gameport->dev;
+	input_dev->private = a3d;
+	input_dev->open = a3d_open;
+	input_dev->close = a3d_close;
+
 	if (a3d->mode == A3D_MODE_PXL) {
 
 		int axes[] = { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER };
 
 		a3d->length = 33;
 
-		init_input_dev(&a3d->dev);
-
-		a3d->dev.evbit[0] |= BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL);
-		a3d->dev.relbit[0] |= BIT(REL_X) | BIT(REL_Y);
-		a3d->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_THROTTLE) | BIT(ABS_RUDDER)
-				   | BIT(ABS_HAT0X) | BIT(ABS_HAT0Y) | BIT(ABS_HAT1X) | BIT(ABS_HAT1Y);
-
-		a3d->dev.keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE)
-						 | BIT(BTN_SIDE) | BIT(BTN_EXTRA);
-
-		a3d->dev.keybit[LONG(BTN_JOYSTICK)] |= BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_PINKIE);
+		input_dev->evbit[0] |= BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL);
+		input_dev->relbit[0] |= BIT(REL_X) | BIT(REL_Y);
+		input_dev->absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_THROTTLE) | BIT(ABS_RUDDER)
+					| BIT(ABS_HAT0X) | BIT(ABS_HAT0Y) | BIT(ABS_HAT1X) | BIT(ABS_HAT1Y);
+		input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE)
+							| BIT(BTN_SIDE) | BIT(BTN_EXTRA);
+		input_dev->keybit[LONG(BTN_JOYSTICK)] |= BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP)
+							| BIT(BTN_PINKIE);
 
 		a3d_read(a3d, data);
 
 		for (i = 0; i < 4; i++) {
 			if (i < 2)
-				input_set_abs_params(&a3d->dev, axes[i], 48, a3d->dev.abs[axes[i]] * 2 - 48, 0, 8);
+				input_set_abs_params(input_dev, axes[i], 48, input_dev->abs[axes[i]] * 2 - 48, 0, 8);
 			else
-				input_set_abs_params(&a3d->dev, axes[i], 2, 253, 0, 0);
-			input_set_abs_params(&a3d->dev, ABS_HAT0X + i, -1, 1, 0, 0);
+				input_set_abs_params(input_dev, axes[i], 2, 253, 0, 0);
+			input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0);
 		}
 
 	} else {
 		a3d->length = 29;
 
-		init_input_dev(&a3d->dev);
-
-		a3d->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_REL);
-		a3d->dev.relbit[0] |= BIT(REL_X) | BIT(REL_Y);
-		a3d->dev.keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE);
+		input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_REL);
+		input_dev->relbit[0] |= BIT(REL_X) | BIT(REL_Y);
+		input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE);
 
 		a3d_read(a3d, data);
 
@@ -358,24 +370,17 @@ static int a3d_connect(struct gameport *
 		}
 	}
 
-	a3d->dev.private = a3d;
-	a3d->dev.open = a3d_open;
-	a3d->dev.close = a3d_close;
-
-	a3d->dev.name = a3d_names[a3d->mode];
-	a3d->dev.phys = a3d->phys;
-	a3d->dev.id.bustype = BUS_GAMEPORT;
-	a3d->dev.id.vendor = GAMEPORT_ID_VENDOR_MADCATZ;
-	a3d->dev.id.product = a3d->mode;
-	a3d->dev.id.version = 0x0100;
-
-	input_register_device(&a3d->dev);
-	printk(KERN_INFO "input: %s on %s\n", a3d_names[a3d->mode], a3d->phys);
+	err = input_register_device(a3d->dev);
+	if (err)
+		goto fail3;
 
 	return 0;
 
-fail2:	gameport_close(gameport);
-fail1:  gameport_set_drvdata(gameport, NULL);
+ fail3:	if (a3d->adc)
+		gameport_unregister_port(a3d->adc);
+ fail2:	gameport_close(gameport);
+ fail1:	gameport_set_drvdata(gameport, NULL);
+	input_free_device(input_dev);
 	kfree(a3d);
 	return err;
 }
@@ -384,11 +389,9 @@ static void a3d_disconnect(struct gamepo
 {
 	struct a3d *a3d = gameport_get_drvdata(gameport);
 
-	input_unregister_device(&a3d->dev);
-	if (a3d->adc) {
+	input_unregister_device(a3d->dev);
+	if (a3d->adc)
 		gameport_unregister_port(a3d->adc);
-		a3d->adc = NULL;
-	}
 	gameport_close(gameport);
 	gameport_set_drvdata(gameport, NULL);
 	kfree(a3d);
@@ -397,6 +400,7 @@ static void a3d_disconnect(struct gamepo
 static struct gameport_driver a3d_drv = {
 	.driver		= {
 		.name	= "adc",
+		.owner	= THIS_MODULE,
 	},
 	.description	= DRIVER_DESC,
 	.connect	= a3d_connect,
diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c
index 499344c..dcffc34 100644
--- a/drivers/input/joystick/db9.c
+++ b/drivers/input/joystick/db9.c
@@ -275,68 +275,70 @@ static unsigned char db9_saturn_read_pac
 /*
  * db9_saturn_report() analyzes packet and reports.
  */
-static int db9_saturn_report(unsigned char id, unsigned char data[60], struct input_dev *dev, int n, int max_pads)
+static int db9_saturn_report(unsigned char id, unsigned char data[60], struct input_dev *devs[], int n, int max_pads)
 {
+	struct input_dev *dev;
 	int tmp, i, j;
 
 	tmp = (id == 0x41) ? 60 : 10;
-	for (j = 0; (j < tmp) && (n < max_pads); j += 10, n++) {
+	for (j = 0; j < tmp && n < max_pads; j += 10, n++) {
+		dev = devs[n];
 		switch (data[j]) {
 		case 0x16: /* multi controller (analog 4 axis) */
-			input_report_abs(dev + n, db9_abs[5], data[j + 6]);
+			input_report_abs(dev, db9_abs[5], data[j + 6]);
 		case 0x15: /* mission stick (analog 3 axis) */
-			input_report_abs(dev + n, db9_abs[3], data[j + 4]);
-			input_report_abs(dev + n, db9_abs[4], data[j + 5]);
+			input_report_abs(dev, db9_abs[3], data[j + 4]);
+			input_report_abs(dev, db9_abs[4], data[j + 5]);
 		case 0x13: /* racing controller (analog 1 axis) */
-			input_report_abs(dev + n, db9_abs[2], data[j + 3]);
+			input_report_abs(dev, db9_abs[2], data[j + 3]);
 		case 0x34: /* saturn keyboard (udlr ZXC ASD QE Esc) */
 		case 0x02: /* digital pad (digital 2 axis + buttons) */
-			input_report_abs(dev + n, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64));
-			input_report_abs(dev + n, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16));
+			input_report_abs(dev, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64));
+			input_report_abs(dev, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16));
 			for (i = 0; i < 9; i++)
-				input_report_key(dev + n, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]);
+				input_report_key(dev, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]);
 			break;
 		case 0x19: /* mission stick x2 (analog 6 axis + buttons) */
-			input_report_abs(dev + n, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64));
-			input_report_abs(dev + n, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16));
+			input_report_abs(dev, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64));
+			input_report_abs(dev, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16));
 			for (i = 0; i < 9; i++)
-				input_report_key(dev + n, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]);
-			input_report_abs(dev + n, db9_abs[2], data[j + 3]);
-			input_report_abs(dev + n, db9_abs[3], data[j + 4]);
-			input_report_abs(dev + n, db9_abs[4], data[j + 5]);
+				input_report_key(dev, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]);
+			input_report_abs(dev, db9_abs[2], data[j + 3]);
+			input_report_abs(dev, db9_abs[3], data[j + 4]);
+			input_report_abs(dev, db9_abs[4], data[j + 5]);
 			/*
-			input_report_abs(dev + n, db9_abs[8], (data[j + 6] & 128 ? 0 : 1) - (data[j + 6] & 64 ? 0 : 1));
-			input_report_abs(dev + n, db9_abs[9], (data[j + 6] & 32 ? 0 : 1) - (data[j + 6] & 16 ? 0 : 1));
+			input_report_abs(dev, db9_abs[8], (data[j + 6] & 128 ? 0 : 1) - (data[j + 6] & 64 ? 0 : 1));
+			input_report_abs(dev, db9_abs[9], (data[j + 6] & 32 ? 0 : 1) - (data[j + 6] & 16 ? 0 : 1));
 			*/
-			input_report_abs(dev + n, db9_abs[6], data[j + 7]);
-			input_report_abs(dev + n, db9_abs[7], data[j + 8]);
-			input_report_abs(dev + n, db9_abs[5], data[j + 9]);
+			input_report_abs(dev, db9_abs[6], data[j + 7]);
+			input_report_abs(dev, db9_abs[7], data[j + 8]);
+			input_report_abs(dev, db9_abs[5], data[j + 9]);
 			break;
 		case 0xd3: /* sankyo ff (analog 1 axis + stop btn) */
-			input_report_key(dev + n, BTN_A, data[j + 3] & 0x80);
-			input_report_abs(dev + n, db9_abs[2], data[j + 3] & 0x7f);
+			input_report_key(dev, BTN_A, data[j + 3] & 0x80);
+			input_report_abs(dev, db9_abs[2], data[j + 3] & 0x7f);
 			break;
 		case 0xe3: /* shuttle mouse (analog 2 axis + buttons. signed value) */
-			input_report_key(dev + n, BTN_START, data[j + 1] & 0x08);
-			input_report_key(dev + n, BTN_A, data[j + 1] & 0x04);
-			input_report_key(dev + n, BTN_C, data[j + 1] & 0x02);
-			input_report_key(dev + n, BTN_B, data[j + 1] & 0x01);
-			input_report_abs(dev + n, db9_abs[2], data[j + 2] ^ 0x80);
-			input_report_abs(dev + n, db9_abs[3], (0xff-(data[j + 3] ^ 0x80))+1); /* */
+			input_report_key(dev, BTN_START, data[j + 1] & 0x08);
+			input_report_key(dev, BTN_A, data[j + 1] & 0x04);
+			input_report_key(dev, BTN_C, data[j + 1] & 0x02);
+			input_report_key(dev, BTN_B, data[j + 1] & 0x01);
+			input_report_abs(dev, db9_abs[2], data[j + 2] ^ 0x80);
+			input_report_abs(dev, db9_abs[3], (0xff-(data[j + 3] ^ 0x80))+1); /* */
 			break;
 		case 0xff:
 		default: /* no pad */
-			input_report_abs(dev + n, db9_abs[0], 0);
-			input_report_abs(dev + n, db9_abs[1], 0);
+			input_report_abs(dev, db9_abs[0], 0);
+			input_report_abs(dev, db9_abs[1], 0);
 			for (i = 0; i < 9; i++)
-				input_report_key(dev + n, db9_cd32_btn[i], 0);
+				input_report_key(dev, db9_cd32_btn[i], 0);
 			break;
 		}
 	}
 	return n;
 }
 
-static int db9_saturn(int mode, struct parport *port, struct input_dev *dev)
+static int db9_saturn(int mode, struct parport *port, struct input_dev *devs[])
 {
 	unsigned char id, data[60];
 	int type, n, max_pads;
@@ -361,7 +363,7 @@ static int db9_saturn(int mode, struct p
 	max_pads = min(db9_modes[mode].n_pads, DB9_MAX_DEVICES);
 	for (tmp = 0, i = 0; i < n; i++) {
 		id = db9_saturn_read_packet(port, data, type + i, 1);
-		tmp = db9_saturn_report(id, data, dev, tmp, max_pads);
+		tmp = db9_saturn_report(id, data, devs, tmp, max_pads);
 	}
 	return 0;
 }
@@ -489,7 +491,7 @@ static void db9_timer(unsigned long priv
 		case DB9_SATURN_DPP:
 		case DB9_SATURN_DPP_2:
 
-			db9_saturn(db9->mode, port, dev);
+			db9_saturn(db9->mode, port, db9->dev);
 			break;
 
 		case DB9_CD32_PAD:
@@ -614,7 +616,7 @@ static struct db9 __init *db9_probe(int 
 		if (!input_dev) {
 			printk(KERN_ERR "db9.c: Not enough memory for input device\n");
 			err = -ENOMEM;
-			goto err_free_devs;
+			goto err_unreg_devs;
 		}
 
 		sprintf(db9->phys[i], "%s/input%d", db9->pd->port->name, i);
@@ -640,13 +642,17 @@ static struct db9 __init *db9_probe(int 
 				input_set_abs_params(input_dev, db9_abs[j], 1, 255, 0, 0);
 		}
 
-		input_register_device(input_dev);
+		err = input_register_device(input_dev);
+		if (err)
+			goto err_free_dev;
 	}
 
 	parport_put_port(pp);
 	return db9;
 
- err_free_devs:
+ err_free_dev:
+	input_free_device(db9->dev[i]);
+ err_unreg_devs:
 	while (--i >= 0)
 		input_unregister_device(db9->dev[i]);
 	kfree(db9);
@@ -658,7 +664,7 @@ static struct db9 __init *db9_probe(int 
 	return ERR_PTR(err);
 }
 
-static void __exit db9_remove(struct db9 *db9)
+static void db9_remove(struct db9 *db9)
 {
 	int i;
 
@@ -696,7 +702,8 @@ static int __init db9_init(void)
 
 	if (err) {
 		while (--i >= 0)
-			db9_remove(db9_base[i]);
+			if (db9_base[i])
+				db9_remove(db9_base[i]);
 		return err;
 	}
 
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
index 7df2d82..900587a 100644
--- a/drivers/input/joystick/gamecon.c
+++ b/drivers/input/joystick/gamecon.c
@@ -159,6 +159,48 @@ static void gc_n64_read_packet(struct gc
 
 }
 
+static void gc_n64_process_packet(struct gc *gc)
+{
+	unsigned char data[GC_N64_LENGTH];
+	signed char axes[2];
+	struct input_dev *dev;
+	int i, j, s;
+
+	gc_n64_read_packet(gc, data);
+
+	for (i = 0; i < GC_MAX_DEVICES; i++) {
+
+		dev = gc->dev[i];
+		if (!dev)
+			continue;
+
+		s = gc_status_bit[i];
+
+		if (s & gc->pads[GC_N64] & ~(data[8] | data[9])) {
+
+			axes[0] = axes[1] = 0;
+
+			for (j = 0; j < 8; j++) {
+				if (data[23 - j] & s)
+					axes[0] |= 1 << j;
+				if (data[31 - j] & s)
+					axes[1] |= 1 << j;
+			}
+
+			input_report_abs(dev, ABS_X,  axes[0]);
+			input_report_abs(dev, ABS_Y, -axes[1]);
+
+			input_report_abs(dev, ABS_HAT0X, !(s & data[6]) - !(s & data[7]));
+			input_report_abs(dev, ABS_HAT0Y, !(s & data[4]) - !(s & data[5]));
+
+			for (j = 0; j < 10; j++)
+				input_report_key(dev, gc_n64_btn[j], s & data[gc_n64_bytes[j]]);
+
+			input_sync(dev);
+		}
+	}
+}
+
 /*
  * NES/SNES support.
  */
@@ -198,6 +240,39 @@ static void gc_nes_read_packet(struct gc
 	}
 }
 
+static void gc_nes_process_packet(struct gc *gc)
+{
+	unsigned char data[GC_SNES_LENGTH];
+	struct input_dev *dev;
+	int i, j, s;
+
+	gc_nes_read_packet(gc, gc->pads[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH, data);
+
+	for (i = 0; i < GC_MAX_DEVICES; i++) {
+
+		dev = gc->dev[i];
+		if (!dev)
+			continue;
+
+		s = gc_status_bit[i];
+
+		if (s & (gc->pads[GC_NES] | gc->pads[GC_SNES])) {
+			input_report_abs(dev, ABS_X, !(s & data[6]) - !(s & data[7]));
+			input_report_abs(dev, ABS_Y, !(s & data[4]) - !(s & data[5]));
+		}
+
+		if (s & gc->pads[GC_NES])
+			for (j = 0; j < 4; j++)
+				input_report_key(dev, gc_snes_btn[j], s & data[gc_nes_bytes[j]]);
+
+		if (s & gc->pads[GC_SNES])
+			for (j = 0; j < 8; j++)
+				input_report_key(dev, gc_snes_btn[j], s & data[gc_snes_bytes[j]]);
+
+		input_sync(dev);
+	}
+}
+
 /*
  * Multisystem joystick support
  */
@@ -219,6 +294,35 @@ static void gc_multi_read_packet(struct 
 	}
 }
 
+static void gc_multi_process_packet(struct gc *gc)
+{
+	unsigned char data[GC_MULTI2_LENGTH];
+	struct input_dev *dev;
+	int i, s;
+
+	gc_multi_read_packet(gc, gc->pads[GC_MULTI2] ? GC_MULTI2_LENGTH : GC_MULTI_LENGTH, data);
+
+	for (i = 0; i < GC_MAX_DEVICES; i++) {
+
+		dev = gc->dev[i];
+		if (!dev)
+			continue;
+
+		s = gc_status_bit[i];
+
+		if (s & (gc->pads[GC_MULTI] | gc->pads[GC_MULTI2])) {
+			input_report_abs(dev, ABS_X,  !(s & data[2]) - !(s & data[3]));
+			input_report_abs(dev, ABS_Y,  !(s & data[0]) - !(s & data[1]));
+			input_report_key(dev, BTN_TRIGGER, s & data[4]);
+		}
+
+		if (s & gc->pads[GC_MULTI2])
+			input_report_key(dev, BTN_THUMB, s & data[5]);
+
+		input_sync(dev);
+	}
+}
+
 /*
  * PSX support
  *
@@ -263,10 +367,11 @@ static short gc_psx_ddr_btn[] = { BTN_0,
  * the psx pad.
  */
 
-static void gc_psx_command(struct gc *gc, int b, unsigned char data[5])
+static void gc_psx_command(struct gc *gc, int b, unsigned char data[GC_MAX_DEVICES])
 {
 	int i, j, cmd, read;
-	for (i = 0; i < 5; i++)
+
+	for (i = 0; i < GC_MAX_DEVICES; i++)
 		data[i] = 0;
 
 	for (i = 0; i < GC_PSX_LENGTH; i++, b >>= 1) {
@@ -274,7 +379,7 @@ static void gc_psx_command(struct gc *gc
 		parport_write_data(gc->pd->port, cmd | GC_PSX_POWER);
 		udelay(gc_psx_delay);
 		read = parport_read_status(gc->pd->port) ^ 0x80;
-		for (j = 0; j < 5; j++)
+		for (j = 0; j < GC_MAX_DEVICES; j++)
 			data[j] |= (read & gc_status_bit[j] & (gc->pads[GC_PSX] | gc->pads[GC_DDR])) ? (1 << i) : 0;
 		parport_write_data(gc->pd->port, cmd | GC_PSX_CLOCK | GC_PSX_POWER);
 		udelay(gc_psx_delay);
@@ -286,11 +391,12 @@ static void gc_psx_command(struct gc *gc
  * device identifier code.
  */
 
-static void gc_psx_read_packet(struct gc *gc, unsigned char data[5][GC_PSX_BYTES], unsigned char id[5])
+static void gc_psx_read_packet(struct gc *gc, unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES],
+			       unsigned char id[GC_MAX_DEVICES])
 {
 	int i, j, max_len = 0;
 	unsigned long flags;
-	unsigned char data2[5];
+	unsigned char data2[GC_MAX_DEVICES];
 
 	parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER);	/* Select pad */
 	udelay(gc_psx_delay);
@@ -303,7 +409,7 @@ static void gc_psx_read_packet(struct gc
 	gc_psx_command(gc, 0x42, id);							/* Get device ids */
 	gc_psx_command(gc, 0, data2);							/* Dump status */
 
-	for (i =0; i < 5; i++)								/* Find the longest pad */
+	for (i =0; i < GC_MAX_DEVICES; i++)								/* Find the longest pad */
 		if((gc_status_bit[i] & (gc->pads[GC_PSX] | gc->pads[GC_DDR]))
 			&& (GC_PSX_LEN(id[i]) > max_len)
 			&& (GC_PSX_LEN(id[i]) <= GC_PSX_BYTES))
@@ -311,7 +417,7 @@ static void gc_psx_read_packet(struct gc
 
 	for (i = 0; i < max_len; i++) {						/* Read in all the data */
 		gc_psx_command(gc, 0, data2);
-		for (j = 0; j < 5; j++)
+		for (j = 0; j < GC_MAX_DEVICES; j++)
 			data[j][i] = data2[j];
 	}
 
@@ -319,185 +425,124 @@ static void gc_psx_read_packet(struct gc
 
 	parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER);
 
-	for(i = 0; i < 5; i++)								/* Set id's to the real value */
+	for(i = 0; i < GC_MAX_DEVICES; i++)								/* Set id's to the real value */
 		id[i] = GC_PSX_ID(id[i]);
 }
 
-/*
- * gc_timer() reads and analyzes console pads data.
- */
-
-#define GC_MAX_LENGTH GC_N64_LENGTH
-
-static void gc_timer(unsigned long private)
+static void gc_psx_process_packet(struct gc *gc)
 {
-	struct gc *gc = (void *) private;
-	unsigned char data[GC_MAX_LENGTH];
-	unsigned char data_psx[5][GC_PSX_BYTES];
-	int i, j, s;
-
-/*
- * N64 pads - must be read first, any read confuses them for 200 us
- */
+	unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES];
+	unsigned char id[GC_MAX_DEVICES];
+	struct input_dev *dev;
+	int i, j;
 
-	if (gc->pads[GC_N64]) {
+	gc_psx_read_packet(gc, data, id);
 
-		gc_n64_read_packet(gc, data);
+	for (i = 0; i < GC_MAX_DEVICES; i++) {
 
-		for (i = 0; i < 5; i++) {
+		dev = gc->dev[i];
+		if (!dev)
+			continue;
 
-			s = gc_status_bit[i];
+		switch (id[i]) {
 
-			if (s & gc->pads[GC_N64] & ~(data[8] | data[9])) {
+			case GC_PSX_RUMBLE:
 
-				signed char axes[2];
-				axes[0] = axes[1] = 0;
+				input_report_key(dev, BTN_THUMBL, ~data[i][0] & 0x04);
+				input_report_key(dev, BTN_THUMBR, ~data[i][0] & 0x02);
 
-				for (j = 0; j < 8; j++) {
-					if (data[23 - j] & s) axes[0] |= 1 << j;
-					if (data[31 - j] & s) axes[1] |= 1 << j;
-				}
+			case GC_PSX_NEGCON:
+			case GC_PSX_ANALOG:
 
-				input_report_abs(gc->dev[i], ABS_X,  axes[0]);
-				input_report_abs(gc->dev[i], ABS_Y, -axes[1]);
+				if (gc->pads[GC_DDR] & gc_status_bit[i]) {
+					for(j = 0; j < 4; j++)
+						input_report_key(dev, gc_psx_ddr_btn[j], ~data[i][0] & (0x10 << j));
+				} else {
+					for (j = 0; j < 4; j++)
+						input_report_abs(dev, gc_psx_abs[j + 2], data[i][j + 2]);
 
-				input_report_abs(gc->dev[i], ABS_HAT0X, !(s & data[6]) - !(s & data[7]));
-				input_report_abs(gc->dev[i], ABS_HAT0Y, !(s & data[4]) - !(s & data[5]));
+					input_report_abs(dev, ABS_X, 128 + !(data[i][0] & 0x20) * 127 - !(data[i][0] & 0x80) * 128);
+					input_report_abs(dev, ABS_Y, 128 + !(data[i][0] & 0x40) * 127 - !(data[i][0] & 0x10) * 128);
+				}
 
-				for (j = 0; j < 10; j++)
-					input_report_key(gc->dev[i], gc_n64_btn[j], s & data[gc_n64_bytes[j]]);
+				for (j = 0; j < 8; j++)
+					input_report_key(dev, gc_psx_btn[j], ~data[i][1] & (1 << j));
 
-				input_sync(gc->dev[i]);
-			}
-		}
-	}
+				input_report_key(dev, BTN_START,  ~data[i][0] & 0x08);
+				input_report_key(dev, BTN_SELECT, ~data[i][0] & 0x01);
 
-/*
- * NES and SNES pads
- */
+				input_sync(dev);
 
-	if (gc->pads[GC_NES] || gc->pads[GC_SNES]) {
+				break;
 
-		gc_nes_read_packet(gc, gc->pads[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH, data);
+			case GC_PSX_NORMAL:
+				if (gc->pads[GC_DDR] & gc_status_bit[i]) {
+					for(j = 0; j < 4; j++)
+						input_report_key(dev, gc_psx_ddr_btn[j], ~data[i][0] & (0x10 << j));
+				} else {
+					input_report_abs(dev, ABS_X, 128 + !(data[i][0] & 0x20) * 127 - !(data[i][0] & 0x80) * 128);
+					input_report_abs(dev, ABS_Y, 128 + !(data[i][0] & 0x40) * 127 - !(data[i][0] & 0x10) * 128);
+
+					/* for some reason if the extra axes are left unset they drift */
+					/* for (j = 0; j < 4; j++)
+						input_report_abs(dev, gc_psx_abs[j + 2], 128);
+					 * This needs to be debugged properly,
+					 * maybe fuzz processing needs to be done in input_sync()
+					 *				 --vojtech
+					 */
+				}
 
-		for (i = 0; i < 5; i++) {
+				for (j = 0; j < 8; j++)
+					input_report_key(dev, gc_psx_btn[j], ~data[i][1] & (1 << j));
 
-			s = gc_status_bit[i];
+				input_report_key(dev, BTN_START,  ~data[i][0] & 0x08);
+				input_report_key(dev, BTN_SELECT, ~data[i][0] & 0x01);
 
-			if (s & (gc->pads[GC_NES] | gc->pads[GC_SNES])) {
-				input_report_abs(gc->dev[i], ABS_X, !(s & data[6]) - !(s & data[7]));
-				input_report_abs(gc->dev[i], ABS_Y, !(s & data[4]) - !(s & data[5]));
-			}
+				input_sync(dev);
 
-			if (s & gc->pads[GC_NES])
-				for (j = 0; j < 4; j++)
-					input_report_key(gc->dev[i], gc_snes_btn[j], s & data[gc_nes_bytes[j]]);
+				break;
 
-			if (s & gc->pads[GC_SNES])
-				for (j = 0; j < 8; j++)
-					input_report_key(gc->dev[i], gc_snes_btn[j], s & data[gc_snes_bytes[j]]);
-
-			input_sync(gc->dev[i]);
+			case 0: /* not a pad, ignore */
+				break;
 		}
 	}
+}
 
 /*
- * Multi and Multi2 joysticks
+ * gc_timer() initiates reads of console pads data.
  */
 
-	if (gc->pads[GC_MULTI] || gc->pads[GC_MULTI2]) {
+static void gc_timer(unsigned long private)
+{
+	struct gc *gc = (void *) private;
 
-		gc_multi_read_packet(gc, gc->pads[GC_MULTI2] ? GC_MULTI2_LENGTH : GC_MULTI_LENGTH, data);
+/*
+ * N64 pads - must be read first, any read confuses them for 200 us
+ */
 
-		for (i = 0; i < 5; i++) {
+	if (gc->pads[GC_N64])
+		gc_n64_process_packet(gc);
 
-			s = gc_status_bit[i];
+/*
+ * NES and SNES pads
+ */
 
-			if (s & (gc->pads[GC_MULTI] | gc->pads[GC_MULTI2])) {
-				input_report_abs(gc->dev[i], ABS_X,  !(s & data[2]) - !(s & data[3]));
-				input_report_abs(gc->dev[i], ABS_Y,  !(s & data[0]) - !(s & data[1]));
-				input_report_key(gc->dev[i], BTN_TRIGGER, s & data[4]);
-			}
+	if (gc->pads[GC_NES] || gc->pads[GC_SNES])
+		gc_nes_process_packet(gc);
 
-			if (s & gc->pads[GC_MULTI2])
-				input_report_key(gc->dev[i], BTN_THUMB, s & data[5]);
+/*
+ * Multi and Multi2 joysticks
+ */
 
-			input_sync(gc->dev[i]);
-		}
-	}
+	if (gc->pads[GC_MULTI] || gc->pads[GC_MULTI2])
+		gc_multi_process_packet(gc);
 
 /*
  * PSX controllers
  */
 
-	if (gc->pads[GC_PSX] || gc->pads[GC_DDR]) {
-
-		gc_psx_read_packet(gc, data_psx, data);
-
-		for (i = 0; i < 5; i++) {
-			switch (data[i]) {
-
-				case GC_PSX_RUMBLE:
-
-					input_report_key(gc->dev[i], BTN_THUMBL, ~data_psx[i][0] & 0x04);
-					input_report_key(gc->dev[i], BTN_THUMBR, ~data_psx[i][0] & 0x02);
-
-				case GC_PSX_NEGCON:
-				case GC_PSX_ANALOG:
-
-					if (gc->pads[GC_DDR] & gc_status_bit[i]) {
-						for(j = 0; j < 4; j++)
-							input_report_key(gc->dev[i], gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j));
-					} else {
-						for (j = 0; j < 4; j++)
-							input_report_abs(gc->dev[i], gc_psx_abs[j+2], data_psx[i][j + 2]);
-
-						input_report_abs(gc->dev[i], ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128);
-						input_report_abs(gc->dev[i], ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128);
-					}
-
-					for (j = 0; j < 8; j++)
-						input_report_key(gc->dev[i], gc_psx_btn[j], ~data_psx[i][1] & (1 << j));
-
-					input_report_key(gc->dev[i], BTN_START,  ~data_psx[i][0] & 0x08);
-					input_report_key(gc->dev[i], BTN_SELECT, ~data_psx[i][0] & 0x01);
-
-					input_sync(gc->dev[i]);
-
-					break;
-
-				case GC_PSX_NORMAL:
-					if (gc->pads[GC_DDR] & gc_status_bit[i]) {
-						for(j = 0; j < 4; j++)
-							input_report_key(gc->dev[i], gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j));
-					} else {
-						input_report_abs(gc->dev[i], ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128);
-						input_report_abs(gc->dev[i], ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128);
-
-						/* for some reason if the extra axes are left unset they drift */
-						/* for (j = 0; j < 4; j++)
-							input_report_abs(gc->dev[i], gc_psx_abs[j+2], 128);
-						 * This needs to be debugged properly,
-						 * maybe fuzz processing needs to be done in input_sync()
-						 *				 --vojtech
-						 */
-					}
-
-					for (j = 0; j < 8; j++)
-						input_report_key(gc->dev[i], gc_psx_btn[j], ~data_psx[i][1] & (1 << j));
-
-					input_report_key(gc->dev[i], BTN_START,  ~data_psx[i][0] & 0x08);
-					input_report_key(gc->dev[i], BTN_SELECT, ~data_psx[i][0] & 0x01);
-
-					input_sync(gc->dev[i]);
-
-					break;
-
-				case 0: /* not a pad, ignore */
-					break;
-			}
-		}
-	}
+	if (gc->pads[GC_PSX] || gc->pads[GC_DDR])
+		gc_psx_process_packet(gc);
 
 	mod_timer(&gc->timer, jiffies + GC_REFRESH_TIME);
 }
@@ -654,16 +699,18 @@ static struct gc __init *gc_probe(int pa
 	gc->timer.data = (long) gc;
 	gc->timer.function = gc_timer;
 
-	for (i = 0; i < n_pads; i++) {
+	for (i = 0; i < n_pads && i < GC_MAX_DEVICES; i++) {
 		if (!pads[i])
 			continue;
 
 		sprintf(gc->phys[i], "%s/input%d", gc->pd->port->name, i);
 		err = gc_setup_pad(gc, i, pads[i]);
 		if (err)
-			goto err_free_devs;
+			goto err_unreg_devs;
 
-		input_register_device(gc->dev[i]);
+		err = input_register_device(gc->dev[i]);
+		if (err)
+			goto err_free_dev;
 	}
 
 	if (!gc->pads[0]) {
@@ -675,9 +722,12 @@ static struct gc __init *gc_probe(int pa
 	parport_put_port(pp);
 	return gc;
 
- err_free_devs:
+ err_free_dev:
+	input_free_device(gc->dev[i]);
+ err_unreg_devs:
 	while (--i >= 0)
-		input_unregister_device(gc->dev[i]);
+		if (gc->dev[i])
+			input_unregister_device(gc->dev[i]);
  err_free_gc:
 	kfree(gc);
  err_unreg_pardev:
@@ -688,7 +738,7 @@ static struct gc __init *gc_probe(int pa
 	return ERR_PTR(err);
 }
 
-static void __exit gc_remove(struct gc *gc)
+static void gc_remove(struct gc *gc)
 {
 	int i;
 
@@ -726,7 +776,8 @@ static int __init gc_init(void)
 
 	if (err) {
 		while (--i >= 0)
-			gc_remove(gc_base[i]);
+			if (gc_base[i])
+				gc_remove(gc_base[i]);
 		return err;
 	}
 
diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c
index a936e7a..20cb98a 100644
--- a/drivers/input/joystick/grip.c
+++ b/drivers/input/joystick/grip.c
@@ -192,6 +192,9 @@ static void grip_poll(struct gameport *g
 	for (i = 0; i < 2; i++) {
 
 		dev = grip->dev[i];
+		if (!dev)
+			continue;
+
 		grip->reads++;
 
 		switch (grip->mode[i]) {
@@ -381,12 +384,15 @@ static int grip_connect(struct gameport 
 			if (t > 0)
 				set_bit(t, input_dev->keybit);
 
-		input_register_device(grip->dev[i]);
+		err = input_register_device(grip->dev[i]);
+		if (err)
+			goto fail4;
 	}
 
 	return 0;
 
- fail3: for (i = 0; i < 2; i++)
+ fail4:	input_free_device(grip->dev[i]);
+ fail3:	while (--i >= 0)
 		if (grip->dev[i])
 			input_unregister_device(grip->dev[i]);
  fail2:	gameport_close(gameport);
@@ -411,6 +417,7 @@ static void grip_disconnect(struct gamep
 static struct gameport_driver grip_drv = {
 	.driver		= {
 		.name	= "grip",
+		.owner	= THIS_MODULE,
 	},
 	.description	= DRIVER_DESC,
 	.connect	= grip_connect,
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
index 64b9c31..b6bc049 100644
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -345,7 +345,7 @@ int iforce_init_device(struct iforce *if
 	int i;
 
 	input_dev = input_allocate_device();
-	if (input_dev)
+	if (!input_dev)
 		return -ENOMEM;
 
 	init_waitqueue_head(&iforce->wait);
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
index 4a26292..76cb1f8 100644
--- a/drivers/input/joystick/iforce/iforce-packets.c
+++ b/drivers/input/joystick/iforce/iforce-packets.c
@@ -167,9 +167,9 @@ void iforce_process_packet(struct iforce
 		iforce->expect_packet = 0;
 		iforce->ecmd = cmd;
 		memcpy(iforce->edata, data, IFORCE_MAX_LENGTH);
-		wake_up(&iforce->wait);
 	}
 #endif
+	wake_up(&iforce->wait);
 
 	if (!iforce->type) {
 		being_used--;
@@ -264,7 +264,7 @@ int iforce_get_id_packet(struct iforce *
 		wait_event_interruptible_timeout(iforce->wait,
 			iforce->ctrl->status != -EINPROGRESS, HZ);
 
-		if (iforce->ctrl->status != -EINPROGRESS) {
+		if (iforce->ctrl->status) {
 			usb_unlink_urb(iforce->ctrl);
 			return -1;
 		}
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index bc2fce6..fe79d15 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -95,7 +95,6 @@ static void iforce_usb_irq(struct urb *u
 		goto exit;
 	}
 
-	wake_up(&iforce->wait);
 	iforce_process_packet(iforce,
 		(iforce->data[0] << 8) | (urb->actual_length - 1), iforce->data + 1, regs);
 
diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c
index 78dd163..2b2ec10 100644
--- a/drivers/input/joystick/sidewinder.c
+++ b/drivers/input/joystick/sidewinder.c
@@ -736,7 +736,7 @@ static int sw_connect(struct gameport *g
 		sprintf(sw->name, "Microsoft SideWinder %s", sw_name[sw->type]);
 		sprintf(sw->phys[i], "%s/input%d", gameport->phys, i);
 
-		input_dev = input_allocate_device();
+		sw->dev[i] = input_dev = input_allocate_device();
 		if (!input_dev) {
 			err = -ENOMEM;
 			goto fail3;
@@ -771,12 +771,15 @@ static int sw_connect(struct gameport *g
 
 		dbg("%s%s [%d-bit id %d data %d]\n", sw->name, comment, m, l, k);
 
-		input_register_device(sw->dev[i]);
+		err = input_register_device(sw->dev[i]);
+		if (err)
+			goto fail4;
 	}
 
 	return 0;
 
- fail3: while (--i >= 0)
+ fail4:	input_free_device(sw->dev[i]);
+ fail3:	while (--i >= 0)
 		input_unregister_device(sw->dev[i]);
  fail2:	gameport_close(gameport);
  fail1:	gameport_set_drvdata(gameport, NULL);
@@ -801,6 +804,7 @@ static void sw_disconnect(struct gamepor
 static struct gameport_driver sw_drv = {
 	.driver		= {
 		.name	= "sidewinder",
+		.owner	= THIS_MODULE,
 	},
 	.description	= DRIVER_DESC,
 	.connect	= sw_connect,
diff --git a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c
index 60e2aac..bb23ed2 100644
--- a/drivers/input/joystick/tmdc.c
+++ b/drivers/input/joystick/tmdc.c
@@ -284,13 +284,13 @@ static int tmdc_setup_port(struct tmdc *
 	struct tmdc_port *port;
 	struct input_dev *input_dev;
 	int i, j, b = 0;
+	int err;
 
 	tmdc->port[idx] = port = kzalloc(sizeof (struct tmdc_port), GFP_KERNEL);
 	input_dev = input_allocate_device();
 	if (!port || !input_dev) {
-		kfree(port);
-		input_free_device(input_dev);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto fail;
 	}
 
 	port->mode = data[TMDC_BYTE_ID];
@@ -347,9 +347,15 @@ static int tmdc_setup_port(struct tmdc *
 		b += port->btnc[i];
 	}
 
-	input_register_device(port->dev);
+	err = input_register_device(port->dev);
+	if (err)
+		goto fail;
 
 	return 0;
+
+ fail:	input_free_device(input_dev);
+	kfree(port);
+	return err;
 }
 
 /*
@@ -424,6 +430,7 @@ static void tmdc_disconnect(struct gamep
 static struct gameport_driver tmdc_drv = {
 	.driver		= {
 		.name	= "tmdc",
+		.owner	= THIS_MODULE,
 	},
 	.description	= DRIVER_DESC,
 	.connect	= tmdc_connect,
diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c
index 7e97649..b154938 100644
--- a/drivers/input/joystick/turbografx.c
+++ b/drivers/input/joystick/turbografx.c
@@ -204,14 +204,14 @@ static struct tgfx __init *tgfx_probe(in
 		if (n_buttons[i] > 6) {
 			printk(KERN_ERR "turbografx.c: Invalid number of buttons %d\n", n_buttons[i]);
 			err = -EINVAL;
-			goto err_free_devs;
+			goto err_unreg_devs;
 		}
 
 		tgfx->dev[i] = input_dev = input_allocate_device();
 		if (!input_dev) {
 			printk(KERN_ERR "turbografx.c: Not enough memory for input device\n");
 			err = -ENOMEM;
-			goto err_free_devs;
+			goto err_unreg_devs;
 		}
 
 		tgfx->sticks |= (1 << i);
@@ -238,7 +238,9 @@ static struct tgfx __init *tgfx_probe(in
 		for (j = 0; j < n_buttons[i]; j++)
 			set_bit(tgfx_buttons[j], input_dev->keybit);
 
-		input_register_device(tgfx->dev[i]);
+		err = input_register_device(tgfx->dev[i]);
+		if (err)
+			goto err_free_dev;
 	}
 
         if (!tgfx->sticks) {
@@ -249,9 +251,12 @@ static struct tgfx __init *tgfx_probe(in
 
 	return tgfx;
 
- err_free_devs:
+ err_free_dev:
+	input_free_device(tgfx->dev[i]);
+ err_unreg_devs:
 	while (--i >= 0)
-		input_unregister_device(tgfx->dev[i]);
+		if (tgfx->dev[i])
+			input_unregister_device(tgfx->dev[i]);
  err_free_tgfx:
 	kfree(tgfx);
  err_unreg_pardev:
@@ -262,7 +267,7 @@ static struct tgfx __init *tgfx_probe(in
 	return ERR_PTR(err);
 }
 
-static void __exit tgfx_remove(struct tgfx *tgfx)
+static void tgfx_remove(struct tgfx *tgfx)
 {
 	int i;
 
@@ -300,7 +305,8 @@ static int __init tgfx_init(void)
 
 	if (err) {
 		while (--i >= 0)
-			tgfx_remove(tgfx_base[i]);
+			if (tgfx_base[i])
+				tgfx_remove(tgfx_base[i]);
 		return err;
 	}
 
diff --git a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c
index cd3a1e7..7f8b009 100644
--- a/drivers/input/joystick/twidjoy.c
+++ b/drivers/input/joystick/twidjoy.c
@@ -265,13 +265,13 @@ static struct serio_driver twidjoy_drv =
  * The functions for inserting/removing us as a module.
  */
 
-int __init twidjoy_init(void)
+static int __init twidjoy_init(void)
 {
 	serio_register_driver(&twidjoy_drv);
 	return 0;
 }
 
-void __exit twidjoy_exit(void)
+static void __exit twidjoy_exit(void)
 {
 	serio_unregister_driver(&twidjoy_drv);
 }
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index e08dbe0..4bad588 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -50,6 +50,18 @@ config INPUT_WISTRON_BTNS
 	  To compile this driver as a module, choose M here: the module will
 	  be called wistron_btns.
 
+config INPUT_IXP4XX_BEEPER
+	tristate "IXP4XX Beeper support"
+	depends on ARCH_IXP4XX
+	help
+	  If you say yes here, you can connect a beeper to the
+	  ixp4xx gpio pins. This is used by the LinkSys NSLU2.
+
+	  If unsure, say Y.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ixp4xx-beeper.
+
 config INPUT_UINPUT
 	tristate "User level driver support"
 	help
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index ce44cce..184c412 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_INPUT_98SPKR)		+= 98spkr.o
 obj-$(CONFIG_INPUT_UINPUT)		+= uinput.o
 obj-$(CONFIG_INPUT_WISTRON_BTNS)	+= wistron_btns.o
 obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
+obj-$(CONFIG_INPUT_IXP4XX_BEEPER)	+= ixp4xx-beeper.o
diff --git a/drivers/input/misc/ixp4xx-beeper.c b/drivers/input/misc/ixp4xx-beeper.c
new file mode 100644
index 0000000..d448bb5
--- /dev/null
+++ b/drivers/input/misc/ixp4xx-beeper.c
@@ -0,0 +1,183 @@
+/*
+ * Generic IXP4xx beeper driver
+ *
+ * Copyright (C) 2005 Tower Technologies
+ *
+ * based on nslu2-io.c
+ *  Copyright (C) 2004 Karen Spearel
+ *
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
+ * Maintainers: http://www.nslu2-linux.org/
+ *
+ * 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/module.h>
+#include <linux/input.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <asm/hardware.h>
+
+MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
+MODULE_DESCRIPTION("ixp4xx beeper driver");
+MODULE_LICENSE("GPL");
+
+static DEFINE_SPINLOCK(beep_lock);
+
+static void ixp4xx_spkr_control(unsigned int pin, unsigned int count)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&beep_lock, flags);
+
+	 if (count) {
+		gpio_line_config(pin, IXP4XX_GPIO_OUT);
+		gpio_line_set(pin, IXP4XX_GPIO_LOW);
+
+		*IXP4XX_OSRT2 = (count & ~IXP4XX_OST_RELOAD_MASK) | IXP4XX_OST_ENABLE;
+	} else {
+		gpio_line_config(pin, IXP4XX_GPIO_IN);
+		gpio_line_set(pin, IXP4XX_GPIO_HIGH);
+
+		*IXP4XX_OSRT2 = 0;
+	}
+
+	spin_unlock_irqrestore(&beep_lock, flags);
+}
+
+static int ixp4xx_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+{
+	unsigned int pin = (unsigned int) dev->private;
+	unsigned int count = 0;
+
+	if (type != EV_SND)
+		return -1;
+
+	switch (code) {
+		case SND_BELL:
+			if (value)
+				value = 1000;
+		case SND_TONE:
+			break;
+		default:
+			return -1;
+	}
+
+	if (value > 20 && value < 32767)
+#ifndef FREQ
+		count = (ixp4xx_get_board_tick_rate() / (value * 4)) - 1;
+#else
+		count = (FREQ / (value * 4)) - 1;
+#endif
+
+	ixp4xx_spkr_control(pin, count);
+
+	return 0;
+}
+
+static irqreturn_t ixp4xx_spkr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	/* clear interrupt */
+	*IXP4XX_OSST = IXP4XX_OSST_TIMER_2_PEND;
+
+	/* flip the beeper output */
+	*IXP4XX_GPIO_GPOUTR ^= (1 << (unsigned int) dev_id);
+
+	return IRQ_HANDLED;
+}
+
+static int __devinit ixp4xx_spkr_probe(struct platform_device *dev)
+{
+	struct input_dev *input_dev;
+	int err;
+
+	input_dev = input_allocate_device();
+	if (!input_dev)
+		return -ENOMEM;
+
+	input_dev->private = (void *) dev->id;
+	input_dev->name = "ixp4xx beeper",
+	input_dev->phys = "ixp4xx/gpio";
+	input_dev->id.bustype = BUS_HOST;
+	input_dev->id.vendor  = 0x001f;
+	input_dev->id.product = 0x0001;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &dev->dev;
+
+	input_dev->evbit[0] = BIT(EV_SND);
+	input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+	input_dev->event = ixp4xx_spkr_event;
+
+	err = request_irq(IRQ_IXP4XX_TIMER2, &ixp4xx_spkr_interrupt,
+			  SA_INTERRUPT | SA_TIMER, "ixp4xx-beeper", (void *) dev->id);
+	if (err)
+		goto err_free_device;
+
+	err = input_register_device(input_dev);
+	if (err)
+		goto err_free_irq;
+
+	platform_set_drvdata(dev, input_dev);
+
+	return 0;
+
+ err_free_irq:
+	free_irq(IRQ_IXP4XX_TIMER2, dev);
+ err_free_device:
+	input_free_device(input_dev);
+
+	return err;
+}
+
+static int __devexit ixp4xx_spkr_remove(struct platform_device *dev)
+{
+	struct input_dev *input_dev = platform_get_drvdata(dev);
+	unsigned int pin = (unsigned int) input_dev->private;
+
+	input_unregister_device(input_dev);
+	platform_set_drvdata(dev, NULL);
+
+	/* turn the speaker off */
+	disable_irq(IRQ_IXP4XX_TIMER2);
+	ixp4xx_spkr_control(pin, 0);
+
+	free_irq(IRQ_IXP4XX_TIMER2, dev);
+
+	return 0;
+}
+
+static void ixp4xx_spkr_shutdown(struct platform_device *dev)
+{
+	struct input_dev *input_dev = platform_get_drvdata(dev);
+	unsigned int pin = (unsigned int) input_dev->private;
+
+	/* turn off the speaker */
+	disable_irq(IRQ_IXP4XX_TIMER2);
+	ixp4xx_spkr_control(pin, 0);
+}
+
+static struct platform_driver ixp4xx_spkr_platform_driver = {
+	.driver		= {
+		.name	= "ixp4xx-beeper",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= ixp4xx_spkr_probe,
+	.remove		= __devexit_p(ixp4xx_spkr_remove),
+	.shutdown	= ixp4xx_spkr_shutdown,
+};
+
+static int __init ixp4xx_spkr_init(void)
+{
+	return platform_driver_register(&ixp4xx_spkr_platform_driver);
+}
+
+static void __exit ixp4xx_spkr_exit(void)
+{
+	platform_driver_unregister(&ixp4xx_spkr_platform_driver);
+}
+
+module_init(ixp4xx_spkr_init);
+module_exit(ixp4xx_spkr_exit);
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 7665fd9..19b1b01 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -403,6 +403,7 @@ static int genius_detect(struct psmouse 
 		set_bit(REL_WHEEL, psmouse->dev->relbit);
 
 		psmouse->vendor = "Genius";
+		psmouse->name = "Mouse";
 		psmouse->pktsize = 4;
 	}
 
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 81fd7a9..9abed18 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -356,7 +356,7 @@ static void mousedev_free(struct mousede
 	kfree(mousedev);
 }
 
-static int mixdev_release(void)
+static void mixdev_release(void)
 {
 	struct input_handle *handle;
 
@@ -370,8 +370,6 @@ static int mixdev_release(void)
 				mousedev_free(mousedev);
 		}
 	}
-
-	return 0;
 }
 
 static int mousedev_release(struct inode * inode, struct file * file)
@@ -384,9 +382,8 @@ static int mousedev_release(struct inode
 
 	if (!--list->mousedev->open) {
 		if (list->mousedev->minor == MOUSEDEV_MIX)
-			return mixdev_release();
-
-		if (!mousedev_mix.open) {
+			mixdev_release();
+		else if (!mousedev_mix.open) {
 			if (list->mousedev->exist)
 				input_close_device(&list->mousedev->handle);
 			else
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index dd8c6a9..b45a45c 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -29,9 +29,6 @@
 #ifdef	CONFIG_ARCH_OMAP
 #include <asm/arch/gpio.h>
 #endif
-
-#else
-#define	set_irq_type(irq,type)	do{}while(0)
 #endif
 
 
@@ -509,14 +506,14 @@ static int __devinit ads7846_probe(struc
 	ts->msg.complete = ads7846_rx;
 	ts->msg.context = ts;
 
-	if (request_irq(spi->irq, ads7846_irq, SA_SAMPLE_RANDOM,
-				spi->dev.bus_id, ts)) {
+	if (request_irq(spi->irq, ads7846_irq,
+			SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING,
+			spi->dev.bus_id, ts)) {
 		dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
 		input_unregister_device(&ts->input);
 		kfree(ts);
 		return -EBUSY;
 	}
-	set_irq_type(spi->irq, IRQT_FALLING);
 
 	dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq);
 
diff --git a/drivers/input/touchscreen/mk712.c b/drivers/input/touchscreen/mk712.c
index 4844d25..3226830 100644
--- a/drivers/input/touchscreen/mk712.c
+++ b/drivers/input/touchscreen/mk712.c
@@ -154,7 +154,7 @@ static void mk712_close(struct input_dev
 	spin_unlock_irqrestore(&mk712_lock, flags);
 }
 
-int __init mk712_init(void)
+static int __init mk712_init(void)
 {
 	int err;
 
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index ed6d317..69596f6 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -140,10 +140,9 @@ static int macio_uevent(struct device *d
 {
 	struct macio_dev * macio_dev;
 	struct of_device * of;
-	char *scratch, *compat;
+	char *scratch, *compat, *compat2;
 	int i = 0;
-	int length = 0;
-	int cplen, seen = 0;
+	int length, cplen, cplen2, seen = 0;
 
 	if (!dev)
 		return -ENODEV;
@@ -153,23 +152,22 @@ static int macio_uevent(struct device *d
 		return -ENODEV;
 
 	of = &macio_dev->ofdev;
-	scratch = buffer;
 
 	/* stuff we want to pass to /sbin/hotplug */
-	envp[i++] = scratch;
-	length += scnprintf (scratch, buffer_size - length, "OF_NAME=%s",
-	                     of->node->name);
-	if ((buffer_size - length <= 0) || (i >= num_envp))
-		return -ENOMEM;
+	envp[i++] = scratch = buffer;
+	length = scnprintf (scratch, buffer_size, "OF_NAME=%s", of->node->name);
 	++length;
+	buffer_size -= length;
+	if ((buffer_size <= 0) || (i >= num_envp))
+		return -ENOMEM;
 	scratch += length;
 
 	envp[i++] = scratch;
-	length += scnprintf (scratch, buffer_size - length, "OF_TYPE=%s",
-	                     of->node->type);
-	if ((buffer_size - length <= 0) || (i >= num_envp))
-		return -ENOMEM;
+	length = scnprintf (scratch, buffer_size, "OF_TYPE=%s", of->node->type);
 	++length;
+	buffer_size -= length;
+	if ((buffer_size <= 0) || (i >= num_envp))
+		return -ENOMEM;
 	scratch += length;
 
         /* Since the compatible field can contain pretty much anything
@@ -177,29 +175,55 @@ static int macio_uevent(struct device *d
          * up using a number of environment variables instead. */
 
 	compat = (char *) get_property(of->node, "compatible", &cplen);
+	compat2 = compat;
+	cplen2= cplen;
 	while (compat && cplen > 0) {
-		int l;
                 envp[i++] = scratch;
-		length += scnprintf (scratch, buffer_size - length,
+		length = scnprintf (scratch, buffer_size,
 		                     "OF_COMPATIBLE_%d=%s", seen, compat);
-		if ((buffer_size - length <= 0) || (i >= num_envp))
+		++length;
+		buffer_size -= length;
+		if ((buffer_size <= 0) || (i >= num_envp))
 			return -ENOMEM;
-		length++;
 		scratch += length;
-		l = strlen (compat) + 1;
-		compat += l;
-		cplen -= l;
+		length = strlen (compat) + 1;
+		compat += length;
+		cplen -= length;
 		seen++;
 	}
 
 	envp[i++] = scratch;
-	length += scnprintf (scratch, buffer_size - length,
-	                     "OF_COMPATIBLE_N=%d", seen);
-	if ((buffer_size - length <= 0) || (i >= num_envp))
-		return -ENOMEM;
+	length = scnprintf (scratch, buffer_size, "OF_COMPATIBLE_N=%d", seen);
 	++length;
+	buffer_size -= length;
+	if ((buffer_size <= 0) || (i >= num_envp))
+		return -ENOMEM;
 	scratch += length;
 
+	envp[i++] = scratch;
+	length = scnprintf (scratch, buffer_size, "MODALIAS=of:N%sT%s",
+			of->node->name, of->node->type);
+	/* overwrite '\0' */
+	buffer_size -= length;
+	if ((buffer_size <= 0) || (i >= num_envp))
+		return -ENOMEM;
+	scratch += length;
+
+	if (!compat2) {
+		compat2 = "";
+		cplen2 = 1;
+	}
+	while (cplen2 > 0) {
+		length = snprintf (scratch, buffer_size, "C%s", compat2);
+		buffer_size -= length;
+		if (buffer_size <= 0)
+			return -ENOMEM;
+		scratch += length;
+		length = strlen (compat2) + 1;
+		compat2 += length;
+		cplen2 -= length;
+	}
+
 	envp[i] = NULL;
 
 	return 0;
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 1235135..442e2be 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -1359,16 +1359,11 @@ static int ctl_ioctl(struct inode *inode
 	 * Copy the parameters into kernel space.
 	 */
 	r = copy_params(user, &param);
-	if (r) {
-		current->flags &= ~PF_MEMALLOC;
-		return r;
-	}
 
-	/*
-	 * FIXME: eventually we will remove the PF_MEMALLOC flag
-	 * here.  However the tools still do nasty things like
-	 * 'load' while a device is suspended.
-	 */
+	current->flags &= ~PF_MEMALLOC;
+
+	if (r)
+		return r;
 
 	r = validate_params(cmd, param);
 	if (r)
@@ -1386,7 +1381,6 @@ static int ctl_ioctl(struct inode *inode
 
  out:
 	free_params(param);
-	current->flags &= ~PF_MEMALLOC;
 	return r;
 }
 
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
index efe4adf..74039db 100644
--- a/drivers/md/dm-log.c
+++ b/drivers/md/dm-log.c
@@ -112,7 +112,7 @@ void dm_destroy_dirty_log(struct dirty_l
 /*
  * The on-disk version of the metadata.
  */
-#define MIRROR_DISK_VERSION 1
+#define MIRROR_DISK_VERSION 2
 #define LOG_OFFSET 2
 
 struct log_header {
@@ -157,7 +157,6 @@ struct log_c {
 	struct log_header *disk_header;
 
 	struct io_region bits_location;
-	uint32_t *disk_bits;
 };
 
 /*
@@ -166,20 +165,20 @@ struct log_c {
  */
 static  inline int log_test_bit(uint32_t *bs, unsigned bit)
 {
-	return test_bit(bit, (unsigned long *) bs) ? 1 : 0;
+	return ext2_test_bit(bit, (unsigned long *) bs) ? 1 : 0;
 }
 
 static inline void log_set_bit(struct log_c *l,
 			       uint32_t *bs, unsigned bit)
 {
-	set_bit(bit, (unsigned long *) bs);
+	ext2_set_bit(bit, (unsigned long *) bs);
 	l->touched = 1;
 }
 
 static inline void log_clear_bit(struct log_c *l,
 				 uint32_t *bs, unsigned bit)
 {
-	clear_bit(bit, (unsigned long *) bs);
+	ext2_clear_bit(bit, (unsigned long *) bs);
 	l->touched = 1;
 }
 
@@ -219,6 +218,11 @@ static int read_header(struct log_c *log
 		log->header.nr_regions = 0;
 	}
 
+#ifdef __LITTLE_ENDIAN
+	if (log->header.version == 1)
+		log->header.version = 2;
+#endif
+
 	if (log->header.version != MIRROR_DISK_VERSION) {
 		DMWARN("incompatible disk log version");
 		return -EINVAL;
@@ -239,45 +243,24 @@ static inline int write_header(struct lo
 /*----------------------------------------------------------------
  * Bits IO
  *--------------------------------------------------------------*/
-static inline void bits_to_core(uint32_t *core, uint32_t *disk, unsigned count)
-{
-	unsigned i;
-
-	for (i = 0; i < count; i++)
-		core[i] = le32_to_cpu(disk[i]);
-}
-
-static inline void bits_to_disk(uint32_t *core, uint32_t *disk, unsigned count)
-{
-	unsigned i;
-
-	/* copy across the clean/dirty bitset */
-	for (i = 0; i < count; i++)
-		disk[i] = cpu_to_le32(core[i]);
-}
-
 static int read_bits(struct log_c *log)
 {
 	int r;
 	unsigned long ebits;
 
 	r = dm_io_sync_vm(1, &log->bits_location, READ,
-			  log->disk_bits, &ebits);
+			  log->clean_bits, &ebits);
 	if (r)
 		return r;
 
-	bits_to_core(log->clean_bits, log->disk_bits,
-		     log->bitset_uint32_count);
 	return 0;
 }
 
 static int write_bits(struct log_c *log)
 {
 	unsigned long ebits;
-	bits_to_disk(log->clean_bits, log->disk_bits,
-		     log->bitset_uint32_count);
 	return dm_io_sync_vm(1, &log->bits_location, WRITE,
-			     log->disk_bits, &ebits);
+			     log->clean_bits, &ebits);
 }
 
 /*----------------------------------------------------------------
@@ -433,11 +416,6 @@ static int disk_ctr(struct dirty_log *lo
 	size = dm_round_up(lc->bitset_uint32_count * sizeof(uint32_t),
 			   1 << SECTOR_SHIFT);
 	lc->bits_location.count = size >> SECTOR_SHIFT;
-	lc->disk_bits = vmalloc(size);
-	if (!lc->disk_bits) {
-		vfree(lc->disk_header);
-		goto bad;
-	}
 	return 0;
 
  bad:
@@ -451,7 +429,6 @@ static void disk_dtr(struct dirty_log *l
 	struct log_c *lc = (struct log_c *) log->context;
 	dm_put_device(lc->ti, lc->log_dev);
 	vfree(lc->disk_header);
-	vfree(lc->disk_bits);
 	core_dtr(log);
 }
 
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 87727d8..f3759dd 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -373,16 +373,11 @@ static inline ulong round_up(ulong n, ul
 
 static void read_snapshot_metadata(struct dm_snapshot *s)
 {
-	if (s->have_metadata)
-		return;
-
 	if (s->store.read_metadata(&s->store)) {
 		down_write(&s->lock);
 		s->valid = 0;
 		up_write(&s->lock);
 	}
-
-	s->have_metadata = 1;
 }
 
 /*
@@ -471,7 +466,7 @@ static int snapshot_ctr(struct dm_target
 	s->chunk_shift = ffs(chunk_size) - 1;
 
 	s->valid = 1;
-	s->have_metadata = 0;
+	s->active = 0;
 	s->last_percent = 0;
 	init_rwsem(&s->lock);
 	s->table = ti->table;
@@ -506,7 +501,11 @@ static int snapshot_ctr(struct dm_target
 		goto bad5;
 	}
 
+	/* Metadata must only be loaded into one table at once */
+	read_snapshot_metadata(s);
+
 	/* Add snapshot to the list of snapshots for this origin */
+	/* Exceptions aren't triggered till snapshot_resume() is called */
 	if (register_snapshot(s)) {
 		r = -EINVAL;
 		ti->error = "Cannot register snapshot origin";
@@ -793,6 +792,9 @@ static int snapshot_map(struct dm_target
 	if (!s->valid)
 		return -EIO;
 
+	if (unlikely(bio_barrier(bio)))
+		return -EOPNOTSUPP;
+
 	/*
 	 * Write to snapshot - higher level takes care of RW/RO
 	 * flags so we should only get this if we are
@@ -862,7 +864,9 @@ static void snapshot_resume(struct dm_ta
 {
 	struct dm_snapshot *s = (struct dm_snapshot *) ti->private;
 
-	read_snapshot_metadata(s);
+	down_write(&s->lock);
+	s->active = 1;
+	up_write(&s->lock);
 }
 
 static int snapshot_status(struct dm_target *ti, status_type_t type,
@@ -932,8 +936,8 @@ static int __origin_write(struct list_he
 	/* Do all the snapshots on this origin */
 	list_for_each_entry (snap, snapshots, list) {
 
-		/* Only deal with valid snapshots */
-		if (!snap->valid)
+		/* Only deal with valid and active snapshots */
+		if (!snap->valid || !snap->active)
 			continue;
 
 		/* Nothing to do if writing beyond end of snapshot */
@@ -1057,6 +1061,9 @@ static int origin_map(struct dm_target *
 	struct dm_dev *dev = (struct dm_dev *) ti->private;
 	bio->bi_bdev = dev->bdev;
 
+	if (unlikely(bio_barrier(bio)))
+		return -EOPNOTSUPP;
+
 	/* Only tell snapshots if this is a write */
 	return (bio_rw(bio) == WRITE) ? do_origin(dev, bio) : 1;
 }
@@ -1104,7 +1111,7 @@ static int origin_status(struct dm_targe
 
 static struct target_type origin_target = {
 	.name    = "snapshot-origin",
-	.version = {1, 0, 1},
+	.version = {1, 1, 0},
 	.module  = THIS_MODULE,
 	.ctr     = origin_ctr,
 	.dtr     = origin_dtr,
@@ -1115,7 +1122,7 @@ static struct target_type origin_target 
 
 static struct target_type snapshot_target = {
 	.name    = "snapshot",
-	.version = {1, 0, 1},
+	.version = {1, 1, 0},
 	.module  = THIS_MODULE,
 	.ctr     = snapshot_ctr,
 	.dtr     = snapshot_dtr,
diff --git a/drivers/md/dm-snap.h b/drivers/md/dm-snap.h
index 375aa24..fdec1e2 100644
--- a/drivers/md/dm-snap.h
+++ b/drivers/md/dm-snap.h
@@ -99,7 +99,9 @@ struct dm_snapshot {
 
 	/* You can't use a snapshot if this is 0 (e.g. if full) */
 	int valid;
-	int have_metadata;
+
+	/* Origin writes don't trigger exceptions until this is set */
+	int active;
 
 	/* Used for display of table */
 	char type;
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index a6f2dc6..9b1e2f5 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -508,7 +508,7 @@ int dm_get_device(struct dm_target *ti, 
 		if (q->merge_bvec_fn)
 			rs->max_sectors =
 				min_not_zero(rs->max_sectors,
-					     (unsigned short)(PAGE_SIZE >> 9));
+					     (unsigned int) (PAGE_SIZE >> 9));
 
 		rs->max_phys_segments =
 			min_not_zero(rs->max_phys_segments,
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 8c16359..e9adeb9 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -31,6 +31,7 @@ struct dm_io {
 	int error;
 	struct bio *bio;
 	atomic_t io_count;
+	unsigned long start_time;
 };
 
 /*
@@ -244,6 +245,36 @@ static inline void free_tio(struct mappe
 	mempool_free(tio, md->tio_pool);
 }
 
+static void start_io_acct(struct dm_io *io)
+{
+	struct mapped_device *md = io->md;
+
+	io->start_time = jiffies;
+
+	preempt_disable();
+	disk_round_stats(dm_disk(md));
+	preempt_enable();
+	dm_disk(md)->in_flight = atomic_inc_return(&md->pending);
+}
+
+static int end_io_acct(struct dm_io *io)
+{
+	struct mapped_device *md = io->md;
+	struct bio *bio = io->bio;
+	unsigned long duration = jiffies - io->start_time;
+	int pending;
+	int rw = bio_data_dir(bio);
+
+	preempt_disable();
+	disk_round_stats(dm_disk(md));
+	preempt_enable();
+	dm_disk(md)->in_flight = pending = atomic_dec_return(&md->pending);
+
+	disk_stat_add(dm_disk(md), ticks[rw], duration);
+
+	return !pending;
+}
+
 /*
  * Add the bio to the list of deferred io.
  */
@@ -299,7 +330,7 @@ static void dec_pending(struct dm_io *io
 		io->error = error;
 
 	if (atomic_dec_and_test(&io->io_count)) {
-		if (atomic_dec_and_test(&io->md->pending))
+		if (end_io_acct(io))
 			/* nudge anyone waiting on suspend queue */
 			wake_up(&io->md->wait);
 
@@ -554,7 +585,7 @@ static void __split_bio(struct mapped_de
 	ci.sector_count = bio_sectors(bio);
 	ci.idx = bio->bi_idx;
 
-	atomic_inc(&md->pending);
+	start_io_acct(ci.io);
 	while (ci.sector_count)
 		__clone_and_map(&ci);
 
@@ -573,10 +604,14 @@ static void __split_bio(struct mapped_de
 static int dm_request(request_queue_t *q, struct bio *bio)
 {
 	int r;
+	int rw = bio_data_dir(bio);
 	struct mapped_device *md = q->queuedata;
 
 	down_read(&md->io_lock);
 
+	disk_stat_inc(dm_disk(md), ios[rw]);
+	disk_stat_add(dm_disk(md), sectors[rw], bio_sectors(bio));
+
 	/*
 	 * If we're suspended we have to queue
 	 * this io for later.
diff --git a/drivers/md/kcopyd.c b/drivers/md/kcopyd.c
index ca99979..8b3515f 100644
--- a/drivers/md/kcopyd.c
+++ b/drivers/md/kcopyd.c
@@ -8,6 +8,7 @@
  * completion notification.
  */
 
+#include <asm/types.h>
 #include <asm/atomic.h>
 
 #include <linux/blkdev.h>
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c
index 0b6c209..aad4a18 100644
--- a/drivers/media/video/hexium_orion.c
+++ b/drivers/media/video/hexium_orion.c
@@ -484,7 +484,7 @@ static struct saa7146_ext_vv vv_data = {
 };
 
 static struct saa7146_extension extension = {
-	.name = "hexium HV-PCI6/Orion",
+	.name = "hexium HV-PCI6 Orion",
 	.flags = 0,		// SAA7146_USE_I2C_IRQ,
 
 	.pci_tbl = &pci_tbl[0],
diff --git a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile
index 8a2e265..33ace37 100644
--- a/drivers/message/fusion/Makefile
+++ b/drivers/message/fusion/Makefile
@@ -29,6 +29,8 @@
 #  For mptctl:
 #CFLAGS_mptctl.o += -DMPT_DEBUG_IOCTL
 #
+#  For mptfc:
+#CFLAGS_mptfc.o += -DMPT_DEBUG_FC
 
 #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC
 
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index d890b2b..9a2c760 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -81,6 +81,10 @@ MODULE_LICENSE("GPL");
 /*
  *  cmd line parameters
  */
+static int mpt_msi_enable;
+module_param(mpt_msi_enable, int, 0);
+MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)");
+
 #ifdef MFCNT
 static int mfcounter = 0;
 #define PRINT_MF_COUNT 20000
@@ -174,7 +178,7 @@ static void	mpt_get_fw_exp_ver(char *buf
 static int	ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
 static void	mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
 static void	mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
-static void	mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info);
+static void	mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
 static void	mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
 
 /* module entry point */
@@ -313,7 +317,7 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa)
 		if (ioc->bus_type == FC)
 			mpt_fc_log_info(ioc, log_info);
 		else if (ioc->bus_type == SPI)
-			mpt_sp_log_info(ioc, log_info);
+			mpt_spi_log_info(ioc, log_info);
 		else if (ioc->bus_type == SAS)
 			mpt_sas_log_info(ioc, log_info);
 	}
@@ -1444,6 +1448,9 @@ mpt_attach(struct pci_dev *pdev, const s
 
 	ioc->pci_irq = -1;
 	if (pdev->irq) {
+		if (mpt_msi_enable && !pci_enable_msi(pdev))
+			printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n", ioc->name);
+
 		r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc);
 
 		if (r < 0) {
@@ -1483,6 +1490,10 @@ mpt_attach(struct pci_dev *pdev, const s
 
 		list_del(&ioc->list);
 		free_irq(ioc->pci_irq, ioc);
+		if (mpt_msi_enable)
+			pci_disable_msi(pdev);
+		if (ioc->alt_ioc)
+			ioc->alt_ioc->alt_ioc = NULL;
 		iounmap(mem);
 		kfree(ioc);
 		pci_set_drvdata(pdev, NULL);
@@ -2136,6 +2147,8 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc)
 
 	if (ioc->pci_irq != -1) {
 		free_irq(ioc->pci_irq, ioc);
+		if (mpt_msi_enable)
+			pci_disable_msi(ioc->pcidev);
 		ioc->pci_irq = -1;
 	}
 
@@ -2157,6 +2170,10 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc)
 	sz_last = ioc->alloc_total;
 	dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
 			ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
+
+	if (ioc->alt_ioc)
+		ioc->alt_ioc->alt_ioc = NULL;
+
 	kfree(ioc);
 }
 
@@ -2770,13 +2787,16 @@ SendPortEnable(MPT_ADAPTER *ioc, int por
 
 	/* RAID FW may take a long time to enable
 	 */
-	if ( (ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
-			> MPI_FW_HEADER_PID_PROD_TARGET_SCSI ) {
-		rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
-				reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag);
+	if (((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
+	    > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) ||
+	    (ioc->bus_type == SAS)) {
+		rc = mpt_handshake_req_reply_wait(ioc, req_sz,
+		(u32*)&port_enable, reply_sz, (u16*)&reply_buf,
+		300 /*seconds*/, sleepFlag);
 	} else {
-		rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
-				reply_sz, (u16*)&reply_buf, 30 /*seconds*/, sleepFlag);
+		rc = mpt_handshake_req_reply_wait(ioc, req_sz,
+		(u32*)&port_enable, reply_sz, (u16*)&reply_buf,
+		30 /*seconds*/, sleepFlag);
 	}
 	return rc;
 }
@@ -4387,6 +4407,138 @@ mptbase_sas_persist_operation(MPT_ADAPTE
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+
+static void
+mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
+    MpiEventDataRaid_t * pRaidEventData)
+{
+	int 	volume;
+	int 	reason;
+	int 	disk;
+	int 	status;
+	int 	flags;
+	int 	state;
+
+	volume	= pRaidEventData->VolumeID;
+	reason	= pRaidEventData->ReasonCode;
+	disk	= pRaidEventData->PhysDiskNum;
+	status	= le32_to_cpu(pRaidEventData->SettingsStatus);
+	flags	= (status >> 0) & 0xff;
+	state	= (status >> 8) & 0xff;
+
+	if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
+		return;
+	}
+
+	if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
+	     reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
+	    (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
+		printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d\n",
+			ioc->name, disk);
+	} else {
+		printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
+			ioc->name, volume);
+	}
+
+	switch(reason) {
+	case MPI_EVENT_RAID_RC_VOLUME_CREATED:
+		printk(MYIOC_s_INFO_FMT "  volume has been created\n",
+			ioc->name);
+		break;
+
+	case MPI_EVENT_RAID_RC_VOLUME_DELETED:
+
+		printk(MYIOC_s_INFO_FMT "  volume has been deleted\n",
+			ioc->name);
+		break;
+
+	case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
+		printk(MYIOC_s_INFO_FMT "  volume settings have been changed\n",
+			ioc->name);
+		break;
+
+	case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
+		printk(MYIOC_s_INFO_FMT "  volume is now %s%s%s%s\n",
+			ioc->name,
+			state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
+			 ? "optimal"
+			 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
+			  ? "degraded"
+			  : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
+			   ? "failed"
+			   : "state unknown",
+			flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
+			 ? ", enabled" : "",
+			flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
+			 ? ", quiesced" : "",
+			flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
+			 ? ", resync in progress" : "" );
+		break;
+
+	case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
+		printk(MYIOC_s_INFO_FMT "  volume membership of PhysDisk %d has changed\n",
+			ioc->name, disk);
+		break;
+
+	case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
+		printk(MYIOC_s_INFO_FMT "  PhysDisk has been created\n",
+			ioc->name);
+		break;
+
+	case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
+		printk(MYIOC_s_INFO_FMT "  PhysDisk has been deleted\n",
+			ioc->name);
+		break;
+
+	case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
+		printk(MYIOC_s_INFO_FMT "  PhysDisk settings have been changed\n",
+			ioc->name);
+		break;
+
+	case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
+		printk(MYIOC_s_INFO_FMT "  PhysDisk is now %s%s%s\n",
+			ioc->name,
+			state == MPI_PHYSDISK0_STATUS_ONLINE
+			 ? "online"
+			 : state == MPI_PHYSDISK0_STATUS_MISSING
+			  ? "missing"
+			  : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
+			   ? "not compatible"
+			   : state == MPI_PHYSDISK0_STATUS_FAILED
+			    ? "failed"
+			    : state == MPI_PHYSDISK0_STATUS_INITIALIZING
+			     ? "initializing"
+			     : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
+			      ? "offline requested"
+			      : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
+			       ? "failed requested"
+			       : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
+			        ? "offline"
+			        : "state unknown",
+			flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
+			 ? ", out of sync" : "",
+			flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
+			 ? ", quiesced" : "" );
+		break;
+
+	case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
+		printk(MYIOC_s_INFO_FMT "  Domain Validation needed for PhysDisk %d\n",
+			ioc->name, disk);
+		break;
+
+	case MPI_EVENT_RAID_RC_SMART_DATA:
+		printk(MYIOC_s_INFO_FMT "  SMART data received, ASC/ASCQ = %02xh/%02xh\n",
+			ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
+		break;
+
+	case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
+		printk(MYIOC_s_INFO_FMT "  replacement of PhysDisk %d has started\n",
+			ioc->name, disk);
+		break;
+	}
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *	GetIoUnitPage2 - Retrieve BIOS version and boot order information.
  *	@ioc: Pointer to MPT_ADAPTER structure
@@ -4598,6 +4750,14 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc
 				SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t  *) pbuf;
 				MpiDeviceInfo_t	*pdevice = NULL;
 
+				/*
+				 * Save "Set to Avoid SCSI Bus Resets" flag
+				 */
+				ioc->spi_data.bus_reset =
+				    (le32_to_cpu(pPP2->PortFlags) &
+			        MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
+				    0 : 1 ;
+
 				/* Save the Port Page 2 data
 				 * (reformat into a 32bit quantity)
 				 */
@@ -5967,6 +6127,10 @@ ProcessEventNotification(MPT_ADAPTER *io
 			}
 		}
 		break;
+	case MPI_EVENT_INTEGRATED_RAID:
+		mptbase_raid_process_event_data(ioc,
+		    (MpiEventDataRaid_t *)pEventReply->Data);
+		break;
 	default:
 		break;
 	}
@@ -6046,7 +6210,7 @@ mpt_fc_log_info(MPT_ADAPTER *ioc, u32 lo
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- *	mpt_sp_log_info - Log information returned from SCSI Parallel IOC.
+ *	mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
  *	@ioc: Pointer to MPT_ADAPTER structure
  *	@mr: Pointer to MPT reply frame
  *	@log_info: U32 LogInfo word from the IOC
@@ -6054,7 +6218,7 @@ mpt_fc_log_info(MPT_ADAPTER *ioc, u32 lo
  *	Refer to lsi/sp_log.h.
  */
 static void
-mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
+mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
 {
 	u32 info = log_info & 0x00FF0000;
 	char *desc = "unknown";
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 47053ac..ea2649e 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -76,8 +76,8 @@
 #define COPYRIGHT	"Copyright (c) 1999-2005 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON	"3.03.06"
-#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.03.06"
+#define MPT_LINUX_VERSION_COMMON	"3.03.07"
+#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.03.07"
 #define WHAT_MAGIC_STRING		"@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
@@ -123,7 +123,7 @@
 #define  MPT_MAX_FRAME_SIZE		128
 #define  MPT_DEFAULT_FRAME_SIZE		128
 
-#define  MPT_REPLY_FRAME_SIZE		0x40  /* Must be a multiple of 8 */
+#define  MPT_REPLY_FRAME_SIZE		0x50  /* Must be a multiple of 8 */
 
 #define  MPT_SG_REQ_128_SCALE		1
 #define  MPT_SG_REQ_96_SCALE		2
@@ -510,9 +510,10 @@ struct mptfc_rport_info
 {
 	struct list_head list;
 	struct fc_rport *rport;
-	VirtDevice	*vdev;
+	struct scsi_target *starget;
 	FCDevicePage0_t pg0;
 	u8		flags;
+	u8		remap_needed;
 };
 
 /*
@@ -631,6 +632,7 @@ typedef struct _MPT_ADAPTER
 	struct mutex		 sas_topology_mutex;
 	MPT_SAS_MGMT		 sas_mgmt;
 	int			 num_ports;
+	struct work_struct	 mptscsih_persistTask;
 
 	struct list_head	 fc_rports;
 	spinlock_t		 fc_rport_lock; /* list and ri flags */
@@ -803,6 +805,12 @@ typedef struct _mpt_sge {
 #define dreplyprintk(x)
 #endif
 
+#ifdef DMPT_DEBUG_FC
+#define dfcprintk(x) printk x
+#else
+#define dfcprintk(x)
+#endif
+
 #ifdef MPT_DEBUG_TM
 #define dtmprintk(x) printk x
 #define DBG_DUMP_TM_REQUEST_FRAME(mfp) \
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index b102c76..c3a3499 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -93,10 +93,11 @@ static int	mptfcDoneCtx = -1;
 static int	mptfcTaskCtx = -1;
 static int	mptfcInternalCtx = -1; /* Used only for internal commands */
 
-int mptfc_slave_alloc(struct scsi_device *device);
+static int mptfc_target_alloc(struct scsi_target *starget);
+static int mptfc_slave_alloc(struct scsi_device *sdev);
 static int mptfc_qcmd(struct scsi_cmnd *SCpnt,
-    void (*done)(struct scsi_cmnd *));
-
+		      void (*done)(struct scsi_cmnd *));
+static void mptfc_target_destroy(struct scsi_target *starget);
 static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
 static void __devexit mptfc_remove(struct pci_dev *pdev);
 
@@ -107,10 +108,10 @@ static struct scsi_host_template mptfc_d
 	.name				= "MPT FC Host",
 	.info				= mptscsih_info,
 	.queuecommand			= mptfc_qcmd,
-	.target_alloc			= mptscsih_target_alloc,
+	.target_alloc			= mptfc_target_alloc,
 	.slave_alloc			= mptfc_slave_alloc,
 	.slave_configure		= mptscsih_slave_configure,
-	.target_destroy			= mptscsih_target_destroy,
+	.target_destroy			= mptfc_target_destroy,
 	.slave_destroy			= mptscsih_slave_destroy,
 	.change_queue_depth 		= mptscsih_change_queue_depth,
 	.eh_abort_handler		= mptscsih_abort,
@@ -348,14 +349,33 @@ mptfc_generate_rport_ids(FCDevicePage0_t
 }
 
 static void
+mptfc_remap_sdev(struct scsi_device *sdev, void *arg)
+{
+	VirtDevice		*vdev;
+	VirtTarget		*vtarget;
+	struct scsi_target	*starget;
+
+	starget = scsi_target(sdev);
+	if (starget->hostdata == arg) {
+		vtarget = arg;
+		vdev = sdev->hostdata;
+		if (vdev) {
+			vdev->bus_id = vtarget->bus_id;
+			vdev->target_id = vtarget->target_id;
+		}
+	}
+}
+
+static void
 mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
 {
 	struct fc_rport_identifiers rport_ids;
 	struct fc_rport		*rport;
 	struct mptfc_rport_info	*ri;
-	int			match = 0;
-	u64			port_name;
+	int			new_ri = 1;
+	u64			pn;
 	unsigned long		flags;
+	VirtTarget		*vtarget;
 
 	if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0)
 		return;
@@ -363,14 +383,14 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int
 	/* scan list looking for a match */
 	spin_lock_irqsave(&ioc->fc_rport_lock, flags);
 	list_for_each_entry(ri, &ioc->fc_rports, list) {
-		port_name = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
-		if (port_name == rport_ids.port_name) {	/* match */
+		pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
+		if (pn == rport_ids.port_name) {	/* match */
 			list_move_tail(&ri->list, &ioc->fc_rports);
-			match = 1;
+			new_ri = 0;
 			break;
 		}
 	}
-	if (!match) {	/* allocate one */
+	if (new_ri) {	/* allocate one */
 		spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
 		ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL);
 		if (!ri)
@@ -382,40 +402,43 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int
 	ri->pg0 = *pg0;	/* add/update pg0 data */
 	ri->flags &= ~MPT_RPORT_INFO_FLAGS_MISSING;
 
+	/* MPT_RPORT_INFO_FLAGS_REGISTERED - rport not previously deleted */
 	if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) {
 		ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED;
 		spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
-		rport = fc_remote_port_add(ioc->sh,channel, &rport_ids);
+		rport = fc_remote_port_add(ioc->sh, channel, &rport_ids);
 		spin_lock_irqsave(&ioc->fc_rport_lock, flags);
 		if (rport) {
-			if (*((struct mptfc_rport_info **)rport->dd_data) != ri) {
-				ri->flags &= ~MPT_RPORT_INFO_FLAGS_MAPPED_VDEV;
-				ri->vdev = NULL;
-				ri->rport = rport;
-				*((struct mptfc_rport_info **)rport->dd_data) = ri;
-			}
-			rport->dev_loss_tmo = mptfc_dev_loss_tmo;
+			ri->rport = rport;
+			if (new_ri) /* may have been reset by user */
+				rport->dev_loss_tmo = mptfc_dev_loss_tmo;
+			*((struct mptfc_rport_info **)rport->dd_data) = ri;
 			/*
 			 * if already mapped, remap here.  If not mapped,
-			 * slave_alloc will allocate vdev and map
+			 * target_alloc will allocate vtarget and map,
+			 * slave_alloc will fill in vdev from vtarget.
 			 */
-			if (ri->flags & MPT_RPORT_INFO_FLAGS_MAPPED_VDEV) {
-				ri->vdev->target_id = ri->pg0.CurrentTargetID;
-				ri->vdev->bus_id = ri->pg0.CurrentBus;
-				ri->vdev->vtarget->target_id = ri->vdev->target_id;
-				ri->vdev->vtarget->bus_id = ri->vdev->bus_id;
+			if (ri->starget) {
+				vtarget = ri->starget->hostdata;
+				if (vtarget) {
+					vtarget->target_id = pg0->CurrentTargetID;
+					vtarget->bus_id = pg0->CurrentBus;
+					starget_for_each_device(ri->starget,
+						vtarget,mptfc_remap_sdev);
+				}
+				ri->remap_needed = 0;
 			}
-			#ifdef MPT_DEBUG
-			printk ("mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
+			dfcprintk ((MYIOC_s_INFO_FMT
+				"mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
 				"rport tid %d, tmo %d\n",
-					ioc->sh->host_no,
+					ioc->name,
+					oc->sh->host_no,
 					pg0->PortIdentifier,
 					pg0->WWNN,
 					pg0->WWPN,
 					pg0->CurrentTargetID,
 					ri->rport->scsi_target_id,
-					ri->rport->dev_loss_tmo);
-			#endif
+					ri->rport->dev_loss_tmo));
 		} else {
 			list_del(&ri->list);
 			kfree(ri);
@@ -427,6 +450,65 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int
 }
 
 /*
+ *	OS entry point to allow for host driver to free allocated memory
+ *	Called if no device present or device being unloaded
+ */
+static void
+mptfc_target_destroy(struct scsi_target *starget)
+{
+	struct fc_rport		*rport;
+	struct mptfc_rport_info *ri;
+
+	rport = starget_to_rport(starget);
+	if (rport) {
+		ri = *((struct mptfc_rport_info **)rport->dd_data);
+		if (ri)	/* better be! */
+			ri->starget = NULL;
+	}
+	if (starget->hostdata)
+		kfree(starget->hostdata);
+	starget->hostdata = NULL;
+}
+
+/*
+ *	OS entry point to allow host driver to alloc memory
+ *	for each scsi target. Called once per device the bus scan.
+ *	Return non-zero if allocation fails.
+ */
+static int
+mptfc_target_alloc(struct scsi_target *starget)
+{
+	VirtTarget		*vtarget;
+	struct fc_rport		*rport;
+	struct mptfc_rport_info *ri;
+	int			rc;
+
+	vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
+	if (!vtarget)
+		return -ENOMEM;
+	starget->hostdata = vtarget;
+
+	rc = -ENODEV;
+	rport = starget_to_rport(starget);
+	if (rport) {
+		ri = *((struct mptfc_rport_info **)rport->dd_data);
+		if (ri) {	/* better be! */
+			vtarget->target_id = ri->pg0.CurrentTargetID;
+			vtarget->bus_id = ri->pg0.CurrentBus;
+			ri->starget = starget;
+			ri->remap_needed = 0;
+			rc = 0;
+		}
+	}
+	if (rc != 0) {
+		kfree(vtarget);
+		starget->hostdata = NULL;
+	}
+
+	return rc;
+}
+
+/*
  *	OS entry point to allow host driver to alloc memory
  *	for each scsi device. Called once per device the bus scan.
  *	Return non-zero if allocation fails.
@@ -440,7 +522,6 @@ mptfc_slave_alloc(struct scsi_device *sd
 	VirtDevice		*vdev;
 	struct scsi_target	*starget;
 	struct fc_rport		*rport;
-	struct mptfc_rport_info *ri;
 	unsigned long		flags;
 
 
@@ -451,55 +532,44 @@ mptfc_slave_alloc(struct scsi_device *sd
 
 	hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
 
-	vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
+	vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
 	if (!vdev) {
 		printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
 				hd->ioc->name, sizeof(VirtDevice));
 		return -ENOMEM;
 	}
-	memset(vdev, 0, sizeof(VirtDevice));
 
 	spin_lock_irqsave(&hd->ioc->fc_rport_lock,flags);
 
-	if (!(ri = *((struct mptfc_rport_info **)rport->dd_data))) {
-		spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);
-		kfree(vdev);
-		return -ENODEV;
-	}
-
 	sdev->hostdata = vdev;
 	starget = scsi_target(sdev);
 	vtarget = starget->hostdata;
+
 	if (vtarget->num_luns == 0) {
+		vtarget->ioc_id = hd->ioc->id;
 		vtarget->tflags = MPT_TARGET_FLAGS_Q_YES |
 		    		  MPT_TARGET_FLAGS_VALID_INQUIRY;
 		hd->Targets[sdev->id] = vtarget;
 	}
 
-	vtarget->target_id = vdev->target_id;
-	vtarget->bus_id = vdev->bus_id;
-
 	vdev->vtarget = vtarget;
 	vdev->ioc_id = hd->ioc->id;
 	vdev->lun = sdev->lun;
-	vdev->target_id = ri->pg0.CurrentTargetID;
-	vdev->bus_id = ri->pg0.CurrentBus;
-
-	ri->flags |= MPT_RPORT_INFO_FLAGS_MAPPED_VDEV;
-	ri->vdev = vdev;
+	vdev->target_id = vtarget->target_id;
+	vdev->bus_id = vtarget->bus_id;
 
 	spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);
 
 	vtarget->num_luns++;
 
-#ifdef MPT_DEBUG
-	printk ("mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
+	dfcprintk ((MYIOC_s_INFO_FMT
+		"mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
 	        "CurrentTargetID %d, %x %llx %llx\n",
-			sdev->host->host_no,
-			vtarget->num_luns,
-			sdev->id, ri->pg0.CurrentTargetID,
-			ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN);
-#endif
+		ioc->name,
+		sdev->host->host_no,
+		vtarget->num_luns,
+		sdev->id, ri->pg0.CurrentTargetID,
+		ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN));
 
 	return 0;
 }
@@ -507,6 +577,7 @@ mptfc_slave_alloc(struct scsi_device *sd
 static int
 mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 {
+	struct mptfc_rport_info	*ri;
 	struct fc_rport	*rport = starget_to_rport(scsi_target(SCpnt->device));
 	int		err;
 
@@ -516,6 +587,10 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void
 		done(SCpnt);
 		return 0;
 	}
+	ri = *((struct mptfc_rport_info **)rport->dd_data);
+	if (unlikely(ri->remap_needed))
+		return SCSI_MLQUEUE_HOST_BUSY;
+
 	return mptscsih_qcmd(SCpnt,done);
 }
 
@@ -591,16 +666,20 @@ mptfc_rescan_devices(void *arg)
 
 				ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
 					       MPT_RPORT_INFO_FLAGS_MISSING);
+				ri->remap_needed = 1;
 				fc_remote_port_delete(ri->rport);
 				/*
 				 * remote port not really deleted 'cause
 				 * binding is by WWPN and driver only
-				 * registers FCP_TARGETs
+				 * registers FCP_TARGETs but cannot trust
+				 * data structures.
 				 */
-				#ifdef MPT_DEBUG
-				printk ("mptfc_rescan.%d: %llx deleted\n",
-					ioc->sh->host_no, ri->pg0.WWPN);
-				#endif
+				ri->rport = NULL;
+				dfcprintk ((MYIOC_s_INFO_FMT
+					"mptfc_rescan.%d: %llx deleted\n",
+					ioc->name,
+					ioc->sh->host_no,
+					ri->pg0.WWPN));
 			}
 		}
 		spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
@@ -872,9 +951,8 @@ mptfc_init(void)
 	}
 
 	error = pci_register_driver(&mptfc_driver);
-	if (error) {
+	if (error)
 		fc_release_transport(mptfc_transport_template);
-	}
 
 	return error;
 }
@@ -885,7 +963,8 @@ mptfc_init(void)
  *	@pdev: Pointer to pci_dev structure
  *
  */
-static void __devexit mptfc_remove(struct pci_dev *pdev)
+static void __devexit
+mptfc_remove(struct pci_dev *pdev)
 {
 	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
 	struct mptfc_rport_info *p, *n;
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 5a06d8d..2512d0e 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -89,6 +89,8 @@ static int	mptsasMgmtCtx = -1;
 enum mptsas_hotplug_action {
 	MPTSAS_ADD_DEVICE,
 	MPTSAS_DEL_DEVICE,
+	MPTSAS_ADD_RAID,
+	MPTSAS_DEL_RAID,
 };
 
 struct mptsas_hotplug_event {
@@ -114,6 +116,7 @@ struct mptsas_hotplug_event {
 
 struct mptsas_devinfo {
 	u16	handle;		/* unique id to address this device */
+	u16	handle_parent;	/* unique id to address parent device */
 	u8	phy_id;		/* phy number of parent device */
 	u8	port_id;	/* sas physical port this device
 				   is assoc'd with */
@@ -301,9 +304,8 @@ mptsas_slave_alloc(struct scsi_device *s
 	}
 	mutex_unlock(&hd->ioc->sas_topology_mutex);
 
-	printk("No matching SAS device found!!\n");
 	kfree(vdev);
-	return -ENODEV;
+	return -ENXIO;
 
  out:
 	vtarget->ioc_id = vdev->ioc_id;
@@ -321,6 +323,7 @@ mptsas_slave_destroy(struct scsi_device 
 	struct sas_rphy *rphy;
 	struct mptsas_portinfo *p;
 	int i;
+	VirtDevice *vdev;
 
 	/*
 	 * Handle hotplug removal case.
@@ -344,8 +347,29 @@ mptsas_slave_destroy(struct scsi_device 
  out:
 	mutex_unlock(&hd->ioc->sas_topology_mutex);
 	/*
-	 * TODO: Issue target reset to flush firmware outstanding commands.
+	 * Issue target reset to flush firmware outstanding commands.
 	 */
+	vdev = sdev->hostdata;
+	if (vdev->configured_lun){
+		if (mptscsih_TMHandler(hd,
+		     MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
+		     vdev->bus_id,
+		     vdev->target_id,
+		     0, 0, 5 /* 5 second timeout */)
+		     < 0){
+
+			/* The TM request failed!
+			 * Fatal error case.
+			 */
+			printk(MYIOC_s_WARN_FMT
+		       "Error processing TaskMgmt id=%d TARGET_RESET\n",
+				hd->ioc->name,
+				vdev->target_id);
+
+			hd->tmPending = 0;
+			hd->tmState = TM_STATE_NONE;
+		}
+	}
 	mptscsih_slave_destroy(sdev);
 }
 
@@ -714,6 +738,7 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, 
 	mptsas_print_device_pg0(buffer);
 
 	device_info->handle = le16_to_cpu(buffer->DevHandle);
+	device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
 	device_info->phy_id = buffer->PhyNum;
 	device_info->port_id = buffer->PhysicalPort;
 	device_info->id = buffer->TargetID;
@@ -863,6 +888,26 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc
 	return error;
 }
 
+/*
+ * Returns true if there is a scsi end device
+ */
+static inline int
+mptsas_is_end_device(struct mptsas_devinfo * attached)
+{
+	if ((attached->handle) &&
+	    (attached->device_info &
+	    MPI_SAS_DEVICE_INFO_END_DEVICE) &&
+	    ((attached->device_info &
+	    MPI_SAS_DEVICE_INFO_SSP_TARGET) |
+	    (attached->device_info &
+	    MPI_SAS_DEVICE_INFO_STP_TARGET) |
+	    (attached->device_info &
+	    MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
+		return 1;
+	else
+		return 0;
+}
+
 static void
 mptsas_parse_device_info(struct sas_identify *identify,
 		struct mptsas_devinfo *device_info)
@@ -1227,7 +1272,7 @@ mptsas_find_phyinfo_by_parent(MPT_ADAPTE
 }
 
 static struct mptsas_phyinfo *
-mptsas_find_phyinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
+mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id)
 {
 	struct mptsas_portinfo *port_info;
 	struct mptsas_phyinfo *phy_info = NULL;
@@ -1239,12 +1284,12 @@ mptsas_find_phyinfo_by_handle(MPT_ADAPTE
 	 */
 	mutex_lock(&ioc->sas_topology_mutex);
 	list_for_each_entry(port_info, &ioc->sas_topology, list) {
-		for (i = 0; i < port_info->num_phys; i++) {
-			if (port_info->phy_info[i].attached.handle == handle) {
-				phy_info = &port_info->phy_info[i];
-				break;
-			}
-		}
+		for (i = 0; i < port_info->num_phys; i++)
+			if (mptsas_is_end_device(&port_info->phy_info[i].attached))
+				if (port_info->phy_info[i].attached.id == id) {
+					phy_info = &port_info->phy_info[i];
+					break;
+				}
 	}
 	mutex_unlock(&ioc->sas_topology_mutex);
 
@@ -1258,36 +1303,58 @@ mptsas_hotplug_work(void *arg)
 	MPT_ADAPTER *ioc = ev->ioc;
 	struct mptsas_phyinfo *phy_info;
 	struct sas_rphy *rphy;
+	struct scsi_device *sdev;
 	char *ds = NULL;
-
-	if (ev->device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
-		ds = "ssp";
-	if (ev->device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
-		ds = "stp";
-	if (ev->device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
-		ds = "sata";
+	struct mptsas_devinfo sas_device;
 
 	switch (ev->event_type) {
 	case MPTSAS_DEL_DEVICE:
-		printk(MYIOC_s_INFO_FMT
-		       "removing %s device, channel %d, id %d, phy %d\n",
-		       ioc->name, ds, ev->channel, ev->id, ev->phy_id);
 
-		phy_info = mptsas_find_phyinfo_by_handle(ioc, ev->handle);
+		phy_info = mptsas_find_phyinfo_by_target(ioc, ev->id);
 		if (!phy_info) {
 			printk("mptsas: remove event for non-existant PHY.\n");
 			break;
 		}
 
+		if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
+			ds = "ssp";
+		if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
+			ds = "stp";
+		if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
+			ds = "sata";
+
+		printk(MYIOC_s_INFO_FMT
+		       "removing %s device, channel %d, id %d, phy %d\n",
+		       ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
+
 		if (phy_info->rphy) {
 			sas_rphy_delete(phy_info->rphy);
 			phy_info->rphy = NULL;
 		}
 		break;
 	case MPTSAS_ADD_DEVICE:
-		printk(MYIOC_s_INFO_FMT
-		       "attaching %s device, channel %d, id %d, phy %d\n",
-		       ioc->name, ds, ev->channel, ev->id, ev->phy_id);
+
+		/*
+		 * When there is no sas address,
+		 * RAID volumes are being deleted,
+		 * and hidden phy disk are being added.
+		 * We don't know the SAS data yet,
+		 * so lookup sas device page to get
+		 * pertaining info
+		 */
+		if (!ev->sas_address) {
+			if (mptsas_sas_device_pg0(ioc,
+			    &sas_device, ev->id,
+			    (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
+			     MPI_SAS_DEVICE_PGAD_FORM_SHIFT)))
+				break;
+			ev->handle = sas_device.handle;
+			ev->parent_handle = sas_device.handle_parent;
+			ev->channel = sas_device.channel;
+			ev->phy_id = sas_device.phy_id;
+			ev->sas_address = sas_device.sas_address;
+			ev->device_info = sas_device.device_info;
+		}
 
 		phy_info = mptsas_find_phyinfo_by_parent(ioc,
 				ev->parent_handle, ev->phy_id);
@@ -1310,10 +1377,23 @@ mptsas_hotplug_work(void *arg)
 		phy_info->attached.sas_address = ev->sas_address;
 		phy_info->attached.device_info = ev->device_info;
 
+		if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
+			ds = "ssp";
+		if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
+			ds = "stp";
+		if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
+			ds = "sata";
+
+		printk(MYIOC_s_INFO_FMT
+		       "attaching %s device, channel %d, id %d, phy %d\n",
+		       ioc->name, ds, ev->channel, ev->id, ev->phy_id);
+
+
 		rphy = sas_rphy_alloc(phy_info->phy);
 		if (!rphy)
 			break; /* non-fatal: an rphy can be added later */
 
+		rphy->scsi_target_id = phy_info->attached.id;
 		mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
 		if (sas_rphy_add(rphy)) {
 			sas_rphy_free(rphy);
@@ -1322,6 +1402,40 @@ mptsas_hotplug_work(void *arg)
 
 		phy_info->rphy = rphy;
 		break;
+	case MPTSAS_ADD_RAID:
+		sdev = scsi_device_lookup(
+			ioc->sh,
+			ioc->num_ports,
+			ev->id,
+			0);
+		if (sdev) {
+			scsi_device_put(sdev);
+			break;
+		}
+		printk(MYIOC_s_INFO_FMT
+		       "attaching device, channel %d, id %d\n",
+		       ioc->name, ioc->num_ports, ev->id);
+		scsi_add_device(ioc->sh,
+			ioc->num_ports,
+			ev->id,
+			0);
+		mpt_findImVolumes(ioc);
+		break;
+	case MPTSAS_DEL_RAID:
+		sdev = scsi_device_lookup(
+			ioc->sh,
+			ioc->num_ports,
+			ev->id,
+			0);
+		if (!sdev)
+			break;
+		printk(MYIOC_s_INFO_FMT
+		       "removing device, channel %d, id %d\n",
+		       ioc->name, ioc->num_ports, ev->id);
+		scsi_remove_device(sdev);
+		scsi_device_put(sdev);
+		mpt_findImVolumes(ioc);
+		break;
 	}
 
 	kfree(ev);
@@ -1372,23 +1486,94 @@ mptscsih_send_sas_event(MPT_ADAPTER *ioc
 	schedule_work(&ev->work);
 }
 
+static void
+mptscsih_send_raid_event(MPT_ADAPTER *ioc,
+		EVENT_DATA_RAID *raid_event_data)
+{
+	struct mptsas_hotplug_event *ev;
+	RAID_VOL0_STATUS * volumeStatus;
+
+	if (ioc->bus_type != SAS)
+		return;
+
+	ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
+	if (!ev) {
+		printk(KERN_WARNING "mptsas: lost hotplug event\n");
+		return;
+	}
+
+	memset(ev,0,sizeof(struct mptsas_hotplug_event));
+	INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
+	ev->ioc = ioc;
+	ev->id = raid_event_data->VolumeID;
+
+	switch (raid_event_data->ReasonCode) {
+	case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
+		ev->event_type = MPTSAS_ADD_DEVICE;
+		break;
+	case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
+		ev->event_type = MPTSAS_DEL_DEVICE;
+		break;
+	case MPI_EVENT_RAID_RC_VOLUME_DELETED:
+		ev->event_type = MPTSAS_DEL_RAID;
+		break;
+	case MPI_EVENT_RAID_RC_VOLUME_CREATED:
+		ev->event_type = MPTSAS_ADD_RAID;
+		break;
+	case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
+		volumeStatus = (RAID_VOL0_STATUS *) &
+		    raid_event_data->SettingsStatus;
+		ev->event_type = (volumeStatus->State ==
+		    MPI_RAIDVOL0_STATUS_STATE_FAILED) ?
+		    MPTSAS_DEL_RAID : MPTSAS_ADD_RAID;
+		break;
+	default:
+		break;
+	}
+	schedule_work(&ev->work);
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* work queue thread to clear the persitency table */
+static void
+mptscsih_sas_persist_clear_table(void * arg)
+{
+	MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
+
+	mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
+}
+
 static int
 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
 {
+	int rc=1;
 	u8 event = le32_to_cpu(reply->Event) & 0xFF;
 
 	if (!ioc->sh)
-		return 1;
+		goto out;
 
 	switch (event) {
 	case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
 		mptscsih_send_sas_event(ioc,
 			(EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);
-		return 1;		/* currently means nothing really */
-
+		break;
+	case MPI_EVENT_INTEGRATED_RAID:
+		mptscsih_send_raid_event(ioc,
+			(EVENT_DATA_RAID *)reply->Data);
+		break;
+	case MPI_EVENT_PERSISTENT_TABLE_FULL:
+		INIT_WORK(&ioc->mptscsih_persistTask,
+		    mptscsih_sas_persist_clear_table,
+		    (void *)ioc);
+		schedule_work(&ioc->mptscsih_persistTask);
+		break;
 	default:
-		return mptscsih_event_process(ioc, reply);
+		rc = mptscsih_event_process(ioc, reply);
+		break;
 	}
+ out:
+
+	return rc;
 }
 
 static int
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index cdac557..05789e5 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -144,7 +144,6 @@ static int	mptscsih_tm_pending_wait(MPT_
 static int	mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
 static u32	SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
 
-static int	mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
 static int	mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
 
 int		mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
@@ -159,11 +158,9 @@ static int	mptscsih_writeIOCPage4(MPT_SC
 int		mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
 static int	mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
 static void	mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
-static void	mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget);
+static void	mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
 static int	mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
 
-static struct work_struct   mptscsih_persistTask;
-
 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
 static int	mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
 static void	mptscsih_domainValidation(void *hd);
@@ -563,11 +560,24 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_F
 	MPT_SCSI_HOST	*hd;
 	SCSIIORequest_t	*pScsiReq;
 	SCSIIOReply_t	*pScsiReply;
-	u16		 req_idx;
+	u16		 req_idx, req_idx_MR;
 
 	hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
 
 	req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
+	req_idx_MR = (mr != NULL) ?
+	    le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
+	if ((req_idx != req_idx_MR) ||
+	    (mf->u.frame.linkage.arg1 == 0xdeadbeaf)) {
+		printk(MYIOC_s_ERR_FMT "Received a mf that was already freed\n",
+		    ioc->name);
+		printk (MYIOC_s_ERR_FMT
+		    "req_idx=%x req_idx_MR=%x mf=%p mr=%p sc=%p\n",
+		    ioc->name, req_idx, req_idx_MR, mf, mr,
+		    hd->ScsiLookup[req_idx_MR]);
+		return 0;
+	}
+
 	sc = hd->ScsiLookup[req_idx];
 	if (sc == NULL) {
 		MPIHeader_t *hdr = (MPIHeader_t *)mf;
@@ -730,6 +740,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_F
 
 			break;
 
+		case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:		/* 0x0044 */
+			sc->resid=0;
 		case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
 		case MPI_IOCSTATUS_SUCCESS:			/* 0x0000 */
 			if (scsi_status == MPI_SCSI_STATUS_BUSY)
@@ -789,7 +801,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_F
 		case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:	/* 0x0006 */
 		case MPI_IOCSTATUS_INVALID_FIELD:		/* 0x0007 */
 		case MPI_IOCSTATUS_INVALID_STATE:		/* 0x0008 */
-		case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:		/* 0x0044 */
 		case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */
 		case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:	/* 0x004A */
 		default:
@@ -1530,7 +1541,7 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *i
  *
  *	Returns 0 for SUCCESS or -1 if FAILED.
  */
-static int
+int
 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
 {
 	MPT_ADAPTER	*ioc;
@@ -1721,6 +1732,20 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd
 	return retval;
 }
 
+static int
+mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
+{
+	switch (ioc->bus_type) {
+	case FC:
+		return 40;
+	case SAS:
+		return 10;
+	case SPI:
+	default:
+		return 2;
+	}
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *	mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
@@ -1792,7 +1817,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
 	vdev = SCpnt->device->hostdata;
 	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
 		vdev->bus_id, vdev->target_id, vdev->lun,
-		ctx2abort, 2 /* 2 second timeout */);
+		ctx2abort, mptscsih_get_tm_timeout(ioc));
 
 	printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
 		hd->ioc->name,
@@ -1843,7 +1868,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SC
 	vdev = SCpnt->device->hostdata;
 	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
 		vdev->bus_id, vdev->target_id,
-		0, 0, 5 /* 5 second timeout */);
+		0, 0, mptscsih_get_tm_timeout(hd->ioc));
 
 	printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
 		hd->ioc->name,
@@ -1893,7 +1918,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SC
 
 	vdev = SCpnt->device->hostdata;
 	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
-		vdev->bus_id, 0, 0, 0, 5 /* 5 second timeout */);
+		vdev->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
 
 	printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
 		hd->ioc->name,
@@ -2016,6 +2041,42 @@ mptscsih_tm_wait_for_completion(MPT_SCSI
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+static void
+mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
+{
+	char *desc;
+
+	switch (response_code) {
+	case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
+		desc = "The task completed.";
+		break;
+	case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
+		desc = "The IOC received an invalid frame status.";
+		break;
+	case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
+		desc = "The task type is not supported.";
+		break;
+	case MPI_SCSITASKMGMT_RSP_TM_FAILED:
+		desc = "The requested task failed.";
+		break;
+	case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
+		desc = "The task completed successfully.";
+		break;
+	case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
+		desc = "The LUN request is invalid.";
+		break;
+	case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
+		desc = "The task is in the IOC queue and has not been sent to target.";
+		break;
+	default:
+		desc = "unknown";
+		break;
+	}
+	printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
+		ioc->name, response_code, desc);
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *	mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
  *	@ioc: Pointer to MPT_ADAPTER structure
@@ -2064,6 +2125,11 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *
 		/* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
 		tmType = pScsiTmReq->TaskType;
 
+		if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
+		    pScsiTmReply->ResponseCode)
+			mptscsih_taskmgmt_response_code(ioc,
+			    pScsiTmReply->ResponseCode);
+
 		dtmprintk((MYIOC_s_WARN_FMT "  TaskType = %d, TerminationCount=%d\n",
 				ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
 		DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
@@ -2255,7 +2321,7 @@ mptscsih_slave_destroy(struct scsi_devic
 	vtarget->luns[0] &= ~(1 << vdevice->lun);
 	vtarget->num_luns--;
 	if (vtarget->num_luns == 0) {
-		mptscsih_negotiate_to_asyn_narrow(hd, vtarget);
+		mptscsih_negotiate_to_asyn_narrow(hd, vdevice);
 		if (hd->ioc->bus_type == SPI) {
 			if (mptscsih_is_phys_disk(hd->ioc, vtarget->target_id)) {
 				hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
@@ -2585,16 +2651,6 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* work queue thread to clear the persitency table */
-static void
-mptscsih_sas_persist_clear_table(void * arg)
-{
-	MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
-
-	mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 int
 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
 {
@@ -2656,13 +2712,6 @@ mptscsih_event_process(MPT_ADAPTER *ioc,
 		break;
 	}
 
-	/* Persistent table is full. */
-	case MPI_EVENT_PERSISTENT_TABLE_FULL:
-		INIT_WORK(&mptscsih_persistTask,
-		    mptscsih_sas_persist_clear_table,(void *)ioc);
-		schedule_work(&mptscsih_persistTask);
-		break;
-
 	case MPI_EVENT_NONE:				/* 00 */
 	case MPI_EVENT_LOG_DATA:			/* 01 */
 	case MPI_EVENT_STATE_CHANGE:			/* 02 */
@@ -3863,8 +3912,9 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTER
  *
  */
 static void
-mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget)
+mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
 {
+	VirtTarget		*vtarget = vdevice->vtarget;
 	MPT_ADAPTER		*ioc= hd->ioc;
 	SCSIDevicePage1_t	*pcfg1Data;
 	CONFIGPARMS		 cfg;
@@ -3874,7 +3924,8 @@ mptscsih_negotiate_to_asyn_narrow(MPT_SC
 	int			 requested, configuration, data,i;
 	u8			 flags, factor;
 
-	if (ioc->bus_type != SPI)
+	if ((ioc->bus_type != SPI) ||
+		(!vdevice->configured_lun))
 		return;
 
 	if (!ioc->spi_data.sdp1length)
@@ -3910,7 +3961,7 @@ mptscsih_negotiate_to_asyn_narrow(MPT_SC
 			}
 			mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
 				&configuration, flags);
-			dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
+			dnegoprintk(("nego asyn narrow: id=%d width=0 factor=MPT_ASYNC "
 				"offset=0 negoFlags=%x request=%x config=%x\n",
 				id, flags, requested, configuration));
 			pcfg1Data->RequestedParameters = cpu_to_le32(requested);
@@ -3923,7 +3974,7 @@ mptscsih_negotiate_to_asyn_narrow(MPT_SC
 		flags = vtarget->negoFlags;
 		mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
 				&configuration, flags);
-		dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
+		dnegoprintk(("nego asyn narrow: id=%d width=0 factor=MPT_ASYNC "
 			"offset=0 negoFlags=%x request=%x config=%x\n",
 			vtarget->target_id, flags, requested, configuration));
 		pcfg1Data->RequestedParameters = cpu_to_le32(requested);
@@ -5620,5 +5671,6 @@ EXPORT_SYMBOL(mptscsih_event_process);
 EXPORT_SYMBOL(mptscsih_ioc_reset);
 EXPORT_SYMBOL(mptscsih_change_queue_depth);
 EXPORT_SYMBOL(mptscsih_timer_expired);
+EXPORT_SYMBOL(mptscsih_TMHandler);
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index d3cba12..44b248d 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -108,3 +108,4 @@ extern int mptscsih_event_process(MPT_AD
 extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
 extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth);
 extern void mptscsih_timer_expired(unsigned long data);
+extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 7dce292..f148dfa 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -384,6 +384,14 @@ mptspi_probe(struct pci_dev *pdev, const
 		goto out_mptspi_probe;
 	}
 
+	/*
+	 * issue internal bus reset
+	 */
+	if (ioc->spi_data.bus_reset)
+		mptscsih_TMHandler(hd,
+		    MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
+		    0, 0, 0, 0, 5);
+
 	scsi_scan_host(sh);
 	return 0;
 
@@ -445,7 +453,7 @@ static void __exit
 mptspi_exit(void)
 {
 	pci_unregister_driver(&mptspi_driver);
-	
+
 	mpt_reset_deregister(mptspiDoneCtx);
 	dprintk((KERN_INFO MYNAM
 	  ": Deregistered for IOC reset notifications\n"));
diff --git a/drivers/misc/ibmasm/uart.c b/drivers/misc/ibmasm/uart.c
index 7e98434..9783caf 100644
--- a/drivers/misc/ibmasm/uart.c
+++ b/drivers/misc/ibmasm/uart.c
@@ -50,7 +50,7 @@ void ibmasm_register_uart(struct service
 	memset(&uport, 0, sizeof(struct uart_port));
 	uport.irq	= sp->irq;
 	uport.uartclk	= 3686400;
-	uport.flags	= UPF_AUTOPROBE | UPF_SHARE_IRQ;
+	uport.flags	= UPF_SHARE_IRQ;
 	uport.iotype	= UPIO_MEM;
 	uport.membase	= iomem_base;
 
diff --git a/drivers/mtd/maps/tsunami_flash.c b/drivers/mtd/maps/tsunami_flash.c
index 9e21e6c..0f915ac 100644
--- a/drivers/mtd/maps/tsunami_flash.c
+++ b/drivers/mtd/maps/tsunami_flash.c
@@ -62,7 +62,7 @@ static void tsunami_flash_copy_to(
 static struct map_info tsunami_flash_map = {
 	.name = "flash chip on the Tsunami TIG bus",
 	.size = MAX_TIG_FLASH_SIZE,
-	.phys = NO_XIP;
+	.phys = NO_XIP,
 	.bankwidth = 1,
 	.read = tsunami_flash_read8,
 	.copy_from = tsunami_flash_copy_from,
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 1421941..6a6a084 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -7,6 +7,7 @@ menu "Network device support"
 
 config NETDEVICES
 	depends on NET
+	default y if UML
 	bool "Network device support"
 	---help---
 	  You can say N here if you don't intend to connect your Linux box to
@@ -1914,6 +1915,15 @@ config E1000_NAPI
 
 	  If in doubt, say N.
 
+config E1000_DISABLE_PACKET_SPLIT
+	bool "Disable Packet Split for PCI express adapters"
+	depends on E1000
+	help
+	  Say Y here if you want to use the legacy receive path for PCI express
+	  hadware.
+
+	  If in doubt, say N.
+
 source "drivers/net/ixp2000/Kconfig"
 
 config MYRI_SBUS
@@ -2024,13 +2034,28 @@ config SKGE
 	  It does not support the link failover and network management 
 	  features that "portable" vendor supplied sk98lin driver does.
 
+	  This driver supports adapters based on the original Yukon chipset:
+	  Marvell 88E8001, Belkin F5D5005, CNet GigaCard, DLink DGE-530T,
+	  Linksys EG1032/EG1064, 3Com 3C940/3C940B, SysKonnect SK-9871/9872.
+
+	  It does not support the newer Yukon2 chipset: a separate driver,
+	  sky2, is provided for Yukon2-based adapters.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called skge.  This is recommended.
 
 config SKY2
 	tristate "SysKonnect Yukon2 support (EXPERIMENTAL)"
 	depends on PCI && EXPERIMENTAL
 	select CRC32
 	---help---
-	  This driver support the Marvell Yukon 2 Gigabit Ethernet adapter.
+	  This driver supports Gigabit Ethernet adapters based on the the
+	  Marvell Yukon 2 chipset:
+	  Marvell 88E8021/88E8022/88E8035/88E8036/88E8038/88E8050/88E8052/
+	  88E8053/88E8055/88E8061/88E8062, SysKonnect SK-9E21D/SK-9S21
+
+	  This driver does not support the original Yukon chipset: a seperate
+	  driver, skge, is provided for Yukon-based adapters.
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called sky2.  This is recommended.
@@ -2040,8 +2065,15 @@ config SK98LIN
 	depends on PCI
 	---help---
 	  Say Y here if you have a Marvell Yukon or SysKonnect SK-98xx/SK-95xx
-	  compliant Gigabit Ethernet Adapter. The following adapters are supported
-	  by this driver:
+	  compliant Gigabit Ethernet Adapter.
+
+	  This driver supports the original Yukon chipset. A cleaner driver is 
+	  also available (skge) which seems to work better than this one.
+
+	  This driver does not support the newer Yukon2 chipset. A seperate
+	  driver, sky2, is provided to support Yukon2-based adapters.
+
+	  The following adapters are supported by this driver:
 	    - 3Com 3C940 Gigabit LOM Ethernet Adapter
 	    - 3Com 3C941 Gigabit LOM Ethernet Adapter
 	    - Allied Telesyn AT-2970LX Gigabit Ethernet Adapter
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index b8953de..b508812 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -1002,6 +1002,8 @@ static int __devinit ace_init(struct net
 
 	mac1 = 0;
 	for(i = 0; i < 4; i++) {
+		int tmp;
+
 		mac1 = mac1 << 8;
 		tmp = read_eeprom_byte(dev, 0x8c+i);
 		if (tmp < 0) {
@@ -1012,6 +1014,8 @@ static int __devinit ace_init(struct net
 	}
 	mac2 = 0;
 	for(i = 4; i < 8; i++) {
+		int tmp;
+
 		mac2 = mac2 << 8;
 		tmp = read_eeprom_byte(dev, 0x8c+i);
 		if (tmp < 0) {
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 7aa49b9..c3267e4 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1399,7 +1399,6 @@ static int b44_open(struct net_device *d
 	b44_init_rings(bp);
 	b44_init_hw(bp);
 
-	netif_carrier_off(dev);
 	b44_check_phy(bp);
 
 	err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev);
@@ -1464,7 +1463,7 @@ static int b44_close(struct net_device *
 #endif
 	b44_halt(bp);
 	b44_free_rings(bp);
-	netif_carrier_off(bp->dev);
+	netif_carrier_off(dev);
 
 	spin_unlock_irq(&bp->lock);
 
@@ -2000,6 +1999,8 @@ static int __devinit b44_init_one(struct
 	dev->irq = pdev->irq;
 	SET_ETHTOOL_OPS(dev, &b44_ethtool_ops);
 
+	netif_carrier_off(dev);
+
 	err = b44_get_invariants(bp);
 	if (err) {
 		printk(KERN_ERR PFX "Problem fetching invariants of chip, "
@@ -2136,7 +2137,7 @@ static int __init b44_init(void)
 
 	/* Setup paramaters for syncing RX/TX DMA descriptors */
 	dma_desc_align_mask = ~(dma_desc_align_size - 1);
-	dma_desc_sync_size = max(dma_desc_align_size, sizeof(struct dma_desc));
+	dma_desc_sync_size = max_t(unsigned int, dma_desc_align_size, sizeof(struct dma_desc));
 
 	return pci_module_init(&b44_driver);
 }
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 49fa1e4..a24200d 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -1,6 +1,6 @@
 /* bnx2.c: Broadcom NX2 network driver.
  *
- * Copyright (c) 2004, 2005 Broadcom Corporation
+ * Copyright (c) 2004, 2005, 2006 Broadcom Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -14,8 +14,8 @@
 
 #define DRV_MODULE_NAME		"bnx2"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"1.4.30"
-#define DRV_MODULE_RELDATE	"October 11, 2005"
+#define DRV_MODULE_VERSION	"1.4.31"
+#define DRV_MODULE_RELDATE	"January 19, 2006"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -316,6 +316,10 @@ bnx2_enable_int(struct bnx2 *bp)
 	u32 val;
 
 	REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
+	       BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
+	       BNX2_PCICFG_INT_ACK_CMD_MASK_INT | bp->last_status_idx);
+
+	REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
 	       BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | bp->last_status_idx);
 
 	val = REG_RD(bp, BNX2_HC_COMMAND);
@@ -1171,7 +1175,8 @@ bnx2_init_5708s_phy(struct bnx2 *bp)
 	}
 
 	if ((CHIP_ID(bp) == CHIP_ID_5708_A0) ||
-	    (CHIP_ID(bp) == CHIP_ID_5708_B0)) {
+	    (CHIP_ID(bp) == CHIP_ID_5708_B0) ||
+	    (CHIP_ID(bp) == CHIP_ID_5708_B1)) {
 		/* increase tx signal amplitude */
 		bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
 			       BCM5708S_BLK_ADDR_TX_MISC);
@@ -1326,44 +1331,78 @@ bnx2_set_mac_loopback(struct bnx2 *bp)
 	return 0;
 }
 
+static int bnx2_test_link(struct bnx2 *);
+
 static int
-bnx2_fw_sync(struct bnx2 *bp, u32 msg_data)
+bnx2_set_phy_loopback(struct bnx2 *bp)
+{
+	u32 mac_mode;
+	int rc, i;
+
+	spin_lock_bh(&bp->phy_lock);
+	rc = bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX |
+			    BMCR_SPEED1000);
+	spin_unlock_bh(&bp->phy_lock);
+	if (rc)
+		return rc;
+
+	for (i = 0; i < 10; i++) {
+		if (bnx2_test_link(bp) == 0)
+			break;
+		udelay(10);
+	}
+
+	mac_mode = REG_RD(bp, BNX2_EMAC_MODE);
+	mac_mode &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX |
+		      BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK |
+		      BNX2_EMAC_MODE_25G);
+
+	mac_mode |= BNX2_EMAC_MODE_PORT_GMII;
+	REG_WR(bp, BNX2_EMAC_MODE, mac_mode);
+	bp->link_up = 1;
+	return 0;
+}
+
+static int
+bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int silent)
 {
 	int i;
 	u32 val;
 
-	if (bp->fw_timed_out)
-		return -EBUSY;
-
 	bp->fw_wr_seq++;
 	msg_data |= bp->fw_wr_seq;
 
 	REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data);
 
 	/* wait for an acknowledgement. */
-	for (i = 0; i < (FW_ACK_TIME_OUT_MS * 1000)/5; i++) {
-		udelay(5);
+	for (i = 0; i < (FW_ACK_TIME_OUT_MS / 10); i++) {
+		msleep(10);
 
 		val = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_MB);
 
 		if ((val & BNX2_FW_MSG_ACK) == (msg_data & BNX2_DRV_MSG_SEQ))
 			break;
 	}
+	if ((msg_data & BNX2_DRV_MSG_DATA) == BNX2_DRV_MSG_DATA_WAIT0)
+		return 0;
 
 	/* If we timed out, inform the firmware that this is the case. */
-	if (((val & BNX2_FW_MSG_ACK) != (msg_data & BNX2_DRV_MSG_SEQ)) &&
-		((msg_data & BNX2_DRV_MSG_DATA) != BNX2_DRV_MSG_DATA_WAIT0)) {
+	if ((val & BNX2_FW_MSG_ACK) != (msg_data & BNX2_DRV_MSG_SEQ)) {
+		if (!silent)
+			printk(KERN_ERR PFX "fw sync timeout, reset code = "
+					    "%x\n", msg_data);
 
 		msg_data &= ~BNX2_DRV_MSG_CODE;
 		msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT;
 
 		REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data);
 
-		bp->fw_timed_out = 1;
-
 		return -EBUSY;
 	}
 
+	if ((val & BNX2_FW_MSG_STATUS_MASK) != BNX2_FW_MSG_STATUS_OK)
+		return -EIO;
+
 	return 0;
 }
 
@@ -1657,7 +1696,7 @@ bnx2_rx_int(struct bnx2 *bp, int budget)
 	rmb();
 	while (sw_cons != hw_cons) {
 		unsigned int len;
-		u16 status;
+		u32 status;
 		struct sw_bd *rx_buf;
 		struct sk_buff *skb;
 
@@ -1673,7 +1712,7 @@ bnx2_rx_int(struct bnx2 *bp, int budget)
 		rx_hdr = (struct l2_fhdr *) skb->data;
 		len = rx_hdr->l2_fhdr_pkt_len - 4;
 
-		if (rx_hdr->l2_fhdr_errors &
+		if ((status = rx_hdr->l2_fhdr_status) &
 			(L2_FHDR_ERRORS_BAD_CRC |
 			L2_FHDR_ERRORS_PHY_DECODE |
 			L2_FHDR_ERRORS_ALIGNMENT |
@@ -1732,15 +1771,13 @@ reuse_rx:
 
 		}
 
-		status = rx_hdr->l2_fhdr_status;
 		skb->ip_summed = CHECKSUM_NONE;
 		if (bp->rx_csum &&
 			(status & (L2_FHDR_STATUS_TCP_SEGMENT |
 			L2_FHDR_STATUS_UDP_DATAGRAM))) {
 
-			u16 cksum = rx_hdr->l2_fhdr_tcp_udp_xsum;
-
-			if (cksum == 0xffff)
+			if (likely((status & (L2_FHDR_ERRORS_TCP_XSUM |
+					      L2_FHDR_ERRORS_UDP_XSUM)) == 0))
 				skb->ip_summed = CHECKSUM_UNNECESSARY;
 		}
 
@@ -1794,7 +1831,7 @@ static irqreturn_t
 bnx2_msi(int irq, void *dev_instance, struct pt_regs *regs)
 {
 	struct net_device *dev = dev_instance;
-	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	prefetch(bp->status_blk);
 	REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
@@ -1814,7 +1851,7 @@ static irqreturn_t
 bnx2_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
 {
 	struct net_device *dev = dev_instance;
-	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	/* When using INTx, it is possible for the interrupt to arrive
 	 * at the CPU before the status block posted prior to the
@@ -1859,7 +1896,7 @@ bnx2_has_work(struct bnx2 *bp)
 static int
 bnx2_poll(struct net_device *dev, int *budget)
 {
-	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	if ((bp->status_blk->status_attn_bits &
 		STATUS_ATTN_BITS_LINK_STATE) !=
@@ -1891,9 +1928,20 @@ bnx2_poll(struct net_device *dev, int *b
 
 	if (!bnx2_has_work(bp)) {
 		netif_rx_complete(dev);
+		if (likely(bp->flags & USING_MSI_FLAG)) {
+			REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
+			       BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
+			       bp->last_status_idx);
+			return 0;
+		}
 		REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
-			BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
-			bp->last_status_idx);
+		       BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
+		       BNX2_PCICFG_INT_ACK_CMD_MASK_INT |
+		       bp->last_status_idx);
+
+		REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
+		       BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
+		       bp->last_status_idx);
 		return 0;
 	}
 
@@ -1906,7 +1954,7 @@ bnx2_poll(struct net_device *dev, int *b
 static void
 bnx2_set_rx_mode(struct net_device *dev)
 {
-	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 	u32 rx_mode, sort_mode;
 	int i;
 
@@ -1916,11 +1964,11 @@ bnx2_set_rx_mode(struct net_device *dev)
 				  BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG);
 	sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN;
 #ifdef BCM_VLAN
-	if (!bp->vlgrp) {
+	if (!bp->vlgrp && !(bp->flags & ASF_ENABLE_FLAG))
 		rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
-	}
 #else
-	rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
+	if (!(bp->flags & ASF_ENABLE_FLAG))
+		rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
 #endif
 	if (dev->flags & IFF_PROMISC) {
 		/* Promiscuous mode. */
@@ -2338,7 +2386,6 @@ bnx2_set_power_state(struct bnx2 *bp, pc
 			val |= BNX2_EMAC_MODE_PORT_MII |
 			       BNX2_EMAC_MODE_MPKT_RCVD |
 			       BNX2_EMAC_MODE_ACPI_RCVD |
-			       BNX2_EMAC_MODE_FORCE_LINK |
 			       BNX2_EMAC_MODE_MPKT;
 
 			REG_WR(bp, BNX2_EMAC_MODE, val);
@@ -2374,7 +2421,8 @@ bnx2_set_power_state(struct bnx2 *bp, pc
 			wol_msg = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL;
 		}
 
-		bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT3 | wol_msg);
+		if (!(bp->flags & NO_WOL_FLAG))
+			bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT3 | wol_msg, 0);
 
 		pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
 		if ((CHIP_ID(bp) == CHIP_ID_5706_A0) ||
@@ -2708,9 +2756,16 @@ bnx2_init_nvram(struct bnx2 *bp)
 	if (j == entry_count) {
 		bp->flash_info = NULL;
 		printk(KERN_ALERT PFX "Unknown flash/EEPROM type.\n");
-		rc = -ENODEV;
+		return -ENODEV;
 	}
 
+	val = REG_RD_IND(bp, bp->shmem_base + BNX2_SHARED_HW_CFG_CONFIG2);
+	val &= BNX2_SHARED_HW_CFG2_NVM_SIZE_MASK;
+	if (val)
+		bp->flash_size = val;
+	else
+		bp->flash_size = bp->flash_info->total_size;
+
 	return rc;
 }
 
@@ -3014,16 +3069,14 @@ bnx2_reset_chip(struct bnx2 *bp, u32 res
 	val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS);
 	udelay(5);
 
+	/* Wait for the firmware to tell us it is ok to issue a reset. */
+	bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1);
+
 	/* Deposit a driver reset signature so the firmware knows that
 	 * this is a soft reset. */
 	REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_RESET_SIGNATURE,
 		   BNX2_DRV_RESET_SIGNATURE_MAGIC);
 
-	bp->fw_timed_out = 0;
-
-	/* Wait for the firmware to tell us it is ok to issue a reset. */
-	bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code);
-
 	/* Do a dummy read to force the chip to complete all current transaction
 	 * before we issue a reset. */
 	val = REG_RD(bp, BNX2_MISC_ID);
@@ -3062,10 +3115,10 @@ bnx2_reset_chip(struct bnx2 *bp, u32 res
 		return -ENODEV;
 	}
 
-	bp->fw_timed_out = 0;
-
 	/* Wait for the firmware to finish its initialization. */
-	bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT1 | reset_code);
+	rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT1 | reset_code, 0);
+	if (rc)
+		return rc;
 
 	if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
 		/* Adjust the voltage regular to two steps lower.  The default
@@ -3083,6 +3136,7 @@ static int
 bnx2_init_chip(struct bnx2 *bp)
 {
 	u32 val;
+	int rc;
 
 	/* Make sure the interrupt is not active. */
 	REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
@@ -3098,7 +3152,7 @@ bnx2_init_chip(struct bnx2 *bp)
 
 	val |= (0x2 << 20) | (1 << 11);
 
-	if ((bp->flags & PCIX_FLAG) && (bp->bus_speed_mhz = 133))
+	if ((bp->flags & PCIX_FLAG) && (bp->bus_speed_mhz == 133))
 		val |= (1 << 23);
 
 	if ((CHIP_NUM(bp) == CHIP_NUM_5706) &&
@@ -3218,17 +3272,22 @@ bnx2_init_chip(struct bnx2 *bp)
 
 	REG_WR(bp, BNX2_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
 
+	if (REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_FEATURE) &
+	    BNX2_PORT_FEATURE_ASF_ENABLED)
+		bp->flags |= ASF_ENABLE_FLAG;
+
 	/* Initialize the receive filter. */
 	bnx2_set_rx_mode(bp->dev);
 
-	bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET);
+	rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET,
+			  0);
 
 	REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, 0x5ffffff);
 	REG_RD(bp, BNX2_MISC_ENABLE_SET_BITS);
 
 	udelay(20);
 
-	return 0;
+	return rc;
 }
 
 
@@ -3880,26 +3939,33 @@ bnx2_test_memory(struct bnx2 *bp)
 	return ret;
 }
 
+#define BNX2_MAC_LOOPBACK	0
+#define BNX2_PHY_LOOPBACK	1
+
 static int
-bnx2_test_loopback(struct bnx2 *bp)
+bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
 {
 	unsigned int pkt_size, num_pkts, i;
 	struct sk_buff *skb, *rx_skb;
 	unsigned char *packet;
-	u16 rx_start_idx, rx_idx, send_idx;
-	u32 send_bseq, val;
+	u16 rx_start_idx, rx_idx;
+	u32 val;
 	dma_addr_t map;
 	struct tx_bd *txbd;
 	struct sw_bd *rx_buf;
 	struct l2_fhdr *rx_hdr;
 	int ret = -ENODEV;
 
-	if (!netif_running(bp->dev))
-		return -ENODEV;
-
-	bp->loopback = MAC_LOOPBACK;
-	bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_DIAG);
-	bnx2_set_mac_loopback(bp);
+	if (loopback_mode == BNX2_MAC_LOOPBACK) {
+		bp->loopback = MAC_LOOPBACK;
+		bnx2_set_mac_loopback(bp);
+	}
+	else if (loopback_mode == BNX2_PHY_LOOPBACK) {
+		bp->loopback = 0;
+		bnx2_set_phy_loopback(bp);
+	}
+	else
+		return -EINVAL;
 
 	pkt_size = 1514;
 	skb = dev_alloc_skb(pkt_size);
@@ -3921,11 +3987,9 @@ bnx2_test_loopback(struct bnx2 *bp)
 	udelay(5);
 	rx_start_idx = bp->status_blk->status_rx_quick_consumer_index0;
 
-	send_idx = 0;
-	send_bseq = 0;
 	num_pkts = 0;
 
-	txbd = &bp->tx_desc_ring[send_idx];
+	txbd = &bp->tx_desc_ring[TX_RING_IDX(bp->tx_prod)];
 
 	txbd->tx_bd_haddr_hi = (u64) map >> 32;
 	txbd->tx_bd_haddr_lo = (u64) map & 0xffffffff;
@@ -3933,13 +3997,11 @@ bnx2_test_loopback(struct bnx2 *bp)
 	txbd->tx_bd_vlan_tag_flags = TX_BD_FLAGS_START | TX_BD_FLAGS_END;
 
 	num_pkts++;
-	send_idx = NEXT_TX_BD(send_idx);
-
-	send_bseq += pkt_size;
-
-	REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, send_idx);
-	REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, send_bseq);
+	bp->tx_prod = NEXT_TX_BD(bp->tx_prod);
+	bp->tx_prod_bseq += pkt_size;
 
+	REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, bp->tx_prod);
+	REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, bp->tx_prod_bseq);
 
 	udelay(100);
 
@@ -3952,7 +4014,7 @@ bnx2_test_loopback(struct bnx2 *bp)
 	pci_unmap_single(bp->pdev, map, pkt_size, PCI_DMA_TODEVICE);
 	dev_kfree_skb_irq(skb);
 
-	if (bp->status_blk->status_tx_quick_consumer_index0 != send_idx) {
+	if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_prod) {
 		goto loopback_test_done;
 	}
 
@@ -3971,7 +4033,7 @@ bnx2_test_loopback(struct bnx2 *bp)
 		pci_unmap_addr(rx_buf, mapping),
 		bp->rx_buf_size, PCI_DMA_FROMDEVICE);
 
-	if (rx_hdr->l2_fhdr_errors &
+	if (rx_hdr->l2_fhdr_status &
 		(L2_FHDR_ERRORS_BAD_CRC |
 		L2_FHDR_ERRORS_PHY_DECODE |
 		L2_FHDR_ERRORS_ALIGNMENT |
@@ -3998,6 +4060,30 @@ loopback_test_done:
 	return ret;
 }
 
+#define BNX2_MAC_LOOPBACK_FAILED	1
+#define BNX2_PHY_LOOPBACK_FAILED	2
+#define BNX2_LOOPBACK_FAILED		(BNX2_MAC_LOOPBACK_FAILED |	\
+					 BNX2_PHY_LOOPBACK_FAILED)
+
+static int
+bnx2_test_loopback(struct bnx2 *bp)
+{
+	int rc = 0;
+
+	if (!netif_running(bp->dev))
+		return BNX2_LOOPBACK_FAILED;
+
+	bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET);
+	spin_lock_bh(&bp->phy_lock);
+	bnx2_init_phy(bp);
+	spin_unlock_bh(&bp->phy_lock);
+	if (bnx2_run_loopback(bp, BNX2_MAC_LOOPBACK))
+		rc |= BNX2_MAC_LOOPBACK_FAILED;
+	if (bnx2_run_loopback(bp, BNX2_PHY_LOOPBACK))
+		rc |= BNX2_PHY_LOOPBACK_FAILED;
+	return rc;
+}
+
 #define NVRAM_SIZE 0x200
 #define CRC32_RESIDUAL 0xdebb20e3
 
@@ -4167,7 +4253,7 @@ bnx2_restart_timer:
 static int
 bnx2_open(struct net_device *dev)
 {
-	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 	int rc;
 
 	bnx2_set_power_state(bp, PCI_D0);
@@ -4280,7 +4366,7 @@ bnx2_reset_task(void *data)
 static void
 bnx2_tx_timeout(struct net_device *dev)
 {
-	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	/* This allows the netif to be shutdown gracefully before resetting */
 	schedule_work(&bp->reset_task);
@@ -4291,7 +4377,7 @@ bnx2_tx_timeout(struct net_device *dev)
 static void
 bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp)
 {
-	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	bnx2_netif_stop(bp);
 
@@ -4305,7 +4391,7 @@ bnx2_vlan_rx_register(struct net_device 
 static void
 bnx2_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid)
 {
-	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	bnx2_netif_stop(bp);
 
@@ -4326,7 +4412,7 @@ bnx2_vlan_rx_kill_vid(struct net_device 
 static int
 bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 	dma_addr_t mapping;
 	struct tx_bd *txbd;
 	struct sw_bd *tx_buf;
@@ -4455,7 +4541,7 @@ bnx2_start_xmit(struct sk_buff *skb, str
 static int
 bnx2_close(struct net_device *dev)
 {
-	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 	u32 reset_code;
 
 	/* Calling flush_scheduled_work() may deadlock because
@@ -4467,7 +4553,9 @@ bnx2_close(struct net_device *dev)
 
 	bnx2_netif_stop(bp);
 	del_timer_sync(&bp->timer);
-	if (bp->wol)
+	if (bp->flags & NO_WOL_FLAG)
+		reset_code = BNX2_DRV_MSG_CODE_UNLOAD;
+	else if (bp->wol)
 		reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL;
 	else
 		reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL;
@@ -4501,7 +4589,7 @@ bnx2_close(struct net_device *dev)
 static struct net_device_stats *
 bnx2_get_stats(struct net_device *dev)
 {
-	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 	struct statistics_block *stats_blk = bp->stats_blk;
 	struct net_device_stats *net_stats = &bp->net_stats;
 
@@ -4575,7 +4663,7 @@ bnx2_get_stats(struct net_device *dev)
 static int
 bnx2_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-  	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	cmd->supported = SUPPORTED_Autoneg;
 	if (bp->phy_flags & PHY_SERDES_FLAG) {
@@ -4622,7 +4710,7 @@ bnx2_get_settings(struct net_device *dev
 static int
 bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-  	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 	u8 autoneg = bp->autoneg;
 	u8 req_duplex = bp->req_duplex;
 	u16 req_line_speed = bp->req_line_speed;
@@ -4694,7 +4782,7 @@ bnx2_set_settings(struct net_device *dev
 static void
 bnx2_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
-  	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	strcpy(info->driver, DRV_MODULE_NAME);
 	strcpy(info->version, DRV_MODULE_VERSION);
@@ -4702,15 +4790,14 @@ bnx2_get_drvinfo(struct net_device *dev,
 	info->fw_version[0] = ((bp->fw_ver & 0xff000000) >> 24) + '0';
 	info->fw_version[2] = ((bp->fw_ver & 0xff0000) >> 16) + '0';
 	info->fw_version[4] = ((bp->fw_ver & 0xff00) >> 8) + '0';
-	info->fw_version[6] = (bp->fw_ver & 0xff) + '0';
-	info->fw_version[1] = info->fw_version[3] = info->fw_version[5] = '.';
-	info->fw_version[7] = 0;
+	info->fw_version[1] = info->fw_version[3] = '.';
+	info->fw_version[5] = 0;
 }
 
 static void
 bnx2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
-  	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	if (bp->flags & NO_WOL_FLAG) {
 		wol->supported = 0;
@@ -4729,7 +4816,7 @@ bnx2_get_wol(struct net_device *dev, str
 static int
 bnx2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
-  	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	if (wol->wolopts & ~WAKE_MAGIC)
 		return -EINVAL;
@@ -4749,7 +4836,7 @@ bnx2_set_wol(struct net_device *dev, str
 static int
 bnx2_nway_reset(struct net_device *dev)
 {
-  	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 	u32 bmcr;
 
 	if (!(bp->autoneg & AUTONEG_SPEED)) {
@@ -4785,19 +4872,19 @@ bnx2_nway_reset(struct net_device *dev)
 static int
 bnx2_get_eeprom_len(struct net_device *dev)
 {
-  	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
-	if (bp->flash_info == 0)
+	if (bp->flash_info == NULL)
 		return 0;
 
-	return (int) bp->flash_info->total_size;
+	return (int) bp->flash_size;
 }
 
 static int
 bnx2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
 		u8 *eebuf)
 {
-  	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 	int rc;
 
 	/* parameters already validated in ethtool_get_eeprom */
@@ -4811,7 +4898,7 @@ static int
 bnx2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
 		u8 *eebuf)
 {
-  	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 	int rc;
 
 	/* parameters already validated in ethtool_set_eeprom */
@@ -4824,7 +4911,7 @@ bnx2_set_eeprom(struct net_device *dev, 
 static int
 bnx2_get_coalesce(struct net_device *dev, struct ethtool_coalesce *coal)
 {
-  	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	memset(coal, 0, sizeof(struct ethtool_coalesce));
 
@@ -4846,7 +4933,7 @@ bnx2_get_coalesce(struct net_device *dev
 static int
 bnx2_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal)
 {
-  	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	bp->rx_ticks = (u16) coal->rx_coalesce_usecs;
 	if (bp->rx_ticks > 0x3ff) bp->rx_ticks = 0x3ff;
@@ -4890,7 +4977,7 @@ bnx2_set_coalesce(struct net_device *dev
 static void
 bnx2_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
 {
-  	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	ering->rx_max_pending = MAX_RX_DESC_CNT;
 	ering->rx_mini_max_pending = 0;
@@ -4907,7 +4994,7 @@ bnx2_get_ringparam(struct net_device *de
 static int
 bnx2_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
 {
-  	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	if ((ering->rx_pending > MAX_RX_DESC_CNT) ||
 		(ering->tx_pending > MAX_TX_DESC_CNT) ||
@@ -4930,7 +5017,7 @@ bnx2_set_ringparam(struct net_device *de
 static void
 bnx2_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
 {
-  	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	epause->autoneg = ((bp->autoneg & AUTONEG_FLOW_CTRL) != 0);
 	epause->rx_pause = ((bp->flow_ctrl & FLOW_CTRL_RX) != 0);
@@ -4940,7 +5027,7 @@ bnx2_get_pauseparam(struct net_device *d
 static int
 bnx2_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
 {
-  	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	bp->req_flow_ctrl = 0;
 	if (epause->rx_pause)
@@ -4967,7 +5054,7 @@ bnx2_set_pauseparam(struct net_device *d
 static u32
 bnx2_get_rx_csum(struct net_device *dev)
 {
-  	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	return bp->rx_csum;
 }
@@ -4975,7 +5062,7 @@ bnx2_get_rx_csum(struct net_device *dev)
 static int
 bnx2_set_rx_csum(struct net_device *dev, u32 data)
 {
-  	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	bp->rx_csum = data;
 	return 0;
@@ -5124,7 +5211,7 @@ bnx2_self_test_count(struct net_device *
 static void
 bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf)
 {
-	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	memset(buf, 0, sizeof(u64) * BNX2_NUM_TESTS);
 	if (etest->flags & ETH_TEST_FL_OFFLINE) {
@@ -5140,10 +5227,8 @@ bnx2_self_test(struct net_device *dev, s
 			buf[1] = 1;
 			etest->flags |= ETH_TEST_FL_FAILED;
 		}
-		if (bnx2_test_loopback(bp) != 0) {
-			buf[2] = 1;
+		if ((buf[2] = bnx2_test_loopback(bp)) != 0)
 			etest->flags |= ETH_TEST_FL_FAILED;
-		}
 
 		if (!netif_running(bp->dev)) {
 			bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
@@ -5200,7 +5285,7 @@ static void
 bnx2_get_ethtool_stats(struct net_device *dev,
 		struct ethtool_stats *stats, u64 *buf)
 {
-	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 	int i;
 	u32 *hw_stats = (u32 *) bp->stats_blk;
 	u8 *stats_len_arr = NULL;
@@ -5240,7 +5325,7 @@ bnx2_get_ethtool_stats(struct net_device
 static int
 bnx2_phys_id(struct net_device *dev, u32 data)
 {
-	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 	int i;
 	u32 save;
 
@@ -5312,7 +5397,7 @@ static int
 bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
 	struct mii_ioctl_data *data = if_mii(ifr);
-	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 	int err;
 
 	switch(cmd) {
@@ -5354,7 +5439,7 @@ static int
 bnx2_change_mac_addr(struct net_device *dev, void *p)
 {
 	struct sockaddr *addr = p;
-	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	if (!is_valid_ether_addr(addr->sa_data))
 		return -EINVAL;
@@ -5370,7 +5455,7 @@ bnx2_change_mac_addr(struct net_device *
 static int
 bnx2_change_mtu(struct net_device *dev, int new_mtu)
 {
-	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	if (((new_mtu + ETH_HLEN) > MAX_ETHERNET_JUMBO_PACKET_SIZE) ||
 		((new_mtu + ETH_HLEN) < MIN_ETHERNET_PACKET_SIZE))
@@ -5391,7 +5476,7 @@ bnx2_change_mtu(struct net_device *dev, 
 static void
 poll_bnx2(struct net_device *dev)
 {
-	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	disable_irq(bp->pdev->irq);
 	bnx2_interrupt(bp->pdev->irq, dev, NULL);
@@ -5409,7 +5494,7 @@ bnx2_init_board(struct pci_dev *pdev, st
 
 	SET_MODULE_OWNER(dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
-	bp = dev->priv;
+	bp = netdev_priv(dev);
 
 	bp->flags = 0;
 	bp->phy_flags = 0;
@@ -5629,6 +5714,9 @@ bnx2_init_board(struct pci_dev *pdev, st
 		}
 	}
 
+	if (CHIP_NUM(bp) == CHIP_NUM_5708)
+		bp->flags |= NO_WOL_FLAG;
+
 	if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
 		bp->tx_quick_cons_trip_int =
 			bp->tx_quick_cons_trip;
@@ -5725,7 +5813,7 @@ bnx2_init_one(struct pci_dev *pdev, cons
 	dev->ethtool_ops = &bnx2_ethtool_ops;
 	dev->weight = 64;
 
-	bp = dev->priv;
+	bp = netdev_priv(dev);
 
 #if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
 	dev->poll_controller = poll_bnx2;
@@ -5784,7 +5872,7 @@ static void __devexit
 bnx2_remove_one(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
-	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	flush_scheduled_work();
 
@@ -5803,7 +5891,7 @@ static int
 bnx2_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
-	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 	u32 reset_code;
 
 	if (!netif_running(dev))
@@ -5812,7 +5900,9 @@ bnx2_suspend(struct pci_dev *pdev, pm_me
 	bnx2_netif_stop(bp);
 	netif_device_detach(dev);
 	del_timer_sync(&bp->timer);
-	if (bp->wol)
+	if (bp->flags & NO_WOL_FLAG)
+		reset_code = BNX2_DRV_MSG_CODE_UNLOAD;
+	else if (bp->wol)
 		reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL;
 	else
 		reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL;
@@ -5826,7 +5916,7 @@ static int
 bnx2_resume(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
-	struct bnx2 *bp = dev->priv;
+	struct bnx2 *bp = netdev_priv(dev);
 
 	if (!netif_running(dev))
 		return 0;
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 76bb5f1..9f691cb 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -1,6 +1,6 @@
 /* bnx2.h: Broadcom NX2 network driver.
  *
- * Copyright (c) 2004, 2005 Broadcom Corporation
+ * Copyright (c) 2004, 2005, 2006 Broadcom Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -277,19 +277,7 @@ struct statistics_block {
  *  l2_fhdr definition
  */
 struct l2_fhdr {
-#if defined(__BIG_ENDIAN)
-	u16 l2_fhdr_errors;
-	u16 l2_fhdr_status;
-#elif defined(__LITTLE_ENDIAN)
-	u16 l2_fhdr_status;
-	u16 l2_fhdr_errors;
-#endif
-		#define L2_FHDR_ERRORS_BAD_CRC		(1<<1)
-		#define L2_FHDR_ERRORS_PHY_DECODE	(1<<2)
-		#define L2_FHDR_ERRORS_ALIGNMENT	(1<<3)
-		#define L2_FHDR_ERRORS_TOO_SHORT	(1<<4)
-		#define L2_FHDR_ERRORS_GIANT_FRAME	(1<<5)
-
+	u32 l2_fhdr_status;
 		#define L2_FHDR_STATUS_RULE_CLASS	(0x7<<0)
 		#define L2_FHDR_STATUS_RULE_P2		(1<<3)
 		#define L2_FHDR_STATUS_RULE_P3		(1<<4)
@@ -301,6 +289,14 @@ struct l2_fhdr {
 		#define L2_FHDR_STATUS_TCP_SEGMENT	(1<<14)
 		#define L2_FHDR_STATUS_UDP_DATAGRAM	(1<<15)
 
+		#define L2_FHDR_ERRORS_BAD_CRC		(1<<17)
+		#define L2_FHDR_ERRORS_PHY_DECODE	(1<<18)
+		#define L2_FHDR_ERRORS_ALIGNMENT	(1<<19)
+		#define L2_FHDR_ERRORS_TOO_SHORT	(1<<20)
+		#define L2_FHDR_ERRORS_GIANT_FRAME	(1<<21)
+		#define L2_FHDR_ERRORS_TCP_XSUM		(1<<28)
+		#define L2_FHDR_ERRORS_UDP_XSUM		(1<<31)
+
 	u32 l2_fhdr_hash;
 #if defined(__BIG_ENDIAN)
 	u16 l2_fhdr_pkt_len;
@@ -3956,6 +3952,7 @@ struct bnx2 {
 #define NO_WOL_FLAG			8
 #define USING_DAC_FLAG			0x10
 #define USING_MSI_FLAG			0x20
+#define ASF_ENABLE_FLAG			0x40
 
 	u32			phy_flags;
 #define PHY_SERDES_FLAG			1
@@ -3986,6 +3983,7 @@ struct bnx2 {
 #define CHIP_ID_5706_A2			0x57060020
 #define CHIP_ID_5708_A0			0x57080000
 #define CHIP_ID_5708_B0			0x57081000
+#define CHIP_ID_5708_B1			0x57081010
 
 #define CHIP_BOND_ID(bp)		(((bp)->chip_id) & 0xf)
 
@@ -3998,7 +3996,7 @@ struct bnx2 {
 	u16			bus_speed_mhz;
 	u8			wol;
 
-	u8			fw_timed_out;
+	u8			pad;
 
 	u16			fw_wr_seq;
 	u16			fw_drv_pulse_wr_seq;
@@ -4074,6 +4072,7 @@ struct bnx2 {
 	struct net_device_stats net_stats;
 
 	struct flash_spec	*flash_info;
+	u32			flash_size;
 };
 
 static u32 bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset);
@@ -4172,7 +4171,7 @@ struct fw_info {
  * the firmware has timed out, the driver will assume there is no firmware
  * running and there won't be any firmware-driver synchronization during a
  * driver reset. */
-#define FW_ACK_TIME_OUT_MS                  50
+#define FW_ACK_TIME_OUT_MS                  100
 
 
 #define BNX2_DRV_RESET_SIGNATURE		0x00000000
@@ -4275,6 +4274,9 @@ struct fw_info {
 #define BNX2_SHARED_HW_CFG_LED_MODE_GPHY1	 0x100
 #define BNX2_SHARED_HW_CFG_LED_MODE_GPHY2	 0x200
 
+#define BNX2_SHARED_HW_CFG_CONFIG2		0x00000040
+#define BNX2_SHARED_HW_CFG2_NVM_SIZE_MASK	 0x00fff000
+
 #define BNX2_DEV_INFO_BC_REV			0x0000004c
 
 #define BNX2_PORT_HW_CFG_MAC_UPPER		0x00000050
diff --git a/drivers/net/bnx2_fw.h b/drivers/net/bnx2_fw.h
index ab07a49..0c21bd8 100644
--- a/drivers/net/bnx2_fw.h
+++ b/drivers/net/bnx2_fw.h
@@ -1,6 +1,6 @@
 /* bnx2_fw.h: Broadcom NX2 network driver.
  *
- * Copyright (c) 2004, 2005 Broadcom Corporation
+ * Copyright (c) 2004, 2005, 2006 Broadcom Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -978,20 +978,20 @@ static u32 bnx2_COM_b06FwSbss[(0x1c/4) +
 static int bnx2_RXP_b06FwReleaseMajor = 0x1;
 static int bnx2_RXP_b06FwReleaseMinor = 0x0;
 static int bnx2_RXP_b06FwReleaseFix = 0x0;
-static u32 bnx2_RXP_b06FwStartAddr = 0x08003104;
+static u32 bnx2_RXP_b06FwStartAddr = 0x08003184;
 static u32 bnx2_RXP_b06FwTextAddr = 0x08000000;
-static int bnx2_RXP_b06FwTextLen = 0x562c;
-static u32 bnx2_RXP_b06FwDataAddr = 0x08005660;
+static int bnx2_RXP_b06FwTextLen = 0x588c;
+static u32 bnx2_RXP_b06FwDataAddr = 0x080058e0;
 static int bnx2_RXP_b06FwDataLen = 0x0;
-static u32 bnx2_RXP_b06FwRodataAddr = 0x00000000;
-static int bnx2_RXP_b06FwRodataLen = 0x0;
-static u32 bnx2_RXP_b06FwBssAddr = 0x08005680;
-static int bnx2_RXP_b06FwBssLen = 0x1394;
-static u32 bnx2_RXP_b06FwSbssAddr = 0x08005660;
-static int bnx2_RXP_b06FwSbssLen = 0x18;
-static u32 bnx2_RXP_b06FwText[(0x562c/4) + 1] = {
-	0x0a000c41, 0x00000000, 0x00000000, 0x0000000d, 0x72787020, 0x322e352e,
-	0x38000000, 0x02050803, 0x00000000, 0x0000000d, 0x00000000, 0x00000000,
+static u32 bnx2_RXP_b06FwRodataAddr = 0x08005890;
+static int bnx2_RXP_b06FwRodataLen = 0x28;
+static u32 bnx2_RXP_b06FwBssAddr = 0x08005900;
+static int bnx2_RXP_b06FwBssLen = 0x13a4;
+static u32 bnx2_RXP_b06FwSbssAddr = 0x080058e0;
+static int bnx2_RXP_b06FwSbssLen = 0x1c;
+static u32 bnx2_RXP_b06FwText[(0x588c/4) + 1] = {
+	0x0a000c61, 0x00000000, 0x00000000, 0x0000000d, 0x72787020, 0x322e362e,
+	0x31000000, 0x02060103, 0x00000000, 0x0000000d, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -1513,408 +1513,435 @@ static u32 bnx2_RXP_b06FwText[(0x562c/4)
 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
-	0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800, 0x24425660,
-	0x3c030800, 0x24636a14, 0xac400000, 0x0043202b, 0x1480fffd, 0x24420004,
-	0x3c1d0800, 0x37bd7ffc, 0x03a0f021, 0x3c100800, 0x26103104, 0x3c1c0800,
-	0x279c5660, 0x0e001035, 0x00000000, 0x0000000d, 0x3c080800, 0x8d023100,
-	0x2c420080, 0x50400001, 0xad003100, 0x8d073100, 0x3c040800, 0x24840100,
-	0x8f460100, 0x00071840, 0x00671821, 0x00031940, 0x00641021, 0xac460000,
-	0x8f450104, 0x00831021, 0xac450004, 0x8f460108, 0xac460008, 0x8f45010c,
-	0xac45000c, 0x8f460114, 0xac460010, 0x8f450118, 0xac450014, 0x8f460124,
-	0xac460018, 0x8f450128, 0xac45001c, 0x8f464010, 0xac460020, 0x8f454014,
-	0xac450024, 0x8f464018, 0xac460028, 0x8f45401c, 0xac45002c, 0x8f464020,
-	0xac460030, 0x8f454024, 0xac450034, 0x8f464028, 0xac460038, 0x8f45402c,
-	0xac45003c, 0x8f464030, 0xac460040, 0x8f454034, 0xac450044, 0x8f464038,
-	0xac460048, 0x8f45403c, 0xac45004c, 0x8f464040, 0xac460050, 0x8f454044,
-	0xac450054, 0x8f464048, 0xac460058, 0x8f45404c, 0x24e70001, 0x00402021,
-	0xad073100, 0x03e00008, 0xac85005c, 0x8f820004, 0x9743010c, 0x00804821,
-	0x00403021, 0x30421000, 0x10400010, 0x306affff, 0x30c20020, 0x1440000e,
-	0x24070005, 0x3c021000, 0x00c21024, 0x10400009, 0x3c030dff, 0x3463ffff,
-	0x3c020e00, 0x00c21024, 0x0062182b, 0x50600004, 0x24070001, 0x0a000cb1,
-	0x3c020800, 0x24070001, 0x3c020800, 0x8c430034, 0x1460001d, 0x00405821,
-	0x8f820010, 0x30424000, 0x1440001a, 0x3c020001, 0x3c021f01, 0x00c24024,
-	0x3c031000, 0x15030015, 0x3c020001, 0x31420200, 0x54400012, 0x3c020001,
-	0x9744010e, 0x24020003, 0xa342018b, 0x97850012, 0x24020002, 0x34e30002,
-	0xaf400180, 0xa742018c, 0xa7430188, 0x24840004, 0x30a5bfff, 0xa744018e,
-	0xa74501a6, 0xaf4801b8, 0x03e00008, 0x00001021, 0x3c020001, 0x00c21024,
-	0x10400039, 0x00000000, 0x9742010e, 0x3c038000, 0x3046ffff, 0x8f4201b8,
-	0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x97840006, 0x8f85000c,
-	0x24020080, 0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0x10a00005,
-	0xa7440190, 0x9743011c, 0x9742011e, 0x0a000cec, 0x00021400, 0x9743011e,
-	0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010, 0x24020003,
-	0x30838000, 0x1060000d, 0xa7420188, 0x93420116, 0x304200fc, 0x005a1021,
-	0x24424004, 0x8c430000, 0x3063ffff, 0x14600005, 0x00000000, 0x3c02ffff,
-	0x34427fff, 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104,
-	0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac,
-	0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x8f820010, 0x30434000,
-	0x10600016, 0x00404021, 0x3c020f00, 0x00c21024, 0x14400012, 0x00000000,
-	0x93420116, 0x34424000, 0x03421821, 0x94650002, 0x2ca21389, 0x1040000b,
-	0x3c020800, 0x24425680, 0x00051942, 0x00031880, 0x00621821, 0x30a5001f,
-	0x8c640000, 0x24020001, 0x00a21004, 0x00822024, 0x01244825, 0x11200039,
-	0x3c021000, 0x9742010e, 0x34e70002, 0x3c038000, 0x24420004, 0x3046ffff,
-	0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x97840006,
-	0x8f85000c, 0x24020180, 0x24030002, 0xaf420180, 0xa743018c, 0xa746018e,
-	0x10a00005, 0xa7440190, 0x9743011c, 0x9742011e, 0x0a000d41, 0x00021400,
-	0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010,
-	0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d,
+	0x3c020800, 0x244258e0, 0x3c030800, 0x24636ca4, 0xac400000, 0x0043202b,
+	0x1480fffd, 0x24420004, 0x3c1d0800, 0x37bd7ffc, 0x03a0f021, 0x3c100800,
+	0x26103184, 0x3c1c0800, 0x279c58e0, 0x0e00104a, 0x00000000, 0x0000000d,
+	0x27bdffe8, 0xafb00010, 0xafbf0014, 0x0e000f1d, 0x00808021, 0x1440000d,
+	0x00000000, 0x8f820010, 0x10400005, 0x00000000, 0x9743011c, 0x9742011e,
+	0x0a000c89, 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825,
+	0xaf830004, 0x8f840008, 0x3c020020, 0x34424000, 0x00821824, 0x54620004,
+	0x3c020020, 0x8f820014, 0x0a000c9a, 0x34421000, 0x34428000, 0x00821824,
+	0x14620004, 0x00000000, 0x8f820014, 0x34428000, 0xaf820014, 0x8f820008,
+	0x9743010c, 0x00403021, 0x30421000, 0x10400010, 0x3069ffff, 0x30c20020,
+	0x1440000e, 0x24070005, 0x3c021000, 0x00c21024, 0x10400009, 0x3c030dff,
+	0x3463ffff, 0x3c020e00, 0x00c21024, 0x0062182b, 0x50600004, 0x24070001,
+	0x0a000cb2, 0x3c020800, 0x24070001, 0x3c020800, 0x8c430034, 0x1460001d,
+	0x00405821, 0x8f820014, 0x30424000, 0x1440001a, 0x3c020001, 0x3c021f01,
+	0x00c24024, 0x3c031000, 0x15030015, 0x3c020001, 0x31220200, 0x14400012,
+	0x3c020001, 0x9744010e, 0x24020003, 0xa342018b, 0x97850016, 0x24020002,
+	0x34e30002, 0xaf400180, 0xa742018c, 0xa7430188, 0x24840004, 0x30a5bfff,
+	0xa744018e, 0xa74501a6, 0xaf4801b8, 0x0a000f19, 0x00001021, 0x3c020001,
+	0x00c21024, 0x1040002f, 0x00000000, 0x9742010e, 0x3c038000, 0x3046ffff,
+	0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x9784000a,
+	0x8f850004, 0x8f870014, 0x24020080, 0x24030002, 0xaf420180, 0x24020003,
+	0xa743018c, 0xa746018e, 0xa7420188, 0x30e28000, 0xa7440190, 0x1040000c,
+	0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000,
+	0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00e21024, 0xaf820014,
+	0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff,
+	0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x0a000f19,
+	0x00001021, 0x8f820014, 0x30434000, 0x10600016, 0x00404021, 0x3c020f00,
+	0x00c21024, 0x14400012, 0x00000000, 0x93420116, 0x34424000, 0x03421821,
+	0x94650002, 0x2ca21389, 0x1040000b, 0x3c020800, 0x24425900, 0x00051942,
+	0x00031880, 0x00621821, 0x30a5001f, 0x8c640000, 0x24020001, 0x00a21004,
+	0x00822024, 0x02048025, 0x12000030, 0x3c021000, 0x9742010e, 0x34e80002,
+	0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd,
+	0x24020003, 0xa342018b, 0x9784000a, 0x8f850004, 0x8f870014, 0x24020180,
+	0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0xa7480188, 0x30e28000,
+	0xa7440190, 0x1040000c, 0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021,
 	0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
-	0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104, 0x3042bfff,
+	0x00e21024, 0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff,
 	0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
-	0xaf4201b8, 0x03e00008, 0x00001021, 0x00c21024, 0x104000e3, 0x3c020800,
-	0x8c430030, 0x10600040, 0x31024000, 0x1040003e, 0x3c030f00, 0x00c31824,
-	0x3c020100, 0x0043102b, 0x1440003a, 0x3c030800, 0x9742010e, 0x34e70002,
+	0xaf4201b8, 0x0a000f19, 0x00001021, 0x00c21024, 0x104000c0, 0x3c020800,
+	0x8c430030, 0x10600037, 0x31024000, 0x10400035, 0x3c030f00, 0x00c31824,
+	0x3c020100, 0x0043102b, 0x14400031, 0x3c030800, 0x9742010e, 0x34e80002,
 	0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd,
-	0x24020003, 0xa342018b, 0x97840006, 0x8f85000c, 0x24020080, 0x24030002,
-	0xaf420180, 0xa743018c, 0xa746018e, 0x10a00005, 0xa7440190, 0x9743011c,
-	0x9742011e, 0x0a000d86, 0x00021400, 0x9743011e, 0x9742011c, 0x00021400,
-	0x00621825, 0xaf4301a8, 0x8f840010, 0x30828000, 0x1040000c, 0xa7470188,
+	0x24020003, 0xa342018b, 0x9784000a, 0x8f850004, 0x8f870014, 0x24020080,
+	0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0xa7480188, 0x30e28000,
+	0xa7440190, 0x1040000c, 0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021,
+	0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
+	0x00e21024, 0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff,
+	0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
+	0xaf4201b8, 0x0a000f19, 0x00001021, 0x3c030800, 0x8c620024, 0x30420008,
+	0x10400035, 0x34ea0002, 0x3c020f00, 0x00c21024, 0x14400032, 0x8d620034,
+	0x31220200, 0x1040002f, 0x8d620034, 0x9742010e, 0x30e8fffb, 0x3c038000,
+	0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003,
+	0xa342018b, 0x9784000a, 0x8f850004, 0x8f870014, 0x24020180, 0x24030002,
+	0xaf420180, 0xa743018c, 0xa746018e, 0xa7480188, 0x30e28000, 0xa7440190,
+	0x1040000c, 0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004,
+	0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00e21024,
+	0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00,
+	0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8,
+	0x8d620034, 0x8f860008, 0x10400012, 0x30c20100, 0x10400010, 0x3c020f00,
+	0x00c21024, 0x3c030200, 0x1043000c, 0x3c020800, 0x8c430038, 0x8f840004,
+	0x3c020800, 0x2442003c, 0x2463ffff, 0x00832024, 0x00822021, 0x90830000,
+	0x24630004, 0x0a000de1, 0x000329c0, 0x00000000, 0x00061602, 0x3042000f,
+	0x000229c0, 0x3c04fc00, 0x00441021, 0x3c030300, 0x0062182b, 0x50600001,
+	0x24050800, 0x9742010e, 0x3148ffff, 0x3c038000, 0x24420004, 0x3046ffff,
+	0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x9783000a,
+	0x8f840004, 0x8f870014, 0x24020002, 0xaf450180, 0xa742018c, 0xa746018e,
+	0xa7480188, 0x30e28000, 0xa7430190, 0x1040000c, 0xaf4401a8, 0x93420116,
+	0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004,
+	0x3c02ffff, 0x34427fff, 0x00e21024, 0xaf820014, 0x97820016, 0x9743010c,
+	0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6,
+	0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x0a000f19, 0x00001021, 0x8f424000,
+	0x30420100, 0x104000d5, 0x3c020800, 0x8c440024, 0x24030001, 0x1483002f,
+	0x00405021, 0x9742010e, 0x34e70002, 0x3c038000, 0x24420004, 0x3045ffff,
+	0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x9783000a,
+	0x8f840004, 0x8f860014, 0x24020002, 0xaf400180, 0xa742018c, 0xa745018e,
+	0xa7470188, 0x30c28000, 0xa7430190, 0x1040000c, 0xaf4401a8, 0x93420116,
+	0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004,
+	0x3c02ffff, 0x34427fff, 0x00c21024, 0xaf820014, 0x97820016, 0x9743010c,
+	0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6,
+	0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x0a000f19, 0x00001021, 0x30820001,
+	0x1040002e, 0x30eb0004, 0x9742010e, 0x30e9fffb, 0x3c038000, 0x24420004,
+	0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b,
+	0x9783000a, 0x8f840004, 0x8f860014, 0x24020002, 0xaf400180, 0xa742018c,
+	0xa745018e, 0xa7470188, 0x30c28000, 0xa7430190, 0x1040000c, 0xaf4401a8,
 	0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff,
-	0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf820010, 0x97820012,
+	0x14600004, 0x3c02ffff, 0x34427fff, 0x00c21024, 0xaf820014, 0x97820016,
 	0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825,
-	0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021,
-	0x3c030800, 0x8c620024, 0x30420008, 0x1040003e, 0x34e80002, 0x3c020f00,
-	0x00c21024, 0x1440003b, 0x8d620034, 0x31420200, 0x10400038, 0x8d620034,
-	0x9742010e, 0x30e7fffb, 0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8,
-	0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x97840006, 0x8f85000c,
-	0x24020180, 0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0x10a00005,
-	0xa7440190, 0x9743011c, 0x9742011e, 0x0a000dca, 0x00021400, 0x9743011e,
-	0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010, 0x30828000,
-	0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004,
-	0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024,
-	0xaf820010, 0x97820012, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00,
-	0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8,
-	0x8d620034, 0x8f860004, 0x1040001a, 0x30c20100, 0x10400018, 0x3c020f00,
-	0x00c21024, 0x3c030200, 0x10430014, 0x00000000, 0x8f82000c, 0x10400004,
-	0x00000000, 0x9742011c, 0x0a000df8, 0x3044ffff, 0x9742011e, 0x3044ffff,
-	0x3c030800, 0x8c620038, 0x3c030800, 0x2463003c, 0x2442ffff, 0x00822024,
-	0x00831821, 0x90620000, 0x24420004, 0x0a000e0d, 0x000229c0, 0x00000000,
-	0x00061602, 0x3042000f, 0x000229c0, 0x3c04fc00, 0x00441021, 0x3c030300,
-	0x0062182b, 0x50600001, 0x24050800, 0x9742010e, 0x3107ffff, 0x3c038000,
+	0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x3127ffff, 0x8d420024,
+	0x30420004, 0x10400030, 0x8d420024, 0x9742010e, 0x30e9fffb, 0x3c038000,
 	0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003,
-	0xa342018b, 0x97830006, 0x8f84000c, 0x24020002, 0xaf450180, 0xa742018c,
-	0xa746018e, 0x10800005, 0xa7430190, 0x9743011c, 0x9742011e, 0x0a000e26,
-	0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8,
-	0x8f840010, 0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc,
-	0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff,
-	0x34427fff, 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104,
-	0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac,
-	0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x8f424000, 0x30420100,
-	0x104000f9, 0x3c020800, 0x8c440024, 0x24030001, 0x14830038, 0x00404821,
-	0x9742010e, 0x34e60002, 0x3c038000, 0x24420004, 0x3045ffff, 0x8f4201b8,
-	0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x97830006, 0x8f84000c,
-	0x24020002, 0xaf400180, 0xa742018c, 0xa745018e, 0x10800005, 0xa7430190,
-	0x9743011c, 0x9742011e, 0x0a000e65, 0x00021400, 0x9743011e, 0x9742011c,
-	0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010, 0x30828000, 0x1040000c,
-	0xa7460188, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000,
-	0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf820010,
-	0x97820012, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff,
-	0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x03e00008,
-	0x00001021, 0x30820001, 0x10400037, 0x30ea0004, 0x9742010e, 0x30e8fffb,
+	0xa342018b, 0x9784000a, 0x8f850004, 0x8f880014, 0x24020100, 0x24030002,
+	0xaf420180, 0xa743018c, 0xa746018e, 0xa7470188, 0x31028000, 0xa7440190,
+	0x1040000c, 0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004,
+	0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x01021024,
+	0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00,
+	0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8,
+	0x3127ffff, 0x8d420024, 0x30420008, 0x1040002d, 0x00000000, 0x9742010e,
+	0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd,
+	0x24020003, 0xa342018b, 0x9784000a, 0x8f850004, 0x8f880014, 0x24020180,
+	0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0xa7470188, 0x31028000,
+	0xa7440190, 0x1040000c, 0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021,
+	0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
+	0x01021024, 0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff,
+	0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
+	0xaf4201b8, 0x15600041, 0x00001021, 0x27440180, 0x3c038000, 0x8f4201b8,
+	0x00431024, 0x1440fffd, 0x24022000, 0x24030002, 0xa4820008, 0xa083000b,
+	0xa4800010, 0x3c021000, 0xaf4201b8, 0x0a000f19, 0x00001021, 0x3c030800,
+	0x8c620024, 0x30420001, 0x1040002e, 0x00001021, 0x9742010e, 0x34e70002,
 	0x3c038000, 0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd,
-	0x24020003, 0xa342018b, 0x97830006, 0x8f84000c, 0x24020002, 0xaf400180,
-	0xa742018c, 0xa745018e, 0x10800005, 0xa7430190, 0x9743011c, 0x9742011e,
-	0x0a000e9f, 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825,
-	0xaf4301a8, 0x8f840010, 0x30828000, 0x1040000c, 0xa7470188, 0x93420116,
-	0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004,
-	0x3c02ffff, 0x34427fff, 0x00821024, 0xaf820010, 0x97820012, 0x9743010c,
-	0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6,
-	0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x3107ffff, 0x8d220024, 0x30420004,
-	0x10400039, 0x8d220024, 0x9742010e, 0x30e8fffb, 0x3c038000, 0x24420004,
-	0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b,
-	0x97840006, 0x8f85000c, 0x24020100, 0x24030002, 0xaf420180, 0xa743018c,
-	0xa746018e, 0x10a00005, 0xa7440190, 0x9743011c, 0x9742011e, 0x0a000eda,
-	0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8,
-	0x8f840010, 0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc,
-	0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff,
-	0x34427fff, 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104,
-	0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac,
-	0x3c021000, 0xaf4201b8, 0x3107ffff, 0x8d220024, 0x30420008, 0x10400036,
-	0x00000000, 0x9742010e, 0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8,
-	0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x97840006, 0x8f85000c,
-	0x24020180, 0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0x10a00005,
-	0xa7440190, 0x9743011c, 0x9742011e, 0x0a000f14, 0x00021400, 0x9743011e,
-	0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010, 0x30828000,
-	0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004,
-	0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024,
-	0xaf820010, 0x97820012, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00,
+	0x24020003, 0xa342018b, 0x9783000a, 0x8f840004, 0x8f860014, 0x24020002,
+	0xaf400180, 0xa742018c, 0xa745018e, 0xa7470188, 0x30c28000, 0xa7430190,
+	0x1040000c, 0xaf4401a8, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004,
+	0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00c21024,
+	0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00,
 	0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8,
-	0x1540004a, 0x00001021, 0x27440180, 0x3c038000, 0x8f4201b8, 0x00431024,
-	0x1440fffd, 0x24022000, 0x24030002, 0xa4820008, 0xa083000b, 0xa4800010,
-	0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x3c030800, 0x8c620024,
-	0x30420001, 0x10400037, 0x00001021, 0x9742010e, 0x34e60002, 0x3c038000,
-	0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003,
-	0xa342018b, 0x97830006, 0x8f84000c, 0x24020002, 0xaf400180, 0xa742018c,
-	0xa745018e, 0x10800005, 0xa7430190, 0x9743011c, 0x9742011e, 0x0a000f5e,
-	0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8,
-	0x8f840010, 0x30828000, 0x1040000c, 0xa7460188, 0x93420116, 0x304200fc,
+	0x00001021, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x8f4b0070,
+	0x93420112, 0x8f840008, 0x00022882, 0x30820100, 0x14400003, 0x24a30003,
+	0x03e00008, 0x00001021, 0x30824000, 0x10400010, 0x27424000, 0x00031880,
+	0x00431021, 0x8c470000, 0x24a30004, 0x00031880, 0x27424000, 0x00431021,
+	0x8c490000, 0x93430116, 0x27424000, 0x306300fc, 0x00431021, 0x8c4a0000,
+	0x0a000f45, 0x3c030800, 0x30822000, 0x1040ffea, 0x00031880, 0x27424000,
+	0x00431021, 0x8c470000, 0x24a30004, 0x00031880, 0x27424000, 0x00431021,
+	0x8c490000, 0x00005021, 0x3c030800, 0x24680100, 0x00071602, 0x00021080,
+	0x00481021, 0x8c460000, 0x00071b82, 0x306303fc, 0x01031821, 0x8c640400,
+	0x00071182, 0x304203fc, 0x01021021, 0x8c450800, 0x30e300ff, 0x00031880,
+	0x01031821, 0x00091602, 0x00021080, 0x01021021, 0x00c43026, 0x8c640c00,
+	0x8c431000, 0x00c53026, 0x00091382, 0x304203fc, 0x01021021, 0x8c451400,
+	0x312200ff, 0x00021080, 0x01021021, 0x00c43026, 0x00c33026, 0x00091982,
+	0x306303fc, 0x01031821, 0x8c641800, 0x8c431c00, 0x00c53026, 0x00c43026,
+	0x11400015, 0x00c33026, 0x000a1602, 0x00021080, 0x01021021, 0x8c432000,
+	0x000a1382, 0x304203fc, 0x01021021, 0x8c452400, 0x314200ff, 0x00021080,
+	0x01021021, 0x00c33026, 0x000a1982, 0x306303fc, 0x01031821, 0x8c642800,
+	0x8c432c00, 0x00c53026, 0x00c43026, 0x00c33026, 0x8f430070, 0x3c050800,
+	0x8ca43100, 0x2c820020, 0x10400008, 0x006b5823, 0x3c020800, 0x24423104,
+	0x00041880, 0x00621821, 0x24820001, 0xac6b0000, 0xaca23100, 0xaf860004,
+	0x03e00008, 0x24020001, 0x27bdffe8, 0xafbf0010, 0x8f460128, 0x8f840010,
+	0xaf460020, 0x8f450104, 0x8f420100, 0x24030800, 0xaf850008, 0xaf820014,
+	0xaf4301b8, 0x1080000a, 0x3c020800, 0x8c430034, 0x10600007, 0x30a22000,
+	0x10400005, 0x34a30100, 0x8f82000c, 0xaf830008, 0x24420001, 0xaf82000c,
+	0x3c020800, 0x8c4300c0, 0x10600006, 0x3c030800, 0x8c6200c4, 0x24040001,
+	0x24420001, 0x0a000fd5, 0xac6200c4, 0x8f820008, 0x3c030010, 0x00431024,
+	0x14400009, 0x3c02001f, 0x3c030800, 0x8c620020, 0x00002021, 0x24420001,
+	0x0e000c78, 0xac620020, 0x0a000fd5, 0x00402021, 0x3442ff00, 0x14c20009,
+	0x2403bfff, 0x3c030800, 0x8c620020, 0x24040001, 0x24420001, 0x0e000c78,
+	0xac620020, 0x0a000fd5, 0x00402021, 0x8f820014, 0x00431024, 0x14400006,
+	0x00000000, 0xaf400048, 0x0e0011a9, 0xaf400040, 0x0a000fd5, 0x00402021,
+	0x0e001563, 0x00000000, 0x00402021, 0x10800005, 0x3c024000, 0x8f430124,
+	0x3c026020, 0xac430014, 0x3c024000, 0xaf420138, 0x00000000, 0x8fbf0010,
+	0x03e00008, 0x27bd0018, 0x27bdffe0, 0xafbf0018, 0xafb10014, 0xafb00010,
+	0x8f420140, 0xaf420020, 0x8f430148, 0x3c027000, 0x00621824, 0x3c023000,
+	0x10620021, 0x0043102b, 0x14400006, 0x3c024000, 0x3c022000, 0x10620009,
+	0x3c024000, 0x0a001040, 0x00000000, 0x10620045, 0x3c025000, 0x10620047,
+	0x3c024000, 0x0a001040, 0x00000000, 0x27440180, 0x3c038000, 0x8f4201b8,
+	0x00431024, 0x1440fffd, 0x00000000, 0x8f420148, 0x24030002, 0xa083000b,
+	0x00021402, 0xa4820008, 0x8f430148, 0xa4830010, 0x8f420144, 0x3c031000,
+	0xac820024, 0xaf4301b8, 0x0a001040, 0x3c024000, 0x8f420148, 0x24030002,
+	0x3044ffff, 0x00021402, 0x305000ff, 0x1203000c, 0x27510180, 0x2a020003,
+	0x10400005, 0x24020003, 0x0600001d, 0x36053000, 0x0a001027, 0x3c038000,
+	0x12020007, 0x00000000, 0x0a001034, 0x00000000, 0x0e00112c, 0x00000000,
+	0x0a001025, 0x00402021, 0x0e00113e, 0x00000000, 0x00402021, 0x36053000,
+	0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, 0xa6250008,
+	0xa222000b, 0xa6240010, 0x8f420144, 0x3c031000, 0xae220024, 0xaf4301b8,
+	0x0a001040, 0x3c024000, 0x0000000d, 0x00000000, 0x240002bf, 0x0a001040,
+	0x3c024000, 0x0e001441, 0x00000000, 0x0a001040, 0x3c024000, 0x0e0015ea,
+	0x00000000, 0x3c024000, 0xaf420178, 0x00000000, 0x8fbf0018, 0x8fb10014,
+	0x8fb00010, 0x03e00008, 0x27bd0020, 0x24020800, 0x03e00008, 0xaf4201b8,
+	0x27bdffe8, 0x3c04600c, 0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000,
+	0x2403ff7f, 0x3c106000, 0x00431024, 0x3442380c, 0x24030003, 0xac825000,
+	0x3c020008, 0xaf430008, 0x8e040808, 0x0342d825, 0x8e020808, 0x3c030800,
+	0xac600020, 0x3084fff0, 0x2c840001, 0x3042fff0, 0x38420010, 0x2c420001,
+	0xaf840010, 0xaf820000, 0x0e00160c, 0x00000000, 0x0e001561, 0x00000000,
+	0x3c020400, 0x3442000c, 0x3c03ffff, 0x34630806, 0xae021948, 0xae03194c,
+	0x8e021980, 0x34420200, 0xae021980, 0x8f500000, 0x32020003, 0x1040fffd,
+	0x32020001, 0x10400004, 0x32020002, 0x0e000f92, 0x00000000, 0x32020002,
+	0x1040fff6, 0x00000000, 0x0e000fe0, 0x00000000, 0x0a001071, 0x00000000,
+	0x27bdffe8, 0x3c04600c, 0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000,
+	0x2403ff7f, 0x3c106000, 0x00431024, 0x3442380c, 0x24030003, 0xac825000,
+	0x3c020008, 0xaf430008, 0x8e040808, 0x0342d825, 0x8e020808, 0x3c030800,
+	0xac600020, 0x3084fff0, 0x2c840001, 0x3042fff0, 0x38420010, 0x2c420001,
+	0xaf840010, 0xaf820000, 0x0e00160c, 0x00000000, 0x0e001561, 0x00000000,
+	0x3c020400, 0x3442000c, 0x3c03ffff, 0x34630806, 0xae021948, 0xae03194c,
+	0x8e021980, 0x8fbf0014, 0x34420200, 0xae021980, 0x8fb00010, 0x03e00008,
+	0x27bd0018, 0x00804821, 0x30a5ffff, 0x30c6ffff, 0x30e7ffff, 0x3c038000,
+	0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x9783000a,
+	0x8f840004, 0x8f880014, 0xaf490180, 0xa745018c, 0xa746018e, 0xa7470188,
+	0x31028000, 0xa7430190, 0x1040000c, 0xaf4401a8, 0x93420116, 0x304200fc,
 	0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff,
-	0x34427fff, 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104,
+	0x34427fff, 0x01021024, 0xaf820014, 0x97820016, 0x9743010c, 0x8f440104,
 	0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac,
-	0x3c021000, 0xaf4201b8, 0x00001021, 0x03e00008, 0x00000000, 0x27bdffe8,
-	0xafbf0010, 0x8f460128, 0x8f84000c, 0xaf460020, 0x8f450104, 0x8f420100,
-	0x24030800, 0xaf850004, 0xaf820010, 0xaf4301b8, 0x1080000a, 0x3c020800,
-	0x8c430034, 0x10600007, 0x30a22000, 0x10400005, 0x34a30100, 0x8f820008,
-	0xaf830004, 0x24420001, 0xaf820008, 0x3c020800, 0x8c4300c0, 0x10600006,
-	0x3c030800, 0x8c6200c4, 0x24040001, 0x24420001, 0x0a000fc0, 0xac6200c4,
-	0x8f820004, 0x3c030010, 0x00431024, 0x14400009, 0x3c02001f, 0x3c030800,
-	0x8c620020, 0x00002021, 0x24420001, 0x0e000c99, 0xac620020, 0x0a000fc0,
-	0x00402021, 0x3442ff00, 0x14c20009, 0x2403bfff, 0x3c030800, 0x8c620020,
-	0x24040001, 0x24420001, 0x0e000c99, 0xac620020, 0x0a000fc0, 0x00402021,
-	0x8f820010, 0x00431024, 0x14400006, 0x00000000, 0xaf400048, 0x0e001144,
-	0xaf400040, 0x0a000fc0, 0x00402021, 0x0e0014c9, 0x00000000, 0x00402021,
-	0x10800005, 0x3c024000, 0x8f430124, 0x3c026020, 0xac430014, 0x3c024000,
-	0xaf420138, 0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe0,
-	0xafbf0018, 0xafb10014, 0xafb00010, 0x8f420140, 0xaf420020, 0x8f430148,
-	0x3c027000, 0x00621824, 0x3c023000, 0x10620021, 0x0043102b, 0x14400006,
-	0x3c024000, 0x3c022000, 0x10620009, 0x3c024000, 0x0a00102b, 0x00000000,
-	0x10620045, 0x3c025000, 0x10620047, 0x3c024000, 0x0a00102b, 0x00000000,
+	0x3c021000, 0xaf4201b8, 0x03e00008, 0x00000000, 0x27440180, 0x3c038000,
+	0x8f4201b8, 0x00431024, 0x1440fffd, 0x24022000, 0x24030002, 0xa4820008,
+	0xa083000b, 0xa4800010, 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00000000,
 	0x27440180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000,
 	0x8f420148, 0x24030002, 0xa083000b, 0x00021402, 0xa4820008, 0x8f430148,
-	0xa4830010, 0x8f420144, 0x3c031000, 0xac820024, 0xaf4301b8, 0x0a00102b,
-	0x3c024000, 0x8f420148, 0x24030002, 0x3044ffff, 0x00021402, 0x305000ff,
-	0x1203000c, 0x27510180, 0x2a020003, 0x10400005, 0x24020003, 0x0600001d,
-	0x36053000, 0x0a001012, 0x3c038000, 0x12020007, 0x00000000, 0x0a00101f,
-	0x00000000, 0x0e00111f, 0x00000000, 0x0a001010, 0x00402021, 0x0e001131,
-	0x00000000, 0x00402021, 0x36053000, 0x3c038000, 0x8f4201b8, 0x00431024,
-	0x1440fffd, 0x24020002, 0xa6250008, 0xa222000b, 0xa6240010, 0x8f420144,
-	0x3c031000, 0xae220024, 0xaf4301b8, 0x0a00102b, 0x3c024000, 0x0000000d,
-	0x00000000, 0x24000295, 0x0a00102b, 0x3c024000, 0x0e0013a7, 0x00000000,
-	0x0a00102b, 0x3c024000, 0x0e001552, 0x00000000, 0x3c024000, 0xaf420178,
-	0x00000000, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020,
-	0x24020800, 0x03e00008, 0xaf4201b8, 0x27bdffe8, 0x3c04600c, 0xafbf0014,
-	0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f, 0x3c106000, 0x00431024,
-	0x3442380c, 0x24030003, 0xac825000, 0x3c020008, 0xaf430008, 0x8e040808,
-	0x0342d825, 0x8e020808, 0x3c030800, 0xac600020, 0x3084fff0, 0x2c840001,
-	0x3042fff0, 0x38420010, 0x2c420001, 0xaf84000c, 0xaf820000, 0x0e001574,
-	0x00000000, 0x0e0014c7, 0x00000000, 0x3c020400, 0x3442000c, 0x3c03ffff,
-	0x34630806, 0xae021948, 0xae03194c, 0x8e021980, 0x34420200, 0xae021980,
-	0x8f500000, 0x32020003, 0x1040fffd, 0x32020001, 0x10400004, 0x32020002,
-	0x0e000f7d, 0x00000000, 0x32020002, 0x1040fff6, 0x00000000, 0x0e000fcb,
-	0x00000000, 0x0a00105c, 0x00000000, 0x27bdffe8, 0x3c04600c, 0xafbf0014,
-	0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f, 0x3c106000, 0x00431024,
-	0x3442380c, 0x24030003, 0xac825000, 0x3c020008, 0xaf430008, 0x8e040808,
-	0x0342d825, 0x8e020808, 0x3c030800, 0xac600020, 0x3084fff0, 0x2c840001,
-	0x3042fff0, 0x38420010, 0x2c420001, 0xaf84000c, 0xaf820000, 0x0e001574,
-	0x00000000, 0x0e0014c7, 0x00000000, 0x3c020400, 0x3442000c, 0x3c03ffff,
-	0x34630806, 0xae021948, 0xae03194c, 0x8e021980, 0x8fbf0014, 0x34420200,
-	0xae021980, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x30a5ffff, 0x30c6ffff,
-	0x30e7ffff, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003,
-	0xa342018b, 0x97830006, 0x8f82000c, 0xaf440180, 0xa745018c, 0xa746018e,
-	0x10400005, 0xa7430190, 0x9743011c, 0x9742011e, 0x0a0010ad, 0x00021400,
-	0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010,
-	0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021,
-	0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
-	0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104, 0x3042bfff,
-	0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
-	0xaf4201b8, 0x03e00008, 0x00000000, 0x27440180, 0x3c038000, 0x8f4201b8,
-	0x00431024, 0x1440fffd, 0x24022000, 0x24030002, 0xa4820008, 0xa083000b,
-	0xa4800010, 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00000000, 0x27440180,
-	0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x8f420148,
-	0x24030002, 0xa083000b, 0x00021402, 0xa4820008, 0x8f430148, 0xa4830010,
-	0x8f420144, 0x3c031000, 0xac820024, 0x03e00008, 0xaf4301b8, 0x27bdffe0,
-	0xafbf0018, 0xafb10014, 0xafb00010, 0x8f420148, 0x24030002, 0x3044ffff,
-	0x00021402, 0x305000ff, 0x1203000c, 0x27510180, 0x2a020003, 0x10400005,
-	0x24020003, 0x0600001d, 0x36053000, 0x0a00110a, 0x3c038000, 0x12020007,
-	0x00000000, 0x0a001117, 0x00000000, 0x0e00111f, 0x00000000, 0x0a001108,
-	0x00402021, 0x0e001131, 0x00000000, 0x00402021, 0x36053000, 0x3c038000,
-	0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, 0xa6250008, 0xa222000b,
-	0xa6240010, 0x8f420144, 0x3c031000, 0xae220024, 0xaf4301b8, 0x0a00111b,
-	0x8fbf0018, 0x0000000d, 0x00000000, 0x24000295, 0x8fbf0018, 0x8fb10014,
-	0x8fb00010, 0x03e00008, 0x27bd0020, 0x3084ffff, 0x2c821389, 0x1040000d,
-	0x00001021, 0x3c030800, 0x24635680, 0x00042942, 0x00052880, 0x00a32821,
-	0x3086001f, 0x8ca40000, 0x24030001, 0x00c31804, 0x00832025, 0x03e00008,
-	0xaca40000, 0x03e00008, 0x24020091, 0x3084ffff, 0x2c821389, 0x1040000e,
-	0x00001021, 0x3c030800, 0x24635680, 0x00042942, 0x00052880, 0x00a32821,
-	0x3086001f, 0x24030001, 0x8ca40000, 0x00c31804, 0x00031827, 0x00832024,
-	0x03e00008, 0xaca40000, 0x03e00008, 0x24020091, 0x27bdffb0, 0xafbf0048,
-	0x93620023, 0x30420010, 0x1440025b, 0x24020001, 0x93420116, 0x93630005,
-	0x34424000, 0x30630001, 0x14600005, 0x03425821, 0x0e001548, 0x00000000,
-	0x0a0013a5, 0x8fbf0048, 0x93420112, 0x8f430104, 0x3c040020, 0x34424000,
-	0x00641824, 0x10600012, 0x03422821, 0x27450180, 0x3c038000, 0x8f4201b8,
+	0xa4830010, 0x8f420144, 0x3c031000, 0xac820024, 0x03e00008, 0xaf4301b8,
+	0x27bdffe0, 0xafbf0018, 0xafb10014, 0xafb00010, 0x8f420148, 0x24030002,
+	0x3044ffff, 0x00021402, 0x305000ff, 0x1203000c, 0x27510180, 0x2a020003,
+	0x10400005, 0x24020003, 0x0600001d, 0x36053000, 0x0a001117, 0x3c038000,
+	0x12020007, 0x00000000, 0x0a001124, 0x00000000, 0x0e00112c, 0x00000000,
+	0x0a001115, 0x00402021, 0x0e00113e, 0x00000000, 0x00402021, 0x36053000,
+	0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, 0xa6250008,
+	0xa222000b, 0xa6240010, 0x8f420144, 0x3c031000, 0xae220024, 0xaf4301b8,
+	0x0a001128, 0x8fbf0018, 0x0000000d, 0x00000000, 0x240002bf, 0x8fbf0018,
+	0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3084ffff, 0x2c821389,
+	0x1040000d, 0x00001021, 0x3c030800, 0x24635900, 0x00042942, 0x00052880,
+	0x00a32821, 0x3086001f, 0x8ca40000, 0x24030001, 0x00c31804, 0x00832025,
+	0x03e00008, 0xaca40000, 0x03e00008, 0x24020091, 0x3084ffff, 0x2c821389,
+	0x1040000e, 0x00001021, 0x3c030800, 0x24635900, 0x00042942, 0x00052880,
+	0x00a32821, 0x3086001f, 0x24030001, 0x8ca40000, 0x00c31804, 0x00031827,
+	0x00832024, 0x03e00008, 0xaca40000, 0x03e00008, 0x24020091, 0x9482000c,
+	0x24870014, 0x00021302, 0x00021080, 0x00824021, 0x00e8182b, 0x1060004f,
+	0x00000000, 0x90e30000, 0x2c620009, 0x10400047, 0x3c020800, 0x24425890,
+	0x00031880, 0x00621821, 0x8c640000, 0x00800008, 0x00000000, 0x0a0011a4,
+	0x24e70001, 0x90e30001, 0x2402000a, 0x54620024, 0x01003821, 0x01071023,
+	0x2c42000a, 0x54400020, 0x01003821, 0x3c050800, 0x8ca26c98, 0x24e70002,
+	0x34420100, 0xaca26c98, 0x90e30000, 0x90e20001, 0x90e40002, 0x90e60003,
+	0x24e70004, 0x24a56c98, 0x00031e00, 0x00021400, 0x00621825, 0x00042200,
+	0x00641825, 0x00661825, 0xaca30004, 0x90e20000, 0x90e30001, 0x90e40002,
+	0x90e60003, 0x24e70004, 0x00021600, 0x00031c00, 0x00431025, 0x00042200,
+	0x00441025, 0x00461025, 0x0a0011a4, 0xaca20008, 0x90e30001, 0x24020004,
+	0x1062000e, 0x00601021, 0x0a00119e, 0x01001021, 0x90e30001, 0x24020003,
+	0x10620008, 0x00601021, 0x0a00119e, 0x01001021, 0x90e30001, 0x24020002,
+	0x14620003, 0x01001021, 0x00601021, 0x00e21021, 0x0a0011a4, 0x00403821,
+	0x90e20001, 0x0a0011a4, 0x00e23821, 0x01003821, 0x00e8102b, 0x5440ffb4,
+	0x90e30000, 0x03e00008, 0x24020001, 0x27bdff90, 0x3c030800, 0xafbf006c,
+	0xafbe0068, 0xafb70064, 0xafb60060, 0xafb5005c, 0xafb40058, 0xafb30054,
+	0xafb20050, 0xafb1004c, 0xafb00048, 0xac606c98, 0x93620023, 0x30420010,
+	0x1440027c, 0x24020001, 0x93420116, 0x93630005, 0x34424000, 0x30630001,
+	0x14600005, 0x0342b021, 0x0e0015e0, 0x00000000, 0x0a001436, 0x8fbf006c,
+	0x93420112, 0x8f430104, 0x3c040020, 0x34424000, 0x00641824, 0x10600012,
+	0x03422821, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd,
+	0x00000000, 0x8f420128, 0xaca20000, 0x8f640040, 0x24030008, 0x240240c1,
+	0xa4a20008, 0x24020002, 0xa0a2000b, 0x3c021000, 0x0a0011f1, 0xa0a3000a,
+	0x8f420104, 0x3c030040, 0x00431024, 0x1040001d, 0x3c038000, 0x27450180,
+	0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128, 0xaca20000,
+	0x8f640040, 0x24030010, 0x240240c1, 0xa4a20008, 0x24020002, 0xa0a3000a,
+	0x24030008, 0xa0a2000b, 0x3c021000, 0xa4a30010, 0xa0a00012, 0xa0a00013,
+	0xaca00014, 0xaca00024, 0xaca00028, 0xaca0002c, 0xaca40018, 0x0e0015e0,
+	0xaf4201b8, 0x0a001436, 0x8fbf006c, 0x8f820000, 0x10400016, 0x00000000,
+	0x8f420104, 0x3c030001, 0x00431024, 0x10400011, 0x00000000, 0x8ca3000c,
+	0x8f620030, 0x1462022d, 0x24020001, 0x8ca30010, 0x8f62002c, 0x14620229,
+	0x24020001, 0x9763003a, 0x96c20000, 0x14430225, 0x24020001, 0x97630038,
+	0x96c20002, 0x14430221, 0x24020001, 0xaf400048, 0xaf400054, 0xaf400040,
+	0x8f740040, 0x8f650048, 0x00b43023, 0x04c10004, 0x00000000, 0x0000000d,
+	0x00000000, 0x240001af, 0x9742011a, 0x3052ffff, 0x12400004, 0x8ed30004,
+	0x02721021, 0x0a001228, 0x2451ffff, 0x02608821, 0x92d7000d, 0xa7a00020,
+	0xa3a0001a, 0xafa00028, 0x9362003f, 0x32e30004, 0x1060003a, 0x305000ff,
+	0x24040012, 0x16040006, 0x24020001, 0x3c040800, 0x8c830028, 0x24630001,
+	0x0a001328, 0xac830028, 0x8f620044, 0x16620010, 0x27a60010, 0x27450180,
+	0x3c038000, 0x2402001a, 0xa7a20020, 0x24020020, 0xafb40028, 0xa3b00022,
+	0xa3a40023, 0xa3a2001a, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000,
+	0x0a00130d, 0x00000000, 0x8f620044, 0x02621023, 0x0440001a, 0x02651023,
+	0x044100d9, 0x24020001, 0x3c020800, 0x8c4300d8, 0x10600004, 0x24020001,
+	0xa7a20020, 0x0a00125e, 0xafb40028, 0x2402001a, 0xa7a20020, 0x24020020,
+	0xafb40028, 0xa3b00022, 0xa3a40023, 0xa3a2001a, 0x27a60010, 0x27450180,
+	0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x0a00130d,
+	0x00000000, 0x0a001328, 0x24020001, 0x0293f023, 0x1bc00016, 0x025e102a,
+	0x54400007, 0x32f700fe, 0x57d2000f, 0x027e9821, 0x32e20001, 0x5440000c,
+	0x027e9821, 0x32f700fe, 0x0240f021, 0x3c040800, 0x8c8300c8, 0x00009021,
+	0x24020001, 0xa7a20020, 0xafb40028, 0x24630001, 0x0a001282, 0xac8300c8,
+	0x025e1023, 0x0a001282, 0x3052ffff, 0x0000f021, 0x24a2ffff, 0x02221823,
+	0x1860001f, 0x0072102a, 0x54400019, 0x00a08821, 0x97a20020, 0x3c040800,
+	0x8c8300cc, 0xafb40028, 0x34420001, 0x24630001, 0xa7a20020, 0x02741026,
+	0x2c420001, 0xac8300cc, 0x2cc30001, 0x00431024, 0x1440000a, 0x02401821,
+	0x27a60010, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd,
+	0x00000000, 0x0a00130d, 0x00000000, 0x00a08821, 0x02431023, 0x3052ffff,
+	0x0a0012ae, 0x32f700f6, 0x02741023, 0x18400008, 0x97a20020, 0x3c040800,
+	0x8c8300d4, 0xafb30028, 0x34420400, 0x24630001, 0xa7a20020, 0xac8300d4,
+	0x32e20002, 0x1040001c, 0x32e20010, 0x8f620044, 0x1662000d, 0x27a60010,
+	0x97a20020, 0x27450180, 0x3c038000, 0xafb40028, 0x34420001, 0xa7a20020,
+	0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x0a00130d, 0x00000000,
+	0x97a20020, 0x27450180, 0x3c038000, 0xafb40028, 0x34420001, 0xa7a20020,
+	0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x0a00130d, 0x00000000,
+	0x54400003, 0x8ed50008, 0x0a001328, 0x24020001, 0x8f630054, 0x26a2ffff,
+	0x00431023, 0x18400011, 0x27a60010, 0x97a20020, 0x3c040800, 0x8c8300d0,
+	0x27450180, 0x3c078000, 0xafb40028, 0x34420001, 0x24630001, 0xa7a20020,
+	0xac8300d0, 0x8f4201b8, 0x00471024, 0x1440fffd, 0x00000000, 0x0a00130d,
+	0x00000000, 0x32e20020, 0x10400011, 0x00000000, 0x96c20012, 0x0052102b,
+	0x10400008, 0x97a20020, 0x96d20012, 0x12400003, 0x02721021, 0x0a0012f2,
+	0x2451ffff, 0x02608821, 0x97a20020, 0x93a3001a, 0x34420008, 0x34630004,
+	0xa7a20020, 0xa3a3001a, 0x8f420104, 0x3c030080, 0x00431024, 0x10400037,
+	0x3a03000a, 0x0e001151, 0x02c02021, 0x24030002, 0x1443002b, 0x3c030800,
+	0x27a60010, 0x97a20020, 0x27450180, 0x3c038000, 0xafb40028, 0x34420001,
+	0xa7a20020, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128,
+	0xaca20000, 0x8cc30018, 0x240240c1, 0xa4a20008, 0xaca30018, 0x90c4000a,
+	0x24020002, 0xa0a2000b, 0xa0a4000a, 0x94c20010, 0xa4a20010, 0x90c30012,
+	0xa0a30012, 0x90c20013, 0xa0a20013, 0x8cc30014, 0xaca30014, 0x8cc20024,
+	0xaca20024, 0x8cc30028, 0xaca30028, 0x8cc4002c, 0x24020001, 0x3c031000,
+	0xaca4002c, 0xaf4301b8, 0xaf400044, 0xaf400050, 0x0a001436, 0x8fbf006c,
+	0x8c626c98, 0x30420100, 0x10400003, 0x24636c98, 0x8c620004, 0xaf62017c,
+	0x3a03000a, 0x2c630001, 0x3a02000c, 0x2c420001, 0x00621825, 0x14600003,
+	0x2402000e, 0x56020030, 0x00009021, 0x52400008, 0x96c4000e, 0x12400004,
+	0xa7b20040, 0x02721021, 0x0a001343, 0x2451ffff, 0x02608821, 0x96c4000e,
+	0x93630035, 0x8f62004c, 0x00642004, 0x00952021, 0x00821023, 0x18400015,
+	0x00000000, 0x8f620018, 0x02621023, 0x1c400015, 0x97a20020, 0x8f620018,
+	0x1662001c, 0x00000000, 0x8f62001c, 0x02a21023, 0x1c40000e, 0x97a20020,
+	0x8f62001c, 0x16a20015, 0x00000000, 0x8f620058, 0x00821023, 0x18400011,
+	0x97a20020, 0x0a001364, 0xafb10028, 0x8f620058, 0x00821023, 0x0441000b,
+	0x97a20020, 0xafb10028, 0xafb30034, 0xafb50038, 0xafa4003c, 0x34420020,
+	0x0a00136d, 0xa7a20020, 0x02809821, 0x02608821, 0x8f640058, 0x8f62004c,
+	0x02a21023, 0x18400009, 0x00000000, 0x8f620054, 0x02a21023, 0x1c400005,
+	0x97a20020, 0xafb10028, 0xafb50024, 0x0a001385, 0x34420040, 0x9742011a,
+	0x1440000c, 0x24020014, 0x8f620058, 0x14820009, 0x24020014, 0x8f63004c,
+	0x8f620054, 0x10620004, 0x97a20020, 0xafb10028, 0x34420080, 0xa7a20020,
+	0x24020014, 0x1202000a, 0x2a020015, 0x10400005, 0x2402000c, 0x12020006,
+	0x32e20001, 0x0a0013c6, 0x00000000, 0x24020016, 0x16020035, 0x32e20001,
+	0x8f620084, 0x24420001, 0x16a20031, 0x32e20001, 0x24020014, 0x12020021,
+	0x2a020015, 0x10400005, 0x2402000c, 0x12020008, 0x32e20001, 0x0a0013c6,
+	0x00000000, 0x24020016, 0x1202000c, 0x32e20001, 0x0a0013c6, 0x00000000,
+	0x97a30020, 0x2402000e, 0xafb10028, 0xa3b00022, 0xa3a20023, 0xafb50024,
+	0x34630054, 0x0a0013c5, 0xa7a30020, 0x97a20020, 0x93a4001a, 0x24030010,
+	0xafb10028, 0xa3b00022, 0xa3a30023, 0xafb50024, 0x3442005d, 0x34840002,
+	0xa7a20020, 0x0a0013c5, 0xa3a4001a, 0x97a20020, 0x24030012, 0xa3a30023,
+	0x93a3001a, 0xafb10028, 0xa3b00022, 0xafb50024, 0x3042fffe, 0x3442005c,
+	0x34630002, 0xa7a20020, 0xa3a3001a, 0x32e20001, 0x10400030, 0x2402000c,
+	0x12020013, 0x2a02000d, 0x10400005, 0x2402000a, 0x12020008, 0x97a20020,
+	0x0a0013f8, 0x32e20009, 0x2402000e, 0x1202001b, 0x32e20009, 0x0a0013f9,
+	0x0002102b, 0x93a4001a, 0x24030008, 0xafb10028, 0xa3b00022, 0xa3a30023,
+	0x0a0013f4, 0x34420013, 0x97a30020, 0x30620004, 0x14400005, 0x93a2001a,
+	0x3463001b, 0xa7a30020, 0x0a0013e7, 0x24030016, 0x3463001b, 0xa7a30020,
+	0x24030010, 0xafb10028, 0xa3b00022, 0xa3a30023, 0x34420002, 0x0a0013f7,
+	0xa3a2001a, 0x97a20020, 0x93a4001a, 0x24030010, 0xafb10028, 0xa3b00022,
+	0xa3a30023, 0x3442001b, 0x34840002, 0xa7a20020, 0xa3a4001a, 0x32e20009,
+	0x0002102b, 0x00021023, 0x30420007, 0x12400015, 0x34450003, 0x8f820018,
+	0x24030800, 0x27440180, 0x24420001, 0xaf820018, 0x24020004, 0xaf4301b8,
+	0xa4850008, 0xa082000b, 0x93430120, 0x00003021, 0x3c021000, 0xa492000e,
+	0xac950024, 0xac930028, 0x007e1821, 0xa483000c, 0xaf4201b8, 0x0a001413,
+	0x97a20020, 0x24060001, 0x97a20020, 0x10400020, 0x27450180, 0x3c038000,
+	0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128, 0xaca20000,
+	0x8fa30028, 0x240240c1, 0xa4a20008, 0xaca30018, 0x93a4001a, 0x24020002,
+	0xa0a2000b, 0xa0a4000a, 0x97a20020, 0xa4a20010, 0x93a30022, 0xa0a30012,
+	0x93a20023, 0xa0a20013, 0x8fa30024, 0xaca30014, 0x8fa20034, 0xaca20024,
+	0x8fa30038, 0xaca30028, 0x8fa2003c, 0x3c031000, 0xaca2002c, 0xaf4301b8,
+	0x00c01021, 0x8fbf006c, 0x8fbe0068, 0x8fb70064, 0x8fb60060, 0x8fb5005c,
+	0x8fb40058, 0x8fb30054, 0x8fb20050, 0x8fb1004c, 0x8fb00048, 0x03e00008,
+	0x27bd0070, 0x8f470140, 0x8f460148, 0x3c028000, 0x00c24024, 0x00062c02,
+	0x30a300ff, 0x24020019, 0x106200e7, 0x27440180, 0x2862001a, 0x1040001f,
+	0x24020008, 0x106200be, 0x28620009, 0x1040000d, 0x24020001, 0x10620046,
+	0x28620002, 0x50400005, 0x24020006, 0x1060002e, 0x00a01821, 0x0a00155e,
+	0x00000000, 0x1062005b, 0x00a01821, 0x0a00155e, 0x00000000, 0x2402000b,
+	0x10620084, 0x2862000c, 0x10400005, 0x24020009, 0x106200bc, 0x00061c02,
+	0x0a00155e, 0x00000000, 0x2402000e, 0x106200b7, 0x00061c02, 0x0a00155e,
+	0x00000000, 0x28620021, 0x10400009, 0x2862001f, 0x104000c1, 0x2402001b,
+	0x106200bf, 0x2402001c, 0x1062009a, 0x00061c02, 0x0a00155e, 0x00000000,
+	0x240200c2, 0x106200ca, 0x286200c3, 0x10400005, 0x24020080, 0x1062005a,
+	0x00a01821, 0x0a00155e, 0x00000000, 0x240200c9, 0x106200cd, 0x30c5ffff,
+	0x0a00155e, 0x00000000, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd,
+	0x24020001, 0xa4830008, 0x24030002, 0xac870000, 0xac800004, 0xa082000a,
+	0xa083000b, 0xa4860010, 0x8f430144, 0x3c021000, 0xac800028, 0xac830024,
+	0x3c036000, 0xaf4201b8, 0x03e00008, 0xac600808, 0x11000009, 0x00a01821,
+	0x3c020800, 0x24030002, 0xa0436c88, 0x24426c88, 0xac470008, 0x8f430144,
+	0x03e00008, 0xac430004, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd,
+	0x24020002, 0xac800000, 0xac870004, 0xa4830008, 0xa082000a, 0xa082000b,
+	0xa4860010, 0xac800024, 0x8f420144, 0x3c031000, 0xac820028, 0x3c026000,
+	0xaf4301b8, 0x03e00008, 0xac400808, 0x3c080800, 0x3c058000, 0x8f4201b8,
+	0x00451024, 0x1440fffd, 0x00000000, 0xac870000, 0x91026c88, 0x00002821,
+	0x10400002, 0x25076c88, 0x8ce50008, 0xac850004, 0xa4830008, 0x91036c88,
+	0x24020002, 0xa082000b, 0xa4860010, 0x34630001, 0xa083000a, 0x8f420144,
+	0xac820024, 0x91036c88, 0x10600002, 0x00001021, 0x8ce20004, 0xac820028,
+	0x3c021000, 0xaf4201b8, 0x3c026000, 0xa1006c88, 0x03e00008, 0xac400808,
+	0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020002, 0xa082000b,
+	0xa4830008, 0xa4860010, 0x8f420144, 0x3c031000, 0xa4820012, 0x03e00008,
+	0xaf4301b8, 0x30c2ffff, 0x14400028, 0x00061c02, 0x93620005, 0x30420004,
+	0x14400020, 0x3c029000, 0x34420001, 0x00e21025, 0xaf420020, 0x3c038000,
+	0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620005, 0x3c038000,
+	0x34630001, 0x00e31825, 0x34420004, 0xa3620005, 0xaf430020, 0x93620005,
+	0x30420004, 0x14400003, 0x3c038000, 0x0000000d, 0x3c038000, 0x8f4201b8,
+	0x00431024, 0x1440fffd, 0x24020005, 0x3c031000, 0xac870000, 0xa082000b,
+	0xaf4301b8, 0x0a00150d, 0x00061c02, 0x0000000d, 0x03e00008, 0x00000000,
+	0x00061c02, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020001,
+	0xa4830008, 0x24030002, 0xac870000, 0xac800004, 0xa082000a, 0xa083000b,
+	0xa4860010, 0x8f430144, 0x3c021000, 0xac800028, 0xac830024, 0x03e00008,
+	0xaf4201b8, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020002,
+	0xac800000, 0xac870004, 0xa4830008, 0xa082000a, 0xa082000b, 0xa4860010,
+	0xac800024, 0x8f420144, 0x3c031000, 0xac820028, 0x03e00008, 0xaf4301b8,
+	0x00061c02, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020001,
+	0xa4830008, 0x24030002, 0xa082000a, 0x3c021000, 0xac870000, 0xac800004,
+	0xa083000b, 0xa4860010, 0xac800024, 0xac800028, 0x03e00008, 0xaf4201b8,
+	0x00a01821, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020002,
+	0xac870000, 0xac800004, 0xa4830008, 0xa080000a, 0x0a001518, 0xa082000b,
+	0x8f440144, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002,
+	0x240340c9, 0xaf470180, 0xa342018b, 0x3c021000, 0xa7430188, 0xaf4401a4,
+	0xaf4501a8, 0xaf4001ac, 0x03e00008, 0xaf4201b8, 0x0000000d, 0x03e00008,
+	0x00000000, 0x03e00008, 0x00000000, 0x8f420100, 0x3042003e, 0x14400011,
+	0x24020001, 0xaf400048, 0x8f420100, 0x304207c0, 0x10400005, 0x00000000,
+	0xaf40004c, 0xaf400050, 0x03e00008, 0x24020001, 0xaf400054, 0xaf400040,
+	0x8f420100, 0x30423800, 0x54400001, 0xaf400044, 0x24020001, 0x03e00008,
+	0x00000000, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002,
+	0x240340c9, 0xaf440180, 0xa342018b, 0x3c021000, 0xa7430188, 0xaf4501a4,
+	0xaf4601a8, 0xaf4701ac, 0x03e00008, 0xaf4201b8, 0x3c029000, 0x34420001,
+	0x00822025, 0xaf440020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
+	0x00000000, 0x03e00008, 0x00000000, 0x3c028000, 0x34420001, 0x00822025,
+	0x03e00008, 0xaf440020, 0x308600ff, 0x27450180, 0x3c038000, 0x8f4201b8,
 	0x00431024, 0x1440fffd, 0x00000000, 0x8f420128, 0xaca20000, 0x8f640040,
 	0x24030008, 0x240240c1, 0xa4a20008, 0x24020002, 0xa0a2000b, 0x3c021000,
-	0x0a001181, 0xa0a3000a, 0x8f420104, 0x3c030040, 0x00431024, 0x1040001d,
-	0x3c038000, 0x27450180, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000,
-	0x8f420128, 0xaca20000, 0x8f640040, 0x24030010, 0x240240c1, 0xa4a20008,
-	0x24020002, 0xa0a3000a, 0x24030008, 0xa0a2000b, 0x3c021000, 0xa4a30010,
-	0xa0a00012, 0xa0a00013, 0xaca00014, 0xaca00024, 0xaca00028, 0xaca0002c,
-	0xaca40018, 0x0e001548, 0xaf4201b8, 0x0a0013a5, 0x8fbf0048, 0x8f820000,
-	0x10400016, 0x00000000, 0x8f420104, 0x3c030001, 0x00431024, 0x10400011,
-	0x00000000, 0x8ca3000c, 0x8f620030, 0x1462020c, 0x24020001, 0x8ca30010,
-	0x8f62002c, 0x14620208, 0x24020001, 0x9763003a, 0x95620000, 0x14430204,
-	0x24020001, 0x97630038, 0x95620002, 0x14430200, 0x24020001, 0xaf400048,
-	0xaf400054, 0xaf400040, 0x8f690040, 0x8f6a0048, 0x01497023, 0x05c10004,
-	0x00000000, 0x0000000d, 0x00000000, 0x24000169, 0x9742011a, 0x3046ffff,
-	0x10c00004, 0x8d680004, 0x01061021, 0x0a0011b8, 0x2445ffff, 0x01002821,
-	0x916c000d, 0xa7a00020, 0xa3a0001a, 0xafa00028, 0x9362003f, 0x31830004,
-	0x1060003a, 0x304700ff, 0x24040012, 0x14e40006, 0x24020001, 0x3c040800,
-	0x8c830028, 0x24630001, 0x0a00128d, 0xac830028, 0x8f620044, 0x15020010,
-	0x27a60010, 0x27450180, 0x3c038000, 0x2402001a, 0xa7a20020, 0x24020020,
-	0xafa90028, 0xa3a70022, 0xa3a40023, 0xa3a2001a, 0x8f4201b8, 0x00431024,
-	0x1440fffd, 0x00000000, 0x0a001272, 0x00000000, 0x8f620044, 0x01021023,
-	0x0440001a, 0x010a1023, 0x044100ae, 0x24020001, 0x3c020800, 0x8c4300d8,
-	0x10600004, 0x24020001, 0xa7a20020, 0x0a0011ee, 0xafa90028, 0x2402001a,
-	0xa7a20020, 0x24020020, 0xafa90028, 0xa3a70022, 0xa3a40023, 0xa3a2001a,
-	0x27a60010, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd,
-	0x00000000, 0x0a001272, 0x00000000, 0x0a00128d, 0x24020001, 0x01286823,
-	0x19a00016, 0x00cd102a, 0x54400007, 0x318c00fe, 0x55a6000f, 0x010d4021,
-	0x31820001, 0x5440000c, 0x010d4021, 0x318c00fe, 0x00c06821, 0x3c040800,
-	0x8c8300c8, 0x00003021, 0x24020001, 0xa7a20020, 0xafa90028, 0x24630001,
-	0x0a001212, 0xac8300c8, 0x00cd1023, 0x0a001212, 0x3046ffff, 0x00006821,
-	0x2542ffff, 0x00a21823, 0x1860001e, 0x0066102a, 0x14400018, 0x01402821,
-	0x97a20020, 0x3c040800, 0x8c8300cc, 0xafa90028, 0x34420001, 0x24630001,
-	0xa7a20020, 0x01091026, 0x2c420001, 0xac8300cc, 0x2dc30001, 0x00431024,
-	0x1440000a, 0x00c01821, 0x27a60010, 0x27450180, 0x3c038000, 0x8f4201b8,
-	0x00431024, 0x1440fffd, 0x00000000, 0x0a001272, 0x00000000, 0x00c31023,
-	0x3046ffff, 0x0a00123d, 0x318c00f6, 0x01091023, 0x18400008, 0x97a20020,
-	0x3c040800, 0x8c8300d4, 0xafa80028, 0x34420400, 0x24630001, 0xa7a20020,
-	0xac8300d4, 0x31820002, 0x1040001c, 0x31820010, 0x8f620044, 0x1502000d,
-	0x27a60010, 0x97a20020, 0x27450180, 0x3c038000, 0xafa90028, 0x34420001,
-	0xa7a20020, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x0a001272,
-	0x00000000, 0x97a20020, 0x27450180, 0x3c038000, 0xafa90028, 0x34420001,
-	0xa7a20020, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x0a001272,
-	0x00000000, 0x54400003, 0x8d6a0008, 0x0a00128d, 0x24020001, 0x8f630054,
-	0x2542ffff, 0x00431023, 0x1840002e, 0x97a20020, 0x27a60010, 0x3c040800,
-	0x8c8300d0, 0x27450180, 0x3c078000, 0xafa90028, 0x34420001, 0x24630001,
-	0xa7a20020, 0xac8300d0, 0x8f4201b8, 0x00471024, 0x1440fffd, 0x00000000,
-	0x8f420128, 0xaca20000, 0x8cc30018, 0x240240c1, 0xa4a20008, 0xaca30018,
-	0x90c4000a, 0x24020002, 0xa0a2000b, 0xa0a4000a, 0x94c20010, 0xa4a20010,
-	0x90c30012, 0xa0a30012, 0x90c20013, 0xa0a20013, 0x8cc30014, 0xaca30014,
-	0x8cc20024, 0xaca20024, 0x8cc30028, 0xaca30028, 0x8cc4002c, 0x24020001,
-	0x3c031000, 0xaca4002c, 0xaf4301b8, 0xaf400044, 0xaf400050, 0x0a0013a5,
-	0x8fbf0048, 0x31820020, 0x10400011, 0x00000000, 0x95620012, 0x0046102b,
-	0x10400008, 0x97a20020, 0x95660012, 0x10c00003, 0x01061021, 0x0a00129e,
-	0x2445ffff, 0x01002821, 0x97a20020, 0x93a3001a, 0x34420008, 0x34630004,
-	0xa7a20020, 0xa3a3001a, 0x8f420104, 0x38e3000a, 0x2c630001, 0x38e2000c,
-	0x2c420001, 0x00621825, 0x14600003, 0x2402000e, 0x54e2002a, 0x00003021,
-	0x50c00008, 0x9564000e, 0x10c00004, 0xa7a60040, 0x01061021, 0x0a0012b6,
-	0x2445ffff, 0x01002821, 0x9564000e, 0x93630035, 0x8f62004c, 0x00642004,
-	0x008a2021, 0x00821023, 0x1840001d, 0x00000000, 0x8f620018, 0x01021023,
-	0x1c40000f, 0x97a20020, 0x8f620018, 0x15020016, 0x00000000, 0x8f62001c,
-	0x01421023, 0x1c400008, 0x97a20020, 0x8f62001c, 0x1542000f, 0x00000000,
-	0x8f620058, 0x00821023, 0x1840000b, 0x97a20020, 0xafa50028, 0xafa80034,
-	0xafaa0038, 0xafa4003c, 0x34420020, 0x0a0012da, 0xa7a20020, 0x01204021,
-	0x01002821, 0x8f640058, 0x8f62004c, 0x01421023, 0x18400009, 0x00000000,
-	0x8f620054, 0x01421023, 0x1c400005, 0x97a20020, 0xafa50028, 0xafaa0024,
-	0x0a0012f2, 0x34420040, 0x9742011a, 0x1440000c, 0x24020014, 0x8f620058,
-	0x14820009, 0x24020014, 0x8f63004c, 0x8f620054, 0x10620004, 0x97a20020,
-	0xafa50028, 0x34420080, 0xa7a20020, 0x24020014, 0x10e2000a, 0x28e20015,
-	0x10400005, 0x2402000c, 0x10e20006, 0x31820001, 0x0a001333, 0x00000000,
-	0x24020016, 0x14e20035, 0x31820001, 0x8f620084, 0x24420001, 0x15420031,
-	0x31820001, 0x24020014, 0x10e20021, 0x28e20015, 0x10400005, 0x2402000c,
-	0x10e20008, 0x31820001, 0x0a001333, 0x00000000, 0x24020016, 0x10e2000c,
-	0x31820001, 0x0a001333, 0x00000000, 0x97a30020, 0x2402000e, 0xafa50028,
-	0xa3a70022, 0xa3a20023, 0xafaa0024, 0x34630054, 0x0a001332, 0xa7a30020,
-	0x97a20020, 0x93a4001a, 0x24030010, 0xafa50028, 0xa3a70022, 0xa3a30023,
-	0xafaa0024, 0x3442005d, 0x34840002, 0xa7a20020, 0x0a001332, 0xa3a4001a,
-	0x97a20020, 0x24030012, 0xa3a30023, 0x93a3001a, 0xafa50028, 0xa3a70022,
-	0xafaa0024, 0x3042fffe, 0x3442005c, 0x34630002, 0xa7a20020, 0xa3a3001a,
-	0x31820001, 0x10400030, 0x2402000c, 0x10e20013, 0x28e2000d, 0x10400005,
-	0x2402000a, 0x10e20008, 0x97a20020, 0x0a001365, 0x31820009, 0x2402000e,
-	0x10e2001b, 0x31820009, 0x0a001366, 0x0002102b, 0x93a4001a, 0x24030008,
-	0xafa50028, 0xa3a70022, 0xa3a30023, 0x0a001361, 0x34420013, 0x97a30020,
-	0x30620004, 0x14400005, 0x93a2001a, 0x3463001b, 0xa7a30020, 0x0a001354,
-	0x24030016, 0x3463001b, 0xa7a30020, 0x24030010, 0xafa50028, 0xa3a70022,
-	0xa3a30023, 0x34420002, 0x0a001364, 0xa3a2001a, 0x97a20020, 0x93a4001a,
-	0x24030010, 0xafa50028, 0xa3a70022, 0xa3a30023, 0x3442001b, 0x34840002,
-	0xa7a20020, 0xa3a4001a, 0x31820009, 0x0002102b, 0x00021023, 0x30420007,
-	0x10c00017, 0x34440003, 0x8f820014, 0x24030800, 0x27450180, 0x24420001,
-	0xaf820014, 0x24020004, 0xaf4301b8, 0xa4a40008, 0xa0a2000b, 0x93440120,
-	0x3c031000, 0xa4a6000e, 0xacaa0024, 0xaca80028, 0x008d2021, 0xa4a4000c,
-	0xaf4301b8, 0x97a20020, 0x00003021, 0x3042ffbf, 0x0a001381, 0xa7a20020,
-	0x24060001, 0x97a20020, 0x10400020, 0x27450180, 0x3c038000, 0x8f4201b8,
-	0x00431024, 0x1440fffd, 0x00000000, 0x8f420128, 0xaca20000, 0x8fa30028,
-	0x240240c1, 0xa4a20008, 0xaca30018, 0x93a4001a, 0x24020002, 0xa0a2000b,
-	0xa0a4000a, 0x97a20020, 0xa4a20010, 0x93a30022, 0xa0a30012, 0x93a20023,
-	0xa0a20013, 0x8fa30024, 0xaca30014, 0x8fa20034, 0xaca20024, 0x8fa30038,
-	0xaca30028, 0x8fa2003c, 0x3c031000, 0xaca2002c, 0xaf4301b8, 0x00c01021,
-	0x8fbf0048, 0x03e00008, 0x27bd0050, 0x8f470140, 0x8f460148, 0x3c028000,
-	0x00c24024, 0x00062c02, 0x30a300ff, 0x24020019, 0x106200e7, 0x27440180,
-	0x2862001a, 0x1040001f, 0x24020008, 0x106200be, 0x28620009, 0x1040000d,
-	0x24020001, 0x10620046, 0x28620002, 0x50400005, 0x24020006, 0x1060002e,
-	0x00a01821, 0x0a0014c4, 0x00000000, 0x1062005b, 0x00a01821, 0x0a0014c4,
-	0x00000000, 0x2402000b, 0x10620084, 0x2862000c, 0x10400005, 0x24020009,
-	0x106200bc, 0x00061c02, 0x0a0014c4, 0x00000000, 0x2402000e, 0x106200b7,
-	0x00061c02, 0x0a0014c4, 0x00000000, 0x28620021, 0x10400009, 0x2862001f,
-	0x104000c1, 0x2402001b, 0x106200bf, 0x2402001c, 0x1062009a, 0x00061c02,
-	0x0a0014c4, 0x00000000, 0x240200c2, 0x106200ca, 0x286200c3, 0x10400005,
-	0x24020080, 0x1062005a, 0x00a01821, 0x0a0014c4, 0x00000000, 0x240200c9,
-	0x106200cd, 0x30c5ffff, 0x0a0014c4, 0x00000000, 0x3c058000, 0x8f4201b8,
-	0x00451024, 0x1440fffd, 0x24020001, 0xa4830008, 0x24030002, 0xac870000,
-	0xac800004, 0xa082000a, 0xa083000b, 0xa4860010, 0x8f430144, 0x3c021000,
-	0xac800028, 0xac830024, 0x3c036000, 0xaf4201b8, 0x03e00008, 0xac600808,
-	0x11000009, 0x00a01821, 0x3c020800, 0x24030002, 0xa0436a08, 0x24426a08,
-	0xac470008, 0x8f430144, 0x03e00008, 0xac430004, 0x3c058000, 0x8f4201b8,
-	0x00451024, 0x1440fffd, 0x24020002, 0xac800000, 0xac870004, 0xa4830008,
-	0xa082000a, 0xa082000b, 0xa4860010, 0xac800024, 0x8f420144, 0x3c031000,
-	0xac820028, 0x3c026000, 0xaf4301b8, 0x03e00008, 0xac400808, 0x3c080800,
-	0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x00000000, 0xac870000,
-	0x91026a08, 0x00002821, 0x10400002, 0x25076a08, 0x8ce50008, 0xac850004,
-	0xa4830008, 0x91036a08, 0x24020002, 0xa082000b, 0xa4860010, 0x34630001,
-	0xa083000a, 0x8f420144, 0xac820024, 0x91036a08, 0x10600002, 0x00001021,
-	0x8ce20004, 0xac820028, 0x3c021000, 0xaf4201b8, 0x3c026000, 0xa1006a08,
-	0x03e00008, 0xac400808, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd,
-	0x24020002, 0xa082000b, 0xa4830008, 0xa4860010, 0x8f420144, 0x3c031000,
-	0xa4820012, 0x03e00008, 0xaf4301b8, 0x30c2ffff, 0x14400028, 0x00061c02,
-	0x93620005, 0x30420004, 0x14400020, 0x3c029000, 0x34420001, 0x00e21025,
-	0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000,
-	0x93620005, 0x3c038000, 0x34630001, 0x00e31825, 0x34420004, 0xa3620005,
-	0xaf430020, 0x93620005, 0x30420004, 0x14400003, 0x3c038000, 0x0000000d,
-	0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020005, 0x3c031000,
-	0xac870000, 0xa082000b, 0xaf4301b8, 0x0a001473, 0x00061c02, 0x0000000d,
-	0x03e00008, 0x00000000, 0x00061c02, 0x3c058000, 0x8f4201b8, 0x00451024,
-	0x1440fffd, 0x24020001, 0xa4830008, 0x24030002, 0xac870000, 0xac800004,
-	0xa082000a, 0xa083000b, 0xa4860010, 0x8f430144, 0x3c021000, 0xac800028,
-	0xac830024, 0x03e00008, 0xaf4201b8, 0x3c058000, 0x8f4201b8, 0x00451024,
-	0x1440fffd, 0x24020002, 0xac800000, 0xac870004, 0xa4830008, 0xa082000a,
-	0xa082000b, 0xa4860010, 0xac800024, 0x8f420144, 0x3c031000, 0xac820028,
-	0x03e00008, 0xaf4301b8, 0x00061c02, 0x3c058000, 0x8f4201b8, 0x00451024,
-	0x1440fffd, 0x24020001, 0xa4830008, 0x24030002, 0xa082000a, 0x3c021000,
-	0xac870000, 0xac800004, 0xa083000b, 0xa4860010, 0xac800024, 0xac800028,
-	0x03e00008, 0xaf4201b8, 0x00a01821, 0x3c058000, 0x8f4201b8, 0x00451024,
-	0x1440fffd, 0x24020002, 0xac870000, 0xac800004, 0xa4830008, 0xa080000a,
-	0x0a00147e, 0xa082000b, 0x8f440144, 0x3c038000, 0x8f4201b8, 0x00431024,
-	0x1440fffd, 0x24020002, 0x240340c9, 0xaf470180, 0xa342018b, 0x3c021000,
-	0xa7430188, 0xaf4401a4, 0xaf4501a8, 0xaf4001ac, 0x03e00008, 0xaf4201b8,
-	0x0000000d, 0x03e00008, 0x00000000, 0x03e00008, 0x00000000, 0x8f420100,
-	0x3042003e, 0x14400011, 0x24020001, 0xaf400048, 0x8f420100, 0x304207c0,
-	0x10400005, 0x00000000, 0xaf40004c, 0xaf400050, 0x03e00008, 0x24020001,
-	0xaf400054, 0xaf400040, 0x8f420100, 0x30423800, 0x54400001, 0xaf400044,
-	0x24020001, 0x03e00008, 0x00000000, 0x3c038000, 0x8f4201b8, 0x00431024,
-	0x1440fffd, 0x24020002, 0x240340c9, 0xaf440180, 0xa342018b, 0x3c021000,
-	0xa7430188, 0xaf4501a4, 0xaf4601a8, 0xaf4701ac, 0x03e00008, 0xaf4201b8,
-	0x3c029000, 0x34420001, 0x00822025, 0xaf440020, 0x3c038000, 0x8f420020,
-	0x00431024, 0x1440fffd, 0x00000000, 0x03e00008, 0x00000000, 0x3c028000,
-	0x34420001, 0x00822025, 0x03e00008, 0xaf440020, 0x308600ff, 0x27450180,
-	0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128,
-	0xaca20000, 0x8f640040, 0x24030008, 0x240240c1, 0xa4a20008, 0x24020002,
-	0xa0a2000b, 0x3c021000, 0xa0a6000a, 0xa4a30010, 0xa0a00012, 0xa0a00013,
-	0xaca00014, 0xaca00024, 0xaca00028, 0xaca0002c, 0xaca40018, 0x03e00008,
-	0xaf4201b8, 0x24020001, 0xacc40000, 0x03e00008, 0xa4e50000, 0x03e00008,
-	0x24020001, 0x24020001, 0xaf400044, 0x03e00008, 0xaf400050, 0x00803021,
-	0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000,
-	0x8f420128, 0xaca20000, 0x8cc30018, 0x240240c1, 0xa4a20008, 0xaca30018,
-	0x90c4000a, 0x24020002, 0xa0a2000b, 0xa0a4000a, 0x94c20010, 0xa4a20010,
-	0x90c30012, 0xa0a30012, 0x90c20013, 0xa0a20013, 0x8cc30014, 0xaca30014,
-	0x8cc20024, 0xaca20024, 0x8cc30028, 0xaca30028, 0x8cc2002c, 0x3c031000,
-	0xaca2002c, 0x24020001, 0xaf4301b8, 0xaf400044, 0x03e00008, 0xaf400050,
-	0x27bdffe8, 0xafbf0010, 0x0e001032, 0x00000000, 0x00002021, 0x0e000c99,
-	0xaf400180, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x8f460148, 0x27450180,
-	0x3c038000, 0x00061402, 0x304700ff, 0x8f4201b8, 0x00431024, 0x1440fffd,
-	0x00000000, 0x8f440140, 0x00061202, 0x304200ff, 0x00061c02, 0xaca20004,
-	0x24020002, 0xa4a30008, 0x30c300ff, 0xa0a2000b, 0xaca30024, 0x10e0000a,
-	0xaca40000, 0x28e20004, 0x14400005, 0x24020001, 0x24020005, 0x54e20005,
-	0xa0a0000a, 0x24020001, 0x0a001571, 0xa0a2000a, 0xa0a0000a, 0x3c021000,
-	0x03e00008, 0xaf4201b8, 0x03e00008, 0x00001021, 0x10c00007, 0x00000000,
-	0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000, 0x14c0fffb, 0x24840004,
-	0x03e00008, 0x00000000, 0x0a001587, 0x00a01021, 0xac860000, 0x00000000,
-	0x00000000, 0x24840004, 0x00a01021, 0x1440fffa, 0x24a5ffff, 0x03e00008,
-	0x00000000, 0x00000000 };
+	0xa0a6000a, 0xa4a30010, 0xa0a00012, 0xa0a00013, 0xaca00014, 0xaca00024,
+	0xaca00028, 0xaca0002c, 0xaca40018, 0x03e00008, 0xaf4201b8, 0x24020001,
+	0xacc40000, 0x03e00008, 0xa4e50000, 0x24020001, 0xaf400044, 0x03e00008,
+	0xaf400050, 0x00803021, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024,
+	0x1440fffd, 0x00000000, 0x8f420128, 0xaca20000, 0x8cc30018, 0x240240c1,
+	0xa4a20008, 0xaca30018, 0x90c4000a, 0x24020002, 0xa0a2000b, 0xa0a4000a,
+	0x94c20010, 0xa4a20010, 0x90c30012, 0xa0a30012, 0x90c20013, 0xa0a20013,
+	0x8cc30014, 0xaca30014, 0x8cc20024, 0xaca20024, 0x8cc30028, 0xaca30028,
+	0x8cc2002c, 0x3c031000, 0xaca2002c, 0x24020001, 0xaf4301b8, 0xaf400044,
+	0x03e00008, 0xaf400050, 0x27bdffe8, 0xafbf0010, 0x0e001047, 0x00000000,
+	0x00002021, 0x0e000c78, 0xaf400180, 0x8fbf0010, 0x03e00008, 0x27bd0018,
+	0x8f460148, 0x27450180, 0x3c038000, 0x00061402, 0x304700ff, 0x8f4201b8,
+	0x00431024, 0x1440fffd, 0x00000000, 0x8f440140, 0x00061202, 0x304200ff,
+	0x00061c02, 0xaca20004, 0x24020002, 0xa4a30008, 0x30c300ff, 0xa0a2000b,
+	0xaca30024, 0x10e0000a, 0xaca40000, 0x28e20004, 0x14400005, 0x24020001,
+	0x24020005, 0x54e20005, 0xa0a0000a, 0x24020001, 0x0a001609, 0xa0a2000a,
+	0xa0a0000a, 0x3c021000, 0x03e00008, 0xaf4201b8, 0x03e00008, 0x00001021,
+	0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000,
+	0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a00161f, 0x00a01021,
+	0xac860000, 0x00000000, 0x00000000, 0x24840004, 0x00a01021, 0x1440fffa,
+	0x24a5ffff, 0x03e00008, 0x00000000, 0x00000000 }; 
 
 static u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x0 };
-static u32 bnx2_RXP_b06FwRodata[(0x0/4) + 1] = { 0x0 };
-static u32 bnx2_RXP_b06FwBss[(0x1394/4) + 1] = { 0x0 };
-static u32 bnx2_RXP_b06FwSbss[(0x18/4) + 1] = { 0x0 };
+static u32 bnx2_RXP_b06FwRodata[(0x28/4) + 1] = {
+	0x0800468c, 0x0800458c, 0x08004630, 0x08004648, 0x08004660, 0x08004680,
+	0x0800468c, 0x0800468c, 0x08004594, 0x00000000, 0x00000000 };
+static u32 bnx2_RXP_b06FwBss[(0x13a4/4) + 1] = { 0x0 };
+static u32 bnx2_RXP_b06FwSbss[(0x1c/4) + 1] = { 0x0 };
 
 static u32 bnx2_rv2p_proc1[] = {
 	0x00000008, 0xac000001, 0x0000000c, 0x2f800001, 0x00000010, 0x213f0004,
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 2582d98..4ff006c 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -576,7 +576,7 @@ static int bond_update_speed_duplex(stru
 	slave->duplex = DUPLEX_FULL;
 
 	if (slave_dev->ethtool_ops) {
-		u32 res;
+		int res;
 
 		if (!slave_dev->ethtool_ops->get_settings) {
 			return -1;
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 1f7ca45..6e295fc 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -335,6 +335,30 @@ static inline void cas_mask_intr(struct 
 		cas_disable_irq(cp, i);
 }
 
+static inline void cas_buffer_init(cas_page_t *cp)
+{
+	struct page *page = cp->buffer;
+	atomic_set((atomic_t *)&page->lru.next, 1);
+}
+
+static inline int cas_buffer_count(cas_page_t *cp)
+{
+	struct page *page = cp->buffer;
+	return atomic_read((atomic_t *)&page->lru.next);
+}
+
+static inline void cas_buffer_inc(cas_page_t *cp)
+{
+	struct page *page = cp->buffer;
+	atomic_inc((atomic_t *)&page->lru.next);
+}
+
+static inline void cas_buffer_dec(cas_page_t *cp)
+{
+	struct page *page = cp->buffer;
+	atomic_dec((atomic_t *)&page->lru.next);
+}
+
 static void cas_enable_irq(struct cas *cp, const int ring)
 {
 	if (ring == 0) { /* all but TX_DONE */
@@ -472,6 +496,7 @@ static int cas_page_free(struct cas *cp,
 {
 	pci_unmap_page(cp->pdev, page->dma_addr, cp->page_size, 
 		       PCI_DMA_FROMDEVICE);
+	cas_buffer_dec(page);
 	__free_pages(page->buffer, cp->page_order);
 	kfree(page);
 	return 0;
@@ -501,6 +526,7 @@ static cas_page_t *cas_page_alloc(struct
 	page->buffer = alloc_pages(flags, cp->page_order);
 	if (!page->buffer)
 		goto page_err;
+	cas_buffer_init(page);
 	page->dma_addr = pci_map_page(cp->pdev, page->buffer, 0,
 				      cp->page_size, PCI_DMA_FROMDEVICE);
 	return page;
@@ -579,7 +605,7 @@ static void cas_spare_recover(struct cas
 	list_for_each_safe(elem, tmp, &list) {
 		cas_page_t *page = list_entry(elem, cas_page_t, list);
 
-		if (page_count(page->buffer) > 1) 
+		if (cas_buffer_count(page) > 1)
 			continue;
 
 		list_del(elem);
@@ -1347,7 +1373,7 @@ static inline cas_page_t *cas_page_spare
 	cas_page_t *page = cp->rx_pages[1][index];
 	cas_page_t *new;
 
-	if (page_count(page->buffer) == 1)
+	if (cas_buffer_count(page) == 1)
 		return page;
 
 	new = cas_page_dequeue(cp);
@@ -1367,7 +1393,7 @@ static cas_page_t *cas_page_swap(struct 
 	cas_page_t **page1 = cp->rx_pages[1];
 
 	/* swap if buffer is in use */
-	if (page_count(page0[index]->buffer) > 1) {
+	if (cas_buffer_count(page0[index]) > 1) {
 		cas_page_t *new = cas_page_spare(cp, index);
 		if (new) {
 			page1[index] = page0[index];
@@ -1925,8 +1951,8 @@ static void cas_tx(struct net_device *de
 	u64 compwb = le64_to_cpu(cp->init_block->tx_compwb);
 #endif
 	if (netif_msg_intr(cp))
-		printk(KERN_DEBUG "%s: tx interrupt, status: 0x%x, %lx\n",
-			cp->dev->name, status, compwb);
+		printk(KERN_DEBUG "%s: tx interrupt, status: 0x%x, %llx\n",
+			cp->dev->name, status, (unsigned long long)compwb);
 	/* process all the rings */
 	for (ring = 0; ring < N_TX_RINGS; ring++) {
 #ifdef USE_TX_COMPWB
@@ -2039,6 +2065,7 @@ static int cas_rx_process_pkt(struct cas
 		skb->len      += hlen - swivel;
 
 		get_page(page->buffer);
+		cas_buffer_inc(page);
 		frag->page = page->buffer;
 		frag->page_offset = off;
 		frag->size = hlen - swivel;
@@ -2063,6 +2090,7 @@ static int cas_rx_process_pkt(struct cas
 			frag++;
 
 			get_page(page->buffer);
+			cas_buffer_inc(page);
 			frag->page = page->buffer;
 			frag->page_offset = 0;
 			frag->size = hlen;
@@ -2225,7 +2253,7 @@ static int cas_post_rxds_ringN(struct ca
 	released = 0;
 	while (entry != last) {
 		/* make a new buffer if it's still in use */
-		if (page_count(page[entry]->buffer) > 1) {
+		if (cas_buffer_count(page[entry]) > 1) {
 			cas_page_t *new = cas_page_dequeue(cp);
 			if (!new) {
 				/* let the timer know that we need to 
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 4726722..bf1fd2b 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1,25 +1,25 @@
 /*******************************************************************************
 
-  
+
   Copyright(c) 1999 - 2005 Intel Corporation. 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) 
+
+  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 
+
+  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 
+  this program; if not, write to the Free Software Foundation, Inc., 59
   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-  
+
   The full GNU General Public License is included in this distribution in the
   file called LICENSE.
-  
+
   Contact Information:
   Linux NICS <linux.nics@intel.com>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
@@ -160,7 +160,7 @@
 
 #define DRV_NAME		"e100"
 #define DRV_EXT		"-NAPI"
-#define DRV_VERSION		"3.4.14-k4"DRV_EXT
+#define DRV_VERSION		"3.5.10-k2"DRV_EXT
 #define DRV_DESCRIPTION		"Intel(R) PRO/100 Network Driver"
 #define DRV_COPYRIGHT		"Copyright(c) 1999-2005 Intel Corporation"
 #define PFX			DRV_NAME ": "
@@ -320,7 +320,7 @@ enum cuc_dump {
 	cuc_dump_complete       = 0x0000A005,
 	cuc_dump_reset_complete = 0x0000A007,
 };
-		
+
 enum port {
 	software_reset  = 0x0000,
 	selftest        = 0x0001,
@@ -715,10 +715,10 @@ static u16 e100_eeprom_read(struct nic *
 		ctrl = (cmd_addr_data & (1 << i)) ? eecs | eedi : eecs;
 		writeb(ctrl, &nic->csr->eeprom_ctrl_lo);
 		e100_write_flush(nic); udelay(4);
-		
+
 		writeb(ctrl | eesk, &nic->csr->eeprom_ctrl_lo);
 		e100_write_flush(nic); udelay(4);
-		
+
 		/* Eeprom drives a dummy zero to EEDO after receiving
 		 * complete address.  Use this to adjust addr_len. */
 		ctrl = readb(&nic->csr->eeprom_ctrl_lo);
@@ -726,7 +726,7 @@ static u16 e100_eeprom_read(struct nic *
 			*addr_len -= (i - 16);
 			i = 17;
 		}
-		
+
 		data = (data << 1) | (ctrl & eedo ? 1 : 0);
 	}
 
@@ -1170,7 +1170,7 @@ static void e100_configure(struct nic *n
 0x00000000, 0x00000000, 0x00000000, 0x00000000, \
 }
 
-static void e100_load_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb)
+static void e100_setup_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb)
 {
 /* *INDENT-OFF* */
 	static struct {
@@ -1213,13 +1213,13 @@ static void e100_load_ucode(struct nic *
 *  driver can change the algorithm.
 *
 *  INTDELAY - This loads the dead-man timer with its inital value.
-*    When this timer expires the interrupt is asserted, and the 
+*    When this timer expires the interrupt is asserted, and the
 *    timer is reset each time a new packet is received.  (see
 *    BUNDLEMAX below to set the limit on number of chained packets)
 *    The current default is 0x600 or 1536.  Experiments show that
 *    the value should probably stay within the 0x200 - 0x1000.
 *
-*  BUNDLEMAX - 
+*  BUNDLEMAX -
 *    This sets the maximum number of frames that will be bundled.  In
 *    some situations, such as the TCP windowing algorithm, it may be
 *    better to limit the growth of the bundle size than let it go as
@@ -1229,7 +1229,7 @@ static void e100_load_ucode(struct nic *
 *    an interrupt for every frame received.  If you do not want to put
 *    a limit on the bundle size, set this value to xFFFF.
 *
-*  BUNDLESMALL - 
+*  BUNDLESMALL -
 *    This contains a bit-mask describing the minimum size frame that
 *    will be bundled.  The default masks the lower 7 bits, which means
 *    that any frame less than 128 bytes in length will not be bundled,
@@ -1244,7 +1244,7 @@ static void e100_load_ucode(struct nic *
 *
 *    The current default is 0xFF80, which masks out the lower 7 bits.
 *    This means that any frame which is x7F (127) bytes or smaller
-*    will cause an immediate interrupt.  Because this value must be a 
+*    will cause an immediate interrupt.  Because this value must be a
 *    bit mask, there are only a few valid values that can be used.  To
 *    turn this feature off, the driver can write the value xFFFF to the
 *    lower word of this instruction (in the same way that the other
@@ -1253,7 +1253,7 @@ static void e100_load_ucode(struct nic *
 *    standard Ethernet frames are <= 2047 bytes in length.
 *************************************************************************/
 
-/* if you wish to disable the ucode functionality, while maintaining the 
+/* if you wish to disable the ucode functionality, while maintaining the
  * workarounds it provides, set the following defines to:
  * BUNDLESMALL 0
  * BUNDLEMAX 1
@@ -1284,12 +1284,46 @@ static void e100_load_ucode(struct nic *
 
 		for (i = 0; i < UCODE_SIZE; i++)
 			cb->u.ucode[i] = cpu_to_le32(ucode[i]);
-		cb->command = cpu_to_le16(cb_ucode);
+		cb->command = cpu_to_le16(cb_ucode | cb_el);
 		return;
 	}
 
 noloaducode:
-	cb->command = cpu_to_le16(cb_nop);
+	cb->command = cpu_to_le16(cb_nop | cb_el);
+}
+
+static inline int e100_exec_cb_wait(struct nic *nic, struct sk_buff *skb,
+	void (*cb_prepare)(struct nic *, struct cb *, struct sk_buff *))
+{
+	int err = 0, counter = 50;
+	struct cb *cb = nic->cb_to_clean;
+
+	if ((err = e100_exec_cb(nic, NULL, e100_setup_ucode)))
+		DPRINTK(PROBE,ERR, "ucode cmd failed with error %d\n", err);
+
+	/* must restart cuc */
+	nic->cuc_cmd = cuc_start;
+
+	/* wait for completion */
+	e100_write_flush(nic);
+	udelay(10);
+
+	/* wait for possibly (ouch) 500ms */
+	while (!(cb->status & cpu_to_le16(cb_complete))) {
+		msleep(10);
+		if (!--counter) break;
+	}
+
+	/* ack any interupts, something could have been set */
+	writeb(~0, &nic->csr->scb.stat_ack);
+
+	/* if the command failed, or is not OK, notify and return */
+	if (!counter || !(cb->status & cpu_to_le16(cb_ok))) {
+		DPRINTK(PROBE,ERR, "ucode load failed\n");
+		err = -EPERM;
+	}
+
+	return err;
 }
 
 static void e100_setup_iaaddr(struct nic *nic, struct cb *cb,
@@ -1357,13 +1391,13 @@ static int e100_phy_init(struct nic *nic
 		mdio_write(netdev, nic->mii.phy_id, MII_NSC_CONG, cong);
 	}
 
-	if((nic->mac >= mac_82550_D102) || ((nic->flags & ich) && 
+	if((nic->mac >= mac_82550_D102) || ((nic->flags & ich) &&
 	   (mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000))) {
 		/* enable/disable MDI/MDI-X auto-switching.
 		   MDI/MDI-X auto-switching is disabled for 82551ER/QM chips */
 		if((nic->mac == mac_82551_E) || (nic->mac == mac_82551_F) ||
-		   (nic->mac == mac_82551_10) || (nic->mii.force_media) || 
-		   !(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled)) 
+		   (nic->mac == mac_82551_10) || (nic->mii.force_media) ||
+		   !(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))
 			mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG, 0);
 		else
 			mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG, NCONFIG_AUTO_SWITCH);
@@ -1388,7 +1422,7 @@ static int e100_hw_init(struct nic *nic)
 		return err;
 	if((err = e100_exec_cmd(nic, ruc_load_base, 0)))
 		return err;
-	if((err = e100_exec_cb(nic, NULL, e100_load_ucode)))
+	if ((err = e100_exec_cb_wait(nic, NULL, e100_setup_ucode)))
 		return err;
 	if((err = e100_exec_cb(nic, NULL, e100_configure)))
 		return err;
@@ -1493,7 +1527,7 @@ static void e100_update_stats(struct nic
 		}
 	}
 
-	
+
 	if(e100_exec_cmd(nic, cuc_dump_reset, 0))
 		DPRINTK(TX_ERR, DEBUG, "exec cuc_dump_reset failed\n");
 }
@@ -1542,10 +1576,10 @@ static void e100_watchdog(unsigned long 
 	mii_check_link(&nic->mii);
 
 	/* Software generated interrupt to recover from (rare) Rx
-	* allocation failure.
-	* Unfortunately have to use a spinlock to not re-enable interrupts
-	* accidentally, due to hardware that shares a register between the
-	* interrupt mask bit and the SW Interrupt generation bit */
+	 * allocation failure.
+	 * Unfortunately have to use a spinlock to not re-enable interrupts
+	 * accidentally, due to hardware that shares a register between the
+	 * interrupt mask bit and the SW Interrupt generation bit */
 	spin_lock_irq(&nic->cmd_lock);
 	writeb(readb(&nic->csr->scb.cmd_hi) | irq_sw_gen,&nic->csr->scb.cmd_hi);
 	spin_unlock_irq(&nic->cmd_lock);
@@ -1830,7 +1864,7 @@ static void e100_rx_clean(struct nic *ni
 	struct rx *rx_to_start = NULL;
 
 	/* are we already rnr? then pay attention!!! this ensures that
-	 * the state machine progression never allows a start with a 
+	 * the state machine progression never allows a start with a
 	 * partially cleaned list, avoiding a race between hardware
 	 * and rx_to_clean when in NAPI mode */
 	if(RU_SUSPENDED == nic->ru_running)
@@ -2066,7 +2100,7 @@ static void e100_tx_timeout(struct net_d
 {
 	struct nic *nic = netdev_priv(netdev);
 
-	/* Reset outside of interrupt context, to avoid request_irq 
+	/* Reset outside of interrupt context, to avoid request_irq
 	 * in interrupt context */
 	schedule_work(&nic->tx_timeout_task);
 }
@@ -2313,7 +2347,7 @@ static int e100_set_ringparam(struct net
 	struct param_range *rfds = &nic->params.rfds;
 	struct param_range *cbs = &nic->params.cbs;
 
-	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) 
+	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
 		return -EINVAL;
 
 	if(netif_running(netdev))
@@ -2631,7 +2665,9 @@ static int __devinit e100_probe(struct p
 		nic->flags |= wol_magic;
 
 	/* ack any pending wake events, disable PME */
-	pci_enable_wake(pdev, 0, 0);
+	err = pci_enable_wake(pdev, 0, 0);
+	if (err)
+		DPRINTK(PROBE, ERR, "Error clearing wake event\n");
 
 	strcpy(netdev->name, "eth%d");
 	if((err = register_netdev(netdev))) {
@@ -2682,6 +2718,7 @@ static int e100_suspend(struct pci_dev *
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct nic *nic = netdev_priv(netdev);
+	int retval;
 
 	if(netif_running(netdev))
 		e100_down(nic);
@@ -2689,9 +2726,14 @@ static int e100_suspend(struct pci_dev *
 	netif_device_detach(netdev);
 
 	pci_save_state(pdev);
-	pci_enable_wake(pdev, pci_choose_state(pdev, state), nic->flags & (wol_magic | e100_asf(nic)));
+	retval = pci_enable_wake(pdev, pci_choose_state(pdev, state),
+	                         nic->flags & (wol_magic | e100_asf(nic)));
+	if (retval)
+		DPRINTK(PROBE,ERR, "Error enabling wake\n");
 	pci_disable_device(pdev);
-	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+	retval = pci_set_power_state(pdev, pci_choose_state(pdev, state));
+	if (retval)
+		DPRINTK(PROBE,ERR, "Error %d setting power state\n", retval);
 
 	return 0;
 }
@@ -2700,11 +2742,16 @@ static int e100_resume(struct pci_dev *p
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct nic *nic = netdev_priv(netdev);
+	int retval;
 
-	pci_set_power_state(pdev, PCI_D0);
+	retval = pci_set_power_state(pdev, PCI_D0);
+	if (retval)
+		DPRINTK(PROBE,ERR, "Error waking adapter\n");
 	pci_restore_state(pdev);
 	/* ack any pending wake events, disable PME */
-	pci_enable_wake(pdev, 0, 0);
+	retval = pci_enable_wake(pdev, 0, 0);
+	if (retval)
+		DPRINTK(PROBE,ERR, "Error clearing wake events\n");
 	if(e100_hw_init(nic))
 		DPRINTK(HW, ERR, "e100_hw_init failed\n");
 
@@ -2721,12 +2768,15 @@ static void e100_shutdown(struct pci_dev
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct nic *nic = netdev_priv(netdev);
+	int retval;
 
 #ifdef CONFIG_PM
-	pci_enable_wake(pdev, 0, nic->flags & (wol_magic | e100_asf(nic)));
+	retval = pci_enable_wake(pdev, 0, nic->flags & (wol_magic | e100_asf(nic)));
 #else
-	pci_enable_wake(pdev, 0, nic->flags & (wol_magic));
+	retval = pci_enable_wake(pdev, 0, nic->flags & (wol_magic));
 #endif
+	if (retval)
+		DPRINTK(PROBE,ERR, "Error enabling wake\n");
 }
 
 
@@ -2739,7 +2789,7 @@ static struct pci_driver e100_driver = {
 	.suspend =      e100_suspend,
 	.resume =       e100_resume,
 #endif
-	.shutdown =	e100_shutdown,
+	.shutdown =     e100_shutdown,
 };
 
 static int __init e100_init_module(void)
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index e02e9ba..27c7730 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -72,10 +72,6 @@
 #include <linux/mii.h>
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
-#ifdef CONFIG_E1000_MQ
-#include <linux/cpu.h>
-#include <linux/smp.h>
-#endif
 
 #define BAR_0		0
 #define BAR_1		1
@@ -87,6 +83,10 @@
 struct e1000_adapter;
 
 #include "e1000_hw.h"
+#ifdef CONFIG_E1000_MQ
+#include <linux/cpu.h>
+#include <linux/smp.h>
+#endif
 
 #ifdef DBG
 #define E1000_DBG(args...) printk(KERN_DEBUG "e1000: " args)
@@ -169,6 +169,13 @@ struct e1000_buffer {
 	uint16_t next_to_watch;
 };
 
+#ifdef CONFIG_E1000_MQ
+struct e1000_queue_stats {
+	uint64_t packets;
+	uint64_t bytes;
+};
+#endif
+
 struct e1000_ps_page { struct page *ps_page[PS_PAGE_BUFFERS]; };
 struct e1000_ps_page_dma { uint64_t ps_page_dma[PS_PAGE_BUFFERS]; };
 
@@ -191,10 +198,12 @@ struct e1000_tx_ring {
 	spinlock_t tx_lock;
 	uint16_t tdh;
 	uint16_t tdt;
-	uint64_t pkt;
 
 	boolean_t last_tx_tso;
 
+#ifdef CONFIG_E1000_MQ
+	struct e1000_queue_stats tx_stats;
+#endif
 };
 
 struct e1000_rx_ring {
@@ -216,9 +225,17 @@ struct e1000_rx_ring {
 	struct e1000_ps_page *ps_page;
 	struct e1000_ps_page_dma *ps_page_dma;
 
+	struct sk_buff *rx_skb_top;
+	struct sk_buff *rx_skb_prev;
+
+	/* cpu for rx queue */
+	int cpu;
+
 	uint16_t rdh;
 	uint16_t rdt;
-	uint64_t pkt;
+#ifdef CONFIG_E1000_MQ
+	struct e1000_queue_stats rx_stats;
+#endif
 };
 
 #define E1000_DESC_UNUSED(R) \
@@ -251,6 +268,9 @@ struct e1000_adapter {
 	uint16_t link_speed;
 	uint16_t link_duplex;
 	spinlock_t stats_lock;
+#ifdef CONFIG_E1000_NAPI
+	spinlock_t tx_queue_lock;
+#endif
 	atomic_t irq_sem;
 	struct work_struct tx_timeout_task;
 	struct work_struct watchdog_task;
@@ -264,6 +284,7 @@ struct e1000_adapter {
 #ifdef CONFIG_E1000_MQ
 	struct e1000_tx_ring **cpu_tx_ring; /* per-cpu */
 #endif
+	unsigned long tx_queue_len;
 	uint32_t txd_cmd;
 	uint32_t tx_int_delay;
 	uint32_t tx_abs_int_delay;
@@ -271,9 +292,11 @@ struct e1000_adapter {
 	uint64_t gotcl_old;
 	uint64_t tpt_old;
 	uint64_t colc_old;
+	uint32_t tx_timeout_count;
 	uint32_t tx_fifo_head;
 	uint32_t tx_head_addr;
 	uint32_t tx_fifo_size;
+	uint8_t  tx_timeout_factor;
 	atomic_t tx_fifo_stall;
 	boolean_t pcix_82544;
 	boolean_t detect_tx_hung;
@@ -281,14 +304,15 @@ struct e1000_adapter {
 	/* RX */
 #ifdef CONFIG_E1000_NAPI
 	boolean_t (*clean_rx) (struct e1000_adapter *adapter,
-			       struct e1000_rx_ring *rx_ring,
-			       int *work_done, int work_to_do);
+						   struct e1000_rx_ring *rx_ring,
+						   int *work_done, int work_to_do);
 #else
 	boolean_t (*clean_rx) (struct e1000_adapter *adapter,
-			       struct e1000_rx_ring *rx_ring);
+						   struct e1000_rx_ring *rx_ring);
 #endif
 	void (*alloc_rx_buf) (struct e1000_adapter *adapter,
-			      struct e1000_rx_ring *rx_ring);
+						  struct e1000_rx_ring *rx_ring,
+						  int cleaned_count);
 	struct e1000_rx_ring *rx_ring;      /* One per active queue */
 #ifdef CONFIG_E1000_NAPI
 	struct net_device *polling_netdev;  /* One per active queue */
@@ -296,13 +320,15 @@ struct e1000_adapter {
 #ifdef CONFIG_E1000_MQ
 	struct net_device **cpu_netdev;     /* per-cpu */
 	struct call_async_data_struct rx_sched_call_data;
-	int cpu_for_queue[4];
+	cpumask_t cpumask;
 #endif
-	int num_queues;
+	int num_tx_queues;
+	int num_rx_queues;
 
 	uint64_t hw_csum_err;
 	uint64_t hw_csum_good;
 	uint64_t rx_hdr_split;
+	uint32_t alloc_rx_buff_failed;
 	uint32_t rx_int_delay;
 	uint32_t rx_abs_int_delay;
 	boolean_t rx_csum;
@@ -330,6 +356,7 @@ struct e1000_adapter {
 	struct e1000_rx_ring test_rx_ring;
 
 
+	u32 *config_space;
 	int msg_enable;
 #ifdef CONFIG_PCI_MSI
 	boolean_t have_msi;
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index c88f1a3..5cedc81 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -80,6 +80,7 @@ static const struct e1000_stats e1000_gs
 	{ "tx_deferred_ok", E1000_STAT(stats.dc) },
 	{ "tx_single_coll_ok", E1000_STAT(stats.scc) },
 	{ "tx_multi_coll_ok", E1000_STAT(stats.mcc) },
+	{ "tx_timeout_count", E1000_STAT(tx_timeout_count) },
 	{ "rx_long_length_errors", E1000_STAT(stats.roc) },
 	{ "rx_short_length_errors", E1000_STAT(stats.ruc) },
 	{ "rx_align_errors", E1000_STAT(stats.algnerrc) },
@@ -93,9 +94,20 @@ static const struct e1000_stats e1000_gs
 	{ "rx_csum_offload_good", E1000_STAT(hw_csum_good) },
 	{ "rx_csum_offload_errors", E1000_STAT(hw_csum_err) },
 	{ "rx_header_split", E1000_STAT(rx_hdr_split) },
+	{ "alloc_rx_buff_failed", E1000_STAT(alloc_rx_buff_failed) },
 };
-#define E1000_STATS_LEN	\
+
+#ifdef CONFIG_E1000_MQ
+#define E1000_QUEUE_STATS_LEN \
+	(((struct e1000_adapter *)netdev->priv)->num_tx_queues + \
+	 ((struct e1000_adapter *)netdev->priv)->num_rx_queues) \
+	* (sizeof(struct e1000_queue_stats) / sizeof(uint64_t))
+#else
+#define E1000_QUEUE_STATS_LEN 0
+#endif
+#define E1000_GLOBAL_STATS_LEN	\
 	sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats)
+#define E1000_STATS_LEN (E1000_GLOBAL_STATS_LEN + E1000_QUEUE_STATS_LEN)
 static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = {
 	"Register test  (offline)", "Eeprom test    (offline)",
 	"Interrupt test (offline)", "Loopback test  (offline)",
@@ -109,7 +121,7 @@ e1000_get_settings(struct net_device *ne
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 
-	if(hw->media_type == e1000_media_type_copper) {
+	if (hw->media_type == e1000_media_type_copper) {
 
 		ecmd->supported = (SUPPORTED_10baseT_Half |
 		                   SUPPORTED_10baseT_Full |
@@ -121,7 +133,7 @@ e1000_get_settings(struct net_device *ne
 
 		ecmd->advertising = ADVERTISED_TP;
 
-		if(hw->autoneg == 1) {
+		if (hw->autoneg == 1) {
 			ecmd->advertising |= ADVERTISED_Autoneg;
 
 			/* the e1000 autoneg seems to match ethtool nicely */
@@ -132,7 +144,7 @@ e1000_get_settings(struct net_device *ne
 		ecmd->port = PORT_TP;
 		ecmd->phy_address = hw->phy_addr;
 
-		if(hw->mac_type == e1000_82543)
+		if (hw->mac_type == e1000_82543)
 			ecmd->transceiver = XCVR_EXTERNAL;
 		else
 			ecmd->transceiver = XCVR_INTERNAL;
@@ -148,13 +160,13 @@ e1000_get_settings(struct net_device *ne
 
 		ecmd->port = PORT_FIBRE;
 
-		if(hw->mac_type >= e1000_82545)
+		if (hw->mac_type >= e1000_82545)
 			ecmd->transceiver = XCVR_INTERNAL;
 		else
 			ecmd->transceiver = XCVR_EXTERNAL;
 	}
 
-	if(netif_carrier_ok(adapter->netdev)) {
+	if (netif_carrier_ok(adapter->netdev)) {
 
 		e1000_get_speed_and_duplex(hw, &adapter->link_speed,
 		                                   &adapter->link_duplex);
@@ -163,7 +175,7 @@ e1000_get_settings(struct net_device *ne
 		/* unfortunatly FULL_DUPLEX != DUPLEX_FULL
 		 *          and HALF_DUPLEX != DUPLEX_HALF */
 
-		if(adapter->link_duplex == FULL_DUPLEX)
+		if (adapter->link_duplex == FULL_DUPLEX)
 			ecmd->duplex = DUPLEX_FULL;
 		else
 			ecmd->duplex = DUPLEX_HALF;
@@ -183,13 +195,21 @@ e1000_set_settings(struct net_device *ne
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 
-	if(ecmd->autoneg == AUTONEG_ENABLE) {
+	/* When SoL/IDER sessions are active, autoneg/speed/duplex
+	 * cannot be changed */
+	if (e1000_check_phy_reset_block(hw)) {
+		DPRINTK(DRV, ERR, "Cannot change link characteristics "
+		        "when SoL/IDER is active.\n");
+		return -EINVAL;
+	}
+
+	if (ecmd->autoneg == AUTONEG_ENABLE) {
 		hw->autoneg = 1;
-		if(hw->media_type == e1000_media_type_fiber)
+		if (hw->media_type == e1000_media_type_fiber)
 			hw->autoneg_advertised = ADVERTISED_1000baseT_Full |
 				     ADVERTISED_FIBRE |
 				     ADVERTISED_Autoneg;
-		else 
+		else
 			hw->autoneg_advertised = ADVERTISED_10baseT_Half |
 						  ADVERTISED_10baseT_Full |
 						  ADVERTISED_100baseT_Half |
@@ -199,12 +219,12 @@ e1000_set_settings(struct net_device *ne
 						  ADVERTISED_TP;
 		ecmd->advertising = hw->autoneg_advertised;
 	} else
-		if(e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex))
+		if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex))
 			return -EINVAL;
 
 	/* reset the link */
 
-	if(netif_running(adapter->netdev)) {
+	if (netif_running(adapter->netdev)) {
 		e1000_down(adapter);
 		e1000_reset(adapter);
 		e1000_up(adapter);
@@ -221,14 +241,14 @@ e1000_get_pauseparam(struct net_device *
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 
-	pause->autoneg = 
+	pause->autoneg =
 		(adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
-	
-	if(hw->fc == e1000_fc_rx_pause)
+
+	if (hw->fc == e1000_fc_rx_pause)
 		pause->rx_pause = 1;
-	else if(hw->fc == e1000_fc_tx_pause)
+	else if (hw->fc == e1000_fc_tx_pause)
 		pause->tx_pause = 1;
-	else if(hw->fc == e1000_fc_full) {
+	else if (hw->fc == e1000_fc_full) {
 		pause->rx_pause = 1;
 		pause->tx_pause = 1;
 	}
@@ -240,31 +260,30 @@ e1000_set_pauseparam(struct net_device *
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
-	
+
 	adapter->fc_autoneg = pause->autoneg;
 
-	if(pause->rx_pause && pause->tx_pause)
+	if (pause->rx_pause && pause->tx_pause)
 		hw->fc = e1000_fc_full;
-	else if(pause->rx_pause && !pause->tx_pause)
+	else if (pause->rx_pause && !pause->tx_pause)
 		hw->fc = e1000_fc_rx_pause;
-	else if(!pause->rx_pause && pause->tx_pause)
+	else if (!pause->rx_pause && pause->tx_pause)
 		hw->fc = e1000_fc_tx_pause;
-	else if(!pause->rx_pause && !pause->tx_pause)
+	else if (!pause->rx_pause && !pause->tx_pause)
 		hw->fc = e1000_fc_none;
 
 	hw->original_fc = hw->fc;
 
-	if(adapter->fc_autoneg == AUTONEG_ENABLE) {
-		if(netif_running(adapter->netdev)) {
+	if (adapter->fc_autoneg == AUTONEG_ENABLE) {
+		if (netif_running(adapter->netdev)) {
 			e1000_down(adapter);
 			e1000_up(adapter);
 		} else
 			e1000_reset(adapter);
-	}
-	else
+	} else
 		return ((hw->media_type == e1000_media_type_fiber) ?
 			e1000_setup_link(hw) : e1000_force_mac_fc(hw));
-	
+
 	return 0;
 }
 
@@ -281,14 +300,14 @@ e1000_set_rx_csum(struct net_device *net
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	adapter->rx_csum = data;
 
-	if(netif_running(netdev)) {
+	if (netif_running(netdev)) {
 		e1000_down(adapter);
 		e1000_up(adapter);
 	} else
 		e1000_reset(adapter);
 	return 0;
 }
-	
+
 static uint32_t
 e1000_get_tx_csum(struct net_device *netdev)
 {
@@ -300,7 +319,7 @@ e1000_set_tx_csum(struct net_device *net
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 
-	if(adapter->hw.mac_type < e1000_82543) {
+	if (adapter->hw.mac_type < e1000_82543) {
 		if (!data)
 			return -EINVAL;
 		return 0;
@@ -319,8 +338,8 @@ static int
 e1000_set_tso(struct net_device *netdev, uint32_t data)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
-	if((adapter->hw.mac_type < e1000_82544) ||
-	    (adapter->hw.mac_type == e1000_82547)) 
+	if ((adapter->hw.mac_type < e1000_82544) ||
+	    (adapter->hw.mac_type == e1000_82547))
 		return data ? -EINVAL : 0;
 
 	if (data)
@@ -328,7 +347,7 @@ e1000_set_tso(struct net_device *netdev,
 	else
 		netdev->features &= ~NETIF_F_TSO;
 	return 0;
-} 
+}
 #endif /* NETIF_F_TSO */
 
 static uint32_t
@@ -345,7 +364,7 @@ e1000_set_msglevel(struct net_device *ne
 	adapter->msg_enable = data;
 }
 
-static int 
+static int
 e1000_get_regs_len(struct net_device *netdev)
 {
 #define E1000_REGS_LEN 32
@@ -381,7 +400,7 @@ e1000_get_regs(struct net_device *netdev
 	regs_buff[11] = E1000_READ_REG(hw, TIDV);
 
 	regs_buff[12] = adapter->hw.phy_type;  /* PHY type (IGP=1, M88=0) */
-	if(hw->phy_type == e1000_phy_igp) {
+	if (hw->phy_type == e1000_phy_igp) {
 		e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
 				    IGP01E1000_PHY_AGC_A);
 		e1000_read_phy_reg(hw, IGP01E1000_PHY_AGC_A &
@@ -435,7 +454,7 @@ e1000_get_regs(struct net_device *netdev
 	e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
 	regs_buff[24] = (uint32_t)phy_data;  /* phy local receiver status */
 	regs_buff[25] = regs_buff[24];  /* phy remote receiver status */
-	if(hw->mac_type >= e1000_82540 &&
+	if (hw->mac_type >= e1000_82540 &&
 	   hw->media_type == e1000_media_type_copper) {
 		regs_buff[26] = E1000_READ_REG(hw, MANC);
 	}
@@ -459,7 +478,7 @@ e1000_get_eeprom(struct net_device *netd
 	int ret_val = 0;
 	uint16_t i;
 
-	if(eeprom->len == 0)
+	if (eeprom->len == 0)
 		return -EINVAL;
 
 	eeprom->magic = hw->vendor_id | (hw->device_id << 16);
@@ -469,16 +488,16 @@ e1000_get_eeprom(struct net_device *netd
 
 	eeprom_buff = kmalloc(sizeof(uint16_t) *
 			(last_word - first_word + 1), GFP_KERNEL);
-	if(!eeprom_buff)
+	if (!eeprom_buff)
 		return -ENOMEM;
 
-	if(hw->eeprom.type == e1000_eeprom_spi)
+	if (hw->eeprom.type == e1000_eeprom_spi)
 		ret_val = e1000_read_eeprom(hw, first_word,
 					    last_word - first_word + 1,
 					    eeprom_buff);
 	else {
 		for (i = 0; i < last_word - first_word + 1; i++)
-			if((ret_val = e1000_read_eeprom(hw, first_word + i, 1,
+			if ((ret_val = e1000_read_eeprom(hw, first_word + i, 1,
 							&eeprom_buff[i])))
 				break;
 	}
@@ -505,10 +524,10 @@ e1000_set_eeprom(struct net_device *netd
 	int max_len, first_word, last_word, ret_val = 0;
 	uint16_t i;
 
-	if(eeprom->len == 0)
+	if (eeprom->len == 0)
 		return -EOPNOTSUPP;
 
-	if(eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
+	if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
 		return -EFAULT;
 
 	max_len = hw->eeprom.word_size * 2;
@@ -516,19 +535,19 @@ e1000_set_eeprom(struct net_device *netd
 	first_word = eeprom->offset >> 1;
 	last_word = (eeprom->offset + eeprom->len - 1) >> 1;
 	eeprom_buff = kmalloc(max_len, GFP_KERNEL);
-	if(!eeprom_buff)
+	if (!eeprom_buff)
 		return -ENOMEM;
 
 	ptr = (void *)eeprom_buff;
 
-	if(eeprom->offset & 1) {
+	if (eeprom->offset & 1) {
 		/* need read/modify/write of first changed EEPROM word */
 		/* only the second byte of the word is being modified */
 		ret_val = e1000_read_eeprom(hw, first_word, 1,
 					    &eeprom_buff[0]);
 		ptr++;
 	}
-	if(((eeprom->offset + eeprom->len) & 1) && (ret_val == 0)) {
+	if (((eeprom->offset + eeprom->len) & 1) && (ret_val == 0)) {
 		/* need read/modify/write of last changed EEPROM word */
 		/* only the first byte of the word is being modified */
 		ret_val = e1000_read_eeprom(hw, last_word, 1,
@@ -547,9 +566,9 @@ e1000_set_eeprom(struct net_device *netd
 	ret_val = e1000_write_eeprom(hw, first_word,
 				     last_word - first_word + 1, eeprom_buff);
 
-	/* Update the checksum over the first part of the EEPROM if needed 
+	/* Update the checksum over the first part of the EEPROM if needed
 	 * and flush shadow RAM for 82573 conrollers */
-	if((ret_val == 0) && ((first_word <= EEPROM_CHECKSUM_REG) || 
+	if ((ret_val == 0) && ((first_word <= EEPROM_CHECKSUM_REG) ||
 				(hw->mac_type == e1000_82573)))
 		e1000_update_eeprom_checksum(hw);
 
@@ -567,21 +586,21 @@ e1000_get_drvinfo(struct net_device *net
 
 	strncpy(drvinfo->driver,  e1000_driver_name, 32);
 	strncpy(drvinfo->version, e1000_driver_version, 32);
-	
-	/* EEPROM image version # is reported as firware version # for
+
+	/* EEPROM image version # is reported as firmware version # for
 	 * 8257{1|2|3} controllers */
 	e1000_read_eeprom(&adapter->hw, 5, 1, &eeprom_data);
 	switch (adapter->hw.mac_type) {
 	case e1000_82571:
 	case e1000_82572:
 	case e1000_82573:
-		sprintf(firmware_version, "%d.%d-%d", 
+		sprintf(firmware_version, "%d.%d-%d",
 			(eeprom_data & 0xF000) >> 12,
 			(eeprom_data & 0x0FF0) >> 4,
 			eeprom_data & 0x000F);
 		break;
 	default:
-		sprintf(firmware_version, "n/a");
+		sprintf(firmware_version, "N/A");
 	}
 
 	strncpy(drvinfo->fw_version, firmware_version, 32);
@@ -613,7 +632,7 @@ e1000_get_ringparam(struct net_device *n
 	ring->rx_jumbo_pending = 0;
 }
 
-static int 
+static int
 e1000_set_ringparam(struct net_device *netdev,
                     struct ethtool_ringparam *ring)
 {
@@ -623,8 +642,8 @@ e1000_set_ringparam(struct net_device *n
 	struct e1000_rx_ring *rxdr, *rx_old, *rx_new;
 	int i, err, tx_ring_size, rx_ring_size;
 
-	tx_ring_size = sizeof(struct e1000_tx_ring) * adapter->num_queues;
-	rx_ring_size = sizeof(struct e1000_rx_ring) * adapter->num_queues;
+	tx_ring_size = sizeof(struct e1000_tx_ring) * adapter->num_tx_queues;
+	rx_ring_size = sizeof(struct e1000_rx_ring) * adapter->num_rx_queues;
 
 	if (netif_running(adapter->netdev))
 		e1000_down(adapter);
@@ -650,25 +669,25 @@ e1000_set_ringparam(struct net_device *n
 	txdr = adapter->tx_ring;
 	rxdr = adapter->rx_ring;
 
-	if((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
+	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
 		return -EINVAL;
 
 	rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD);
 	rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ?
 		E1000_MAX_RXD : E1000_MAX_82544_RXD));
-	E1000_ROUNDUP(rxdr->count, REQ_RX_DESCRIPTOR_MULTIPLE); 
+	E1000_ROUNDUP(rxdr->count, REQ_RX_DESCRIPTOR_MULTIPLE);
 
 	txdr->count = max(ring->tx_pending,(uint32_t)E1000_MIN_TXD);
 	txdr->count = min(txdr->count,(uint32_t)(mac_type < e1000_82544 ?
 		E1000_MAX_TXD : E1000_MAX_82544_TXD));
-	E1000_ROUNDUP(txdr->count, REQ_TX_DESCRIPTOR_MULTIPLE); 
+	E1000_ROUNDUP(txdr->count, REQ_TX_DESCRIPTOR_MULTIPLE);
 
-	for (i = 0; i < adapter->num_queues; i++) {
+	for (i = 0; i < adapter->num_tx_queues; i++)
 		txdr[i].count = txdr->count;
+	for (i = 0; i < adapter->num_rx_queues; i++)
 		rxdr[i].count = rxdr->count;
-	}
 
-	if(netif_running(adapter->netdev)) {
+	if (netif_running(adapter->netdev)) {
 		/* Try to get new resources before deleting old */
 		if ((err = e1000_setup_all_rx_resources(adapter)))
 			goto err_setup_rx;
@@ -688,7 +707,7 @@ e1000_set_ringparam(struct net_device *n
 		kfree(rx_old);
 		adapter->rx_ring = rx_new;
 		adapter->tx_ring = tx_new;
-		if((err = e1000_up(adapter)))
+		if ((err = e1000_up(adapter)))
 			return err;
 	}
 
@@ -707,10 +726,10 @@ err_setup_rx:
 	uint32_t pat, value;                                                   \
 	uint32_t test[] =                                                      \
 		{0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};              \
-	for(pat = 0; pat < sizeof(test)/sizeof(test[0]); pat++) {              \
+	for (pat = 0; pat < sizeof(test)/sizeof(test[0]); pat++) {              \
 		E1000_WRITE_REG(&adapter->hw, R, (test[pat] & W));             \
 		value = E1000_READ_REG(&adapter->hw, R);                       \
-		if(value != (test[pat] & W & M)) {                             \
+		if (value != (test[pat] & W & M)) {                             \
 			DPRINTK(DRV, ERR, "pattern test reg %04X failed: got " \
 			        "0x%08X expected 0x%08X\n",                    \
 			        E1000_##R, value, (test[pat] & W & M));        \
@@ -726,7 +745,7 @@ err_setup_rx:
 	uint32_t value;                                                        \
 	E1000_WRITE_REG(&adapter->hw, R, W & M);                               \
 	value = E1000_READ_REG(&adapter->hw, R);                               \
-	if((W & M) != (value & M)) {                                          \
+	if ((W & M) != (value & M)) {                                          \
 		DPRINTK(DRV, ERR, "set/check reg %04X test failed: got 0x%08X "\
 		        "expected 0x%08X\n", E1000_##R, (value & M), (W & M)); \
 		*data = (adapter->hw.mac_type < e1000_82543) ?                 \
@@ -762,7 +781,7 @@ e1000_reg_test(struct e1000_adapter *ada
 	value = (E1000_READ_REG(&adapter->hw, STATUS) & toggle);
 	E1000_WRITE_REG(&adapter->hw, STATUS, toggle);
 	after = E1000_READ_REG(&adapter->hw, STATUS) & toggle;
-	if(value != after) {
+	if (value != after) {
 		DPRINTK(DRV, ERR, "failed STATUS register test got: "
 		        "0x%08X expected: 0x%08X\n", after, value);
 		*data = 1;
@@ -790,7 +809,7 @@ e1000_reg_test(struct e1000_adapter *ada
 	REG_SET_AND_CHECK(RCTL, 0x06DFB3FE, 0x003FFFFB);
 	REG_SET_AND_CHECK(TCTL, 0xFFFFFFFF, 0x00000000);
 
-	if(adapter->hw.mac_type >= e1000_82543) {
+	if (adapter->hw.mac_type >= e1000_82543) {
 
 		REG_SET_AND_CHECK(RCTL, 0x06DFB3FE, 0xFFFFFFFF);
 		REG_PATTERN_TEST(RDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
@@ -798,7 +817,7 @@ e1000_reg_test(struct e1000_adapter *ada
 		REG_PATTERN_TEST(TDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
 		REG_PATTERN_TEST(TIDV, 0x0000FFFF, 0x0000FFFF);
 
-		for(i = 0; i < E1000_RAR_ENTRIES; i++) {
+		for (i = 0; i < E1000_RAR_ENTRIES; i++) {
 			REG_PATTERN_TEST(RA + ((i << 1) << 2), 0xFFFFFFFF,
 					 0xFFFFFFFF);
 			REG_PATTERN_TEST(RA + (((i << 1) + 1) << 2), 0x8003FFFF,
@@ -814,7 +833,7 @@ e1000_reg_test(struct e1000_adapter *ada
 
 	}
 
-	for(i = 0; i < E1000_MC_TBL_SIZE; i++)
+	for (i = 0; i < E1000_MC_TBL_SIZE; i++)
 		REG_PATTERN_TEST(MTA + (i << 2), 0xFFFFFFFF, 0xFFFFFFFF);
 
 	*data = 0;
@@ -830,8 +849,8 @@ e1000_eeprom_test(struct e1000_adapter *
 
 	*data = 0;
 	/* Read and add up the contents of the EEPROM */
-	for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
-		if((e1000_read_eeprom(&adapter->hw, i, 1, &temp)) < 0) {
+	for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
+		if ((e1000_read_eeprom(&adapter->hw, i, 1, &temp)) < 0) {
 			*data = 1;
 			break;
 		}
@@ -839,7 +858,7 @@ e1000_eeprom_test(struct e1000_adapter *
 	}
 
 	/* If Checksum is not Correct return error else test passed */
-	if((checksum != (uint16_t) EEPROM_SUM) && !(*data))
+	if ((checksum != (uint16_t) EEPROM_SUM) && !(*data))
 		*data = 2;
 
 	return *data;
@@ -868,9 +887,9 @@ e1000_intr_test(struct e1000_adapter *ad
 	*data = 0;
 
 	/* Hook up test interrupt handler just for this test */
- 	if(!request_irq(irq, &e1000_test_intr, 0, netdev->name, netdev)) {
+ 	if (!request_irq(irq, &e1000_test_intr, 0, netdev->name, netdev)) {
  		shared_int = FALSE;
- 	} else if(request_irq(irq, &e1000_test_intr, SA_SHIRQ,
+ 	} else if (request_irq(irq, &e1000_test_intr, SA_SHIRQ,
 			      netdev->name, netdev)){
 		*data = 1;
 		return -1;
@@ -881,12 +900,12 @@ e1000_intr_test(struct e1000_adapter *ad
 	msec_delay(10);
 
 	/* Test each interrupt */
-	for(; i < 10; i++) {
+	for (; i < 10; i++) {
 
 		/* Interrupt to test */
 		mask = 1 << i;
 
- 		if(!shared_int) {
+ 		if (!shared_int) {
  			/* Disable the interrupt to be reported in
  			 * the cause register and then force the same
  			 * interrupt and see if one gets posted.  If
@@ -897,8 +916,8 @@ e1000_intr_test(struct e1000_adapter *ad
  			E1000_WRITE_REG(&adapter->hw, IMC, mask);
  			E1000_WRITE_REG(&adapter->hw, ICS, mask);
  			msec_delay(10);
- 
- 			if(adapter->test_icr & mask) {
+
+ 			if (adapter->test_icr & mask) {
  				*data = 3;
  				break;
  			}
@@ -915,12 +934,12 @@ e1000_intr_test(struct e1000_adapter *ad
 		E1000_WRITE_REG(&adapter->hw, ICS, mask);
 		msec_delay(10);
 
-		if(!(adapter->test_icr & mask)) {
+		if (!(adapter->test_icr & mask)) {
 			*data = 4;
 			break;
 		}
 
- 		if(!shared_int) {
+ 		if (!shared_int) {
 			/* Disable the other interrupts to be reported in
 			 * the cause register and then force the other
 			 * interrupts and see if any get posted.  If
@@ -932,7 +951,7 @@ e1000_intr_test(struct e1000_adapter *ad
 			E1000_WRITE_REG(&adapter->hw, ICS, ~mask & 0x00007FFF);
 			msec_delay(10);
 
-			if(adapter->test_icr) {
+			if (adapter->test_icr) {
 				*data = 5;
 				break;
 			}
@@ -957,40 +976,39 @@ e1000_free_desc_rings(struct e1000_adapt
 	struct pci_dev *pdev = adapter->pdev;
 	int i;
 
-	if(txdr->desc && txdr->buffer_info) {
-		for(i = 0; i < txdr->count; i++) {
-			if(txdr->buffer_info[i].dma)
+	if (txdr->desc && txdr->buffer_info) {
+		for (i = 0; i < txdr->count; i++) {
+			if (txdr->buffer_info[i].dma)
 				pci_unmap_single(pdev, txdr->buffer_info[i].dma,
 						 txdr->buffer_info[i].length,
 						 PCI_DMA_TODEVICE);
-			if(txdr->buffer_info[i].skb)
+			if (txdr->buffer_info[i].skb)
 				dev_kfree_skb(txdr->buffer_info[i].skb);
 		}
 	}
 
-	if(rxdr->desc && rxdr->buffer_info) {
-		for(i = 0; i < rxdr->count; i++) {
-			if(rxdr->buffer_info[i].dma)
+	if (rxdr->desc && rxdr->buffer_info) {
+		for (i = 0; i < rxdr->count; i++) {
+			if (rxdr->buffer_info[i].dma)
 				pci_unmap_single(pdev, rxdr->buffer_info[i].dma,
 						 rxdr->buffer_info[i].length,
 						 PCI_DMA_FROMDEVICE);
-			if(rxdr->buffer_info[i].skb)
+			if (rxdr->buffer_info[i].skb)
 				dev_kfree_skb(rxdr->buffer_info[i].skb);
 		}
 	}
 
-	if(txdr->desc) {
+	if (txdr->desc) {
 		pci_free_consistent(pdev, txdr->size, txdr->desc, txdr->dma);
 		txdr->desc = NULL;
 	}
-	if(rxdr->desc) {
+	if (rxdr->desc) {
 		pci_free_consistent(pdev, rxdr->size, rxdr->desc, rxdr->dma);
 		rxdr->desc = NULL;
 	}
 
 	kfree(txdr->buffer_info);
 	txdr->buffer_info = NULL;
-
 	kfree(rxdr->buffer_info);
 	rxdr->buffer_info = NULL;
 
@@ -1008,11 +1026,11 @@ e1000_setup_desc_rings(struct e1000_adap
 
 	/* Setup Tx descriptor ring and Tx buffers */
 
-	if(!txdr->count)
-		txdr->count = E1000_DEFAULT_TXD;   
+	if (!txdr->count)
+		txdr->count = E1000_DEFAULT_TXD;
 
 	size = txdr->count * sizeof(struct e1000_buffer);
-	if(!(txdr->buffer_info = kmalloc(size, GFP_KERNEL))) {
+	if (!(txdr->buffer_info = kmalloc(size, GFP_KERNEL))) {
 		ret_val = 1;
 		goto err_nomem;
 	}
@@ -1020,7 +1038,7 @@ e1000_setup_desc_rings(struct e1000_adap
 
 	txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
 	E1000_ROUNDUP(txdr->size, 4096);
-	if(!(txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma))) {
+	if (!(txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma))) {
 		ret_val = 2;
 		goto err_nomem;
 	}
@@ -1039,12 +1057,12 @@ e1000_setup_desc_rings(struct e1000_adap
 			E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT |
 			E1000_FDX_COLLISION_DISTANCE << E1000_COLD_SHIFT);
 
-	for(i = 0; i < txdr->count; i++) {
+	for (i = 0; i < txdr->count; i++) {
 		struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*txdr, i);
 		struct sk_buff *skb;
 		unsigned int size = 1024;
 
-		if(!(skb = alloc_skb(size, GFP_KERNEL))) {
+		if (!(skb = alloc_skb(size, GFP_KERNEL))) {
 			ret_val = 3;
 			goto err_nomem;
 		}
@@ -1064,18 +1082,18 @@ e1000_setup_desc_rings(struct e1000_adap
 
 	/* Setup Rx descriptor ring and Rx buffers */
 
-	if(!rxdr->count)
-		rxdr->count = E1000_DEFAULT_RXD;   
+	if (!rxdr->count)
+		rxdr->count = E1000_DEFAULT_RXD;
 
 	size = rxdr->count * sizeof(struct e1000_buffer);
-	if(!(rxdr->buffer_info = kmalloc(size, GFP_KERNEL))) {
+	if (!(rxdr->buffer_info = kmalloc(size, GFP_KERNEL))) {
 		ret_val = 4;
 		goto err_nomem;
 	}
 	memset(rxdr->buffer_info, 0, size);
 
 	rxdr->size = rxdr->count * sizeof(struct e1000_rx_desc);
-	if(!(rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma))) {
+	if (!(rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma))) {
 		ret_val = 5;
 		goto err_nomem;
 	}
@@ -1095,11 +1113,11 @@ e1000_setup_desc_rings(struct e1000_adap
 		(adapter->hw.mc_filter_type << E1000_RCTL_MO_SHIFT);
 	E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
 
-	for(i = 0; i < rxdr->count; i++) {
+	for (i = 0; i < rxdr->count; i++) {
 		struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rxdr, i);
 		struct sk_buff *skb;
 
-		if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN,
+		if (!(skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN,
 				GFP_KERNEL))) {
 			ret_val = 6;
 			goto err_nomem;
@@ -1208,15 +1226,15 @@ e1000_nonintegrated_phy_loopback(struct 
 
 	/* Check Phy Configuration */
 	e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg);
-	if(phy_reg != 0x4100)
+	if (phy_reg != 0x4100)
 		 return 9;
 
 	e1000_read_phy_reg(&adapter->hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_reg);
-	if(phy_reg != 0x0070)
+	if (phy_reg != 0x0070)
 		return 10;
 
 	e1000_read_phy_reg(&adapter->hw, 29, &phy_reg);
-	if(phy_reg != 0x001A)
+	if (phy_reg != 0x001A)
 		return 11;
 
 	return 0;
@@ -1230,7 +1248,7 @@ e1000_integrated_phy_loopback(struct e10
 
 	adapter->hw.autoneg = FALSE;
 
-	if(adapter->hw.phy_type == e1000_phy_m88) {
+	if (adapter->hw.phy_type == e1000_phy_m88) {
 		/* Auto-MDI/MDIX Off */
 		e1000_write_phy_reg(&adapter->hw,
 				    M88E1000_PHY_SPEC_CTRL, 0x0808);
@@ -1250,14 +1268,14 @@ e1000_integrated_phy_loopback(struct e10
 		     E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */
 		     E1000_CTRL_FD);	 /* Force Duplex to FULL */
 
-	if(adapter->hw.media_type == e1000_media_type_copper &&
+	if (adapter->hw.media_type == e1000_media_type_copper &&
 	   adapter->hw.phy_type == e1000_phy_m88) {
 		ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */
 	} else {
 		/* Set the ILOS bit on the fiber Nic is half
 		 * duplex link is detected. */
 		stat_reg = E1000_READ_REG(&adapter->hw, STATUS);
-		if((stat_reg & E1000_STATUS_FD) == 0)
+		if ((stat_reg & E1000_STATUS_FD) == 0)
 			ctrl_reg |= (E1000_CTRL_ILOS | E1000_CTRL_SLU);
 	}
 
@@ -1266,7 +1284,7 @@ e1000_integrated_phy_loopback(struct e10
 	/* Disable the receiver on the PHY so when a cable is plugged in, the
 	 * PHY does not begin to autoneg when a cable is reconnected to the NIC.
 	 */
-	if(adapter->hw.phy_type == e1000_phy_m88)
+	if (adapter->hw.phy_type == e1000_phy_m88)
 		e1000_phy_disable_receiver(adapter);
 
 	udelay(500);
@@ -1282,14 +1300,14 @@ e1000_set_phy_loopback(struct e1000_adap
 
 	switch (adapter->hw.mac_type) {
 	case e1000_82543:
-		if(adapter->hw.media_type == e1000_media_type_copper) {
+		if (adapter->hw.media_type == e1000_media_type_copper) {
 			/* Attempt to setup Loopback mode on Non-integrated PHY.
 			 * Some PHY registers get corrupted at random, so
 			 * attempt this 10 times.
 			 */
-			while(e1000_nonintegrated_phy_loopback(adapter) &&
+			while (e1000_nonintegrated_phy_loopback(adapter) &&
 			      count++ < 10);
-			if(count < 11)
+			if (count < 11)
 				return 0;
 		}
 		break;
@@ -1327,11 +1345,11 @@ e1000_set_phy_loopback(struct e1000_adap
 static int
 e1000_setup_loopback_test(struct e1000_adapter *adapter)
 {
-	uint32_t rctl;
 	struct e1000_hw *hw = &adapter->hw;
+	uint32_t rctl;
 
 	if (hw->media_type == e1000_media_type_fiber ||
-	   hw->media_type == e1000_media_type_internal_serdes) {
+	    hw->media_type == e1000_media_type_internal_serdes) {
 		switch (hw->mac_type) {
 		case e1000_82545:
 		case e1000_82546:
@@ -1362,25 +1380,25 @@ e1000_setup_loopback_test(struct e1000_a
 static void
 e1000_loopback_cleanup(struct e1000_adapter *adapter)
 {
+	struct e1000_hw *hw = &adapter->hw;
 	uint32_t rctl;
 	uint16_t phy_reg;
-	struct e1000_hw *hw = &adapter->hw;
 
-	rctl = E1000_READ_REG(&adapter->hw, RCTL);
+	rctl = E1000_READ_REG(hw, RCTL);
 	rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
-	E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+	E1000_WRITE_REG(hw, RCTL, rctl);
 
 	switch (hw->mac_type) {
 	case e1000_82571:
 	case e1000_82572:
 		if (hw->media_type == e1000_media_type_fiber ||
-		   hw->media_type == e1000_media_type_internal_serdes){
+		    hw->media_type == e1000_media_type_internal_serdes) {
 #define E1000_SERDES_LB_OFF 0x400
 			E1000_WRITE_REG(hw, SCTL, E1000_SERDES_LB_OFF);
 			msec_delay(10);
 			break;
 		}
-		/* fall thru for Cu adapters */
+		/* Fall Through */
 	case e1000_82545:
 	case e1000_82546:
 	case e1000_82545_rev_3:
@@ -1401,7 +1419,7 @@ static void
 e1000_create_lbtest_frame(struct sk_buff *skb, unsigned int frame_size)
 {
 	memset(skb->data, 0xFF, frame_size);
-	frame_size = (frame_size % 2) ? (frame_size - 1) : frame_size;
+	frame_size &= ~1;
 	memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1);
 	memset(&skb->data[frame_size / 2 + 10], 0xBE, 1);
 	memset(&skb->data[frame_size / 2 + 12], 0xAF, 1);
@@ -1410,9 +1428,9 @@ e1000_create_lbtest_frame(struct sk_buff
 static int
 e1000_check_lbtest_frame(struct sk_buff *skb, unsigned int frame_size)
 {
-	frame_size = (frame_size % 2) ? (frame_size - 1) : frame_size;
-	if(*(skb->data + 3) == 0xFF) {
-		if((*(skb->data + frame_size / 2 + 10) == 0xBE) &&
+	frame_size &= ~1;
+	if (*(skb->data + 3) == 0xFF) {
+		if ((*(skb->data + frame_size / 2 + 10) == 0xBE) &&
 		   (*(skb->data + frame_size / 2 + 12) == 0xAF)) {
 			return 0;
 		}
@@ -1431,53 +1449,53 @@ e1000_run_loopback_test(struct e1000_ada
 
 	E1000_WRITE_REG(&adapter->hw, RDT, rxdr->count - 1);
 
-	/* Calculate the loop count based on the largest descriptor ring 
+	/* Calculate the loop count based on the largest descriptor ring
 	 * The idea is to wrap the largest ring a number of times using 64
 	 * send/receive pairs during each loop
 	 */
 
-	if(rxdr->count <= txdr->count)
+	if (rxdr->count <= txdr->count)
 		lc = ((txdr->count / 64) * 2) + 1;
 	else
 		lc = ((rxdr->count / 64) * 2) + 1;
 
 	k = l = 0;
-	for(j = 0; j <= lc; j++) { /* loop count loop */
-		for(i = 0; i < 64; i++) { /* send the packets */
-			e1000_create_lbtest_frame(txdr->buffer_info[i].skb, 
+	for (j = 0; j <= lc; j++) { /* loop count loop */
+		for (i = 0; i < 64; i++) { /* send the packets */
+			e1000_create_lbtest_frame(txdr->buffer_info[i].skb,
 					1024);
-			pci_dma_sync_single_for_device(pdev, 
+			pci_dma_sync_single_for_device(pdev,
 					txdr->buffer_info[k].dma,
 				    	txdr->buffer_info[k].length,
 				    	PCI_DMA_TODEVICE);
-			if(unlikely(++k == txdr->count)) k = 0;
+			if (unlikely(++k == txdr->count)) k = 0;
 		}
 		E1000_WRITE_REG(&adapter->hw, TDT, k);
 		msec_delay(200);
 		time = jiffies; /* set the start time for the receive */
 		good_cnt = 0;
 		do { /* receive the sent packets */
-			pci_dma_sync_single_for_cpu(pdev, 
+			pci_dma_sync_single_for_cpu(pdev,
 					rxdr->buffer_info[l].dma,
 				    	rxdr->buffer_info[l].length,
 				    	PCI_DMA_FROMDEVICE);
-	
+
 			ret_val = e1000_check_lbtest_frame(
 					rxdr->buffer_info[l].skb,
 				   	1024);
-			if(!ret_val)
+			if (!ret_val)
 				good_cnt++;
-			if(unlikely(++l == rxdr->count)) l = 0;
-			/* time + 20 msecs (200 msecs on 2.4) is more than 
-			 * enough time to complete the receives, if it's 
+			if (unlikely(++l == rxdr->count)) l = 0;
+			/* time + 20 msecs (200 msecs on 2.4) is more than
+			 * enough time to complete the receives, if it's
 			 * exceeded, break and error off
 			 */
 		} while (good_cnt < 64 && jiffies < (time + 20));
-		if(good_cnt != 64) {
+		if (good_cnt != 64) {
 			ret_val = 13; /* ret_val is the same as mis-compare */
-			break; 
+			break;
 		}
-		if(jiffies >= (time + 2)) {
+		if (jiffies >= (time + 2)) {
 			ret_val = 14; /* error code for time out error */
 			break;
 		}
@@ -1488,14 +1506,25 @@ e1000_run_loopback_test(struct e1000_ada
 static int
 e1000_loopback_test(struct e1000_adapter *adapter, uint64_t *data)
 {
-	if((*data = e1000_setup_desc_rings(adapter))) goto err_loopback;
-	if((*data = e1000_setup_loopback_test(adapter)))
-		goto err_loopback_setup;
+	/* PHY loopback cannot be performed if SoL/IDER
+	 * sessions are active */
+	if (e1000_check_phy_reset_block(&adapter->hw)) {
+		DPRINTK(DRV, ERR, "Cannot do PHY loopback test "
+		        "when SoL/IDER is active.\n");
+		*data = 0;
+		goto out;
+	}
+
+	if ((*data = e1000_setup_desc_rings(adapter)))
+		goto out;
+	if ((*data = e1000_setup_loopback_test(adapter)))
+		goto err_loopback;
 	*data = e1000_run_loopback_test(adapter);
 	e1000_loopback_cleanup(adapter);
-err_loopback_setup:
-	e1000_free_desc_rings(adapter);
+
 err_loopback:
+	e1000_free_desc_rings(adapter);
+out:
 	return *data;
 }
 
@@ -1519,17 +1548,17 @@ e1000_link_test(struct e1000_adapter *ad
 		*data = 1;
 	} else {
 		e1000_check_for_link(&adapter->hw);
-		if(adapter->hw.autoneg)  /* if auto_neg is set wait for it */
+		if (adapter->hw.autoneg)  /* if auto_neg is set wait for it */
 			msec_delay(4000);
 
-		if(!(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) {
+		if (!(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) {
 			*data = 1;
 		}
 	}
 	return *data;
 }
 
-static int 
+static int
 e1000_diag_test_count(struct net_device *netdev)
 {
 	return E1000_TEST_LEN;
@@ -1542,7 +1571,7 @@ e1000_diag_test(struct net_device *netde
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	boolean_t if_running = netif_running(netdev);
 
-	if(eth_test->flags == ETH_TEST_FL_OFFLINE) {
+	if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
 		/* Offline tests */
 
 		/* save speed, duplex, autoneg settings */
@@ -1552,27 +1581,27 @@ e1000_diag_test(struct net_device *netde
 
 		/* Link test performed before hardware reset so autoneg doesn't
 		 * interfere with test result */
-		if(e1000_link_test(adapter, &data[4]))
+		if (e1000_link_test(adapter, &data[4]))
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
-		if(if_running)
+		if (if_running)
 			e1000_down(adapter);
 		else
 			e1000_reset(adapter);
 
-		if(e1000_reg_test(adapter, &data[0]))
+		if (e1000_reg_test(adapter, &data[0]))
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
 		e1000_reset(adapter);
-		if(e1000_eeprom_test(adapter, &data[1]))
+		if (e1000_eeprom_test(adapter, &data[1]))
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
 		e1000_reset(adapter);
-		if(e1000_intr_test(adapter, &data[2]))
+		if (e1000_intr_test(adapter, &data[2]))
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
 		e1000_reset(adapter);
-		if(e1000_loopback_test(adapter, &data[3]))
+		if (e1000_loopback_test(adapter, &data[3]))
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
 		/* restore speed, duplex, autoneg settings */
@@ -1581,11 +1610,11 @@ e1000_diag_test(struct net_device *netde
 		adapter->hw.autoneg = autoneg;
 
 		e1000_reset(adapter);
-		if(if_running)
+		if (if_running)
 			e1000_up(adapter);
 	} else {
 		/* Online tests */
-		if(e1000_link_test(adapter, &data[4]))
+		if (e1000_link_test(adapter, &data[4]))
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
 		/* Offline tests aren't run; pass by default */
@@ -1603,7 +1632,7 @@ e1000_get_wol(struct net_device *netdev,
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 
-	switch(adapter->hw.device_id) {
+	switch (adapter->hw.device_id) {
 	case E1000_DEV_ID_82542:
 	case E1000_DEV_ID_82543GC_FIBER:
 	case E1000_DEV_ID_82543GC_COPPER:
@@ -1617,8 +1646,9 @@ e1000_get_wol(struct net_device *netdev,
 
 	case E1000_DEV_ID_82546EB_FIBER:
 	case E1000_DEV_ID_82546GB_FIBER:
+	case E1000_DEV_ID_82571EB_FIBER:
 		/* Wake events only supported on port A for dual fiber */
-		if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) {
+		if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) {
 			wol->supported = 0;
 			wol->wolopts   = 0;
 			return;
@@ -1630,13 +1660,13 @@ e1000_get_wol(struct net_device *netdev,
 				 WAKE_BCAST | WAKE_MAGIC;
 
 		wol->wolopts = 0;
-		if(adapter->wol & E1000_WUFC_EX)
+		if (adapter->wol & E1000_WUFC_EX)
 			wol->wolopts |= WAKE_UCAST;
-		if(adapter->wol & E1000_WUFC_MC)
+		if (adapter->wol & E1000_WUFC_MC)
 			wol->wolopts |= WAKE_MCAST;
-		if(adapter->wol & E1000_WUFC_BC)
+		if (adapter->wol & E1000_WUFC_BC)
 			wol->wolopts |= WAKE_BCAST;
-		if(adapter->wol & E1000_WUFC_MAG)
+		if (adapter->wol & E1000_WUFC_MAG)
 			wol->wolopts |= WAKE_MAGIC;
 		return;
 	}
@@ -1648,7 +1678,7 @@ e1000_set_wol(struct net_device *netdev,
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 
-	switch(adapter->hw.device_id) {
+	switch (adapter->hw.device_id) {
 	case E1000_DEV_ID_82542:
 	case E1000_DEV_ID_82543GC_FIBER:
 	case E1000_DEV_ID_82543GC_COPPER:
@@ -1660,24 +1690,25 @@ e1000_set_wol(struct net_device *netdev,
 
 	case E1000_DEV_ID_82546EB_FIBER:
 	case E1000_DEV_ID_82546GB_FIBER:
+	case E1000_DEV_ID_82571EB_FIBER:
 		/* Wake events only supported on port A for dual fiber */
-		if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
+		if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
 			return wol->wolopts ? -EOPNOTSUPP : 0;
 		/* Fall Through */
 
 	default:
-		if(wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
+		if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
 			return -EOPNOTSUPP;
 
 		adapter->wol = 0;
 
-		if(wol->wolopts & WAKE_UCAST)
+		if (wol->wolopts & WAKE_UCAST)
 			adapter->wol |= E1000_WUFC_EX;
-		if(wol->wolopts & WAKE_MCAST)
+		if (wol->wolopts & WAKE_MCAST)
 			adapter->wol |= E1000_WUFC_MC;
-		if(wol->wolopts & WAKE_BCAST)
+		if (wol->wolopts & WAKE_BCAST)
 			adapter->wol |= E1000_WUFC_BC;
-		if(wol->wolopts & WAKE_MAGIC)
+		if (wol->wolopts & WAKE_MAGIC)
 			adapter->wol |= E1000_WUFC_MAG;
 	}
 
@@ -1695,7 +1726,7 @@ e1000_led_blink_callback(unsigned long d
 {
 	struct e1000_adapter *adapter = (struct e1000_adapter *) data;
 
-	if(test_and_change_bit(E1000_LED_ON, &adapter->led_status))
+	if (test_and_change_bit(E1000_LED_ON, &adapter->led_status))
 		e1000_led_off(&adapter->hw);
 	else
 		e1000_led_on(&adapter->hw);
@@ -1708,11 +1739,11 @@ e1000_phys_id(struct net_device *netdev,
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 
-	if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ))
+	if (!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ))
 		data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ);
 
-	if(adapter->hw.mac_type < e1000_82571) {
-		if(!adapter->blink_timer.function) {
+	if (adapter->hw.mac_type < e1000_82571) {
+		if (!adapter->blink_timer.function) {
 			init_timer(&adapter->blink_timer);
 			adapter->blink_timer.function = e1000_led_blink_callback;
 			adapter->blink_timer.data = (unsigned long) adapter;
@@ -1721,21 +1752,21 @@ e1000_phys_id(struct net_device *netdev,
 		mod_timer(&adapter->blink_timer, jiffies);
 		msleep_interruptible(data * 1000);
 		del_timer_sync(&adapter->blink_timer);
-	}
-	else if(adapter->hw.mac_type < e1000_82573) {
-		E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE |
-			E1000_LEDCTL_LED0_BLINK | E1000_LEDCTL_LED2_BLINK |
-			(E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED2_MODE_SHIFT) |
-			(E1000_LEDCTL_MODE_LINK_ACTIVITY << E1000_LEDCTL_LED0_MODE_SHIFT) |
-			(E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED1_MODE_SHIFT)));
+	} else if (adapter->hw.mac_type < e1000_82573) {
+		E1000_WRITE_REG(&adapter->hw, LEDCTL,
+			(E1000_LEDCTL_LED2_BLINK_RATE |
+			 E1000_LEDCTL_LED0_BLINK | E1000_LEDCTL_LED2_BLINK |
+			 (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED2_MODE_SHIFT) |
+			 (E1000_LEDCTL_MODE_LINK_ACTIVITY << E1000_LEDCTL_LED0_MODE_SHIFT) |
+			 (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED1_MODE_SHIFT)));
 		msleep_interruptible(data * 1000);
-	}
-	else {
-		E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE |
-			E1000_LEDCTL_LED1_BLINK | E1000_LEDCTL_LED2_BLINK | 
-			(E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED2_MODE_SHIFT) |
-			(E1000_LEDCTL_MODE_LINK_ACTIVITY << E1000_LEDCTL_LED1_MODE_SHIFT) |
-			(E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED0_MODE_SHIFT)));
+	} else {
+		E1000_WRITE_REG(&adapter->hw, LEDCTL,
+			(E1000_LEDCTL_LED2_BLINK_RATE |
+			 E1000_LEDCTL_LED1_BLINK | E1000_LEDCTL_LED2_BLINK |
+			 (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED2_MODE_SHIFT) |
+			 (E1000_LEDCTL_MODE_LINK_ACTIVITY << E1000_LEDCTL_LED1_MODE_SHIFT) |
+			 (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED0_MODE_SHIFT)));
 		msleep_interruptible(data * 1000);
 	}
 
@@ -1750,50 +1781,89 @@ static int
 e1000_nway_reset(struct net_device *netdev)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
-	if(netif_running(netdev)) {
+	if (netif_running(netdev)) {
 		e1000_down(adapter);
 		e1000_up(adapter);
 	}
 	return 0;
 }
 
-static int 
+static int
 e1000_get_stats_count(struct net_device *netdev)
 {
 	return E1000_STATS_LEN;
 }
 
-static void 
-e1000_get_ethtool_stats(struct net_device *netdev, 
+static void
+e1000_get_ethtool_stats(struct net_device *netdev,
 		struct ethtool_stats *stats, uint64_t *data)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
+#ifdef CONFIG_E1000_MQ
+	uint64_t *queue_stat;
+	int stat_count = sizeof(struct e1000_queue_stats) / sizeof(uint64_t);
+	int j, k;
+#endif
 	int i;
 
 	e1000_update_stats(adapter);
-	for(i = 0; i < E1000_STATS_LEN; i++) {
-		char *p = (char *)adapter+e1000_gstrings_stats[i].stat_offset;	
-		data[i] = (e1000_gstrings_stats[i].sizeof_stat == 
+	for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
+		char *p = (char *)adapter+e1000_gstrings_stats[i].stat_offset;
+		data[i] = (e1000_gstrings_stats[i].sizeof_stat ==
 			sizeof(uint64_t)) ? *(uint64_t *)p : *(uint32_t *)p;
 	}
+#ifdef CONFIG_E1000_MQ
+	for (j = 0; j < adapter->num_tx_queues; j++) {
+		queue_stat = (uint64_t *)&adapter->tx_ring[j].tx_stats;
+		for (k = 0; k < stat_count; k++)
+			data[i + k] = queue_stat[k];
+		i += k;
+	}
+	for (j = 0; j < adapter->num_rx_queues; j++) {
+		queue_stat = (uint64_t *)&adapter->rx_ring[j].rx_stats;
+		for (k = 0; k < stat_count; k++)
+			data[i + k] = queue_stat[k];
+		i += k;
+	}
+#endif
+/*	BUG_ON(i != E1000_STATS_LEN); */
 }
 
-static void 
+static void
 e1000_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data)
 {
+#ifdef CONFIG_E1000_MQ
+	struct e1000_adapter *adapter = netdev_priv(netdev);
+#endif
+	uint8_t *p = data;
 	int i;
 
-	switch(stringset) {
+	switch (stringset) {
 	case ETH_SS_TEST:
-		memcpy(data, *e1000_gstrings_test, 
+		memcpy(data, *e1000_gstrings_test,
 			E1000_TEST_LEN*ETH_GSTRING_LEN);
 		break;
 	case ETH_SS_STATS:
-		for (i=0; i < E1000_STATS_LEN; i++) {
-			memcpy(data + i * ETH_GSTRING_LEN, 
-			e1000_gstrings_stats[i].stat_string,
-			ETH_GSTRING_LEN);
+		for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
+			memcpy(p, e1000_gstrings_stats[i].stat_string,
+			       ETH_GSTRING_LEN);
+			p += ETH_GSTRING_LEN;
+		}
+#ifdef CONFIG_E1000_MQ
+		for (i = 0; i < adapter->num_tx_queues; i++) {
+			sprintf(p, "tx_queue_%u_packets", i);
+			p += ETH_GSTRING_LEN;
+			sprintf(p, "tx_queue_%u_bytes", i);
+			p += ETH_GSTRING_LEN;
+		}
+		for (i = 0; i < adapter->num_rx_queues; i++) {
+			sprintf(p, "rx_queue_%u_packets", i);
+			p += ETH_GSTRING_LEN;
+			sprintf(p, "rx_queue_%u_bytes", i);
+			p += ETH_GSTRING_LEN;
 		}
+#endif
+/*		BUG_ON(p - data != E1000_STATS_LEN * ETH_GSTRING_LEN); */
 		break;
 	}
 }
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index 136fc03..beeec0f 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -318,6 +318,8 @@ e1000_set_mac_type(struct e1000_hw *hw)
     case E1000_DEV_ID_82546GB_FIBER:
     case E1000_DEV_ID_82546GB_SERDES:
     case E1000_DEV_ID_82546GB_PCIE:
+    case E1000_DEV_ID_82546GB_QUAD_COPPER:
+    case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
         hw->mac_type = e1000_82546_rev_3;
         break;
     case E1000_DEV_ID_82541EI:
@@ -639,6 +641,7 @@ e1000_init_hw(struct e1000_hw *hw)
     uint16_t cmd_mmrbc;
     uint16_t stat_mmrbc;
     uint32_t mta_size;
+    uint32_t ctrl_ext;
 
     DEBUGFUNC("e1000_init_hw");
 
@@ -735,7 +738,6 @@ e1000_init_hw(struct e1000_hw *hw)
             break;
         case e1000_82571:
         case e1000_82572:
-            ctrl |= (1 << 22);
         case e1000_82573:
             ctrl |= E1000_TXDCTL_COUNT_DESC;
             break;
@@ -775,6 +777,15 @@ e1000_init_hw(struct e1000_hw *hw)
      */
     e1000_clear_hw_cntrs(hw);
 
+    if (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER ||
+        hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3) {
+        ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+        /* Relaxed ordering must be disabled to avoid a parity
+         * error crash in a PCI slot. */
+        ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
+        E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+    }
+
     return ret_val;
 }
 
@@ -838,6 +849,11 @@ e1000_setup_link(struct e1000_hw *hw)
 
     DEBUGFUNC("e1000_setup_link");
 
+    /* In the case of the phy reset being blocked, we already have a link.
+     * We do not have to set it up again. */
+    if (e1000_check_phy_reset_block(hw))
+        return E1000_SUCCESS;
+
     /* Read and store word 0x0F of the EEPROM. This word contains bits
      * that determine the hardware's default PAUSE (flow control) mode,
      * a bit that determines whether the HW defaults to enabling or
@@ -1584,10 +1600,10 @@ e1000_phy_setup_autoneg(struct e1000_hw 
     if(ret_val)
         return ret_val;
 
-        /* Read the MII 1000Base-T Control Register (Address 9). */
-        ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg);
-        if(ret_val)
-            return ret_val;
+    /* Read the MII 1000Base-T Control Register (Address 9). */
+    ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg);
+    if(ret_val)
+        return ret_val;
 
     /* Need to parse both autoneg_advertised and fc and set up
      * the appropriate PHY registers.  First we will parse for
@@ -1929,14 +1945,19 @@ e1000_phy_force_speed_duplex(struct e100
 void
 e1000_config_collision_dist(struct e1000_hw *hw)
 {
-    uint32_t tctl;
+    uint32_t tctl, coll_dist;
 
     DEBUGFUNC("e1000_config_collision_dist");
 
+    if (hw->mac_type < e1000_82543)
+        coll_dist = E1000_COLLISION_DISTANCE_82542;
+    else
+        coll_dist = E1000_COLLISION_DISTANCE;
+
     tctl = E1000_READ_REG(hw, TCTL);
 
     tctl &= ~E1000_TCTL_COLD;
-    tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;
+    tctl |= coll_dist << E1000_COLD_SHIFT;
 
     E1000_WRITE_REG(hw, TCTL, tctl);
     E1000_WRITE_FLUSH(hw);
@@ -2982,6 +3003,8 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
         
         if (hw->mac_type < e1000_82571) 
             msec_delay(10);
+        else
+            udelay(100);
         
         E1000_WRITE_REG(hw, CTRL, ctrl);
         E1000_WRITE_FLUSH(hw);
@@ -3881,17 +3904,19 @@ e1000_read_eeprom(struct e1000_hw *hw,
         return -E1000_ERR_EEPROM;
     }
 
-    /* FLASH reads without acquiring the semaphore are safe in 82573-based
-     * controllers.
-     */
-    if ((e1000_is_onboard_nvm_eeprom(hw) == TRUE) ||
-        (hw->mac_type != e1000_82573)) {
-        /* Prepare the EEPROM for reading  */
-        if(e1000_acquire_eeprom(hw) != E1000_SUCCESS)
-            return -E1000_ERR_EEPROM;
+    /* FLASH reads without acquiring the semaphore are safe */
+    if (e1000_is_onboard_nvm_eeprom(hw) == TRUE &&
+    hw->eeprom.use_eerd == FALSE) {
+        switch (hw->mac_type) {
+        default:
+            /* Prepare the EEPROM for reading  */
+            if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
+                return -E1000_ERR_EEPROM;
+            break;
+        }
     }
 
-    if(eeprom->use_eerd == TRUE) {
+    if (eeprom->use_eerd == TRUE) {
         ret_val = e1000_read_eeprom_eerd(hw, offset, words, data);
         if ((e1000_is_onboard_nvm_eeprom(hw) == TRUE) ||
             (hw->mac_type != e1000_82573))
@@ -4398,7 +4423,7 @@ e1000_commit_shadow_ram(struct e1000_hw 
             return -E1000_ERR_EEPROM;
         }
 
-	/* If STM opcode located in bits 15:8 of flop, reset firmware */
+        /* If STM opcode located in bits 15:8 of flop, reset firmware */
         if ((flop & 0xFF00) == E1000_STM_OPCODE) {
             E1000_WRITE_REG(hw, HICR, E1000_HICR_FW_RESET);
         }
@@ -4406,7 +4431,7 @@ e1000_commit_shadow_ram(struct e1000_hw 
         /* Perform the flash update */
         E1000_WRITE_REG(hw, EECD, eecd | E1000_EECD_FLUPD);
 
-	for (i=0; i < attempts; i++) {
+        for (i=0; i < attempts; i++) {
             eecd = E1000_READ_REG(hw, EECD);
             if ((eecd & E1000_EECD_FLUPD) == 0) {
                 break;
@@ -4479,6 +4504,7 @@ e1000_read_mac_addr(struct e1000_hw * hw
         hw->perm_mac_addr[i] = (uint8_t) (eeprom_data & 0x00FF);
         hw->perm_mac_addr[i+1] = (uint8_t) (eeprom_data >> 8);
     }
+
     switch (hw->mac_type) {
     default:
         break;
@@ -6720,6 +6746,12 @@ e1000_get_phy_cfg_done(struct e1000_hw *
         break;
     }
 
+    /* PHY configuration from NVM just starts after EECD_AUTO_RD sets to high.
+     * Need to wait for PHY configuration completion before accessing NVM
+     * and PHY. */
+    if (hw->mac_type == e1000_82573)
+        msec_delay(25);
+
     return E1000_SUCCESS;
 }
 
@@ -6809,7 +6841,8 @@ int32_t
 e1000_check_phy_reset_block(struct e1000_hw *hw)
 {
     uint32_t manc = 0;
-    if(hw->mac_type > e1000_82547_rev_2)
+
+    if (hw->mac_type > e1000_82547_rev_2)
         manc = E1000_READ_REG(hw, MANC);
     return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ?
 	    E1000_BLK_PHY_RESET : E1000_SUCCESS;
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index 7caa357..f1219dd 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -377,6 +377,7 @@ int32_t e1000_swfw_sync_acquire(struct e
 void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask);
 
 /* Filters (multicast, vlan, receive) */
+void e1000_mc_addr_list_update(struct e1000_hw *hw, uint8_t * mc_addr_list, uint32_t mc_addr_count, uint32_t pad, uint32_t rar_used_count);
 uint32_t e1000_hash_mc_addr(struct e1000_hw *hw, uint8_t * mc_addr);
 void e1000_mta_set(struct e1000_hw *hw, uint32_t hash_value);
 void e1000_rar_set(struct e1000_hw *hw, uint8_t * mc_addr, uint32_t rar_index);
@@ -401,7 +402,9 @@ void e1000_read_pci_cfg(struct e1000_hw 
 void e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
 /* Port I/O is only supported on 82544 and newer */
 uint32_t e1000_io_read(struct e1000_hw *hw, unsigned long port);
+uint32_t e1000_read_reg_io(struct e1000_hw *hw, uint32_t offset);
 void e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value);
+void e1000_enable_pciex_master(struct e1000_hw *hw);
 int32_t e1000_disable_pciex_master(struct e1000_hw *hw);
 int32_t e1000_get_software_semaphore(struct e1000_hw *hw);
 void e1000_release_software_semaphore(struct e1000_hw *hw);
@@ -439,6 +442,7 @@ int32_t e1000_check_phy_reset_block(stru
 #define E1000_DEV_ID_82546GB_FIBER       0x107A
 #define E1000_DEV_ID_82546GB_SERDES      0x107B
 #define E1000_DEV_ID_82546GB_PCIE        0x108A
+#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
 #define E1000_DEV_ID_82547EI             0x1019
 #define E1000_DEV_ID_82571EB_COPPER      0x105E
 #define E1000_DEV_ID_82571EB_FIBER       0x105F
@@ -449,6 +453,7 @@ int32_t e1000_check_phy_reset_block(stru
 #define E1000_DEV_ID_82573E              0x108B
 #define E1000_DEV_ID_82573E_IAMT         0x108C
 #define E1000_DEV_ID_82573L              0x109A
+#define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5
 
 
 #define NODE_ADDRESS_SIZE 6
@@ -897,14 +902,14 @@ struct e1000_ffvt_entry {
 #define E1000_TXDCTL   0x03828  /* TX Descriptor Control - RW */
 #define E1000_TADV     0x0382C  /* TX Interrupt Absolute Delay Val - RW */
 #define E1000_TSPMT    0x03830  /* TCP Segmentation PAD & Min Threshold - RW */
-#define E1000_TARC0    0x03840 /* TX Arbitration Count (0) */
-#define E1000_TDBAL1   0x03900 /* TX Desc Base Address Low (1) - RW */
-#define E1000_TDBAH1   0x03904 /* TX Desc Base Address High (1) - RW */
-#define E1000_TDLEN1   0x03908 /* TX Desc Length (1) - RW */
-#define E1000_TDH1     0x03910 /* TX Desc Head (1) - RW */
-#define E1000_TDT1     0x03918 /* TX Desc Tail (1) - RW */
-#define E1000_TXDCTL1  0x03928 /* TX Descriptor Control (1) - RW */
-#define E1000_TARC1    0x03940 /* TX Arbitration Count (1) */
+#define E1000_TARC0    0x03840  /* TX Arbitration Count (0) */
+#define E1000_TDBAL1   0x03900  /* TX Desc Base Address Low (1) - RW */
+#define E1000_TDBAH1   0x03904  /* TX Desc Base Address High (1) - RW */
+#define E1000_TDLEN1   0x03908  /* TX Desc Length (1) - RW */
+#define E1000_TDH1     0x03910  /* TX Desc Head (1) - RW */
+#define E1000_TDT1     0x03918  /* TX Desc Tail (1) - RW */
+#define E1000_TXDCTL1  0x03928  /* TX Descriptor Control (1) - RW */
+#define E1000_TARC1    0x03940  /* TX Arbitration Count (1) */
 #define E1000_CRCERRS  0x04000  /* CRC Error Count - R/clr */
 #define E1000_ALGNERRC 0x04004  /* Alignment Error Count - R/clr */
 #define E1000_SYMERRS  0x04008  /* Symbol Error Count - R/clr */
@@ -1497,6 +1502,7 @@ struct e1000_hw {
 #define E1000_CTRL_EXT_EE_RST    0x00002000 /* Reinitialize from EEPROM */
 #define E1000_CTRL_EXT_IPS       0x00004000 /* Invert Power State */
 #define E1000_CTRL_EXT_SPD_BYPS  0x00008000 /* Speed Select Bypass */
+#define E1000_CTRL_EXT_RO_DIS    0x00020000 /* Relaxed Ordering disable */
 #define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
 #define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
 #define E1000_CTRL_EXT_LINK_MODE_TBI  0x00C00000
@@ -1758,7 +1764,6 @@ struct e1000_hw {
 #define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */
 #define E1000_TXDCTL_COUNT_DESC 0x00400000 /* Enable the counting of desc.
                                               still to be processed. */
-
 /* Transmit Configuration Word */
 #define E1000_TXCW_FD         0x00000020        /* TXCW full duplex */
 #define E1000_TXCW_HD         0x00000040        /* TXCW half duplex */
@@ -1954,6 +1959,23 @@ struct e1000_host_command_info {
 
 #define E1000_MDALIGN          4096
 
+/* PCI-Ex registers */
+
+/* PCI-Ex Control Register */
+#define E1000_GCR_RXD_NO_SNOOP			0x00000001
+#define E1000_GCR_RXDSCW_NO_SNOOP		0x00000002
+#define E1000_GCR_RXDSCR_NO_SNOOP		0x00000004
+#define E1000_GCR_TXD_NO_SNOOP			0x00000008
+#define E1000_GCR_TXDSCW_NO_SNOOP		0x00000010
+#define E1000_GCR_TXDSCR_NO_SNOOP		0x00000020
+
+#define PCI_EX_NO_SNOOP_ALL (E1000_GCR_RXD_NO_SNOOP		| \
+							 E1000_GCR_RXDSCW_NO_SNOOP	| \
+							 E1000_GCR_RXDSCR_NO_SNOOP	| \
+							 E1000_GCR TXD_NO_SNOOP		| \
+							 E1000_GCR_TXDSCW_NO_SNOOP	| \
+							 E1000_GCR_TXDSCR_NO_SNOOP)
+
 #define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
 /* Function Active and Power State to MNG */
 #define E1000_FACTPS_FUNC0_POWER_STATE_MASK         0x00000003
@@ -2077,7 +2099,10 @@ struct e1000_host_command_info {
 /* Collision related configuration parameters */
 #define E1000_COLLISION_THRESHOLD       15
 #define E1000_CT_SHIFT                  4
-#define E1000_COLLISION_DISTANCE        64
+/* Collision distance is a 0-based value that applies to
+ * half-duplex-capable hardware only. */
+#define E1000_COLLISION_DISTANCE        63
+#define E1000_COLLISION_DISTANCE_82542  64
 #define E1000_FDX_COLLISION_DISTANCE    E1000_COLLISION_DISTANCE
 #define E1000_HDX_COLLISION_DISTANCE    E1000_COLLISION_DISTANCE
 #define E1000_COLD_SHIFT                12
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 438a931..31e3329 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -29,11 +29,71 @@
 #include "e1000.h"
 
 /* Change Log
- * 6.0.58       4/20/05
- *   o Accepted ethtool cleanup patch from Stephen Hemminger 
- * 6.0.44+	2/15/05
- *   o applied Anton's patch to resolve tx hang in hardware
- *   o Applied Andrew Mortons patch - e1000 stops working after resume
+ * 6.3.9	12/16/2005
+ *   o incorporate fix for recycled skbs from IBM LTC
+ * 6.3.7	11/18/2005
+ *   o Honor eeprom setting for enabling/disabling Wake On Lan
+ * 6.3.5 	11/17/2005
+ *   o Fix memory leak in rx ring handling for PCI Express adapters
+ * 6.3.4	11/8/05
+ *   o Patch from Jesper Juhl to remove redundant NULL checks for kfree
+ * 6.3.2	9/20/05
+ *   o Render logic that sets/resets DRV_LOAD as inline functions to 
+ *     avoid code replication. If f/w is AMT then set DRV_LOAD only when
+ *     network interface is open.
+ *   o Handle DRV_LOAD set/reset in cases where AMT uses VLANs.
+ *   o Adjust PBA partioning for Jumbo frames using MTU size and not
+ *     rx_buffer_len
+ * 6.3.1	9/19/05
+ *   o Use adapter->tx_timeout_factor in Tx Hung Detect logic 
+       (e1000_clean_tx_irq)
+ *   o Support for 8086:10B5 device (Quad Port)
+ * 6.2.14	9/15/05
+ *   o In AMT enabled configurations, set/reset DRV_LOAD bit on interface 
+ *     open/close 
+ * 6.2.13       9/14/05
+ *   o Invoke e1000_check_mng_mode only for 8257x controllers since it 
+ *     accesses the FWSM that is not supported in other controllers
+ * 6.2.12       9/9/05
+ *   o Add support for device id E1000_DEV_ID_82546GB_QUAD_COPPER
+ *   o set RCTL:SECRC only for controllers newer than 82543. 
+ *   o When the n/w interface comes down reset DRV_LOAD bit to notify f/w.
+ *     This code was moved from e1000_remove to e1000_close
+ * 6.2.10       9/6/05
+ *   o Fix error in updating RDT in el1000_alloc_rx_buffers[_ps] -- one off.
+ *   o Enable fc by default on 82573 controllers (do not read eeprom)
+ *   o Fix rx_errors statistic not to include missed_packet_count
+ *   o Fix rx_dropped statistic not to include missed_packet_count 
+       (Padraig Brady)
+ * 6.2.9        8/30/05
+ *   o Remove call to update statistics from the controller ib e1000_get_stats
+ * 6.2.8        8/30/05
+ *   o Improved algorithm for rx buffer allocation/rdt update
+ *   o Flow control watermarks relative to rx PBA size
+ *   o Simplified 'Tx Hung' detect logic
+ * 6.2.7 	8/17/05
+ *   o Report rx buffer allocation failures and tx timeout counts in stats
+ * 6.2.6 	8/16/05
+ *   o Implement workaround for controller erratum -- linear non-tso packet
+ *     following a TSO gets written back prematurely
+ * 6.2.5	8/15/05
+ *   o Set netdev->tx_queue_len based on link speed/duplex settings.
+ *   o Fix net_stats.rx_fifo_errors <p@draigBrady.com>
+ *   o Do not power off PHY if SoL/IDER session is active
+ * 6.2.4	8/10/05
+ *   o Fix loopback test setup/cleanup for 82571/3 controllers
+ *   o Fix parsing of outgoing packets (e1000_transfer_dhcp_info) to treat
+ *     all packets as raw
+ *   o Prevent operations that will cause the PHY to be reset if SoL/IDER
+ *     sessions are active and log a message
+ * 6.2.2	7/21/05
+ *   o used fixed size descriptors for all MTU sizes, reduces memory load
+ * 6.1.2	4/13/05
+ *   o Fixed ethtool diagnostics
+ *   o Enabled flow control to take default eeprom settings
+ *   o Added stats_lock around e1000_read_phy_reg commands to avoid concurrent
+ *     calls, one from mii_ioctl and other from within update_stats while 
+ *     processing MIIREG ioctl.
  */
 
 char e1000_driver_name[] = "e1000";
@@ -43,7 +103,7 @@ static char e1000_driver_string[] = "Int
 #else
 #define DRIVERNAPI "-NAPI"
 #endif
-#define DRV_VERSION "6.1.16-k2"DRIVERNAPI
+#define DRV_VERSION "6.3.9-k2"DRIVERNAPI
 char e1000_driver_version[] = DRV_VERSION;
 static char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation.";
 
@@ -97,7 +157,9 @@ static struct pci_device_id e1000_pci_tb
 	INTEL_E1000_ETHERNET_DEVICE(0x108A),
 	INTEL_E1000_ETHERNET_DEVICE(0x108B),
 	INTEL_E1000_ETHERNET_DEVICE(0x108C),
+	INTEL_E1000_ETHERNET_DEVICE(0x1099),
 	INTEL_E1000_ETHERNET_DEVICE(0x109A),
+	INTEL_E1000_ETHERNET_DEVICE(0x10B5),
 	/* required last entry */
 	{0,}
 };
@@ -171,9 +233,11 @@ static boolean_t e1000_clean_rx_irq_ps(s
                                        struct e1000_rx_ring *rx_ring);
 #endif
 static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
-                                   struct e1000_rx_ring *rx_ring);
+                                   struct e1000_rx_ring *rx_ring,
+				   int cleaned_count);
 static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
-                                      struct e1000_rx_ring *rx_ring);
+                                      struct e1000_rx_ring *rx_ring,
+				      int cleaned_count);
 static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
 static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
 			   int cmd);
@@ -291,7 +355,7 @@ e1000_irq_disable(struct e1000_adapter *
 static inline void
 e1000_irq_enable(struct e1000_adapter *adapter)
 {
-	if(likely(atomic_dec_and_test(&adapter->irq_sem))) {
+	if (likely(atomic_dec_and_test(&adapter->irq_sem))) {
 		E1000_WRITE_REG(&adapter->hw, IMS, IMS_ENABLE_MASK);
 		E1000_WRITE_FLUSH(&adapter->hw);
 	}
@@ -303,23 +367,91 @@ e1000_update_mng_vlan(struct e1000_adapt
 	struct net_device *netdev = adapter->netdev;
 	uint16_t vid = adapter->hw.mng_cookie.vlan_id;
 	uint16_t old_vid = adapter->mng_vlan_id;
-	if(adapter->vlgrp) {
-		if(!adapter->vlgrp->vlan_devices[vid]) {
-			if(adapter->hw.mng_cookie.status &
+	if (adapter->vlgrp) {
+		if (!adapter->vlgrp->vlan_devices[vid]) {
+			if (adapter->hw.mng_cookie.status &
 				E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
 				e1000_vlan_rx_add_vid(netdev, vid);
 				adapter->mng_vlan_id = vid;
 			} else
 				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
-				
-			if((old_vid != (uint16_t)E1000_MNG_VLAN_NONE) &&
-					(vid != old_vid) && 
+
+			if ((old_vid != (uint16_t)E1000_MNG_VLAN_NONE) &&
+					(vid != old_vid) &&
 					!adapter->vlgrp->vlan_devices[old_vid])
 				e1000_vlan_rx_kill_vid(netdev, old_vid);
 		}
 	}
 }
-	
+
+/**
+ * e1000_release_hw_control - release control of the h/w to f/w
+ * @adapter: address of board private structure
+ *
+ * e1000_release_hw_control resets {CTRL_EXT|FWSM}:DRV_LOAD bit.
+ * For ASF and Pass Through versions of f/w this means that the
+ * driver is no longer loaded. For AMT version (only with 82573) i
+ * of the f/w this means that the netowrk i/f is closed.
+ * 
+ **/
+
+static inline void 
+e1000_release_hw_control(struct e1000_adapter *adapter)
+{
+	uint32_t ctrl_ext;
+	uint32_t swsm;
+
+	/* Let firmware taken over control of h/w */
+	switch (adapter->hw.mac_type) {
+	case e1000_82571:
+	case e1000_82572:
+		ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
+		E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
+				ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
+		break;
+	case e1000_82573:
+		swsm = E1000_READ_REG(&adapter->hw, SWSM);
+		E1000_WRITE_REG(&adapter->hw, SWSM,
+				swsm & ~E1000_SWSM_DRV_LOAD);
+	default:
+		break;
+	}
+}
+
+/**
+ * e1000_get_hw_control - get control of the h/w from f/w
+ * @adapter: address of board private structure
+ *
+ * e1000_get_hw_control sets {CTRL_EXT|FWSM}:DRV_LOAD bit.
+ * For ASF and Pass Through versions of f/w this means that 
+ * the driver is loaded. For AMT version (only with 82573) 
+ * of the f/w this means that the netowrk i/f is open.
+ * 
+ **/
+
+static inline void 
+e1000_get_hw_control(struct e1000_adapter *adapter)
+{
+	uint32_t ctrl_ext;
+	uint32_t swsm;
+	/* Let firmware know the driver has taken over */
+	switch (adapter->hw.mac_type) {
+	case e1000_82571:
+	case e1000_82572:
+		ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
+		E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
+				ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
+		break;
+	case e1000_82573:
+		swsm = E1000_READ_REG(&adapter->hw, SWSM);
+		E1000_WRITE_REG(&adapter->hw, SWSM,
+				swsm | E1000_SWSM_DRV_LOAD);
+		break;
+	default:
+		break;
+	}
+}
+
 int
 e1000_up(struct e1000_adapter *adapter)
 {
@@ -329,10 +461,10 @@ e1000_up(struct e1000_adapter *adapter)
 	/* hardware has been reset, we need to reload some things */
 
 	/* Reset the PHY if it was previously powered down */
-	if(adapter->hw.media_type == e1000_media_type_copper) {
+	if (adapter->hw.media_type == e1000_media_type_copper) {
 		uint16_t mii_reg;
 		e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
-		if(mii_reg & MII_CR_POWER_DOWN)
+		if (mii_reg & MII_CR_POWER_DOWN)
 			e1000_phy_reset(&adapter->hw);
 	}
 
@@ -343,20 +475,26 @@ e1000_up(struct e1000_adapter *adapter)
 	e1000_configure_tx(adapter);
 	e1000_setup_rctl(adapter);
 	e1000_configure_rx(adapter);
-	for (i = 0; i < adapter->num_queues; i++)
-		adapter->alloc_rx_buf(adapter, &adapter->rx_ring[i]);
+	/* call E1000_DESC_UNUSED which always leaves
+	 * at least 1 descriptor unused to make sure
+	 * next_to_use != next_to_clean */
+	for (i = 0; i < adapter->num_rx_queues; i++) {
+		struct e1000_rx_ring *ring = &adapter->rx_ring[i];
+		adapter->alloc_rx_buf(adapter, ring,
+		                      E1000_DESC_UNUSED(ring));
+	}
 
 #ifdef CONFIG_PCI_MSI
-	if(adapter->hw.mac_type > e1000_82547_rev_2) {
+	if (adapter->hw.mac_type > e1000_82547_rev_2) {
 		adapter->have_msi = TRUE;
-		if((err = pci_enable_msi(adapter->pdev))) {
+		if ((err = pci_enable_msi(adapter->pdev))) {
 			DPRINTK(PROBE, ERR,
 			 "Unable to allocate MSI interrupt Error: %d\n", err);
 			adapter->have_msi = FALSE;
 		}
 	}
 #endif
-	if((err = request_irq(adapter->pdev->irq, &e1000_intr,
+	if ((err = request_irq(adapter->pdev->irq, &e1000_intr,
 		              SA_SHIRQ | SA_SAMPLE_RANDOM,
 		              netdev->name, netdev))) {
 		DPRINTK(PROBE, ERR,
@@ -364,6 +502,12 @@ e1000_up(struct e1000_adapter *adapter)
 		return err;
 	}
 
+#ifdef CONFIG_E1000_MQ
+	e1000_setup_queue_mapping(adapter);
+#endif
+
+	adapter->tx_queue_len = netdev->tx_queue_len;
+
 	mod_timer(&adapter->watchdog_timer, jiffies);
 
 #ifdef CONFIG_E1000_NAPI
@@ -378,6 +522,8 @@ void
 e1000_down(struct e1000_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
+	boolean_t mng_mode_enabled = (adapter->hw.mac_type >= e1000_82571) &&
+				     e1000_check_mng_mode(&adapter->hw);
 
 	e1000_irq_disable(adapter);
 #ifdef CONFIG_E1000_MQ
@@ -385,7 +531,7 @@ e1000_down(struct e1000_adapter *adapter
 #endif
 	free_irq(adapter->pdev->irq, netdev);
 #ifdef CONFIG_PCI_MSI
-	if(adapter->hw.mac_type > e1000_82547_rev_2 &&
+	if (adapter->hw.mac_type > e1000_82547_rev_2 &&
 	   adapter->have_msi == TRUE)
 		pci_disable_msi(adapter->pdev);
 #endif
@@ -396,6 +542,7 @@ e1000_down(struct e1000_adapter *adapter
 #ifdef CONFIG_E1000_NAPI
 	netif_poll_disable(netdev);
 #endif
+	netdev->tx_queue_len = adapter->tx_queue_len;
 	adapter->link_speed = 0;
 	adapter->link_duplex = 0;
 	netif_carrier_off(netdev);
@@ -405,12 +552,16 @@ e1000_down(struct e1000_adapter *adapter
 	e1000_clean_all_tx_rings(adapter);
 	e1000_clean_all_rx_rings(adapter);
 
-	/* If WoL is not enabled and management mode is not IAMT
-	 * Power down the PHY so no link is implied when interface is down */
-	if(!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
+	/* Power down the PHY so no link is implied when interface is down *
+	 * The PHY cannot be powered down if any of the following is TRUE *
+	 * (a) WoL is enabled
+	 * (b) AMT is active
+	 * (c) SoL/IDER session is active */
+	if (!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
 	   adapter->hw.media_type == e1000_media_type_copper &&
-	   !e1000_check_mng_mode(&adapter->hw) &&
-	   !(E1000_READ_REG(&adapter->hw, MANC) & E1000_MANC_SMBUS_EN)) {
+	   !(E1000_READ_REG(&adapter->hw, MANC) & E1000_MANC_SMBUS_EN) &&
+	   !mng_mode_enabled &&
+	   !e1000_check_phy_reset_block(&adapter->hw)) {
 		uint16_t mii_reg;
 		e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
 		mii_reg |= MII_CR_POWER_DOWN;
@@ -422,10 +573,8 @@ e1000_down(struct e1000_adapter *adapter
 void
 e1000_reset(struct e1000_adapter *adapter)
 {
-	struct net_device *netdev = adapter->netdev;
 	uint32_t pba, manc;
 	uint16_t fc_high_water_mark = E1000_FC_HIGH_DIFF;
-	uint16_t fc_low_water_mark = E1000_FC_LOW_DIFF;
 
 	/* Repartition Pba for greater than 9k mtu
 	 * To take effect CTRL.RST is required.
@@ -448,19 +597,12 @@ e1000_reset(struct e1000_adapter *adapte
 		break;
 	}
 
-	if((adapter->hw.mac_type != e1000_82573) &&
-	   (adapter->rx_buffer_len > E1000_RXBUFFER_8192)) {
+	if ((adapter->hw.mac_type != e1000_82573) &&
+	   (adapter->netdev->mtu > E1000_RXBUFFER_8192))
 		pba -= 8; /* allocate more FIFO for Tx */
-		/* send an XOFF when there is enough space in the
-		 * Rx FIFO to hold one extra full size Rx packet 
-		*/
-		fc_high_water_mark = netdev->mtu + ENET_HEADER_SIZE + 
-					ETHERNET_FCS_SIZE + 1;
-		fc_low_water_mark = fc_high_water_mark + 8;
-	}
 
 
-	if(adapter->hw.mac_type == e1000_82547) {
+	if (adapter->hw.mac_type == e1000_82547) {
 		adapter->tx_fifo_head = 0;
 		adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
 		adapter->tx_fifo_size =
@@ -471,19 +613,21 @@ e1000_reset(struct e1000_adapter *adapte
 	E1000_WRITE_REG(&adapter->hw, PBA, pba);
 
 	/* flow control settings */
-	adapter->hw.fc_high_water = (pba << E1000_PBA_BYTES_SHIFT) -
-				    fc_high_water_mark;
-	adapter->hw.fc_low_water = (pba << E1000_PBA_BYTES_SHIFT) -
-				   fc_low_water_mark;
+	/* Set the FC high water mark to 90% of the FIFO size.
+	 * Required to clear last 3 LSB */
+	fc_high_water_mark = ((pba * 9216)/10) & 0xFFF8;
+
+	adapter->hw.fc_high_water = fc_high_water_mark;
+	adapter->hw.fc_low_water = fc_high_water_mark - 8;
 	adapter->hw.fc_pause_time = E1000_FC_PAUSE_TIME;
 	adapter->hw.fc_send_xon = 1;
 	adapter->hw.fc = adapter->hw.original_fc;
 
 	/* Allow time for pending master requests to run */
 	e1000_reset_hw(&adapter->hw);
-	if(adapter->hw.mac_type >= e1000_82544)
+	if (adapter->hw.mac_type >= e1000_82544)
 		E1000_WRITE_REG(&adapter->hw, WUC, 0);
-	if(e1000_init_hw(&adapter->hw))
+	if (e1000_init_hw(&adapter->hw))
 		DPRINTK(PROBE, ERR, "Hardware Error\n");
 	e1000_update_mng_vlan(adapter);
 	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
@@ -517,33 +661,31 @@ e1000_probe(struct pci_dev *pdev,
 	struct net_device *netdev;
 	struct e1000_adapter *adapter;
 	unsigned long mmio_start, mmio_len;
-	uint32_t ctrl_ext;
-	uint32_t swsm;
 
 	static int cards_found = 0;
 	int i, err, pci_using_dac;
 	uint16_t eeprom_data;
 	uint16_t eeprom_apme_mask = E1000_EEPROM_APME;
-	if((err = pci_enable_device(pdev)))
+	if ((err = pci_enable_device(pdev)))
 		return err;
 
-	if(!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
+	if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
 		pci_using_dac = 1;
 	} else {
-		if((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {
+		if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {
 			E1000_ERR("No usable DMA configuration, aborting\n");
 			return err;
 		}
 		pci_using_dac = 0;
 	}
 
-	if((err = pci_request_regions(pdev, e1000_driver_name)))
+	if ((err = pci_request_regions(pdev, e1000_driver_name)))
 		return err;
 
 	pci_set_master(pdev);
 
 	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
-	if(!netdev) {
+	if (!netdev) {
 		err = -ENOMEM;
 		goto err_alloc_etherdev;
 	}
@@ -562,15 +704,15 @@ e1000_probe(struct pci_dev *pdev,
 	mmio_len = pci_resource_len(pdev, BAR_0);
 
 	adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
-	if(!adapter->hw.hw_addr) {
+	if (!adapter->hw.hw_addr) {
 		err = -EIO;
 		goto err_ioremap;
 	}
 
-	for(i = BAR_1; i <= BAR_5; i++) {
-		if(pci_resource_len(pdev, i) == 0)
+	for (i = BAR_1; i <= BAR_5; i++) {
+		if (pci_resource_len(pdev, i) == 0)
 			continue;
-		if(pci_resource_flags(pdev, i) & IORESOURCE_IO) {
+		if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
 			adapter->hw.io_base = pci_resource_start(pdev, i);
 			break;
 		}
@@ -607,13 +749,13 @@ e1000_probe(struct pci_dev *pdev,
 
 	/* setup the private structure */
 
-	if((err = e1000_sw_init(adapter)))
+	if ((err = e1000_sw_init(adapter)))
 		goto err_sw_init;
 
-	if((err = e1000_check_phy_reset_block(&adapter->hw)))
+	if ((err = e1000_check_phy_reset_block(&adapter->hw)))
 		DPRINTK(PROBE, INFO, "PHY reset is blocked due to SOL/IDER session.\n");
 
-	if(adapter->hw.mac_type >= e1000_82543) {
+	if (adapter->hw.mac_type >= e1000_82543) {
 		netdev->features = NETIF_F_SG |
 				   NETIF_F_HW_CSUM |
 				   NETIF_F_HW_VLAN_TX |
@@ -622,16 +764,16 @@ e1000_probe(struct pci_dev *pdev,
 	}
 
 #ifdef NETIF_F_TSO
-	if((adapter->hw.mac_type >= e1000_82544) &&
+	if ((adapter->hw.mac_type >= e1000_82544) &&
 	   (adapter->hw.mac_type != e1000_82547))
 		netdev->features |= NETIF_F_TSO;
 
 #ifdef NETIF_F_TSO_IPV6
-	if(adapter->hw.mac_type > e1000_82547_rev_2)
+	if (adapter->hw.mac_type > e1000_82547_rev_2)
 		netdev->features |= NETIF_F_TSO_IPV6;
 #endif
 #endif
-	if(pci_using_dac)
+	if (pci_using_dac)
 		netdev->features |= NETIF_F_HIGHDMA;
 
  	/* hard_start_xmit is safe against parallel locking */
@@ -639,14 +781,14 @@ e1000_probe(struct pci_dev *pdev,
  
 	adapter->en_mng_pt = e1000_enable_mng_pass_thru(&adapter->hw);
 
-	/* before reading the EEPROM, reset the controller to 
+	/* before reading the EEPROM, reset the controller to
 	 * put the device in a known good starting state */
-	
+
 	e1000_reset_hw(&adapter->hw);
 
 	/* make sure the EEPROM is good */
 
-	if(e1000_validate_eeprom_checksum(&adapter->hw) < 0) {
+	if (e1000_validate_eeprom_checksum(&adapter->hw) < 0) {
 		DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
 		err = -EIO;
 		goto err_eeprom;
@@ -654,12 +796,12 @@ e1000_probe(struct pci_dev *pdev,
 
 	/* copy the MAC address out of the EEPROM */
 
-	if(e1000_read_mac_addr(&adapter->hw))
+	if (e1000_read_mac_addr(&adapter->hw))
 		DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
 	memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
 	memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
 
-	if(!is_valid_ether_addr(netdev->perm_addr)) {
+	if (!is_valid_ether_addr(netdev->perm_addr)) {
 		DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
 		err = -EIO;
 		goto err_eeprom;
@@ -699,7 +841,7 @@ e1000_probe(struct pci_dev *pdev,
 	 * enable the ACPI Magic Packet filter
 	 */
 
-	switch(adapter->hw.mac_type) {
+	switch (adapter->hw.mac_type) {
 	case e1000_82542_rev2_0:
 	case e1000_82542_rev2_1:
 	case e1000_82543:
@@ -712,8 +854,7 @@ e1000_probe(struct pci_dev *pdev,
 	case e1000_82546:
 	case e1000_82546_rev_3:
 	case e1000_82571:
-		if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1)
-		   && (adapter->hw.media_type == e1000_media_type_copper)) {
+		if (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1){
 			e1000_read_eeprom(&adapter->hw,
 				EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
 			break;
@@ -724,31 +865,42 @@ e1000_probe(struct pci_dev *pdev,
 			EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
 		break;
 	}
-	if(eeprom_data & eeprom_apme_mask)
+	if (eeprom_data & eeprom_apme_mask)
 		adapter->wol |= E1000_WUFC_MAG;
 
+	/* print bus type/speed/width info */
+	{
+	struct e1000_hw *hw = &adapter->hw;
+	DPRINTK(PROBE, INFO, "(PCI%s:%s:%s) ",
+		((hw->bus_type == e1000_bus_type_pcix) ? "-X" :
+		 (hw->bus_type == e1000_bus_type_pci_express ? " Express":"")),
+		((hw->bus_speed == e1000_bus_speed_2500) ? "2.5Gb/s" :
+		 (hw->bus_speed == e1000_bus_speed_133) ? "133MHz" :
+		 (hw->bus_speed == e1000_bus_speed_120) ? "120MHz" :
+		 (hw->bus_speed == e1000_bus_speed_100) ? "100MHz" :
+		 (hw->bus_speed == e1000_bus_speed_66) ? "66MHz" : "33MHz"),
+		((hw->bus_width == e1000_bus_width_64) ? "64-bit" :
+		 (hw->bus_width == e1000_bus_width_pciex_4) ? "Width x4" :
+		 (hw->bus_width == e1000_bus_width_pciex_1) ? "Width x1" :
+		 "32-bit"));
+	}
+
+	for (i = 0; i < 6; i++)
+		printk("%2.2x%c", netdev->dev_addr[i], i == 5 ? '\n' : ':');
+
 	/* reset the hardware with the new settings */
 	e1000_reset(adapter);
 
-	/* Let firmware know the driver has taken over */
-	switch(adapter->hw.mac_type) {
-	case e1000_82571:
-	case e1000_82572:
-		ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
-		E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
-				ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
-		break;
-	case e1000_82573:
-		swsm = E1000_READ_REG(&adapter->hw, SWSM);
-		E1000_WRITE_REG(&adapter->hw, SWSM,
-				swsm | E1000_SWSM_DRV_LOAD);
-		break;
-	default:
-		break;
-	}
+	/* If the controller is 82573 and f/w is AMT, do not set
+	 * DRV_LOAD until the interface is up.  For all other cases,
+	 * let the f/w know that the h/w is now under the control
+	 * of the driver. */
+	if (adapter->hw.mac_type != e1000_82573 ||
+	    !e1000_check_mng_mode(&adapter->hw))
+		e1000_get_hw_control(adapter);
 
 	strcpy(netdev->name, "eth%d");
-	if((err = register_netdev(netdev)))
+	if ((err = register_netdev(netdev)))
 		goto err_register;
 
 	DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
@@ -782,47 +934,33 @@ e1000_remove(struct pci_dev *pdev)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct e1000_adapter *adapter = netdev_priv(netdev);
-	uint32_t ctrl_ext;
-	uint32_t manc, swsm;
+	uint32_t manc;
 #ifdef CONFIG_E1000_NAPI
 	int i;
 #endif
 
 	flush_scheduled_work();
 
-	if(adapter->hw.mac_type >= e1000_82540 &&
+	if (adapter->hw.mac_type >= e1000_82540 &&
 	   adapter->hw.media_type == e1000_media_type_copper) {
 		manc = E1000_READ_REG(&adapter->hw, MANC);
-		if(manc & E1000_MANC_SMBUS_EN) {
+		if (manc & E1000_MANC_SMBUS_EN) {
 			manc |= E1000_MANC_ARP_EN;
 			E1000_WRITE_REG(&adapter->hw, MANC, manc);
 		}
 	}
 
-	switch(adapter->hw.mac_type) {
-	case e1000_82571:
-	case e1000_82572:
-		ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
-		E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
-				ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
-		break;
-	case e1000_82573:
-		swsm = E1000_READ_REG(&adapter->hw, SWSM);
-		E1000_WRITE_REG(&adapter->hw, SWSM,
-				swsm & ~E1000_SWSM_DRV_LOAD);
-		break;
-
-	default:
-		break;
-	}
+	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
+	 * would have already happened in close and is redundant. */
+	e1000_release_hw_control(adapter);
 
 	unregister_netdev(netdev);
 #ifdef CONFIG_E1000_NAPI
-	for (i = 0; i < adapter->num_queues; i++)
+	for (i = 0; i < adapter->num_rx_queues; i++)
 		__dev_put(&adapter->polling_netdev[i]);
 #endif
 
-	if(!e1000_check_phy_reset_block(&adapter->hw))
+	if (!e1000_check_phy_reset_block(&adapter->hw))
 		e1000_phy_hw_reset(&adapter->hw);
 
 	kfree(adapter->tx_ring);
@@ -881,19 +1019,19 @@ e1000_sw_init(struct e1000_adapter *adap
 
 	/* identify the MAC */
 
-	if(e1000_set_mac_type(hw)) {
+	if (e1000_set_mac_type(hw)) {
 		DPRINTK(PROBE, ERR, "Unknown MAC Type\n");
 		return -EIO;
 	}
 
 	/* initialize eeprom parameters */
 
-	if(e1000_init_eeprom_params(hw)) {
+	if (e1000_init_eeprom_params(hw)) {
 		E1000_ERR("EEPROM initialization failed\n");
 		return -EIO;
 	}
 
-	switch(hw->mac_type) {
+	switch (hw->mac_type) {
 	default:
 		break;
 	case e1000_82541:
@@ -912,7 +1050,7 @@ e1000_sw_init(struct e1000_adapter *adap
 
 	/* Copper options */
 
-	if(hw->media_type == e1000_media_type_copper) {
+	if (hw->media_type == e1000_media_type_copper) {
 		hw->mdix = AUTO_ALL_MODES;
 		hw->disable_polarity_correction = FALSE;
 		hw->master_slave = E1000_MASTER_SLAVE;
@@ -923,15 +1061,34 @@ e1000_sw_init(struct e1000_adapter *adap
 	switch (hw->mac_type) {
 	case e1000_82571:
 	case e1000_82572:
-		adapter->num_queues = 2;
+		/* These controllers support 2 tx queues, but with a single
+		 * qdisc implementation, multiple tx queues aren't quite as
+		 * interesting.  If we can find a logical way of mapping
+		 * flows to a queue, then perhaps we can up the num_tx_queue
+		 * count back to its default.  Until then, we run the risk of
+		 * terrible performance due to SACK overload. */
+		adapter->num_tx_queues = 1;
+		adapter->num_rx_queues = 2;
 		break;
 	default:
-		adapter->num_queues = 1;
+		adapter->num_tx_queues = 1;
+		adapter->num_rx_queues = 1;
 		break;
 	}
-	adapter->num_queues = min(adapter->num_queues, num_online_cpus());
+	adapter->num_rx_queues = min(adapter->num_rx_queues, num_online_cpus());
+	adapter->num_tx_queues = min(adapter->num_tx_queues, num_online_cpus());
+	DPRINTK(DRV, INFO, "Multiqueue Enabled: Rx Queue count = %u %s\n",
+		adapter->num_rx_queues,
+		((adapter->num_rx_queues == 1)
+		 ? ((num_online_cpus() > 1)
+			? "(due to unsupported feature in current adapter)"
+			: "(due to unsupported system configuration)")
+		 : ""));
+	DPRINTK(DRV, INFO, "Multiqueue Enabled: Tx Queue count = %u\n",
+		adapter->num_tx_queues);
 #else
-	adapter->num_queues = 1;
+	adapter->num_tx_queues = 1;
+	adapter->num_rx_queues = 1;
 #endif
 
 	if (e1000_alloc_queues(adapter)) {
@@ -940,17 +1097,14 @@ e1000_sw_init(struct e1000_adapter *adap
 	}
 
 #ifdef CONFIG_E1000_NAPI
-	for (i = 0; i < adapter->num_queues; i++) {
+	for (i = 0; i < adapter->num_rx_queues; i++) {
 		adapter->polling_netdev[i].priv = adapter;
 		adapter->polling_netdev[i].poll = &e1000_clean;
 		adapter->polling_netdev[i].weight = 64;
 		dev_hold(&adapter->polling_netdev[i]);
 		set_bit(__LINK_STATE_START, &adapter->polling_netdev[i].state);
 	}
-#endif
-
-#ifdef CONFIG_E1000_MQ
-	e1000_setup_queue_mapping(adapter);
+	spin_lock_init(&adapter->tx_queue_lock);
 #endif
 
 	atomic_set(&adapter->irq_sem, 1);
@@ -973,13 +1127,13 @@ e1000_alloc_queues(struct e1000_adapter 
 {
 	int size;
 
-	size = sizeof(struct e1000_tx_ring) * adapter->num_queues;
+	size = sizeof(struct e1000_tx_ring) * adapter->num_tx_queues;
 	adapter->tx_ring = kmalloc(size, GFP_KERNEL);
 	if (!adapter->tx_ring)
 		return -ENOMEM;
 	memset(adapter->tx_ring, 0, size);
 
-	size = sizeof(struct e1000_rx_ring) * adapter->num_queues;
+	size = sizeof(struct e1000_rx_ring) * adapter->num_rx_queues;
 	adapter->rx_ring = kmalloc(size, GFP_KERNEL);
 	if (!adapter->rx_ring) {
 		kfree(adapter->tx_ring);
@@ -988,7 +1142,7 @@ e1000_alloc_queues(struct e1000_adapter 
 	memset(adapter->rx_ring, 0, size);
 
 #ifdef CONFIG_E1000_NAPI
-	size = sizeof(struct net_device) * adapter->num_queues;
+	size = sizeof(struct net_device) * adapter->num_rx_queues;
 	adapter->polling_netdev = kmalloc(size, GFP_KERNEL);
 	if (!adapter->polling_netdev) {
 		kfree(adapter->tx_ring);
@@ -998,6 +1152,14 @@ e1000_alloc_queues(struct e1000_adapter 
 	memset(adapter->polling_netdev, 0, size);
 #endif
 
+#ifdef CONFIG_E1000_MQ
+	adapter->rx_sched_call_data.func = e1000_rx_schedule;
+	adapter->rx_sched_call_data.info = adapter->netdev;
+
+	adapter->cpu_netdev = alloc_percpu(struct net_device *);
+	adapter->cpu_tx_ring = alloc_percpu(struct e1000_tx_ring *);
+#endif
+
 	return E1000_SUCCESS;
 }
 
@@ -1017,14 +1179,15 @@ e1000_setup_queue_mapping(struct e1000_a
 	lock_cpu_hotplug();
 	i = 0;
 	for_each_online_cpu(cpu) {
-		*per_cpu_ptr(adapter->cpu_tx_ring, cpu) = &adapter->tx_ring[i % adapter->num_queues];
+		*per_cpu_ptr(adapter->cpu_tx_ring, cpu) = &adapter->tx_ring[i % adapter->num_tx_queues];
 		/* This is incomplete because we'd like to assign separate
 		 * physical cpus to these netdev polling structures and
 		 * avoid saturating a subset of cpus.
 		 */
-		if (i < adapter->num_queues) {
+		if (i < adapter->num_rx_queues) {
 			*per_cpu_ptr(adapter->cpu_netdev, cpu) = &adapter->polling_netdev[i];
-			adapter->cpu_for_queue[i] = cpu;
+			adapter->rx_ring[i].cpu = cpu;
+			cpu_set(cpu, adapter->cpumask);
 		} else
 			*per_cpu_ptr(adapter->cpu_netdev, cpu) = NULL;
 
@@ -1063,14 +1226,20 @@ e1000_open(struct net_device *netdev)
 	if ((err = e1000_setup_all_rx_resources(adapter)))
 		goto err_setup_rx;
 
-	if((err = e1000_up(adapter)))
+	if ((err = e1000_up(adapter)))
 		goto err_up;
 	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
-	if((adapter->hw.mng_cookie.status &
+	if ((adapter->hw.mng_cookie.status &
 			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
 		e1000_update_mng_vlan(adapter);
 	}
 
+	/* If AMT is enabled, let the firmware know that the network
+	 * interface is now open */
+	if (adapter->hw.mac_type == e1000_82573 &&
+	    e1000_check_mng_mode(&adapter->hw))
+		e1000_get_hw_control(adapter);
+
 	return E1000_SUCCESS;
 
 err_up:
@@ -1105,10 +1274,17 @@ e1000_close(struct net_device *netdev)
 	e1000_free_all_tx_resources(adapter);
 	e1000_free_all_rx_resources(adapter);
 
-	if((adapter->hw.mng_cookie.status &
+	if ((adapter->hw.mng_cookie.status &
 			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
 		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
 	}
+
+	/* If AMT is enabled, let the firmware know that the network
+	 * interface is now closed */
+	if (adapter->hw.mac_type == e1000_82573 &&
+	    e1000_check_mng_mode(&adapter->hw))
+		e1000_release_hw_control(adapter);
+
 	return 0;
 }
 
@@ -1153,7 +1329,7 @@ e1000_setup_tx_resources(struct e1000_ad
 	size = sizeof(struct e1000_buffer) * txdr->count;
 
 	txdr->buffer_info = vmalloc_node(size, pcibus_to_node(pdev->bus));
-	if(!txdr->buffer_info) {
+	if (!txdr->buffer_info) {
 		DPRINTK(PROBE, ERR,
 		"Unable to allocate memory for the transmit descriptor ring\n");
 		return -ENOMEM;
@@ -1166,7 +1342,7 @@ e1000_setup_tx_resources(struct e1000_ad
 	E1000_ROUNDUP(txdr->size, 4096);
 
 	txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
-	if(!txdr->desc) {
+	if (!txdr->desc) {
 setup_tx_desc_die:
 		vfree(txdr->buffer_info);
 		DPRINTK(PROBE, ERR,
@@ -1182,8 +1358,8 @@ setup_tx_desc_die:
 				     "at %p\n", txdr->size, txdr->desc);
 		/* Try again, without freeing the previous */
 		txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
-		if(!txdr->desc) {
 		/* Failed allocation, critical failure */
+		if (!txdr->desc) {
 			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
 			goto setup_tx_desc_die;
 		}
@@ -1229,7 +1405,7 @@ e1000_setup_all_tx_resources(struct e100
 {
 	int i, err = 0;
 
-	for (i = 0; i < adapter->num_queues; i++) {
+	for (i = 0; i < adapter->num_tx_queues; i++) {
 		err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
 		if (err) {
 			DPRINTK(PROBE, ERR,
@@ -1254,10 +1430,11 @@ e1000_configure_tx(struct e1000_adapter 
 	uint64_t tdba;
 	struct e1000_hw *hw = &adapter->hw;
 	uint32_t tdlen, tctl, tipg, tarc;
+	uint32_t ipgr1, ipgr2;
 
 	/* Setup the HW Tx Head and Tail descriptor pointers */
 
-	switch (adapter->num_queues) {
+	switch (adapter->num_tx_queues) {
 	case 2:
 		tdba = adapter->tx_ring[1].dma;
 		tdlen = adapter->tx_ring[1].count *
@@ -1287,22 +1464,26 @@ e1000_configure_tx(struct e1000_adapter 
 
 	/* Set the default values for the Tx Inter Packet Gap timer */
 
+	if (hw->media_type == e1000_media_type_fiber ||
+	    hw->media_type == e1000_media_type_internal_serdes)
+		tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
+	else
+		tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
+
 	switch (hw->mac_type) {
 	case e1000_82542_rev2_0:
 	case e1000_82542_rev2_1:
 		tipg = DEFAULT_82542_TIPG_IPGT;
-		tipg |= DEFAULT_82542_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
-		tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
+		ipgr1 = DEFAULT_82542_TIPG_IPGR1;
+		ipgr2 = DEFAULT_82542_TIPG_IPGR2;
 		break;
 	default:
-		if (hw->media_type == e1000_media_type_fiber ||
-		    hw->media_type == e1000_media_type_internal_serdes)
-			tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
-		else
-			tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
-		tipg |= DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
-		tipg |= DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
+		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
+		ipgr2 = DEFAULT_82543_TIPG_IPGR2;
+		break;
 	}
+	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
+	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
 	E1000_WRITE_REG(hw, TIPG, tipg);
 
 	/* Set the Tx Interrupt Delay register */
@@ -1378,7 +1559,7 @@ e1000_setup_rx_resources(struct e1000_ad
 
 	size = sizeof(struct e1000_ps_page) * rxdr->count;
 	rxdr->ps_page = kmalloc(size, GFP_KERNEL);
-	if(!rxdr->ps_page) {
+	if (!rxdr->ps_page) {
 		vfree(rxdr->buffer_info);
 		DPRINTK(PROBE, ERR,
 		"Unable to allocate memory for the receive descriptor ring\n");
@@ -1388,7 +1569,7 @@ e1000_setup_rx_resources(struct e1000_ad
 
 	size = sizeof(struct e1000_ps_page_dma) * rxdr->count;
 	rxdr->ps_page_dma = kmalloc(size, GFP_KERNEL);
-	if(!rxdr->ps_page_dma) {
+	if (!rxdr->ps_page_dma) {
 		vfree(rxdr->buffer_info);
 		kfree(rxdr->ps_page);
 		DPRINTK(PROBE, ERR,
@@ -1397,7 +1578,7 @@ e1000_setup_rx_resources(struct e1000_ad
 	}
 	memset(rxdr->ps_page_dma, 0, size);
 
-	if(adapter->hw.mac_type <= e1000_82547_rev_2)
+	if (adapter->hw.mac_type <= e1000_82547_rev_2)
 		desc_len = sizeof(struct e1000_rx_desc);
 	else
 		desc_len = sizeof(union e1000_rx_desc_packet_split);
@@ -1454,6 +1635,8 @@ setup_rx_desc_die:
 
 	rxdr->next_to_clean = 0;
 	rxdr->next_to_use = 0;
+	rxdr->rx_skb_top = NULL;
+	rxdr->rx_skb_prev = NULL;
 
 	return 0;
 }
@@ -1475,7 +1658,7 @@ e1000_setup_all_rx_resources(struct e100
 {
 	int i, err = 0;
 
-	for (i = 0; i < adapter->num_queues; i++) {
+	for (i = 0; i < adapter->num_rx_queues; i++) {
 		err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
 		if (err) {
 			DPRINTK(PROBE, ERR,
@@ -1498,7 +1681,7 @@ e1000_setup_rctl(struct e1000_adapter *a
 {
 	uint32_t rctl, rfctl;
 	uint32_t psrctl = 0;
-#ifdef CONFIG_E1000_PACKET_SPLIT
+#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
 	uint32_t pages = 0;
 #endif
 
@@ -1510,7 +1693,10 @@ e1000_setup_rctl(struct e1000_adapter *a
 		E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
 		(adapter->hw.mc_filter_type << E1000_RCTL_MO_SHIFT);
 
-	if(adapter->hw.tbi_compatibility_on == 1)
+	if (adapter->hw.mac_type > e1000_82543)
+		rctl |= E1000_RCTL_SECRC;
+
+	if (adapter->hw.tbi_compatibility_on == 1)
 		rctl |= E1000_RCTL_SBP;
 	else
 		rctl &= ~E1000_RCTL_SBP;
@@ -1521,32 +1707,17 @@ e1000_setup_rctl(struct e1000_adapter *a
 		rctl |= E1000_RCTL_LPE;
 
 	/* Setup buffer sizes */
-	if(adapter->hw.mac_type >= e1000_82571) {
+	if (adapter->hw.mac_type >= e1000_82571) {
 		/* We can now specify buffers in 1K increments.
 		 * BSIZE and BSEX are ignored in this case. */
 		rctl |= adapter->rx_buffer_len << 0x11;
 	} else {
 		rctl &= ~E1000_RCTL_SZ_4096;
-		rctl |= E1000_RCTL_BSEX; 
-		switch (adapter->rx_buffer_len) {
-		case E1000_RXBUFFER_2048:
-		default:
-			rctl |= E1000_RCTL_SZ_2048;
-			rctl &= ~E1000_RCTL_BSEX;
-			break;
-		case E1000_RXBUFFER_4096:
-			rctl |= E1000_RCTL_SZ_4096;
-			break;
-		case E1000_RXBUFFER_8192:
-			rctl |= E1000_RCTL_SZ_8192;
-			break;
-		case E1000_RXBUFFER_16384:
-			rctl |= E1000_RCTL_SZ_16384;
-			break;
-		}
+		rctl &= ~E1000_RCTL_BSEX;
+		rctl |= E1000_RCTL_SZ_2048;
 	}
 
-#ifdef CONFIG_E1000_PACKET_SPLIT
+#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
 	/* 82571 and greater support packet-split where the protocol
 	 * header is placed in skb->data and the packet data is
 	 * placed in pages hanging off of skb_shinfo(skb)->nr_frags.
@@ -1570,7 +1741,7 @@ e1000_setup_rctl(struct e1000_adapter *a
 		E1000_WRITE_REG(&adapter->hw, RFCTL, rfctl);
 
 		rctl |= E1000_RCTL_DTYP_PS | E1000_RCTL_SECRC;
-		
+
 		psrctl |= adapter->rx_ps_bsize0 >>
 			E1000_PSRCTL_BSIZE0_SHIFT;
 
@@ -1632,22 +1803,27 @@ e1000_configure_rx(struct e1000_adapter 
 
 	if (hw->mac_type >= e1000_82540) {
 		E1000_WRITE_REG(hw, RADV, adapter->rx_abs_int_delay);
-		if(adapter->itr > 1)
+		if (adapter->itr > 1)
 			E1000_WRITE_REG(hw, ITR,
 				1000000000 / (adapter->itr * 256));
 	}
 
 	if (hw->mac_type >= e1000_82571) {
-		/* Reset delay timers after every interrupt */
 		ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+		/* Reset delay timers after every interrupt */
 		ctrl_ext |= E1000_CTRL_EXT_CANC;
+#ifdef CONFIG_E1000_NAPI
+		/* Auto-Mask interrupts upon ICR read. */
+		ctrl_ext |= E1000_CTRL_EXT_IAME;
+#endif
 		E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+		E1000_WRITE_REG(hw, IAM, ~0);
 		E1000_WRITE_FLUSH(hw);
 	}
 
 	/* Setup the HW Rx Head and Tail Descriptor Pointers and
 	 * the Base and Length of the Rx Descriptor Ring */
-	switch (adapter->num_queues) {
+	switch (adapter->num_rx_queues) {
 #ifdef CONFIG_E1000_MQ
 	case 2:
 		rdba = adapter->rx_ring[1].dma;
@@ -1674,7 +1850,7 @@ e1000_configure_rx(struct e1000_adapter 
 	}
 
 #ifdef CONFIG_E1000_MQ
-	if (adapter->num_queues > 1) {
+	if (adapter->num_rx_queues > 1) {
 		uint32_t random[10];
 
 		get_random_bytes(&random[0], 40);
@@ -1684,7 +1860,7 @@ e1000_configure_rx(struct e1000_adapter 
 			E1000_WRITE_REG(hw, RSSIM, 0);
 		}
 
-		switch (adapter->num_queues) {
+		switch (adapter->num_rx_queues) {
 		case 2:
 		default:
 			reta = 0x00800080;
@@ -1716,13 +1892,13 @@ e1000_configure_rx(struct e1000_adapter 
 	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
 	if (hw->mac_type >= e1000_82543) {
 		rxcsum = E1000_READ_REG(hw, RXCSUM);
-		if(adapter->rx_csum == TRUE) {
+		if (adapter->rx_csum == TRUE) {
 			rxcsum |= E1000_RXCSUM_TUOFL;
 
 			/* Enable 82571 IPv4 payload checksum for UDP fragments
 			 * Must be used in conjunction with packet-split. */
-			if ((hw->mac_type >= e1000_82571) && 
-			   (adapter->rx_ps_pages)) {
+			if ((hw->mac_type >= e1000_82571) &&
+			    (adapter->rx_ps_pages)) {
 				rxcsum |= E1000_RXCSUM_IPPCSE;
 			}
 		} else {
@@ -1776,7 +1952,7 @@ e1000_free_all_tx_resources(struct e1000
 {
 	int i;
 
-	for (i = 0; i < adapter->num_queues; i++)
+	for (i = 0; i < adapter->num_tx_queues; i++)
 		e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
 }
 
@@ -1784,17 +1960,15 @@ static inline void
 e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
 			struct e1000_buffer *buffer_info)
 {
-	if(buffer_info->dma) {
+	if (buffer_info->dma) {
 		pci_unmap_page(adapter->pdev,
 				buffer_info->dma,
 				buffer_info->length,
 				PCI_DMA_TODEVICE);
-		buffer_info->dma = 0;
 	}
-	if(buffer_info->skb) {
+	if (buffer_info->skb)
 		dev_kfree_skb_any(buffer_info->skb);
-		buffer_info->skb = NULL;
-	}
+	memset(buffer_info, 0, sizeof(struct e1000_buffer));
 }
 
 /**
@@ -1813,7 +1987,7 @@ e1000_clean_tx_ring(struct e1000_adapter
 
 	/* Free all the Tx ring sk_buffs */
 
-	for(i = 0; i < tx_ring->count; i++) {
+	for (i = 0; i < tx_ring->count; i++) {
 		buffer_info = &tx_ring->buffer_info[i];
 		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
 	}
@@ -1843,7 +2017,7 @@ e1000_clean_all_tx_rings(struct e1000_ad
 {
 	int i;
 
-	for (i = 0; i < adapter->num_queues; i++)
+	for (i = 0; i < adapter->num_tx_queues; i++)
 		e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
 }
 
@@ -1887,7 +2061,7 @@ e1000_free_all_rx_resources(struct e1000
 {
 	int i;
 
-	for (i = 0; i < adapter->num_queues; i++)
+	for (i = 0; i < adapter->num_rx_queues; i++)
 		e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
 }
 
@@ -1909,12 +2083,9 @@ e1000_clean_rx_ring(struct e1000_adapter
 	unsigned int i, j;
 
 	/* Free all the Rx ring sk_buffs */
-
-	for(i = 0; i < rx_ring->count; i++) {
+	for (i = 0; i < rx_ring->count; i++) {
 		buffer_info = &rx_ring->buffer_info[i];
-		if(buffer_info->skb) {
-			ps_page = &rx_ring->ps_page[i];
-			ps_page_dma = &rx_ring->ps_page_dma[i];
+		if (buffer_info->skb) {
 			pci_unmap_single(pdev,
 					 buffer_info->dma,
 					 buffer_info->length,
@@ -1922,19 +2093,30 @@ e1000_clean_rx_ring(struct e1000_adapter
 
 			dev_kfree_skb(buffer_info->skb);
 			buffer_info->skb = NULL;
-
-			for(j = 0; j < adapter->rx_ps_pages; j++) {
-				if(!ps_page->ps_page[j]) break;
-				pci_unmap_single(pdev,
-						 ps_page_dma->ps_page_dma[j],
-						 PAGE_SIZE, PCI_DMA_FROMDEVICE);
-				ps_page_dma->ps_page_dma[j] = 0;
-				put_page(ps_page->ps_page[j]);
-				ps_page->ps_page[j] = NULL;
-			}
 		}
+		ps_page = &rx_ring->ps_page[i];
+		ps_page_dma = &rx_ring->ps_page_dma[i];
+		for (j = 0; j < adapter->rx_ps_pages; j++) {
+			if (!ps_page->ps_page[j]) break;
+			pci_unmap_page(pdev,
+				       ps_page_dma->ps_page_dma[j],
+				       PAGE_SIZE, PCI_DMA_FROMDEVICE);
+			ps_page_dma->ps_page_dma[j] = 0;
+			put_page(ps_page->ps_page[j]);
+			ps_page->ps_page[j] = NULL;
+		}
+	}
+
+	/* there also may be some cached data in our adapter */
+	if (rx_ring->rx_skb_top) {
+		dev_kfree_skb(rx_ring->rx_skb_top);
+
+		/* rx_skb_prev will be wiped out by rx_skb_top */
+		rx_ring->rx_skb_top = NULL;
+		rx_ring->rx_skb_prev = NULL;
 	}
 
+
 	size = sizeof(struct e1000_buffer) * rx_ring->count;
 	memset(rx_ring->buffer_info, 0, size);
 	size = sizeof(struct e1000_ps_page) * rx_ring->count;
@@ -1963,7 +2145,7 @@ e1000_clean_all_rx_rings(struct e1000_ad
 {
 	int i;
 
-	for (i = 0; i < adapter->num_queues; i++)
+	for (i = 0; i < adapter->num_rx_queues; i++)
 		e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
 }
 
@@ -1984,7 +2166,7 @@ e1000_enter_82542_rst(struct e1000_adapt
 	E1000_WRITE_FLUSH(&adapter->hw);
 	mdelay(5);
 
-	if(netif_running(netdev))
+	if (netif_running(netdev))
 		e1000_clean_all_rx_rings(adapter);
 }
 
@@ -2000,12 +2182,14 @@ e1000_leave_82542_rst(struct e1000_adapt
 	E1000_WRITE_FLUSH(&adapter->hw);
 	mdelay(5);
 
-	if(adapter->hw.pci_cmd_word & PCI_COMMAND_INVALIDATE)
+	if (adapter->hw.pci_cmd_word & PCI_COMMAND_INVALIDATE)
 		e1000_pci_set_mwi(&adapter->hw);
 
-	if(netif_running(netdev)) {
+	if (netif_running(netdev)) {
+		/* No need to loop, because 82542 supports only 1 queue */
+		struct e1000_rx_ring *ring = &adapter->rx_ring[0];
 		e1000_configure_rx(adapter);
-		e1000_alloc_rx_buffers(adapter, &adapter->rx_ring[0]);
+		adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring));
 	}
 }
 
@@ -2023,12 +2207,12 @@ e1000_set_mac(struct net_device *netdev,
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct sockaddr *addr = p;
 
-	if(!is_valid_ether_addr(addr->sa_data))
+	if (!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
 
 	/* 82542 2.0 needs to be in reset to write receive address registers */
 
-	if(adapter->hw.mac_type == e1000_82542_rev2_0)
+	if (adapter->hw.mac_type == e1000_82542_rev2_0)
 		e1000_enter_82542_rst(adapter);
 
 	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
@@ -2042,17 +2226,17 @@ e1000_set_mac(struct net_device *netdev,
 		/* activate the work around */
 		adapter->hw.laa_is_present = 1;
 
-		/* Hold a copy of the LAA in RAR[14] This is done so that 
-		 * between the time RAR[0] gets clobbered  and the time it 
-		 * gets fixed (in e1000_watchdog), the actual LAA is in one 
+		/* Hold a copy of the LAA in RAR[14] This is done so that
+		 * between the time RAR[0] gets clobbered  and the time it
+		 * gets fixed (in e1000_watchdog), the actual LAA is in one
 		 * of the RARs and no incoming packets directed to this port
-		 * are dropped. Eventaully the LAA will be in RAR[0] and 
+		 * are dropped. Eventaully the LAA will be in RAR[0] and
 		 * RAR[14] */
-		e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 
+		e1000_rar_set(&adapter->hw, adapter->hw.mac_addr,
 					E1000_RAR_ENTRIES - 1);
 	}
 
-	if(adapter->hw.mac_type == e1000_82542_rev2_0)
+	if (adapter->hw.mac_type == e1000_82542_rev2_0)
 		e1000_leave_82542_rst(adapter);
 
 	return 0;
@@ -2086,9 +2270,9 @@ e1000_set_multi(struct net_device *netde
 
 	rctl = E1000_READ_REG(hw, RCTL);
 
-	if(netdev->flags & IFF_PROMISC) {
+	if (netdev->flags & IFF_PROMISC) {
 		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
-	} else if(netdev->flags & IFF_ALLMULTI) {
+	} else if (netdev->flags & IFF_ALLMULTI) {
 		rctl |= E1000_RCTL_MPE;
 		rctl &= ~E1000_RCTL_UPE;
 	} else {
@@ -2099,7 +2283,7 @@ e1000_set_multi(struct net_device *netde
 
 	/* 82542 2.0 needs to be in reset to write receive address registers */
 
-	if(hw->mac_type == e1000_82542_rev2_0)
+	if (hw->mac_type == e1000_82542_rev2_0)
 		e1000_enter_82542_rst(adapter);
 
 	/* load the first 14 multicast address into the exact filters 1-14
@@ -2109,7 +2293,7 @@ e1000_set_multi(struct net_device *netde
 	 */
 	mc_ptr = netdev->mc_list;
 
-	for(i = 1; i < rar_entries; i++) {
+	for (i = 1; i < rar_entries; i++) {
 		if (mc_ptr) {
 			e1000_rar_set(hw, mc_ptr->dmi_addr, i);
 			mc_ptr = mc_ptr->next;
@@ -2121,17 +2305,17 @@ e1000_set_multi(struct net_device *netde
 
 	/* clear the old settings from the multicast hash table */
 
-	for(i = 0; i < E1000_NUM_MTA_REGISTERS; i++)
+	for (i = 0; i < E1000_NUM_MTA_REGISTERS; i++)
 		E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
 
 	/* load any remaining addresses into the hash table */
 
-	for(; mc_ptr; mc_ptr = mc_ptr->next) {
+	for (; mc_ptr; mc_ptr = mc_ptr->next) {
 		hash_value = e1000_hash_mc_addr(hw, mc_ptr->dmi_addr);
 		e1000_mta_set(hw, hash_value);
 	}
 
-	if(hw->mac_type == e1000_82542_rev2_0)
+	if (hw->mac_type == e1000_82542_rev2_0)
 		e1000_leave_82542_rst(adapter);
 }
 
@@ -2157,8 +2341,8 @@ e1000_82547_tx_fifo_stall(unsigned long 
 	struct net_device *netdev = adapter->netdev;
 	uint32_t tctl;
 
-	if(atomic_read(&adapter->tx_fifo_stall)) {
-		if((E1000_READ_REG(&adapter->hw, TDT) ==
+	if (atomic_read(&adapter->tx_fifo_stall)) {
+		if ((E1000_READ_REG(&adapter->hw, TDT) ==
 		    E1000_READ_REG(&adapter->hw, TDH)) &&
 		   (E1000_READ_REG(&adapter->hw, TDFT) ==
 		    E1000_READ_REG(&adapter->hw, TDFH)) &&
@@ -2204,24 +2388,24 @@ static void
 e1000_watchdog_task(struct e1000_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
-	struct e1000_tx_ring *txdr = &adapter->tx_ring[0];
+	struct e1000_tx_ring *txdr = adapter->tx_ring;
 	uint32_t link;
 
 	e1000_check_for_link(&adapter->hw);
 	if (adapter->hw.mac_type == e1000_82573) {
 		e1000_enable_tx_pkt_filtering(&adapter->hw);
-		if(adapter->mng_vlan_id != adapter->hw.mng_cookie.vlan_id)
+		if (adapter->mng_vlan_id != adapter->hw.mng_cookie.vlan_id)
 			e1000_update_mng_vlan(adapter);
-	}	
+	}
 
-	if((adapter->hw.media_type == e1000_media_type_internal_serdes) &&
+	if ((adapter->hw.media_type == e1000_media_type_internal_serdes) &&
 	   !(E1000_READ_REG(&adapter->hw, TXCW) & E1000_TXCW_ANE))
 		link = !adapter->hw.serdes_link_down;
 	else
 		link = E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU;
 
-	if(link) {
-		if(!netif_carrier_ok(netdev)) {
+	if (link) {
+		if (!netif_carrier_ok(netdev)) {
 			e1000_get_speed_and_duplex(&adapter->hw,
 			                           &adapter->link_speed,
 			                           &adapter->link_duplex);
@@ -2231,13 +2415,28 @@ e1000_watchdog_task(struct e1000_adapter
 			       adapter->link_duplex == FULL_DUPLEX ?
 			       "Full Duplex" : "Half Duplex");
 
+			/* tweak tx_queue_len according to speed/duplex */
+			netdev->tx_queue_len = adapter->tx_queue_len;
+			adapter->tx_timeout_factor = 1;
+			if (adapter->link_duplex == HALF_DUPLEX) {
+				switch (adapter->link_speed) {
+				case SPEED_10:
+					netdev->tx_queue_len = 10;
+					adapter->tx_timeout_factor = 8;
+					break;
+				case SPEED_100:
+					netdev->tx_queue_len = 100;
+					break;
+				}
+			}
+
 			netif_carrier_on(netdev);
 			netif_wake_queue(netdev);
 			mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ);
 			adapter->smartspeed = 0;
 		}
 	} else {
-		if(netif_carrier_ok(netdev)) {
+		if (netif_carrier_ok(netdev)) {
 			adapter->link_speed = 0;
 			adapter->link_duplex = 0;
 			DPRINTK(LINK, INFO, "NIC Link is Down\n");
@@ -2263,7 +2462,10 @@ e1000_watchdog_task(struct e1000_adapter
 
 	e1000_update_adaptive(&adapter->hw);
 
-	if (adapter->num_queues == 1 && !netif_carrier_ok(netdev)) {
+#ifdef CONFIG_E1000_MQ
+	txdr = *per_cpu_ptr(adapter->cpu_tx_ring, smp_processor_id());
+#endif
+	if (!netif_carrier_ok(netdev)) {
 		if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
 			/* We've lost link, so the controller stops DMA,
 			 * but we've got queued Tx work that's never going
@@ -2274,12 +2476,12 @@ e1000_watchdog_task(struct e1000_adapter
 	}
 
 	/* Dynamic mode for Interrupt Throttle Rate (ITR) */
-	if(adapter->hw.mac_type >= e1000_82540 && adapter->itr == 1) {
+	if (adapter->hw.mac_type >= e1000_82540 && adapter->itr == 1) {
 		/* Symmetric Tx/Rx gets a reduced ITR=2000; Total
 		 * asymmetrical Tx or Rx gets ITR=8000; everyone
 		 * else is between 2000-8000. */
 		uint32_t goc = (adapter->gotcl + adapter->gorcl) / 10000;
-		uint32_t dif = (adapter->gotcl > adapter->gorcl ? 
+		uint32_t dif = (adapter->gotcl > adapter->gorcl ?
 			adapter->gotcl - adapter->gorcl :
 			adapter->gorcl - adapter->gotcl) / 10000;
 		uint32_t itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000;
@@ -2292,7 +2494,7 @@ e1000_watchdog_task(struct e1000_adapter
 	/* Force detection of hung controller every watchdog period */
 	adapter->detect_tx_hung = TRUE;
 
-	/* With 82571 controllers, LAA may be overwritten due to controller 
+	/* With 82571 controllers, LAA may be overwritten due to controller
 	 * reset from the other port. Set the appropriate LAA in RAR[0] */
 	if (adapter->hw.mac_type == e1000_82571 && adapter->hw.laa_is_present)
 		e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 0);
@@ -2314,13 +2516,14 @@ e1000_tso(struct e1000_adapter *adapter,
 {
 #ifdef NETIF_F_TSO
 	struct e1000_context_desc *context_desc;
+	struct e1000_buffer *buffer_info;
 	unsigned int i;
 	uint32_t cmd_length = 0;
 	uint16_t ipcse = 0, tucse, mss;
 	uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
 	int err;
 
-	if(skb_shinfo(skb)->tso_size) {
+	if (skb_shinfo(skb)->tso_size) {
 		if (skb_header_cloned(skb)) {
 			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
 			if (err)
@@ -2329,7 +2532,7 @@ e1000_tso(struct e1000_adapter *adapter,
 
 		hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
 		mss = skb_shinfo(skb)->tso_size;
-		if(skb->protocol == ntohs(ETH_P_IP)) {
+		if (skb->protocol == ntohs(ETH_P_IP)) {
 			skb->nh.iph->tot_len = 0;
 			skb->nh.iph->check = 0;
 			skb->h.th->check =
@@ -2341,7 +2544,7 @@ e1000_tso(struct e1000_adapter *adapter,
 			cmd_length = E1000_TXD_CMD_IP;
 			ipcse = skb->h.raw - skb->data - 1;
 #ifdef NETIF_F_TSO_IPV6
-		} else if(skb->protocol == ntohs(ETH_P_IPV6)) {
+		} else if (skb->protocol == ntohs(ETH_P_IPV6)) {
 			skb->nh.ipv6h->payload_len = 0;
 			skb->h.th->check =
 				~csum_ipv6_magic(&skb->nh.ipv6h->saddr,
@@ -2363,6 +2566,7 @@ e1000_tso(struct e1000_adapter *adapter,
 
 		i = tx_ring->next_to_use;
 		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
+		buffer_info = &tx_ring->buffer_info[i];
 
 		context_desc->lower_setup.ip_fields.ipcss  = ipcss;
 		context_desc->lower_setup.ip_fields.ipcso  = ipcso;
@@ -2374,14 +2578,16 @@ e1000_tso(struct e1000_adapter *adapter,
 		context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
 		context_desc->cmd_and_length = cpu_to_le32(cmd_length);
 
+		buffer_info->time_stamp = jiffies;
+
 		if (++i == tx_ring->count) i = 0;
 		tx_ring->next_to_use = i;
 
-		return 1;
+		return TRUE;
 	}
 #endif
 
-	return 0;
+	return FALSE;
 }
 
 static inline boolean_t
@@ -2389,13 +2595,15 @@ e1000_tx_csum(struct e1000_adapter *adap
               struct sk_buff *skb)
 {
 	struct e1000_context_desc *context_desc;
+	struct e1000_buffer *buffer_info;
 	unsigned int i;
 	uint8_t css;
 
-	if(likely(skb->ip_summed == CHECKSUM_HW)) {
+	if (likely(skb->ip_summed == CHECKSUM_HW)) {
 		css = skb->h.raw - skb->data;
 
 		i = tx_ring->next_to_use;
+		buffer_info = &tx_ring->buffer_info[i];
 		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
 
 		context_desc->upper_setup.tcp_fields.tucss = css;
@@ -2404,6 +2612,8 @@ e1000_tx_csum(struct e1000_adapter *adap
 		context_desc->tcp_seg_setup.data = 0;
 		context_desc->cmd_and_length = cpu_to_le32(E1000_TXD_CMD_DEXT);
 
+		buffer_info->time_stamp = jiffies;
+
 		if (unlikely(++i == tx_ring->count)) i = 0;
 		tx_ring->next_to_use = i;
 
@@ -2429,7 +2639,7 @@ e1000_tx_map(struct e1000_adapter *adapt
 
 	i = tx_ring->next_to_use;
 
-	while(len) {
+	while (len) {
 		buffer_info = &tx_ring->buffer_info[i];
 		size = min(len, max_per_txd);
 #ifdef NETIF_F_TSO
@@ -2445,7 +2655,7 @@ e1000_tx_map(struct e1000_adapter *adapt
 
 		/* Workaround for premature desc write-backs
 		 * in TSO mode.  Append 4-byte sentinel desc */
-		if(unlikely(mss && !nr_frags && size == len && size > 8))
+		if (unlikely(mss && !nr_frags && size == len && size > 8))
 			size -= 4;
 #endif
 		/* work-around for errata 10 and it applies
@@ -2453,13 +2663,13 @@ e1000_tx_map(struct e1000_adapter *adapt
 		 * The fix is to make sure that the first descriptor of a
 		 * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
 		 */
-		if(unlikely((adapter->hw.bus_type == e1000_bus_type_pcix) &&
+		if (unlikely((adapter->hw.bus_type == e1000_bus_type_pcix) &&
 		                (size > 2015) && count == 0))
 		        size = 2015;
-                                                                                
+
 		/* Workaround for potential 82544 hang in PCI-X.  Avoid
 		 * terminating buffers within evenly-aligned dwords. */
-		if(unlikely(adapter->pcix_82544 &&
+		if (unlikely(adapter->pcix_82544 &&
 		   !((unsigned long)(skb->data + offset + size - 1) & 4) &&
 		   size > 4))
 			size -= 4;
@@ -2475,29 +2685,29 @@ e1000_tx_map(struct e1000_adapter *adapt
 		len -= size;
 		offset += size;
 		count++;
-		if(unlikely(++i == tx_ring->count)) i = 0;
+		if (unlikely(++i == tx_ring->count)) i = 0;
 	}
 
-	for(f = 0; f < nr_frags; f++) {
+	for (f = 0; f < nr_frags; f++) {
 		struct skb_frag_struct *frag;
 
 		frag = &skb_shinfo(skb)->frags[f];
 		len = frag->size;
 		offset = frag->page_offset;
 
-		while(len) {
+		while (len) {
 			buffer_info = &tx_ring->buffer_info[i];
 			size = min(len, max_per_txd);
 #ifdef NETIF_F_TSO
 			/* Workaround for premature desc write-backs
 			 * in TSO mode.  Append 4-byte sentinel desc */
-			if(unlikely(mss && f == (nr_frags-1) && size == len && size > 8))
+			if (unlikely(mss && f == (nr_frags-1) && size == len && size > 8))
 				size -= 4;
 #endif
 			/* Workaround for potential 82544 hang in PCI-X.
 			 * Avoid terminating buffers within evenly-aligned
 			 * dwords. */
-			if(unlikely(adapter->pcix_82544 &&
+			if (unlikely(adapter->pcix_82544 &&
 			   !((unsigned long)(frag->page+offset+size-1) & 4) &&
 			   size > 4))
 				size -= 4;
@@ -2514,7 +2724,7 @@ e1000_tx_map(struct e1000_adapter *adapt
 			len -= size;
 			offset += size;
 			count++;
-			if(unlikely(++i == tx_ring->count)) i = 0;
+			if (unlikely(++i == tx_ring->count)) i = 0;
 		}
 	}
 
@@ -2534,35 +2744,35 @@ e1000_tx_queue(struct e1000_adapter *ada
 	uint32_t txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
 	unsigned int i;
 
-	if(likely(tx_flags & E1000_TX_FLAGS_TSO)) {
+	if (likely(tx_flags & E1000_TX_FLAGS_TSO)) {
 		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
 		             E1000_TXD_CMD_TSE;
 		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
 
-		if(likely(tx_flags & E1000_TX_FLAGS_IPV4))
+		if (likely(tx_flags & E1000_TX_FLAGS_IPV4))
 			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
 	}
 
-	if(likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
+	if (likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
 		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
 		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
 	}
 
-	if(unlikely(tx_flags & E1000_TX_FLAGS_VLAN)) {
+	if (unlikely(tx_flags & E1000_TX_FLAGS_VLAN)) {
 		txd_lower |= E1000_TXD_CMD_VLE;
 		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
 	}
 
 	i = tx_ring->next_to_use;
 
-	while(count--) {
+	while (count--) {
 		buffer_info = &tx_ring->buffer_info[i];
 		tx_desc = E1000_TX_DESC(*tx_ring, i);
 		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
 		tx_desc->lower.data =
 			cpu_to_le32(txd_lower | buffer_info->length);
 		tx_desc->upper.data = cpu_to_le32(txd_upper);
-		if(unlikely(++i == tx_ring->count)) i = 0;
+		if (unlikely(++i == tx_ring->count)) i = 0;
 	}
 
 	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
@@ -2597,20 +2807,20 @@ e1000_82547_fifo_workaround(struct e1000
 
 	E1000_ROUNDUP(skb_fifo_len, E1000_FIFO_HDR);
 
-	if(adapter->link_duplex != HALF_DUPLEX)
+	if (adapter->link_duplex != HALF_DUPLEX)
 		goto no_fifo_stall_required;
 
-	if(atomic_read(&adapter->tx_fifo_stall))
+	if (atomic_read(&adapter->tx_fifo_stall))
 		return 1;
 
-	if(skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
+	if (skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
 		atomic_set(&adapter->tx_fifo_stall, 1);
 		return 1;
 	}
 
 no_fifo_stall_required:
 	adapter->tx_fifo_head += skb_fifo_len;
-	if(adapter->tx_fifo_head >= adapter->tx_fifo_size)
+	if (adapter->tx_fifo_head >= adapter->tx_fifo_size)
 		adapter->tx_fifo_head -= adapter->tx_fifo_size;
 	return 0;
 }
@@ -2621,27 +2831,27 @@ e1000_transfer_dhcp_info(struct e1000_ad
 {
 	struct e1000_hw *hw =  &adapter->hw;
 	uint16_t length, offset;
-	if(vlan_tx_tag_present(skb)) {
-		if(!((vlan_tx_tag_get(skb) == adapter->hw.mng_cookie.vlan_id) &&
+	if (vlan_tx_tag_present(skb)) {
+		if (!((vlan_tx_tag_get(skb) == adapter->hw.mng_cookie.vlan_id) &&
 			( adapter->hw.mng_cookie.status &
 			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) )
 			return 0;
 	}
- 	if ((skb->len > MINIMUM_DHCP_PACKET_SIZE) && (!skb->protocol)) {
+	if ((skb->len > MINIMUM_DHCP_PACKET_SIZE) && (!skb->protocol)) {
 		struct ethhdr *eth = (struct ethhdr *) skb->data;
-		if((htons(ETH_P_IP) == eth->h_proto)) {
-			const struct iphdr *ip = 
+		if ((htons(ETH_P_IP) == eth->h_proto)) {
+			const struct iphdr *ip =
 				(struct iphdr *)((uint8_t *)skb->data+14);
-			if(IPPROTO_UDP == ip->protocol) {
-				struct udphdr *udp = 
-					(struct udphdr *)((uint8_t *)ip + 
+			if (IPPROTO_UDP == ip->protocol) {
+				struct udphdr *udp =
+					(struct udphdr *)((uint8_t *)ip +
 						(ip->ihl << 2));
-				if(ntohs(udp->dest) == 67) {
+				if (ntohs(udp->dest) == 67) {
 					offset = (uint8_t *)udp + 8 - skb->data;
 					length = skb->len - offset;
 
 					return e1000_mng_write_dhcp_info(hw,
-							(uint8_t *)udp + 8, 
+							(uint8_t *)udp + 8,
 							length);
 				}
 			}
@@ -2664,7 +2874,7 @@ e1000_xmit_frame(struct sk_buff *skb, st
 	unsigned int nr_frags = 0;
 	unsigned int mss = 0;
 	int count = 0;
-	int tso;
+ 	int tso;
 	unsigned int f;
 	len -= skb->data_len;
 
@@ -2687,16 +2897,35 @@ e1000_xmit_frame(struct sk_buff *skb, st
 	 * 4 = ceil(buffer len/mss).  To make sure we don't
 	 * overrun the FIFO, adjust the max buffer len if mss
 	 * drops. */
-	if(mss) {
+	if (mss) {
+		uint8_t hdr_len;
 		max_per_txd = min(mss << 2, max_per_txd);
 		max_txd_pwr = fls(max_per_txd) - 1;
+
+	/* TSO Workaround for 82571/2 Controllers -- if skb->data
+	 * points to just header, pull a few bytes of payload from
+	 * frags into skb->data */
+		hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
+		if (skb->data_len && (hdr_len == (skb->len - skb->data_len)) &&
+			(adapter->hw.mac_type == e1000_82571 ||
+			adapter->hw.mac_type == e1000_82572)) {
+			unsigned int pull_size;
+			pull_size = min((unsigned int)4, skb->data_len);
+			if (!__pskb_pull_tail(skb, pull_size)) {
+				printk(KERN_ERR "__pskb_pull_tail failed.\n");
+				dev_kfree_skb_any(skb);
+				return -EFAULT;
+			}
+			len = skb->len - skb->data_len;
+		}
 	}
 
-	if((mss) || (skb->ip_summed == CHECKSUM_HW))
+	/* reserve a descriptor for the offload context */
+	if ((mss) || (skb->ip_summed == CHECKSUM_HW))
 		count++;
 	count++;
 #else
-	if(skb->ip_summed == CHECKSUM_HW)
+	if (skb->ip_summed == CHECKSUM_HW)
 		count++;
 #endif
 
@@ -2709,45 +2938,24 @@ e1000_xmit_frame(struct sk_buff *skb, st
 
 	count += TXD_USE_COUNT(len, max_txd_pwr);
 
-	if(adapter->pcix_82544)
+	if (adapter->pcix_82544)
 		count++;
 
-	/* work-around for errata 10 and it applies to all controllers 
+	/* work-around for errata 10 and it applies to all controllers
 	 * in PCI-X mode, so add one more descriptor to the count
 	 */
-	if(unlikely((adapter->hw.bus_type == e1000_bus_type_pcix) &&
+	if (unlikely((adapter->hw.bus_type == e1000_bus_type_pcix) &&
 			(len > 2015)))
 		count++;
 
 	nr_frags = skb_shinfo(skb)->nr_frags;
-	for(f = 0; f < nr_frags; f++)
+	for (f = 0; f < nr_frags; f++)
 		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
 				       max_txd_pwr);
-	if(adapter->pcix_82544)
+	if (adapter->pcix_82544)
 		count += nr_frags;
 
-#ifdef NETIF_F_TSO
-	/* TSO Workaround for 82571/2 Controllers -- if skb->data
-	 * points to just header, pull a few bytes of payload from 
-	 * frags into skb->data */
-	if (skb_shinfo(skb)->tso_size) {
-		uint8_t hdr_len;
-		hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
-		if (skb->data_len && (hdr_len < (skb->len - skb->data_len)) && 
-			(adapter->hw.mac_type == e1000_82571 ||
-			adapter->hw.mac_type == e1000_82572)) {
-			unsigned int pull_size;
-			pull_size = min((unsigned int)4, skb->data_len);
-			if (!__pskb_pull_tail(skb, pull_size)) {
-				printk(KERN_ERR "__pskb_pull_tail failed.\n");
-				dev_kfree_skb_any(skb);
-				return -EFAULT;
-			}
-		}
-	}
-#endif
-
-	if(adapter->hw.tx_pkt_filtering && (adapter->hw.mac_type == e1000_82573) )
+	if (adapter->hw.tx_pkt_filtering && (adapter->hw.mac_type == e1000_82573) )
 		e1000_transfer_dhcp_info(adapter, skb);
 
 	local_irq_save(flags);
@@ -2765,8 +2973,8 @@ e1000_xmit_frame(struct sk_buff *skb, st
 		return NETDEV_TX_BUSY;
 	}
 
-	if(unlikely(adapter->hw.mac_type == e1000_82547)) {
-		if(unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
+	if (unlikely(adapter->hw.mac_type == e1000_82547)) {
+		if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
 			netif_stop_queue(netdev);
 			mod_timer(&adapter->tx_fifo_stall_timer, jiffies);
 			spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
@@ -2774,13 +2982,13 @@ e1000_xmit_frame(struct sk_buff *skb, st
 		}
 	}
 
-	if(unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
+	if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
 		tx_flags |= E1000_TX_FLAGS_VLAN;
 		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
 	}
 
 	first = tx_ring->next_to_use;
-	
+
 	tso = e1000_tso(adapter, tx_ring, skb);
 	if (tso < 0) {
 		dev_kfree_skb_any(skb);
@@ -2833,6 +3041,7 @@ e1000_tx_timeout_task(struct net_device 
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 
+	adapter->tx_timeout_count++;
 	e1000_down(adapter);
 	e1000_up(adapter);
 }
@@ -2850,7 +3059,7 @@ e1000_get_stats(struct net_device *netde
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 
-	e1000_update_stats(adapter);
+	/* only return the current stats */
 	return &adapter->net_stats;
 }
 
@@ -2868,56 +3077,57 @@ e1000_change_mtu(struct net_device *netd
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
 
-	if((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
-		(max_frame > MAX_JUMBO_FRAME_SIZE)) {
-			DPRINTK(PROBE, ERR, "Invalid MTU setting\n");
-			return -EINVAL;
-	}
-
-#define MAX_STD_JUMBO_FRAME_SIZE 9234
-	/* might want this to be bigger enum check... */
-	/* 82571 controllers limit jumbo frame size to 10500 bytes */
-	if ((adapter->hw.mac_type == e1000_82571 || 
-	     adapter->hw.mac_type == e1000_82572) &&
-	    max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
-		DPRINTK(PROBE, ERR, "MTU > 9216 bytes not supported "
-				    "on 82571 and 82572 controllers.\n");
-		return -EINVAL;
-	}
-
-	if(adapter->hw.mac_type == e1000_82573 &&
-	    max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
-		DPRINTK(PROBE, ERR, "Jumbo Frames not supported "
-				    "on 82573\n");
+	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
+	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
+		DPRINTK(PROBE, ERR, "Invalid MTU setting\n");
 		return -EINVAL;
 	}
 
-	if(adapter->hw.mac_type > e1000_82547_rev_2) {
-		adapter->rx_buffer_len = max_frame;
-		E1000_ROUNDUP(adapter->rx_buffer_len, 1024);
-	} else {
-		if(unlikely((adapter->hw.mac_type < e1000_82543) &&
-		   (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE))) {
-			DPRINTK(PROBE, ERR, "Jumbo Frames not supported "
-					    "on 82542\n");
+	/* Adapter-specific max frame size limits. */
+	switch (adapter->hw.mac_type) {
+	case e1000_82542_rev2_0:
+	case e1000_82542_rev2_1:
+	case e1000_82573:
+		if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
+			DPRINTK(PROBE, ERR, "Jumbo Frames not supported.\n");
+			return -EINVAL;
+		}
+		break;
+	case e1000_82571:
+	case e1000_82572:
+#define MAX_STD_JUMBO_FRAME_SIZE 9234
+		if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
+			DPRINTK(PROBE, ERR, "MTU > 9216 not supported.\n");
 			return -EINVAL;
-
-		} else {
-			if(max_frame <= E1000_RXBUFFER_2048) {
-				adapter->rx_buffer_len = E1000_RXBUFFER_2048;
-			} else if(max_frame <= E1000_RXBUFFER_4096) {
-				adapter->rx_buffer_len = E1000_RXBUFFER_4096;
-			} else if(max_frame <= E1000_RXBUFFER_8192) {
-				adapter->rx_buffer_len = E1000_RXBUFFER_8192;
-			} else if(max_frame <= E1000_RXBUFFER_16384) {
-				adapter->rx_buffer_len = E1000_RXBUFFER_16384;
-			}
 		}
+		break;
+	default:
+		/* Capable of supporting up to MAX_JUMBO_FRAME_SIZE limit. */
+		break;
 	}
 
+	/* since the driver code now supports splitting a packet across
+	 * multiple descriptors, most of the fifo related limitations on
+	 * jumbo frame traffic have gone away.
+	 * simply use 2k descriptors for everything.
+	 *
+	 * NOTE: dev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
+	 * means we reserve 2 more, this pushes us to allocate from the next
+	 * larger slab size
+	 * i.e. RXBUFFER_2048 --> size-4096 slab */
+
+	/* recent hardware supports 1KB granularity */
+	if (adapter->hw.mac_type > e1000_82547_rev_2) {
+		adapter->rx_buffer_len =
+		    ((max_frame < E1000_RXBUFFER_2048) ?
+		        max_frame : E1000_RXBUFFER_2048);
+		E1000_ROUNDUP(adapter->rx_buffer_len, 1024);
+	} else
+		adapter->rx_buffer_len = E1000_RXBUFFER_2048;
+
 	netdev->mtu = new_mtu;
 
-	if(netif_running(netdev)) {
+	if (netif_running(netdev)) {
 		e1000_down(adapter);
 		e1000_up(adapter);
 	}
@@ -3004,7 +3214,7 @@ e1000_update_stats(struct e1000_adapter 
 	hw->collision_delta = E1000_READ_REG(hw, COLC);
 	adapter->stats.colc += hw->collision_delta;
 
-	if(hw->mac_type >= e1000_82543) {
+	if (hw->mac_type >= e1000_82543) {
 		adapter->stats.algnerrc += E1000_READ_REG(hw, ALGNERRC);
 		adapter->stats.rxerrc += E1000_READ_REG(hw, RXERRC);
 		adapter->stats.tncrs += E1000_READ_REG(hw, TNCRS);
@@ -3012,7 +3222,7 @@ e1000_update_stats(struct e1000_adapter 
 		adapter->stats.tsctc += E1000_READ_REG(hw, TSCTC);
 		adapter->stats.tsctfc += E1000_READ_REG(hw, TSCTFC);
 	}
-	if(hw->mac_type > e1000_82547_rev_2) {
+	if (hw->mac_type > e1000_82547_rev_2) {
 		adapter->stats.iac += E1000_READ_REG(hw, IAC);
 		adapter->stats.icrxoc += E1000_READ_REG(hw, ICRXOC);
 		adapter->stats.icrxptc += E1000_READ_REG(hw, ICRXPTC);
@@ -3037,12 +3247,11 @@ e1000_update_stats(struct e1000_adapter 
 
 	adapter->net_stats.rx_errors = adapter->stats.rxerrc +
 		adapter->stats.crcerrs + adapter->stats.algnerrc +
-		adapter->stats.rlec + adapter->stats.mpc + 
-		adapter->stats.cexterr;
+		adapter->stats.rlec + adapter->stats.cexterr;
+	adapter->net_stats.rx_dropped = 0;
 	adapter->net_stats.rx_length_errors = adapter->stats.rlec;
 	adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
 	adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
-	adapter->net_stats.rx_fifo_errors = adapter->stats.mpc;
 	adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
 
 	/* Tx Errors */
@@ -3057,14 +3266,14 @@ e1000_update_stats(struct e1000_adapter 
 
 	/* Phy Stats */
 
-	if(hw->media_type == e1000_media_type_copper) {
-		if((adapter->link_speed == SPEED_1000) &&
+	if (hw->media_type == e1000_media_type_copper) {
+		if ((adapter->link_speed == SPEED_1000) &&
 		   (!e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
 			phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
 			adapter->phy_stats.idle_errors += phy_tmp;
 		}
 
-		if((hw->mac_type <= e1000_82546) &&
+		if ((hw->mac_type <= e1000_82546) &&
 		   (hw->phy_type == e1000_phy_m88) &&
 		   !e1000_read_phy_reg(hw, M88E1000_RX_ERR_CNTR, &phy_tmp))
 			adapter->phy_stats.receive_errors += phy_tmp;
@@ -3110,32 +3319,44 @@ e1000_intr(int irq, void *data, struct p
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 	uint32_t icr = E1000_READ_REG(hw, ICR);
-#if defined(CONFIG_E1000_NAPI) && defined(CONFIG_E1000_MQ) || !defined(CONFIG_E1000_NAPI)
+#ifndef CONFIG_E1000_NAPI
 	int i;
+#else
+	/* Interrupt Auto-Mask...upon reading ICR,
+	 * interrupts are masked.  No need for the
+	 * IMC write, but it does mean we should
+	 * account for it ASAP. */
+	if (likely(hw->mac_type >= e1000_82571))
+		atomic_inc(&adapter->irq_sem);
 #endif
 
-	if(unlikely(!icr))
+	if (unlikely(!icr)) {
+#ifdef CONFIG_E1000_NAPI
+		if (hw->mac_type >= e1000_82571)
+			e1000_irq_enable(adapter);
+#endif
 		return IRQ_NONE;  /* Not our interrupt */
+	}
 
-	if(unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
+	if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
 		hw->get_link_status = 1;
 		mod_timer(&adapter->watchdog_timer, jiffies);
 	}
 
 #ifdef CONFIG_E1000_NAPI
-	atomic_inc(&adapter->irq_sem);
-	E1000_WRITE_REG(hw, IMC, ~0);
-	E1000_WRITE_FLUSH(hw);
+	if (unlikely(hw->mac_type < e1000_82571)) {
+		atomic_inc(&adapter->irq_sem);
+		E1000_WRITE_REG(hw, IMC, ~0);
+		E1000_WRITE_FLUSH(hw);
+	}
 #ifdef CONFIG_E1000_MQ
 	if (atomic_read(&adapter->rx_sched_call_data.count) == 0) {
-		cpu_set(adapter->cpu_for_queue[0],
-			adapter->rx_sched_call_data.cpumask);
-		for (i = 1; i < adapter->num_queues; i++) {
-			cpu_set(adapter->cpu_for_queue[i],
-				adapter->rx_sched_call_data.cpumask);
-			atomic_inc(&adapter->irq_sem);
-		}
-		atomic_set(&adapter->rx_sched_call_data.count, i);
+		/* We must setup the cpumask once count == 0 since
+		 * each cpu bit is cleared when the work is done. */
+		adapter->rx_sched_call_data.cpumask = adapter->cpumask;
+		atomic_add(adapter->num_rx_queues - 1, &adapter->irq_sem);
+		atomic_set(&adapter->rx_sched_call_data.count,
+		           adapter->num_rx_queues);
 		smp_call_async_mask(&adapter->rx_sched_call_data);
 	} else {
 		printk("call_data.count == %u\n", atomic_read(&adapter->rx_sched_call_data.count));
@@ -3149,26 +3370,26 @@ e1000_intr(int irq, void *data, struct p
 
 #else /* if !CONFIG_E1000_NAPI */
 	/* Writing IMC and IMS is needed for 82547.
-	   Due to Hub Link bus being occupied, an interrupt
-	   de-assertion message is not able to be sent.
-	   When an interrupt assertion message is generated later,
-	   two messages are re-ordered and sent out.
-	   That causes APIC to think 82547 is in de-assertion
-	   state, while 82547 is in assertion state, resulting
-	   in dead lock. Writing IMC forces 82547 into
-	   de-assertion state.
-	*/
-	if(hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2){
+	 * Due to Hub Link bus being occupied, an interrupt
+	 * de-assertion message is not able to be sent.
+	 * When an interrupt assertion message is generated later,
+	 * two messages are re-ordered and sent out.
+	 * That causes APIC to think 82547 is in de-assertion
+	 * state, while 82547 is in assertion state, resulting
+	 * in dead lock. Writing IMC forces 82547 into
+	 * de-assertion state.
+	 */
+	if (hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2) {
 		atomic_inc(&adapter->irq_sem);
 		E1000_WRITE_REG(hw, IMC, ~0);
 	}
 
-	for(i = 0; i < E1000_MAX_INTR; i++)
-		if(unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
+	for (i = 0; i < E1000_MAX_INTR; i++)
+		if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
 		   !e1000_clean_tx_irq(adapter, adapter->tx_ring)))
 			break;
 
-	if(hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2)
+	if (hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2)
 		e1000_irq_enable(adapter);
 
 #endif /* CONFIG_E1000_NAPI */
@@ -3187,7 +3408,7 @@ e1000_clean(struct net_device *poll_dev,
 {
 	struct e1000_adapter *adapter;
 	int work_to_do = min(*budget, poll_dev->quota);
-	int tx_cleaned, i = 0, work_done = 0;
+	int tx_cleaned = 0, i = 0, work_done = 0;
 
 	/* Must NOT use netdev_priv macro here. */
 	adapter = poll_dev->priv;
@@ -3198,19 +3419,31 @@ e1000_clean(struct net_device *poll_dev,
 
 	while (poll_dev != &adapter->polling_netdev[i]) {
 		i++;
-		if (unlikely(i == adapter->num_queues))
+		if (unlikely(i == adapter->num_rx_queues))
 			BUG();
 	}
 
-	tx_cleaned = e1000_clean_tx_irq(adapter, &adapter->tx_ring[i]);
+	if (likely(adapter->num_tx_queues == 1)) {
+		/* e1000_clean is called per-cpu.  This lock protects
+		 * tx_ring[0] from being cleaned by multiple cpus
+		 * simultaneously.  A failure obtaining the lock means
+		 * tx_ring[0] is currently being cleaned anyway. */
+		if (spin_trylock(&adapter->tx_queue_lock)) {
+			tx_cleaned = e1000_clean_tx_irq(adapter,
+							&adapter->tx_ring[0]);
+			spin_unlock(&adapter->tx_queue_lock);
+		}
+	} else
+		tx_cleaned = e1000_clean_tx_irq(adapter, &adapter->tx_ring[i]);
+
 	adapter->clean_rx(adapter, &adapter->rx_ring[i],
 	                  &work_done, work_to_do);
 
 	*budget -= work_done;
 	poll_dev->quota -= work_done;
-	
+
 	/* If no Tx and not enough Rx work done, exit the polling mode */
-	if((!tx_cleaned && (work_done == 0)) ||
+	if ((!tx_cleaned && (work_done == 0)) ||
 	   !netif_running(adapter->netdev)) {
 quit_polling:
 		netif_rx_complete(poll_dev);
@@ -3242,22 +3475,24 @@ e1000_clean_tx_irq(struct e1000_adapter 
 	eop_desc = E1000_TX_DESC(*tx_ring, eop);
 
 	while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
-		for(cleaned = FALSE; !cleaned; ) {
+		for (cleaned = FALSE; !cleaned; ) {
 			tx_desc = E1000_TX_DESC(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
 			cleaned = (i == eop);
 
+#ifdef CONFIG_E1000_MQ
+			tx_ring->tx_stats.bytes += buffer_info->length;
+#endif
 			e1000_unmap_and_free_tx_resource(adapter, buffer_info);
+			memset(tx_desc, 0, sizeof(struct e1000_tx_desc));
 
-			tx_desc->buffer_addr = 0;
-			tx_desc->lower.data = 0;
-			tx_desc->upper.data = 0;
-
-			if(unlikely(++i == tx_ring->count)) i = 0;
+			if (unlikely(++i == tx_ring->count)) i = 0;
 		}
 
-		tx_ring->pkt++;
-		
+#ifdef CONFIG_E1000_MQ
+		tx_ring->tx_stats.packets++;
+#endif
+
 		eop = tx_ring->buffer_info[i].next_to_watch;
 		eop_desc = E1000_TX_DESC(*tx_ring, eop);
 	}
@@ -3266,7 +3501,7 @@ e1000_clean_tx_irq(struct e1000_adapter 
 
 	spin_lock(&tx_ring->tx_lock);
 
-	if(unlikely(cleaned && netif_queue_stopped(netdev) &&
+	if (unlikely(cleaned && netif_queue_stopped(netdev) &&
 		    netif_carrier_ok(netdev)))
 		netif_wake_queue(netdev);
 
@@ -3276,32 +3511,31 @@ e1000_clean_tx_irq(struct e1000_adapter 
 		/* Detect a transmit hang in hardware, this serializes the
 		 * check with the clearing of time_stamp and movement of i */
 		adapter->detect_tx_hung = FALSE;
-		if (tx_ring->buffer_info[i].dma &&
-		    time_after(jiffies, tx_ring->buffer_info[i].time_stamp + HZ)
+		if (tx_ring->buffer_info[eop].dma &&
+		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
+		               adapter->tx_timeout_factor * HZ)
 		    && !(E1000_READ_REG(&adapter->hw, STATUS) &
-			E1000_STATUS_TXOFF)) {
+		         E1000_STATUS_TXOFF)) {
 
 			/* detected Tx unit hang */
-			i = tx_ring->next_to_clean;
-			eop = tx_ring->buffer_info[i].next_to_watch;
-			eop_desc = E1000_TX_DESC(*tx_ring, eop);
 			DPRINTK(DRV, ERR, "Detected Tx Unit Hang\n"
+					"  Tx Queue             <%lu>\n"
 					"  TDH                  <%x>\n"
 					"  TDT                  <%x>\n"
 					"  next_to_use          <%x>\n"
 					"  next_to_clean        <%x>\n"
 					"buffer_info[next_to_clean]\n"
-					"  dma                  <%llx>\n"
 					"  time_stamp           <%lx>\n"
 					"  next_to_watch        <%x>\n"
 					"  jiffies              <%lx>\n"
 					"  next_to_watch.status <%x>\n",
+				(unsigned long)((tx_ring - adapter->tx_ring) /
+					sizeof(struct e1000_tx_ring)),
 				readl(adapter->hw.hw_addr + tx_ring->tdh),
 				readl(adapter->hw.hw_addr + tx_ring->tdt),
 				tx_ring->next_to_use,
-				i,
-				(unsigned long long)tx_ring->buffer_info[i].dma,
-				tx_ring->buffer_info[i].time_stamp,
+				tx_ring->next_to_clean,
+				tx_ring->buffer_info[eop].time_stamp,
 				eop,
 				jiffies,
 				eop_desc->upper.fields.status);
@@ -3329,21 +3563,21 @@ e1000_rx_checksum(struct e1000_adapter *
 	skb->ip_summed = CHECKSUM_NONE;
 
 	/* 82543 or newer only */
-	if(unlikely(adapter->hw.mac_type < e1000_82543)) return;
+	if (unlikely(adapter->hw.mac_type < e1000_82543)) return;
 	/* Ignore Checksum bit is set */
-	if(unlikely(status & E1000_RXD_STAT_IXSM)) return;
+	if (unlikely(status & E1000_RXD_STAT_IXSM)) return;
 	/* TCP/UDP checksum error bit is set */
-	if(unlikely(errors & E1000_RXD_ERR_TCPE)) {
+	if (unlikely(errors & E1000_RXD_ERR_TCPE)) {
 		/* let the stack verify checksum errors */
 		adapter->hw_csum_err++;
 		return;
 	}
 	/* TCP/UDP Checksum has not been calculated */
-	if(adapter->hw.mac_type <= e1000_82547_rev_2) {
-		if(!(status & E1000_RXD_STAT_TCPCS))
+	if (adapter->hw.mac_type <= e1000_82547_rev_2) {
+		if (!(status & E1000_RXD_STAT_TCPCS))
 			return;
 	} else {
-		if(!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)))
+		if (!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)))
 			return;
 	}
 	/* It must be a TCP or UDP packet with a valid checksum */
@@ -3379,46 +3613,87 @@ e1000_clean_rx_irq(struct e1000_adapter 
 {
 	struct net_device *netdev = adapter->netdev;
 	struct pci_dev *pdev = adapter->pdev;
-	struct e1000_rx_desc *rx_desc;
-	struct e1000_buffer *buffer_info;
-	struct sk_buff *skb;
+	struct e1000_rx_desc *rx_desc, *next_rxd;
+	struct e1000_buffer *buffer_info, *next_buffer;
 	unsigned long flags;
 	uint32_t length;
 	uint8_t last_byte;
 	unsigned int i;
-	boolean_t cleaned = FALSE;
+	int cleaned_count = 0;
+	boolean_t cleaned = FALSE, multi_descriptor = FALSE;
 
 	i = rx_ring->next_to_clean;
 	rx_desc = E1000_RX_DESC(*rx_ring, i);
+	buffer_info = &rx_ring->buffer_info[i];
 
-	while(rx_desc->status & E1000_RXD_STAT_DD) {
-		buffer_info = &rx_ring->buffer_info[i];
+	while (rx_desc->status & E1000_RXD_STAT_DD) {
+		struct sk_buff *skb, *next_skb;
+		u8 status;
 #ifdef CONFIG_E1000_NAPI
-		if(*work_done >= work_to_do)
+		if (*work_done >= work_to_do)
 			break;
 		(*work_done)++;
 #endif
-		cleaned = TRUE;
+		status = rx_desc->status;
+		skb = buffer_info->skb;
+		buffer_info->skb = NULL;
+
+		if (++i == rx_ring->count) i = 0;
+		next_rxd = E1000_RX_DESC(*rx_ring, i);
+		next_buffer = &rx_ring->buffer_info[i];
+		next_skb = next_buffer->skb;
 
+		cleaned = TRUE;
+		cleaned_count++;
 		pci_unmap_single(pdev,
 		                 buffer_info->dma,
 		                 buffer_info->length,
 		                 PCI_DMA_FROMDEVICE);
 
-		skb = buffer_info->skb;
 		length = le16_to_cpu(rx_desc->length);
 
-		if(unlikely(!(rx_desc->status & E1000_RXD_STAT_EOP))) {
-			/* All receives must fit into a single buffer */
-			E1000_DBG("%s: Receive packet consumed multiple"
-				  " buffers\n", netdev->name);
-			dev_kfree_skb_irq(skb);
+		skb_put(skb, length);
+
+		if (!(status & E1000_RXD_STAT_EOP)) {
+			if (!rx_ring->rx_skb_top) {
+				rx_ring->rx_skb_top = skb;
+				rx_ring->rx_skb_top->len = length;
+				rx_ring->rx_skb_prev = skb;
+			} else {
+				if (skb_shinfo(rx_ring->rx_skb_top)->frag_list) {
+					rx_ring->rx_skb_prev->next = skb;
+					skb->prev = rx_ring->rx_skb_prev;
+				} else {
+					skb_shinfo(rx_ring->rx_skb_top)->frag_list = skb;
+				}
+				rx_ring->rx_skb_prev = skb;
+				rx_ring->rx_skb_top->data_len += length;
+			}
 			goto next_desc;
+		} else {
+			if (rx_ring->rx_skb_top) {
+				if (skb_shinfo(rx_ring->rx_skb_top)
+							->frag_list) {
+					rx_ring->rx_skb_prev->next = skb;
+					skb->prev = rx_ring->rx_skb_prev;
+				} else
+					skb_shinfo(rx_ring->rx_skb_top)
+							->frag_list = skb;
+
+				rx_ring->rx_skb_top->data_len += length;
+				rx_ring->rx_skb_top->len +=
+					rx_ring->rx_skb_top->data_len;
+
+				skb = rx_ring->rx_skb_top;
+				multi_descriptor = TRUE;
+				rx_ring->rx_skb_top = NULL;
+				rx_ring->rx_skb_prev = NULL;
+			}
 		}
 
-		if(unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
+		if (unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
 			last_byte = *(skb->data + length - 1);
-			if(TBI_ACCEPT(&adapter->hw, rx_desc->status,
+			if (TBI_ACCEPT(&adapter->hw, status,
 			              rx_desc->errors, length, last_byte)) {
 				spin_lock_irqsave(&adapter->stats_lock, flags);
 				e1000_tbi_adjust_stats(&adapter->hw,
@@ -3433,18 +3708,41 @@ e1000_clean_rx_irq(struct e1000_adapter 
 			}
 		}
 
-		/* Good Receive */
-		skb_put(skb, length - ETHERNET_FCS_SIZE);
+		/* code added for copybreak, this should improve
+		 * performance for small packets with large amounts
+		 * of reassembly being done in the stack */
+#define E1000_CB_LENGTH 256
+		if ((length < E1000_CB_LENGTH) &&
+		   !rx_ring->rx_skb_top &&
+		   /* or maybe (status & E1000_RXD_STAT_EOP) && */
+		   !multi_descriptor) {
+			struct sk_buff *new_skb =
+			    dev_alloc_skb(length + NET_IP_ALIGN);
+			if (new_skb) {
+				skb_reserve(new_skb, NET_IP_ALIGN);
+				new_skb->dev = netdev;
+				memcpy(new_skb->data - NET_IP_ALIGN,
+				       skb->data - NET_IP_ALIGN,
+				       length + NET_IP_ALIGN);
+				/* save the skb in buffer_info as good */
+				buffer_info->skb = skb;
+				skb = new_skb;
+				skb_put(skb, length);
+			}
+		}
+
+		/* end copybreak code */
 
 		/* Receive Checksum Offload */
 		e1000_rx_checksum(adapter,
-				  (uint32_t)(rx_desc->status) |
+				  (uint32_t)(status) |
 				  ((uint32_t)(rx_desc->errors) << 24),
 				  rx_desc->csum, skb);
+
 		skb->protocol = eth_type_trans(skb, netdev);
 #ifdef CONFIG_E1000_NAPI
-		if(unlikely(adapter->vlgrp &&
-			    (rx_desc->status & E1000_RXD_STAT_VP))) {
+		if (unlikely(adapter->vlgrp &&
+			    (status & E1000_RXD_STAT_VP))) {
 			vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
 						 le16_to_cpu(rx_desc->special) &
 						 E1000_RXD_SPC_VLAN_MASK);
@@ -3452,8 +3750,8 @@ e1000_clean_rx_irq(struct e1000_adapter 
 			netif_receive_skb(skb);
 		}
 #else /* CONFIG_E1000_NAPI */
-		if(unlikely(adapter->vlgrp &&
-			    (rx_desc->status & E1000_RXD_STAT_VP))) {
+		if (unlikely(adapter->vlgrp &&
+			    (status & E1000_RXD_STAT_VP))) {
 			vlan_hwaccel_rx(skb, adapter->vlgrp,
 					le16_to_cpu(rx_desc->special) &
 					E1000_RXD_SPC_VLAN_MASK);
@@ -3462,17 +3760,28 @@ e1000_clean_rx_irq(struct e1000_adapter 
 		}
 #endif /* CONFIG_E1000_NAPI */
 		netdev->last_rx = jiffies;
-		rx_ring->pkt++;
+#ifdef CONFIG_E1000_MQ
+		rx_ring->rx_stats.packets++;
+		rx_ring->rx_stats.bytes += length;
+#endif
 
 next_desc:
 		rx_desc->status = 0;
-		buffer_info->skb = NULL;
-		if(unlikely(++i == rx_ring->count)) i = 0;
 
-		rx_desc = E1000_RX_DESC(*rx_ring, i);
+		/* return some buffers to hardware, one at a time is too slow */
+		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
+			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
+			cleaned_count = 0;
+		}
+
+		rx_desc = next_rxd;
+		buffer_info = next_buffer;
 	}
 	rx_ring->next_to_clean = i;
-	adapter->alloc_rx_buf(adapter, rx_ring);
+
+	cleaned_count = E1000_DESC_UNUSED(rx_ring);
+	if (cleaned_count)
+		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
 
 	return cleaned;
 }
@@ -3492,52 +3801,59 @@ e1000_clean_rx_irq_ps(struct e1000_adapt
                       struct e1000_rx_ring *rx_ring)
 #endif
 {
-	union e1000_rx_desc_packet_split *rx_desc;
+	union e1000_rx_desc_packet_split *rx_desc, *next_rxd;
 	struct net_device *netdev = adapter->netdev;
 	struct pci_dev *pdev = adapter->pdev;
-	struct e1000_buffer *buffer_info;
+	struct e1000_buffer *buffer_info, *next_buffer;
 	struct e1000_ps_page *ps_page;
 	struct e1000_ps_page_dma *ps_page_dma;
-	struct sk_buff *skb;
+	struct sk_buff *skb, *next_skb;
 	unsigned int i, j;
 	uint32_t length, staterr;
+	int cleaned_count = 0;
 	boolean_t cleaned = FALSE;
 
 	i = rx_ring->next_to_clean;
 	rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
 	staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
+	buffer_info = &rx_ring->buffer_info[i];
 
-	while(staterr & E1000_RXD_STAT_DD) {
-		buffer_info = &rx_ring->buffer_info[i];
+	while (staterr & E1000_RXD_STAT_DD) {
 		ps_page = &rx_ring->ps_page[i];
 		ps_page_dma = &rx_ring->ps_page_dma[i];
 #ifdef CONFIG_E1000_NAPI
-		if(unlikely(*work_done >= work_to_do))
+		if (unlikely(*work_done >= work_to_do))
 			break;
 		(*work_done)++;
 #endif
+		skb = buffer_info->skb;
+
+		if (++i == rx_ring->count) i = 0;
+		next_rxd = E1000_RX_DESC_PS(*rx_ring, i);
+		next_buffer = &rx_ring->buffer_info[i];
+		next_skb = next_buffer->skb;
+
 		cleaned = TRUE;
+		cleaned_count++;
 		pci_unmap_single(pdev, buffer_info->dma,
 				 buffer_info->length,
 				 PCI_DMA_FROMDEVICE);
 
-		skb = buffer_info->skb;
-
-		if(unlikely(!(staterr & E1000_RXD_STAT_EOP))) {
+		if (unlikely(!(staterr & E1000_RXD_STAT_EOP))) {
 			E1000_DBG("%s: Packet Split buffers didn't pick up"
 				  " the full packet\n", netdev->name);
 			dev_kfree_skb_irq(skb);
 			goto next_desc;
 		}
 
-		if(unlikely(staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK)) {
+		if (unlikely(staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK)) {
 			dev_kfree_skb_irq(skb);
 			goto next_desc;
 		}
 
 		length = le16_to_cpu(rx_desc->wb.middle.length0);
 
-		if(unlikely(!length)) {
+		if (unlikely(!length)) {
 			E1000_DBG("%s: Last part of the packet spanning"
 				  " multiple descriptors\n", netdev->name);
 			dev_kfree_skb_irq(skb);
@@ -3547,8 +3863,8 @@ e1000_clean_rx_irq_ps(struct e1000_adapt
 		/* Good Receive */
 		skb_put(skb, length);
 
-		for(j = 0; j < adapter->rx_ps_pages; j++) {
-			if(!(length = le16_to_cpu(rx_desc->wb.upper.length[j])))
+		for (j = 0; j < adapter->rx_ps_pages; j++) {
+			if (!(length = le16_to_cpu(rx_desc->wb.upper.length[j])))
 				break;
 
 			pci_unmap_page(pdev, ps_page_dma->ps_page_dma[j],
@@ -3568,15 +3884,11 @@ e1000_clean_rx_irq_ps(struct e1000_adapt
 				  rx_desc->wb.lower.hi_dword.csum_ip.csum, skb);
 		skb->protocol = eth_type_trans(skb, netdev);
 
-		if(likely(rx_desc->wb.upper.header_status &
-			  E1000_RXDPS_HDRSTAT_HDRSP)) {
+		if (likely(rx_desc->wb.upper.header_status &
+			  E1000_RXDPS_HDRSTAT_HDRSP))
 			adapter->rx_hdr_split++;
-#ifdef HAVE_RX_ZERO_COPY
-			skb_shinfo(skb)->zero_copy = TRUE;
-#endif
-	        }
 #ifdef CONFIG_E1000_NAPI
-		if(unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
+		if (unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
 			vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
 				le16_to_cpu(rx_desc->wb.middle.vlan) &
 				E1000_RXD_SPC_VLAN_MASK);
@@ -3584,7 +3896,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapt
 			netif_receive_skb(skb);
 		}
 #else /* CONFIG_E1000_NAPI */
-		if(unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
+		if (unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
 			vlan_hwaccel_rx(skb, adapter->vlgrp,
 				le16_to_cpu(rx_desc->wb.middle.vlan) &
 				E1000_RXD_SPC_VLAN_MASK);
@@ -3593,18 +3905,31 @@ e1000_clean_rx_irq_ps(struct e1000_adapt
 		}
 #endif /* CONFIG_E1000_NAPI */
 		netdev->last_rx = jiffies;
-		rx_ring->pkt++;
+#ifdef CONFIG_E1000_MQ
+		rx_ring->rx_stats.packets++;
+		rx_ring->rx_stats.bytes += length;
+#endif
 
 next_desc:
 		rx_desc->wb.middle.status_error &= ~0xFF;
 		buffer_info->skb = NULL;
-		if(unlikely(++i == rx_ring->count)) i = 0;
 
-		rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
+		/* return some buffers to hardware, one at a time is too slow */
+		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
+			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
+			cleaned_count = 0;
+		}
+
+		rx_desc = next_rxd;
+		buffer_info = next_buffer;
+
 		staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
 	}
 	rx_ring->next_to_clean = i;
-	adapter->alloc_rx_buf(adapter, rx_ring);
+
+	cleaned_count = E1000_DESC_UNUSED(rx_ring);
+	if (cleaned_count)
+		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
 
 	return cleaned;
 }
@@ -3616,7 +3941,8 @@ next_desc:
 
 static void
 e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
-                       struct e1000_rx_ring *rx_ring)
+                       struct e1000_rx_ring *rx_ring,
+		       int cleaned_count)
 {
 	struct net_device *netdev = adapter->netdev;
 	struct pci_dev *pdev = adapter->pdev;
@@ -3629,11 +3955,18 @@ e1000_alloc_rx_buffers(struct e1000_adap
 	i = rx_ring->next_to_use;
 	buffer_info = &rx_ring->buffer_info[i];
 
-	while(!buffer_info->skb) {
-		skb = dev_alloc_skb(bufsz);
+	while (cleaned_count--) {
+		if (!(skb = buffer_info->skb))
+			skb = dev_alloc_skb(bufsz);
+		else {
+			skb_trim(skb, 0);
+			goto map_skb;
+		}
+
 
-		if(unlikely(!skb)) {
+		if (unlikely(!skb)) {
 			/* Better luck next round */
+			adapter->alloc_rx_buff_failed++;
 			break;
 		}
 
@@ -3670,6 +4003,7 @@ e1000_alloc_rx_buffers(struct e1000_adap
 
 		buffer_info->skb = skb;
 		buffer_info->length = adapter->rx_buffer_len;
+map_skb:
 		buffer_info->dma = pci_map_single(pdev,
 						  skb->data,
 						  adapter->rx_buffer_len,
@@ -3695,20 +4029,23 @@ e1000_alloc_rx_buffers(struct e1000_adap
 		rx_desc = E1000_RX_DESC(*rx_ring, i);
 		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
 
-		if(unlikely((i & ~(E1000_RX_BUFFER_WRITE - 1)) == i)) {
-			/* Force memory writes to complete before letting h/w
-			 * know there are new descriptors to fetch.  (Only
-			 * applicable for weak-ordered memory model archs,
-			 * such as IA-64). */
-			wmb();
-			writel(i, adapter->hw.hw_addr + rx_ring->rdt);
-		}
-
-		if(unlikely(++i == rx_ring->count)) i = 0;
+		if (unlikely(++i == rx_ring->count))
+			i = 0;
 		buffer_info = &rx_ring->buffer_info[i];
 	}
 
-	rx_ring->next_to_use = i;
+	if (likely(rx_ring->next_to_use != i)) {
+		rx_ring->next_to_use = i;
+		if (unlikely(i-- == 0))
+			i = (rx_ring->count - 1);
+
+		/* Force memory writes to complete before letting h/w
+		 * know there are new descriptors to fetch.  (Only
+		 * applicable for weak-ordered memory model archs,
+		 * such as IA-64). */
+		wmb();
+		writel(i, adapter->hw.hw_addr + rx_ring->rdt);
+	}
 }
 
 /**
@@ -3718,7 +4055,8 @@ e1000_alloc_rx_buffers(struct e1000_adap
 
 static void
 e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
-                          struct e1000_rx_ring *rx_ring)
+                          struct e1000_rx_ring *rx_ring,
+			  int cleaned_count)
 {
 	struct net_device *netdev = adapter->netdev;
 	struct pci_dev *pdev = adapter->pdev;
@@ -3734,16 +4072,18 @@ e1000_alloc_rx_buffers_ps(struct e1000_a
 	ps_page = &rx_ring->ps_page[i];
 	ps_page_dma = &rx_ring->ps_page_dma[i];
 
-	while(!buffer_info->skb) {
+	while (cleaned_count--) {
 		rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
 
-		for(j = 0; j < PS_PAGE_BUFFERS; j++) {
+		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
 			if (j < adapter->rx_ps_pages) {
 				if (likely(!ps_page->ps_page[j])) {
 					ps_page->ps_page[j] =
 						alloc_page(GFP_ATOMIC);
-					if (unlikely(!ps_page->ps_page[j]))
+					if (unlikely(!ps_page->ps_page[j])) {
+						adapter->alloc_rx_buff_failed++;
 						goto no_buffers;
+					}
 					ps_page_dma->ps_page_dma[j] =
 						pci_map_page(pdev,
 							    ps_page->ps_page[j],
@@ -3751,7 +4091,7 @@ e1000_alloc_rx_buffers_ps(struct e1000_a
 							    PCI_DMA_FROMDEVICE);
 				}
 				/* Refresh the desc even if buffer_addrs didn't
-				 * change because each write-back erases 
+				 * change because each write-back erases
 				 * this info.
 				 */
 				rx_desc->read.buffer_addr[j+1] =
@@ -3762,8 +4102,10 @@ e1000_alloc_rx_buffers_ps(struct e1000_a
 
 		skb = dev_alloc_skb(adapter->rx_ps_bsize0 + NET_IP_ALIGN);
 
-		if(unlikely(!skb))
+		if (unlikely(!skb)) {
+			adapter->alloc_rx_buff_failed++;
 			break;
+		}
 
 		/* Make buffer alignment 2 beyond a 16 byte boundary
 		 * this will result in a 16 byte aligned IP header after
@@ -3781,27 +4123,28 @@ e1000_alloc_rx_buffers_ps(struct e1000_a
 
 		rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma);
 
-		if(unlikely((i & ~(E1000_RX_BUFFER_WRITE - 1)) == i)) {
-			/* Force memory writes to complete before letting h/w
-			 * know there are new descriptors to fetch.  (Only
-			 * applicable for weak-ordered memory model archs,
-			 * such as IA-64). */
-			wmb();
-			/* Hardware increments by 16 bytes, but packet split
-			 * descriptors are 32 bytes...so we increment tail
-			 * twice as much.
-			 */
-			writel(i<<1, adapter->hw.hw_addr + rx_ring->rdt);
-		}
-
-		if(unlikely(++i == rx_ring->count)) i = 0;
+		if (unlikely(++i == rx_ring->count)) i = 0;
 		buffer_info = &rx_ring->buffer_info[i];
 		ps_page = &rx_ring->ps_page[i];
 		ps_page_dma = &rx_ring->ps_page_dma[i];
 	}
 
 no_buffers:
-	rx_ring->next_to_use = i;
+	if (likely(rx_ring->next_to_use != i)) {
+		rx_ring->next_to_use = i;
+		if (unlikely(i-- == 0)) i = (rx_ring->count - 1);
+
+		/* Force memory writes to complete before letting h/w
+		 * know there are new descriptors to fetch.  (Only
+		 * applicable for weak-ordered memory model archs,
+		 * such as IA-64). */
+		wmb();
+		/* Hardware increments by 16 bytes, but packet split
+		 * descriptors are 32 bytes...so we increment tail
+		 * twice as much.
+		 */
+		writel(i<<1, adapter->hw.hw_addr + rx_ring->rdt);
+	}
 }
 
 /**
@@ -3815,24 +4158,24 @@ e1000_smartspeed(struct e1000_adapter *a
 	uint16_t phy_status;
 	uint16_t phy_ctrl;
 
-	if((adapter->hw.phy_type != e1000_phy_igp) || !adapter->hw.autoneg ||
+	if ((adapter->hw.phy_type != e1000_phy_igp) || !adapter->hw.autoneg ||
 	   !(adapter->hw.autoneg_advertised & ADVERTISE_1000_FULL))
 		return;
 
-	if(adapter->smartspeed == 0) {
+	if (adapter->smartspeed == 0) {
 		/* If Master/Slave config fault is asserted twice,
 		 * we assume back-to-back */
 		e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_status);
-		if(!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
+		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
 		e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_status);
-		if(!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
+		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
 		e1000_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_ctrl);
-		if(phy_ctrl & CR_1000T_MS_ENABLE) {
+		if (phy_ctrl & CR_1000T_MS_ENABLE) {
 			phy_ctrl &= ~CR_1000T_MS_ENABLE;
 			e1000_write_phy_reg(&adapter->hw, PHY_1000T_CTRL,
 					    phy_ctrl);
 			adapter->smartspeed++;
-			if(!e1000_phy_setup_autoneg(&adapter->hw) &&
+			if (!e1000_phy_setup_autoneg(&adapter->hw) &&
 			   !e1000_read_phy_reg(&adapter->hw, PHY_CTRL,
 				   	       &phy_ctrl)) {
 				phy_ctrl |= (MII_CR_AUTO_NEG_EN |
@@ -3842,12 +4185,12 @@ e1000_smartspeed(struct e1000_adapter *a
 			}
 		}
 		return;
-	} else if(adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
+	} else if (adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
 		/* If still no link, perhaps using 2/3 pair cable */
 		e1000_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_ctrl);
 		phy_ctrl |= CR_1000T_MS_ENABLE;
 		e1000_write_phy_reg(&adapter->hw, PHY_1000T_CTRL, phy_ctrl);
-		if(!e1000_phy_setup_autoneg(&adapter->hw) &&
+		if (!e1000_phy_setup_autoneg(&adapter->hw) &&
 		   !e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_ctrl)) {
 			phy_ctrl |= (MII_CR_AUTO_NEG_EN |
 				     MII_CR_RESTART_AUTO_NEG);
@@ -3855,7 +4198,7 @@ e1000_smartspeed(struct e1000_adapter *a
 		}
 	}
 	/* Restart process after E1000_SMARTSPEED_MAX iterations */
-	if(adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
+	if (adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
 		adapter->smartspeed = 0;
 }
 
@@ -3896,7 +4239,7 @@ e1000_mii_ioctl(struct net_device *netde
 	uint16_t spddplx;
 	unsigned long flags;
 
-	if(adapter->hw.media_type != e1000_media_type_copper)
+	if (adapter->hw.media_type != e1000_media_type_copper)
 		return -EOPNOTSUPP;
 
 	switch (cmd) {
@@ -3904,10 +4247,10 @@ e1000_mii_ioctl(struct net_device *netde
 		data->phy_id = adapter->hw.phy_addr;
 		break;
 	case SIOCGMIIREG:
-		if(!capable(CAP_NET_ADMIN))
+		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
 		spin_lock_irqsave(&adapter->stats_lock, flags);
-		if(e1000_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
+		if (e1000_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
 				   &data->val_out)) {
 			spin_unlock_irqrestore(&adapter->stats_lock, flags);
 			return -EIO;
@@ -3915,23 +4258,23 @@ e1000_mii_ioctl(struct net_device *netde
 		spin_unlock_irqrestore(&adapter->stats_lock, flags);
 		break;
 	case SIOCSMIIREG:
-		if(!capable(CAP_NET_ADMIN))
+		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
-		if(data->reg_num & ~(0x1F))
+		if (data->reg_num & ~(0x1F))
 			return -EFAULT;
 		mii_reg = data->val_in;
 		spin_lock_irqsave(&adapter->stats_lock, flags);
-		if(e1000_write_phy_reg(&adapter->hw, data->reg_num,
+		if (e1000_write_phy_reg(&adapter->hw, data->reg_num,
 					mii_reg)) {
 			spin_unlock_irqrestore(&adapter->stats_lock, flags);
 			return -EIO;
 		}
-		if(adapter->hw.phy_type == e1000_phy_m88) {
+		if (adapter->hw.phy_type == e1000_phy_m88) {
 			switch (data->reg_num) {
 			case PHY_CTRL:
-				if(mii_reg & MII_CR_POWER_DOWN)
+				if (mii_reg & MII_CR_POWER_DOWN)
 					break;
-				if(mii_reg & MII_CR_AUTO_NEG_EN) {
+				if (mii_reg & MII_CR_AUTO_NEG_EN) {
 					adapter->hw.autoneg = 1;
 					adapter->hw.autoneg_advertised = 0x2F;
 				} else {
@@ -3946,14 +4289,14 @@ e1000_mii_ioctl(struct net_device *netde
 						   HALF_DUPLEX;
 					retval = e1000_set_spd_dplx(adapter,
 								    spddplx);
-					if(retval) {
+					if (retval) {
 						spin_unlock_irqrestore(
-							&adapter->stats_lock, 
+							&adapter->stats_lock,
 							flags);
 						return retval;
 					}
 				}
-				if(netif_running(adapter->netdev)) {
+				if (netif_running(adapter->netdev)) {
 					e1000_down(adapter);
 					e1000_up(adapter);
 				} else
@@ -3961,7 +4304,7 @@ e1000_mii_ioctl(struct net_device *netde
 				break;
 			case M88E1000_PHY_SPEC_CTRL:
 			case M88E1000_EXT_PHY_SPEC_CTRL:
-				if(e1000_phy_reset(&adapter->hw)) {
+				if (e1000_phy_reset(&adapter->hw)) {
 					spin_unlock_irqrestore(
 						&adapter->stats_lock, flags);
 					return -EIO;
@@ -3971,9 +4314,9 @@ e1000_mii_ioctl(struct net_device *netde
 		} else {
 			switch (data->reg_num) {
 			case PHY_CTRL:
-				if(mii_reg & MII_CR_POWER_DOWN)
+				if (mii_reg & MII_CR_POWER_DOWN)
 					break;
-				if(netif_running(adapter->netdev)) {
+				if (netif_running(adapter->netdev)) {
 					e1000_down(adapter);
 					e1000_up(adapter);
 				} else
@@ -3995,7 +4338,7 @@ e1000_pci_set_mwi(struct e1000_hw *hw)
 	struct e1000_adapter *adapter = hw->back;
 	int ret_val = pci_set_mwi(adapter->pdev);
 
-	if(ret_val)
+	if (ret_val)
 		DPRINTK(PROBE, ERR, "Error in setting MWI\n");
 }
 
@@ -4044,7 +4387,7 @@ e1000_vlan_rx_register(struct net_device
 	e1000_irq_disable(adapter);
 	adapter->vlgrp = grp;
 
-	if(grp) {
+	if (grp) {
 		/* enable VLAN tag insert/strip */
 		ctrl = E1000_READ_REG(&adapter->hw, CTRL);
 		ctrl |= E1000_CTRL_VME;
@@ -4066,7 +4409,7 @@ e1000_vlan_rx_register(struct net_device
 		rctl = E1000_READ_REG(&adapter->hw, RCTL);
 		rctl &= ~E1000_RCTL_VFE;
 		E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
-		if(adapter->mng_vlan_id != (uint16_t)E1000_MNG_VLAN_NONE) {
+		if (adapter->mng_vlan_id != (uint16_t)E1000_MNG_VLAN_NONE) {
 			e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
 			adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
 		}
@@ -4080,9 +4423,10 @@ e1000_vlan_rx_add_vid(struct net_device 
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	uint32_t vfta, index;
-	if((adapter->hw.mng_cookie.status &
-		E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
-		(vid == adapter->mng_vlan_id))
+
+	if ((adapter->hw.mng_cookie.status &
+	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
+	    (vid == adapter->mng_vlan_id))
 		return;
 	/* add VID to filter table */
 	index = (vid >> 5) & 0x7F;
@@ -4099,15 +4443,19 @@ e1000_vlan_rx_kill_vid(struct net_device
 
 	e1000_irq_disable(adapter);
 
-	if(adapter->vlgrp)
+	if (adapter->vlgrp)
 		adapter->vlgrp->vlan_devices[vid] = NULL;
 
 	e1000_irq_enable(adapter);
 
-	if((adapter->hw.mng_cookie.status &
-		E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
-		(vid == adapter->mng_vlan_id))
+	if ((adapter->hw.mng_cookie.status &
+	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
+	    (vid == adapter->mng_vlan_id)) {
+		/* release control to f/w */
+		e1000_release_hw_control(adapter);
 		return;
+	}
+
 	/* remove VID from filter table */
 	index = (vid >> 5) & 0x7F;
 	vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index);
@@ -4120,10 +4468,10 @@ e1000_restore_vlan(struct e1000_adapter 
 {
 	e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
 
-	if(adapter->vlgrp) {
+	if (adapter->vlgrp) {
 		uint16_t vid;
-		for(vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
-			if(!adapter->vlgrp->vlan_devices[vid])
+		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+			if (!adapter->vlgrp->vlan_devices[vid])
 				continue;
 			e1000_vlan_rx_add_vid(adapter->netdev, vid);
 		}
@@ -4136,13 +4484,13 @@ e1000_set_spd_dplx(struct e1000_adapter 
 	adapter->hw.autoneg = 0;
 
 	/* Fiber NICs only allow 1000 gbps Full duplex */
-	if((adapter->hw.media_type == e1000_media_type_fiber) &&
+	if ((adapter->hw.media_type == e1000_media_type_fiber) &&
 		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
 		DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
 		return -EINVAL;
 	}
 
-	switch(spddplx) {
+	switch (spddplx) {
 	case SPEED_10 + DUPLEX_HALF:
 		adapter->hw.forced_speed_duplex = e1000_10_half;
 		break;
@@ -4168,35 +4516,92 @@ e1000_set_spd_dplx(struct e1000_adapter 
 }
 
 #ifdef CONFIG_PM
+/* these functions save and restore 16 or 64 dwords (64-256 bytes) of config
+ * space versus the 64 bytes that pci_[save|restore]_state handle
+ */
+#define PCIE_CONFIG_SPACE_LEN 256
+#define PCI_CONFIG_SPACE_LEN 64
+static int
+e1000_pci_save_state(struct e1000_adapter *adapter)
+{
+	struct pci_dev *dev = adapter->pdev;
+	int size;
+	int i;
+	if (adapter->hw.mac_type >= e1000_82571)
+		size = PCIE_CONFIG_SPACE_LEN;
+	else
+		size = PCI_CONFIG_SPACE_LEN;
+
+	WARN_ON(adapter->config_space != NULL);
+
+	adapter->config_space = kmalloc(size, GFP_KERNEL);
+	if (!adapter->config_space) {
+		DPRINTK(PROBE, ERR, "unable to allocate %d bytes\n", size);
+		return -ENOMEM;
+	}
+	for (i = 0; i < (size / 4); i++)
+		pci_read_config_dword(dev, i * 4, &adapter->config_space[i]);
+	return 0;
+}
+
+static void
+e1000_pci_restore_state(struct e1000_adapter *adapter)
+{
+	struct pci_dev *dev = adapter->pdev;
+	int size;
+	int i;
+	if (adapter->config_space == NULL)
+		return;
+	if (adapter->hw.mac_type >= e1000_82571)
+		size = PCIE_CONFIG_SPACE_LEN;
+	else
+		size = PCI_CONFIG_SPACE_LEN;
+	for (i = 0; i < (size / 4); i++)
+		pci_write_config_dword(dev, i * 4, adapter->config_space[i]);
+	kfree(adapter->config_space);
+	adapter->config_space = NULL;
+	return;
+}
+#endif /* CONFIG_PM */
+
 static int
 e1000_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct e1000_adapter *adapter = netdev_priv(netdev);
-	uint32_t ctrl, ctrl_ext, rctl, manc, status, swsm;
+	uint32_t ctrl, ctrl_ext, rctl, manc, status;
 	uint32_t wufc = adapter->wol;
+	int retval = 0;
 
 	netif_device_detach(netdev);
 
-	if(netif_running(netdev))
+	if (netif_running(netdev))
 		e1000_down(adapter);
 
+#ifdef CONFIG_PM
+	/* implement our own version of pci_save_state(pdev) because pci 
+	 * express adapters have larger 256 byte config spaces */
+	retval = e1000_pci_save_state(adapter);
+	if (retval)
+		return retval;
+#endif
+
 	status = E1000_READ_REG(&adapter->hw, STATUS);
-	if(status & E1000_STATUS_LU)
+	if (status & E1000_STATUS_LU)
 		wufc &= ~E1000_WUFC_LNKC;
 
-	if(wufc) {
+	if (wufc) {
 		e1000_setup_rctl(adapter);
 		e1000_set_multi(netdev);
 
 		/* turn on all-multi mode if wake on multicast is enabled */
-		if(adapter->wol & E1000_WUFC_MC) {
+		if (adapter->wol & E1000_WUFC_MC) {
 			rctl = E1000_READ_REG(&adapter->hw, RCTL);
 			rctl |= E1000_RCTL_MPE;
 			E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
 		}
 
-		if(adapter->hw.mac_type >= e1000_82540) {
+		if (adapter->hw.mac_type >= e1000_82540) {
 			ctrl = E1000_READ_REG(&adapter->hw, CTRL);
 			/* advertise wake from D3Cold */
 			#define E1000_CTRL_ADVD3WUC 0x00100000
@@ -4207,7 +4612,7 @@ e1000_suspend(struct pci_dev *pdev, pm_m
 			E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
 		}
 
-		if(adapter->hw.media_type == e1000_media_type_fiber ||
+		if (adapter->hw.media_type == e1000_media_type_fiber ||
 		   adapter->hw.media_type == e1000_media_type_internal_serdes) {
 			/* keep the laser running in D3 */
 			ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
@@ -4220,96 +4625,96 @@ e1000_suspend(struct pci_dev *pdev, pm_m
 
 		E1000_WRITE_REG(&adapter->hw, WUC, E1000_WUC_PME_EN);
 		E1000_WRITE_REG(&adapter->hw, WUFC, wufc);
-		pci_enable_wake(pdev, 3, 1);
-		pci_enable_wake(pdev, 4, 1); /* 4 == D3 cold */
+		retval = pci_enable_wake(pdev, PCI_D3hot, 1);
+		if (retval)
+			DPRINTK(PROBE, ERR, "Error enabling D3 wake\n");
+		retval = pci_enable_wake(pdev, PCI_D3cold, 1);
+		if (retval)
+			DPRINTK(PROBE, ERR, "Error enabling D3 cold wake\n");
 	} else {
 		E1000_WRITE_REG(&adapter->hw, WUC, 0);
 		E1000_WRITE_REG(&adapter->hw, WUFC, 0);
-		pci_enable_wake(pdev, 3, 0);
-		pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */
+		retval = pci_enable_wake(pdev, PCI_D3hot, 0);
+		if (retval)
+			DPRINTK(PROBE, ERR, "Error enabling D3 wake\n");
+		retval = pci_enable_wake(pdev, PCI_D3cold, 0); /* 4 == D3 cold */
+		if (retval)
+			DPRINTK(PROBE, ERR, "Error enabling D3 cold wake\n");
 	}
 
-	pci_save_state(pdev);
-
-	if(adapter->hw.mac_type >= e1000_82540 &&
+	if (adapter->hw.mac_type >= e1000_82540 &&
 	   adapter->hw.media_type == e1000_media_type_copper) {
 		manc = E1000_READ_REG(&adapter->hw, MANC);
-		if(manc & E1000_MANC_SMBUS_EN) {
+		if (manc & E1000_MANC_SMBUS_EN) {
 			manc |= E1000_MANC_ARP_EN;
 			E1000_WRITE_REG(&adapter->hw, MANC, manc);
-			pci_enable_wake(pdev, 3, 1);
-			pci_enable_wake(pdev, 4, 1); /* 4 == D3 cold */
+			retval = pci_enable_wake(pdev, PCI_D3hot, 1);
+			if (retval)
+				DPRINTK(PROBE, ERR, "Error enabling D3 wake\n");
+			retval = pci_enable_wake(pdev, PCI_D3cold, 1);
+			if (retval)
+				DPRINTK(PROBE, ERR, "Error enabling D3 cold wake\n");
 		}
 	}
 
-	switch(adapter->hw.mac_type) {
-	case e1000_82571:
-	case e1000_82572:
-		ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
-		E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
-				ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
-		break;
-	case e1000_82573:
-		swsm = E1000_READ_REG(&adapter->hw, SWSM);
-		E1000_WRITE_REG(&adapter->hw, SWSM,
-				swsm & ~E1000_SWSM_DRV_LOAD);
-		break;
-	default:
-		break;
-	}
+	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
+	 * would have already happened in close and is redundant. */
+	e1000_release_hw_control(adapter);
 
 	pci_disable_device(pdev);
-	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+	retval = pci_set_power_state(pdev, pci_choose_state(pdev, state));
+	if (retval)
+		DPRINTK(PROBE, ERR, "Error in setting power state\n");
 
 	return 0;
 }
 
+#ifdef CONFIG_PM
 static int
 e1000_resume(struct pci_dev *pdev)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct e1000_adapter *adapter = netdev_priv(netdev);
-	uint32_t manc, ret_val, swsm;
-	uint32_t ctrl_ext;
+	int retval;
+	uint32_t manc, ret_val;
 
-	pci_set_power_state(pdev, PCI_D0);
-	pci_restore_state(pdev);
+	retval = pci_set_power_state(pdev, PCI_D0);
+	if (retval)
+		DPRINTK(PROBE, ERR, "Error in setting power state\n");
+	e1000_pci_restore_state(adapter);
 	ret_val = pci_enable_device(pdev);
 	pci_set_master(pdev);
 
-	pci_enable_wake(pdev, PCI_D3hot, 0);
-	pci_enable_wake(pdev, PCI_D3cold, 0);
+	retval = pci_enable_wake(pdev, PCI_D3hot, 0);
+	if (retval)
+		DPRINTK(PROBE, ERR, "Error enabling D3 wake\n");
+	retval = pci_enable_wake(pdev, PCI_D3cold, 0);
+	if (retval)
+		DPRINTK(PROBE, ERR, "Error enabling D3 cold wake\n");
 
 	e1000_reset(adapter);
 	E1000_WRITE_REG(&adapter->hw, WUS, ~0);
 
-	if(netif_running(netdev))
+	if (netif_running(netdev))
 		e1000_up(adapter);
 
 	netif_device_attach(netdev);
 
-	if(adapter->hw.mac_type >= e1000_82540 &&
+	if (adapter->hw.mac_type >= e1000_82540 &&
 	   adapter->hw.media_type == e1000_media_type_copper) {
 		manc = E1000_READ_REG(&adapter->hw, MANC);
 		manc &= ~(E1000_MANC_ARP_EN);
 		E1000_WRITE_REG(&adapter->hw, MANC, manc);
 	}
 
-	switch(adapter->hw.mac_type) {
-	case e1000_82571:
-	case e1000_82572:
-		ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
-		E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
-				ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
-		break;
-	case e1000_82573:
-		swsm = E1000_READ_REG(&adapter->hw, SWSM);
-		E1000_WRITE_REG(&adapter->hw, SWSM,
-				swsm | E1000_SWSM_DRV_LOAD);
-		break;
-	default:
-		break;
-	}
+	/* If the controller is 82573 and f/w is AMT, do not set
+	 * DRV_LOAD until the interface is up.  For all other cases,
+	 * let the f/w know that the h/w is now under the control
+	 * of the driver. */
+	if (adapter->hw.mac_type != e1000_82573 ||
+	    !e1000_check_mng_mode(&adapter->hw))
+		e1000_get_hw_control(adapter);
 
 	return 0;
 }
@@ -4327,6 +4732,9 @@ e1000_netpoll(struct net_device *netdev)
 	disable_irq(adapter->pdev->irq);
 	e1000_intr(adapter->pdev->irq, netdev, NULL);
 	e1000_clean_tx_irq(adapter, adapter->tx_ring);
+#ifndef CONFIG_E1000_NAPI
+	adapter->clean_rx(adapter, adapter->rx_ring);
+#endif
 	enable_irq(adapter->pdev->irq);
 }
 #endif
diff --git a/drivers/net/e1000/e1000_osdep.h b/drivers/net/e1000/e1000_osdep.h
index aac64de..9790db9 100644
--- a/drivers/net/e1000/e1000_osdep.h
+++ b/drivers/net/e1000/e1000_osdep.h
@@ -47,7 +47,7 @@
 	                	BUG(); \
 			} else { \
 				msleep(x); \
-			} } while(0)
+			} } while (0)
 
 /* Some workarounds require millisecond delays and are run during interrupt
  * context.  Most notably, when establishing link, the phy may need tweaking
diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c
index ccbbe5a..3768d83 100644
--- a/drivers/net/e1000/e1000_param.c
+++ b/drivers/net/e1000/e1000_param.c
@@ -177,7 +177,7 @@ E1000_PARAM(RxAbsIntDelay, "Receive Abso
  *
  * Valid Range: 100-100000 (0=off, 1=dynamic)
  *
- * Default Value: 1
+ * Default Value: 8000
  */
 
 E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");
@@ -227,7 +227,7 @@ static int __devinit
 e1000_validate_option(int *value, struct e1000_option *opt,
 		struct e1000_adapter *adapter)
 {
-	if(*value == OPTION_UNSET) {
+	if (*value == OPTION_UNSET) {
 		*value = opt->def;
 		return 0;
 	}
@@ -244,7 +244,7 @@ e1000_validate_option(int *value, struct
 		}
 		break;
 	case range_option:
-		if(*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
+		if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
 			DPRINTK(PROBE, INFO,
 					"%s set to %i\n", opt->name, *value);
 			return 0;
@@ -254,10 +254,10 @@ e1000_validate_option(int *value, struct
 		int i;
 		struct e1000_opt_list *ent;
 
-		for(i = 0; i < opt->arg.l.nr; i++) {
+		for (i = 0; i < opt->arg.l.nr; i++) {
 			ent = &opt->arg.l.p[i];
-			if(*value == ent->i) {
-				if(ent->str[0] != '\0')
+			if (*value == ent->i) {
+				if (ent->str[0] != '\0')
 					DPRINTK(PROBE, INFO, "%s\n", ent->str);
 				return 0;
 			}
@@ -291,7 +291,7 @@ void __devinit
 e1000_check_options(struct e1000_adapter *adapter)
 {
 	int bd = adapter->bd_number;
-	if(bd >= E1000_MAX_NIC) {
+	if (bd >= E1000_MAX_NIC) {
 		DPRINTK(PROBE, NOTICE,
 		       "Warning: no configuration for board #%i\n", bd);
 		DPRINTK(PROBE, NOTICE, "Using defaults for all values\n");
@@ -315,12 +315,12 @@ e1000_check_options(struct e1000_adapter
 		if (num_TxDescriptors > bd) {
 			tx_ring->count = TxDescriptors[bd];
 			e1000_validate_option(&tx_ring->count, &opt, adapter);
-			E1000_ROUNDUP(tx_ring->count, 
+			E1000_ROUNDUP(tx_ring->count,
 						REQ_TX_DESCRIPTOR_MULTIPLE);
 		} else {
 			tx_ring->count = opt.def;
 		}
-		for (i = 0; i < adapter->num_queues; i++)
+		for (i = 0; i < adapter->num_tx_queues; i++)
 			tx_ring[i].count = tx_ring->count;
 	}
 	{ /* Receive Descriptor Count */
@@ -341,12 +341,12 @@ e1000_check_options(struct e1000_adapter
 		if (num_RxDescriptors > bd) {
 			rx_ring->count = RxDescriptors[bd];
 			e1000_validate_option(&rx_ring->count, &opt, adapter);
-			E1000_ROUNDUP(rx_ring->count, 
+			E1000_ROUNDUP(rx_ring->count,
 						REQ_RX_DESCRIPTOR_MULTIPLE);
 		} else {
 			rx_ring->count = opt.def;
 		}
-		for (i = 0; i < adapter->num_queues; i++)
+		for (i = 0; i < adapter->num_rx_queues; i++)
 			rx_ring[i].count = rx_ring->count;
 	}
 	{ /* Checksum Offload Enable/Disable */
@@ -388,7 +388,7 @@ e1000_check_options(struct e1000_adapter
 			e1000_validate_option(&fc, &opt, adapter);
 			adapter->hw.fc = adapter->hw.original_fc = fc;
 		} else {
-			adapter->hw.fc = opt.def;
+			adapter->hw.fc = adapter->hw.original_fc = opt.def;
 		}
 	}
 	{ /* Transmit Interrupt Delay */
@@ -403,7 +403,7 @@ e1000_check_options(struct e1000_adapter
 
 		if (num_TxIntDelay > bd) {
 			adapter->tx_int_delay = TxIntDelay[bd];
-			e1000_validate_option(&adapter->tx_int_delay, &opt, 
+			e1000_validate_option(&adapter->tx_int_delay, &opt,
 								adapter);
 		} else {
 			adapter->tx_int_delay = opt.def;
@@ -421,7 +421,7 @@ e1000_check_options(struct e1000_adapter
 
 		if (num_TxAbsIntDelay > bd) {
 			adapter->tx_abs_int_delay = TxAbsIntDelay[bd];
-			e1000_validate_option(&adapter->tx_abs_int_delay, &opt, 
+			e1000_validate_option(&adapter->tx_abs_int_delay, &opt,
 								adapter);
 		} else {
 			adapter->tx_abs_int_delay = opt.def;
@@ -439,7 +439,7 @@ e1000_check_options(struct e1000_adapter
 
 		if (num_RxIntDelay > bd) {
 			adapter->rx_int_delay = RxIntDelay[bd];
-			e1000_validate_option(&adapter->rx_int_delay, &opt, 
+			e1000_validate_option(&adapter->rx_int_delay, &opt,
 								adapter);
 		} else {
 			adapter->rx_int_delay = opt.def;
@@ -457,7 +457,7 @@ e1000_check_options(struct e1000_adapter
 
 		if (num_RxAbsIntDelay > bd) {
 			adapter->rx_abs_int_delay = RxAbsIntDelay[bd];
-			e1000_validate_option(&adapter->rx_abs_int_delay, &opt, 
+			e1000_validate_option(&adapter->rx_abs_int_delay, &opt,
 								adapter);
 		} else {
 			adapter->rx_abs_int_delay = opt.def;
@@ -475,17 +475,17 @@ e1000_check_options(struct e1000_adapter
 
 		if (num_InterruptThrottleRate > bd) {
 			adapter->itr = InterruptThrottleRate[bd];
-			switch(adapter->itr) {
+			switch (adapter->itr) {
 			case 0:
-				DPRINTK(PROBE, INFO, "%s turned off\n", 
+				DPRINTK(PROBE, INFO, "%s turned off\n",
 					opt.name);
 				break;
 			case 1:
-				DPRINTK(PROBE, INFO, "%s set to dynamic mode\n", 
+				DPRINTK(PROBE, INFO, "%s set to dynamic mode\n",
 					opt.name);
 				break;
 			default:
-				e1000_validate_option(&adapter->itr, &opt, 
+				e1000_validate_option(&adapter->itr, &opt,
 					adapter);
 				break;
 			}
@@ -494,7 +494,7 @@ e1000_check_options(struct e1000_adapter
 		}
 	}
 
-	switch(adapter->hw.media_type) {
+	switch (adapter->hw.media_type) {
 	case e1000_media_type_fiber:
 	case e1000_media_type_internal_serdes:
 		e1000_check_fiber_options(adapter);
@@ -518,17 +518,17 @@ static void __devinit
 e1000_check_fiber_options(struct e1000_adapter *adapter)
 {
 	int bd = adapter->bd_number;
-	if(num_Speed > bd) {
+	if (num_Speed > bd) {
 		DPRINTK(PROBE, INFO, "Speed not valid for fiber adapters, "
 		       "parameter ignored\n");
 	}
 
-	if(num_Duplex > bd) {
+	if (num_Duplex > bd) {
 		DPRINTK(PROBE, INFO, "Duplex not valid for fiber adapters, "
 		       "parameter ignored\n");
 	}
 
-	if((num_AutoNeg > bd) && (AutoNeg[bd] != 0x20)) {
+	if ((num_AutoNeg > bd) && (AutoNeg[bd] != 0x20)) {
 		DPRINTK(PROBE, INFO, "AutoNeg other than 1000/Full is "
 				 "not valid for fiber adapters, "
 				 "parameter ignored\n");
@@ -584,6 +584,12 @@ e1000_check_copper_options(struct e1000_
 					 .p = dplx_list }}
 		};
 
+		if (e1000_check_phy_reset_block(&adapter->hw)) {
+			DPRINTK(PROBE, INFO,
+				"Link active due to SoL/IDER Session. "
+			        "Speed/Duplex/AutoNeg parameter ignored.\n");
+			return;
+		}
 		if (num_Duplex > bd) {
 			dplx = Duplex[bd];
 			e1000_validate_option(&dplx, &opt, adapter);
@@ -592,7 +598,7 @@ e1000_check_copper_options(struct e1000_
 		}
 	}
 
-	if((num_AutoNeg > bd) && (speed != 0 || dplx != 0)) {
+	if ((num_AutoNeg > bd) && (speed != 0 || dplx != 0)) {
 		DPRINTK(PROBE, INFO,
 		       "AutoNeg specified along with Speed or Duplex, "
 		       "parameter ignored\n");
@@ -653,7 +659,7 @@ e1000_check_copper_options(struct e1000_
 	switch (speed + dplx) {
 	case 0:
 		adapter->hw.autoneg = adapter->fc_autoneg = 1;
-		if((num_Speed > bd) && (speed != 0 || dplx != 0))
+		if ((num_Speed > bd) && (speed != 0 || dplx != 0))
 			DPRINTK(PROBE, INFO,
 			       "Speed and duplex autonegotiation enabled\n");
 		break;
diff --git a/drivers/net/lp486e.c b/drivers/net/lp486e.c
index 6139f06..94d5ea1 100644
--- a/drivers/net/lp486e.c
+++ b/drivers/net/lp486e.c
@@ -56,8 +56,6 @@ PORT  SIZE ACTION MEANING
 All other communication is through memory!
 */
 
-#define SLOW_DOWN_IO udelay(5)
-
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/delay.h>
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 22c3a37..7ef4b04 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -35,6 +35,8 @@
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <linux/etherdevice.h>
+#include <linux/in.h>
+#include <linux/ip.h>
 
 #include <linux/bitops.h>
 #include <linux/delay.h>
@@ -55,13 +57,15 @@
 /* Constants */
 #define VLAN_HLEN		4
 #define FCS_LEN			4
-#define WRAP			NET_IP_ALIGN + ETH_HLEN + VLAN_HLEN + FCS_LEN
+#define DMA_ALIGN		8	/* hw requires 8-byte alignment */
+#define HW_IP_ALIGN		2	/* hw aligns IP header */
+#define WRAP			HW_IP_ALIGN + ETH_HLEN + VLAN_HLEN + FCS_LEN
 #define RX_SKB_SIZE		((dev->mtu + WRAP + 7) & ~0x7)
 
-#define INT_CAUSE_UNMASK_ALL		0x0007ffff
-#define INT_CAUSE_UNMASK_ALL_EXT	0x0011ffff
-#define INT_CAUSE_MASK_ALL		0x00000000
-#define INT_CAUSE_MASK_ALL_EXT		0x00000000
+#define INT_UNMASK_ALL			0x0007ffff
+#define INT_UNMASK_ALL_EXT		0x0011ffff
+#define INT_MASK_ALL			0x00000000
+#define INT_MASK_ALL_EXT		0x00000000
 #define INT_CAUSE_CHECK_BITS		INT_CAUSE_UNMASK_ALL
 #define INT_CAUSE_CHECK_BITS_EXT	INT_CAUSE_UNMASK_ALL_EXT
 
@@ -78,8 +82,9 @@
 static int eth_port_link_is_up(unsigned int eth_port_num);
 static void eth_port_uc_addr_get(struct net_device *dev,
 						unsigned char *MacAddr);
-static int mv643xx_eth_real_open(struct net_device *);
-static int mv643xx_eth_real_stop(struct net_device *);
+static void eth_port_set_multicast_list(struct net_device *);
+static int mv643xx_eth_open(struct net_device *);
+static int mv643xx_eth_stop(struct net_device *);
 static int mv643xx_eth_change_mtu(struct net_device *, int);
 static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *);
 static void eth_port_init_mac_tables(unsigned int eth_port_num);
@@ -124,15 +129,8 @@ static inline void mv_write(int offset, 
  */
 static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu)
 {
-	struct mv643xx_private *mp = netdev_priv(dev);
-	unsigned long flags;
-
-	spin_lock_irqsave(&mp->lock, flags);
-
-	if ((new_mtu > 9500) || (new_mtu < 64)) {
-		spin_unlock_irqrestore(&mp->lock, flags);
+	if ((new_mtu > 9500) || (new_mtu < 64))
 		return -EINVAL;
-	}
 
 	dev->mtu = new_mtu;
 	/*
@@ -142,17 +140,13 @@ static int mv643xx_eth_change_mtu(struct
 	 * to memory is full, which might fail the open function.
 	 */
 	if (netif_running(dev)) {
-		if (mv643xx_eth_real_stop(dev))
-			printk(KERN_ERR
-				"%s: Fatal error on stopping device\n",
-				dev->name);
-		if (mv643xx_eth_real_open(dev))
+		mv643xx_eth_stop(dev);
+		if (mv643xx_eth_open(dev))
 			printk(KERN_ERR
 				"%s: Fatal error on opening device\n",
 				dev->name);
 	}
 
-	spin_unlock_irqrestore(&mp->lock, flags);
 	return 0;
 }
 
@@ -170,15 +164,19 @@ static void mv643xx_eth_rx_task(void *da
 	struct mv643xx_private *mp = netdev_priv(dev);
 	struct pkt_info pkt_info;
 	struct sk_buff *skb;
+	int unaligned;
 
 	if (test_and_set_bit(0, &mp->rx_task_busy))
 		panic("%s: Error in test_set_bit / clear_bit", dev->name);
 
 	while (mp->rx_ring_skbs < (mp->rx_ring_size - 5)) {
-		skb = dev_alloc_skb(RX_SKB_SIZE);
+		skb = dev_alloc_skb(RX_SKB_SIZE + DMA_ALIGN);
 		if (!skb)
 			break;
 		mp->rx_ring_skbs++;
+		unaligned = (u32)skb->data & (DMA_ALIGN - 1);
+		if (unaligned)
+			skb_reserve(skb, DMA_ALIGN - unaligned);
 		pkt_info.cmd_sts = ETH_RX_ENABLE_INTERRUPT;
 		pkt_info.byte_cnt = RX_SKB_SIZE;
 		pkt_info.buf_ptr = dma_map_single(NULL, skb->data, RX_SKB_SIZE,
@@ -189,7 +187,7 @@ static void mv643xx_eth_rx_task(void *da
 				"%s: Error allocating RX Ring\n", dev->name);
 			break;
 		}
-		skb_reserve(skb, 2);
+		skb_reserve(skb, HW_IP_ALIGN);
 	}
 	clear_bit(0, &mp->rx_task_busy);
 	/*
@@ -207,7 +205,7 @@ static void mv643xx_eth_rx_task(void *da
 	else {
 		/* Return interrupts */
 		mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(mp->port_num),
-							INT_CAUSE_UNMASK_ALL);
+							INT_UNMASK_ALL);
 	}
 #endif
 }
@@ -267,6 +265,8 @@ static void mv643xx_eth_set_rx_mode(stru
 		mp->port_config &= ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
 
 	mv_write(MV643XX_ETH_PORT_CONFIG_REG(mp->port_num), mp->port_config);
+
+	eth_port_set_multicast_list(dev);
 }
 
 /*
@@ -342,8 +342,6 @@ static int mv643xx_eth_free_tx_queue(str
 	if (!(eth_int_cause_ext & (BIT0 | BIT8)))
 		return released;
 
-	spin_lock(&mp->lock);
-
 	/* Check only queue 0 */
 	while (eth_tx_return_desc(mp, &pkt_info) == ETH_OK) {
 		if (pkt_info.cmd_sts & BIT0) {
@@ -351,31 +349,21 @@ static int mv643xx_eth_free_tx_queue(str
 			stats->tx_errors++;
 		}
 
-		/*
-		 * If return_info is different than 0, release the skb.
-		 * The case where return_info is not 0 is only in case
-		 * when transmitted a scatter/gather packet, where only
-		 * last skb releases the whole chain.
-		 */
-		if (pkt_info.return_info) {
-			if (skb_shinfo(pkt_info.return_info)->nr_frags)
-				dma_unmap_page(NULL, pkt_info.buf_ptr,
-						pkt_info.byte_cnt,
-						DMA_TO_DEVICE);
-			else
-				dma_unmap_single(NULL, pkt_info.buf_ptr,
-						pkt_info.byte_cnt,
-						DMA_TO_DEVICE);
+		if (pkt_info.cmd_sts & ETH_TX_FIRST_DESC)
+			dma_unmap_single(NULL, pkt_info.buf_ptr,
+					pkt_info.byte_cnt,
+					DMA_TO_DEVICE);
+		else
+			dma_unmap_page(NULL, pkt_info.buf_ptr,
+					pkt_info.byte_cnt,
+					DMA_TO_DEVICE);
 
+		if (pkt_info.return_info) {
 			dev_kfree_skb_irq(pkt_info.return_info);
 			released = 0;
-		} else
-			dma_unmap_page(NULL, pkt_info.buf_ptr,
-					pkt_info.byte_cnt, DMA_TO_DEVICE);
+		}
 	}
 
-	spin_unlock(&mp->lock);
-
 	return released;
 }
 
@@ -456,6 +444,7 @@ static int mv643xx_eth_receive_queue(str
 			netif_rx(skb);
 #endif
 		}
+		dev->last_rx = jiffies;
 	}
 
 	return received_packets;
@@ -473,7 +462,7 @@ static int mv643xx_eth_receive_queue(str
  */
 
 static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id,
-							struct pt_regs *regs)
+						struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *)dev_id;
 	struct mv643xx_private *mp = netdev_priv(dev);
@@ -482,12 +471,12 @@ static irqreturn_t mv643xx_eth_int_handl
 
 	/* Read interrupt cause registers */
 	eth_int_cause = mv_read(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num)) &
-						INT_CAUSE_UNMASK_ALL;
+						INT_UNMASK_ALL;
 
 	if (eth_int_cause & BIT1)
 		eth_int_cause_ext = mv_read(
 			MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num)) &
-						INT_CAUSE_UNMASK_ALL_EXT;
+						INT_UNMASK_ALL_EXT;
 
 #ifdef MV643XX_NAPI
 	if (!(eth_int_cause & 0x0007fffd)) {
@@ -512,9 +501,10 @@ static irqreturn_t mv643xx_eth_int_handl
 	} else {
 		if (netif_rx_schedule_prep(dev)) {
 			/* Mask all the interrupts */
-			mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), 0);
-			mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG
-								(port_num), 0);
+			mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
+								INT_MASK_ALL);
+			/* wait for previous write to complete */
+			mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num));
 			__netif_rx_schedule(dev);
 		}
 #else
@@ -527,9 +517,12 @@ static irqreturn_t mv643xx_eth_int_handl
 		 * with skb's.
 		 */
 #ifdef MV643XX_RX_QUEUE_FILL_ON_TASK
-		/* Unmask all interrupts on ethernet port */
+		/* Mask all interrupts on ethernet port */
 		mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
-							INT_CAUSE_MASK_ALL);
+							INT_MASK_ALL);
+		/* wait for previous write to take effect */
+		mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num));
+
 		queue_task(&mp->rx_task, &tq_immediate);
 		mark_bh(IMMEDIATE_BH);
 #else
@@ -636,56 +629,6 @@ static unsigned int eth_port_set_tx_coal
 }
 
 /*
- * mv643xx_eth_open
- *
- * This function is called when openning the network device. The function
- * should initialize all the hardware, initialize cyclic Rx/Tx
- * descriptors chain and buffers and allocate an IRQ to the network
- * device.
- *
- * Input :	a pointer to the network device structure
- *
- * Output :	zero of success , nonzero if fails.
- */
-
-static int mv643xx_eth_open(struct net_device *dev)
-{
-	struct mv643xx_private *mp = netdev_priv(dev);
-	unsigned int port_num = mp->port_num;
-	int err;
-
-	spin_lock_irq(&mp->lock);
-
-	err = request_irq(dev->irq, mv643xx_eth_int_handler,
-			SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
-
-	if (err) {
-		printk(KERN_ERR "Can not assign IRQ number to MV643XX_eth%d\n",
-								port_num);
-		err = -EAGAIN;
-		goto out;
-	}
-
-	if (mv643xx_eth_real_open(dev)) {
-		printk("%s: Error opening interface\n", dev->name);
-		err = -EBUSY;
-		goto out_free;
-	}
-
-	spin_unlock_irq(&mp->lock);
-
-	return 0;
-
-out_free:
-	free_irq(dev->irq, dev);
-
-out:
-	spin_unlock_irq(&mp->lock);
-
-	return err;
-}
-
-/*
  * ether_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory.
  *
  * DESCRIPTION:
@@ -777,28 +720,37 @@ static void ether_init_tx_desc_ring(stru
 	mp->port_tx_queue_command |= 1;
 }
 
-/* Helper function for mv643xx_eth_open */
-static int mv643xx_eth_real_open(struct net_device *dev)
+/*
+ * mv643xx_eth_open
+ *
+ * This function is called when openning the network device. The function
+ * should initialize all the hardware, initialize cyclic Rx/Tx
+ * descriptors chain and buffers and allocate an IRQ to the network
+ * device.
+ *
+ * Input :	a pointer to the network device structure
+ *
+ * Output :	zero of success , nonzero if fails.
+ */
+
+static int mv643xx_eth_open(struct net_device *dev)
 {
 	struct mv643xx_private *mp = netdev_priv(dev);
 	unsigned int port_num = mp->port_num;
 	unsigned int size;
+	int err;
+
+	err = request_irq(dev->irq, mv643xx_eth_int_handler,
+			SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
+	if (err) {
+		printk(KERN_ERR "Can not assign IRQ number to MV643XX_eth%d\n",
+								port_num);
+		return -EAGAIN;
+	}
 
 	/* Stop RX Queues */
 	mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), 0x0000ff00);
 
-	/* Clear the ethernet port interrupts */
-	mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
-	mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
-
-	/* Unmask RX buffer and TX end interrupt */
-	mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
-						INT_CAUSE_UNMASK_ALL);
-
-	/* Unmask phy and link status changes interrupts */
-	mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
-						INT_CAUSE_UNMASK_ALL_EXT);
-
 	/* Set the MAC Address */
 	memcpy(mp->port_mac_addr, dev->dev_addr, 6);
 
@@ -818,14 +770,15 @@ static int mv643xx_eth_real_open(struct 
 								GFP_KERNEL);
 	if (!mp->rx_skb) {
 		printk(KERN_ERR "%s: Cannot allocate Rx skb ring\n", dev->name);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto out_free_irq;
 	}
 	mp->tx_skb = kmalloc(sizeof(*mp->tx_skb) * mp->tx_ring_size,
 								GFP_KERNEL);
 	if (!mp->tx_skb) {
 		printk(KERN_ERR "%s: Cannot allocate Tx skb ring\n", dev->name);
-		kfree(mp->rx_skb);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto out_free_rx_skb;
 	}
 
 	/* Allocate TX ring */
@@ -845,9 +798,8 @@ static int mv643xx_eth_real_open(struct 
 	if (!mp->p_tx_desc_area) {
 		printk(KERN_ERR "%s: Cannot allocate Tx Ring (size %d bytes)\n",
 							dev->name, size);
-		kfree(mp->rx_skb);
-		kfree(mp->tx_skb);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto out_free_tx_skb;
 	}
 	BUG_ON((u32) mp->p_tx_desc_area & 0xf);	/* check 16-byte alignment */
 	memset((void *)mp->p_tx_desc_area, 0, mp->tx_desc_area_size);
@@ -874,13 +826,12 @@ static int mv643xx_eth_real_open(struct 
 		printk(KERN_ERR "%s: Freeing previously allocated TX queues...",
 							dev->name);
 		if (mp->rx_sram_size)
-			iounmap(mp->p_rx_desc_area);
+			iounmap(mp->p_tx_desc_area);
 		else
 			dma_free_coherent(NULL, mp->tx_desc_area_size,
 					mp->p_tx_desc_area, mp->tx_desc_dma);
-		kfree(mp->rx_skb);
-		kfree(mp->tx_skb);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto out_free_tx_skb;
 	}
 	memset((void *)mp->p_rx_desc_area, 0, size);
 
@@ -900,9 +851,26 @@ static int mv643xx_eth_real_open(struct 
 	mp->tx_int_coal =
 		eth_port_set_tx_coal(port_num, 133000000, MV643XX_TX_COAL);
 
-	netif_start_queue(dev);
+	/* Clear any pending ethernet port interrupts */
+	mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
+	mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
+
+	/* Unmask phy and link status changes interrupts */
+	mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
+						INT_UNMASK_ALL_EXT);
 
+	/* Unmask RX buffer and TX end interrupt */
+	mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_UNMASK_ALL);
 	return 0;
+
+out_free_tx_skb:
+	kfree(mp->tx_skb);
+out_free_rx_skb:
+	kfree(mp->rx_skb);
+out_free_irq:
+	free_irq(dev->irq, dev);
+
+	return err;
 }
 
 static void mv643xx_eth_free_tx_rings(struct net_device *dev)
@@ -910,14 +878,17 @@ static void mv643xx_eth_free_tx_rings(st
 	struct mv643xx_private *mp = netdev_priv(dev);
 	unsigned int port_num = mp->port_num;
 	unsigned int curr;
+	struct sk_buff *skb;
 
 	/* Stop Tx Queues */
 	mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), 0x0000ff00);
 
 	/* Free outstanding skb's on TX rings */
 	for (curr = 0; mp->tx_ring_skbs && curr < mp->tx_ring_size; curr++) {
-		if (mp->tx_skb[curr]) {
-			dev_kfree_skb(mp->tx_skb[curr]);
+		skb = mp->tx_skb[curr];
+		if (skb) {
+			mp->tx_ring_skbs -= skb_shinfo(skb)->nr_frags;
+			dev_kfree_skb(skb);
 			mp->tx_ring_skbs--;
 		}
 	}
@@ -973,44 +944,32 @@ static void mv643xx_eth_free_rx_rings(st
  * Output :	zero if success , nonzero if fails
  */
 
-/* Helper function for mv643xx_eth_stop */
-
-static int mv643xx_eth_real_stop(struct net_device *dev)
+static int mv643xx_eth_stop(struct net_device *dev)
 {
 	struct mv643xx_private *mp = netdev_priv(dev);
 	unsigned int port_num = mp->port_num;
 
+	/* Mask all interrupts on ethernet port */
+	mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_MASK_ALL);
+	/* wait for previous write to complete */
+	mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num));
+
+#ifdef MV643XX_NAPI
+	netif_poll_disable(dev);
+#endif
 	netif_carrier_off(dev);
 	netif_stop_queue(dev);
 
-	mv643xx_eth_free_tx_rings(dev);
-	mv643xx_eth_free_rx_rings(dev);
-
 	eth_port_reset(mp->port_num);
 
-	/* Disable ethernet port interrupts */
-	mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
-	mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
-
-	/* Mask RX buffer and TX end interrupt */
-	mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), 0);
-
-	/* Mask phy and link status changes interrupts */
-	mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num), 0);
-
-	return 0;
-}
-
-static int mv643xx_eth_stop(struct net_device *dev)
-{
-	struct mv643xx_private *mp = netdev_priv(dev);
-
-	spin_lock_irq(&mp->lock);
+	mv643xx_eth_free_tx_rings(dev);
+	mv643xx_eth_free_rx_rings(dev);
 
-	mv643xx_eth_real_stop(dev);
+#ifdef MV643XX_NAPI
+	netif_poll_enable(dev);
+#endif
 
 	free_irq(dev->irq, dev);
-	spin_unlock_irq(&mp->lock);
 
 	return 0;
 }
@@ -1022,20 +981,17 @@ static void mv643xx_tx(struct net_device
 	struct pkt_info pkt_info;
 
 	while (eth_tx_return_desc(mp, &pkt_info) == ETH_OK) {
-		if (pkt_info.return_info) {
-			if (skb_shinfo(pkt_info.return_info)->nr_frags)
-				dma_unmap_page(NULL, pkt_info.buf_ptr,
-						pkt_info.byte_cnt,
-						DMA_TO_DEVICE);
-			else
-				dma_unmap_single(NULL, pkt_info.buf_ptr,
-						pkt_info.byte_cnt,
-						DMA_TO_DEVICE);
+		if (pkt_info.cmd_sts & ETH_TX_FIRST_DESC)
+			dma_unmap_single(NULL, pkt_info.buf_ptr,
+					pkt_info.byte_cnt,
+					DMA_TO_DEVICE);
+		else
+			dma_unmap_page(NULL, pkt_info.buf_ptr,
+					pkt_info.byte_cnt,
+					DMA_TO_DEVICE);
 
+		if (pkt_info.return_info)
 			dev_kfree_skb_irq(pkt_info.return_info);
-		} else
-			dma_unmap_page(NULL, pkt_info.buf_ptr,
-					pkt_info.byte_cnt, DMA_TO_DEVICE);
 	}
 
 	if (netif_queue_stopped(dev) &&
@@ -1053,14 +1009,11 @@ static int mv643xx_poll(struct net_devic
 	struct mv643xx_private *mp = netdev_priv(dev);
 	int done = 1, orig_budget, work_done;
 	unsigned int port_num = mp->port_num;
-	unsigned long flags;
 
 #ifdef MV643XX_TX_FAST_REFILL
 	if (++mp->tx_clean_threshold > 5) {
-		spin_lock_irqsave(&mp->lock, flags);
 		mv643xx_tx(dev);
 		mp->tx_clean_threshold = 0;
-		spin_unlock_irqrestore(&mp->lock, flags);
 	}
 #endif
 
@@ -1078,21 +1031,35 @@ static int mv643xx_poll(struct net_devic
 	}
 
 	if (done) {
-		spin_lock_irqsave(&mp->lock, flags);
-		__netif_rx_complete(dev);
+		netif_rx_complete(dev);
 		mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
 		mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
 		mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
-						INT_CAUSE_UNMASK_ALL);
-		mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
-						INT_CAUSE_UNMASK_ALL_EXT);
-		spin_unlock_irqrestore(&mp->lock, flags);
+						INT_UNMASK_ALL);
 	}
 
 	return done ? 0 : 1;
 }
 #endif
 
+/* Hardware can't handle unaligned fragments smaller than 9 bytes.
+ * This helper function detects that case.
+ */
+
+static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb)
+{
+	unsigned int frag;
+	skb_frag_t *fragp;
+
+	for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
+		fragp = &skb_shinfo(skb)->frags[frag];
+		if (fragp->size <= 8 && fragp->page_offset & 0x7)
+			return 1;
+	}
+	return 0;
+}
+
+
 /*
  * mv643xx_eth_start_xmit
  *
@@ -1136,12 +1103,19 @@ static int mv643xx_eth_start_xmit(struct
 		return 1;
 	}
 
+#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
+	if (has_tiny_unaligned_frags(skb)) {
+		if ((skb_linearize(skb, GFP_ATOMIC) != 0)) {
+			stats->tx_dropped++;
+			printk(KERN_DEBUG "%s: failed to linearize tiny "
+					"unaligned fragment\n", dev->name);
+			return 1;
+		}
+	}
+
 	spin_lock_irqsave(&mp->lock, flags);
 
-	/* Update packet info data structure -- DMA owned, first last */
-#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
 	if (!skb_shinfo(skb)->nr_frags) {
-linear:
 		if (skb->ip_summed != CHECKSUM_HW) {
 			/* Errata BTS #50, IHL must be 5 if no HW checksum */
 			pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT |
@@ -1150,7 +1124,6 @@ linear:
 					   5 << ETH_TX_IHL_SHIFT;
 			pkt_info.l4i_chk = 0;
 		} else {
-
 			pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT |
 					   ETH_TX_FIRST_DESC |
 					   ETH_TX_LAST_DESC |
@@ -1158,14 +1131,16 @@ linear:
 					   ETH_GEN_IP_V_4_CHECKSUM |
 					   skb->nh.iph->ihl << ETH_TX_IHL_SHIFT;
 			/* CPU already calculated pseudo header checksum. */
-			if (skb->nh.iph->protocol == IPPROTO_UDP) {
+			if ((skb->protocol == ETH_P_IP) &&
+			    (skb->nh.iph->protocol == IPPROTO_UDP) ) {
 				pkt_info.cmd_sts |= ETH_UDP_FRAME;
 				pkt_info.l4i_chk = skb->h.uh->check;
-			} else if (skb->nh.iph->protocol == IPPROTO_TCP)
+			} else if ((skb->protocol == ETH_P_IP) &&
+				   (skb->nh.iph->protocol == IPPROTO_TCP))
 				pkt_info.l4i_chk = skb->h.th->check;
 			else {
 				printk(KERN_ERR
-					"%s: chksum proto != TCP or UDP\n",
+					"%s: chksum proto != IPv4 TCP or UDP\n",
 					dev->name);
 				spin_unlock_irqrestore(&mp->lock, flags);
 				return 1;
@@ -1183,26 +1158,6 @@ linear:
 	} else {
 		unsigned int frag;
 
-		/* Since hardware can't handle unaligned fragments smaller
-		 * than 9 bytes, if we find any, we linearize the skb
-		 * and start again.  When I've seen it, it's always been
-		 * the first frag (probably near the end of the page),
-		 * but we check all frags to be safe.
-		 */
-		for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
-			skb_frag_t *fragp;
-
-			fragp = &skb_shinfo(skb)->frags[frag];
-			if (fragp->size <= 8 && fragp->page_offset & 0x7) {
-				skb_linearize(skb, GFP_ATOMIC);
-				printk(KERN_DEBUG "%s: unaligned tiny fragment"
-						"%d of %d, fixed\n",
-						dev->name, frag,
-						skb_shinfo(skb)->nr_frags);
-				goto linear;
-			}
-		}
-
 		/* first frag which is skb header */
 		pkt_info.byte_cnt = skb_headlen(skb);
 		pkt_info.buf_ptr = dma_map_single(NULL, skb->data,
@@ -1221,14 +1176,16 @@ linear:
 					   ETH_GEN_IP_V_4_CHECKSUM |
 					   skb->nh.iph->ihl << ETH_TX_IHL_SHIFT;
 			/* CPU already calculated pseudo header checksum. */
-			if (skb->nh.iph->protocol == IPPROTO_UDP) {
+			if ((skb->protocol == ETH_P_IP) &&
+			    (skb->nh.iph->protocol == IPPROTO_UDP)) {
 				pkt_info.cmd_sts |= ETH_UDP_FRAME;
 				pkt_info.l4i_chk = skb->h.uh->check;
-			} else if (skb->nh.iph->protocol == IPPROTO_TCP)
+			} else if ((skb->protocol == ETH_P_IP) &&
+				   (skb->nh.iph->protocol == IPPROTO_TCP))
 				pkt_info.l4i_chk = skb->h.th->check;
 			else {
 				printk(KERN_ERR
-					"%s: chksum proto != TCP or UDP\n",
+					"%s: chksum proto != IPv4 TCP or UDP\n",
 					dev->name);
 				spin_unlock_irqrestore(&mp->lock, flags);
 				return 1;
@@ -1288,6 +1245,8 @@ linear:
 		}
 	}
 #else
+	spin_lock_irqsave(&mp->lock, flags);
+
 	pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | ETH_TX_FIRST_DESC |
 							ETH_TX_LAST_DESC;
 	pkt_info.l4i_chk = 0;
@@ -1340,39 +1299,18 @@ static struct net_device_stats *mv643xx_
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
-static inline void mv643xx_enable_irq(struct mv643xx_private *mp)
-{
-	int port_num = mp->port_num;
-	unsigned long flags;
-
-	spin_lock_irqsave(&mp->lock, flags);
-	mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
-					INT_CAUSE_UNMASK_ALL);
-	mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
-					INT_CAUSE_UNMASK_ALL_EXT);
-	spin_unlock_irqrestore(&mp->lock, flags);
-}
-
-static inline void mv643xx_disable_irq(struct mv643xx_private *mp)
-{
-	int port_num = mp->port_num;
-	unsigned long flags;
-
-	spin_lock_irqsave(&mp->lock, flags);
-	mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
-					INT_CAUSE_MASK_ALL);
-	mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
-					INT_CAUSE_MASK_ALL_EXT);
-	spin_unlock_irqrestore(&mp->lock, flags);
-}
-
 static void mv643xx_netpoll(struct net_device *netdev)
 {
 	struct mv643xx_private *mp = netdev_priv(netdev);
+	int port_num = mp->port_num;
+
+	mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_MASK_ALL);
+	/* wait for previous write to complete */
+	mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num));
 
-	mv643xx_disable_irq(mp);
 	mv643xx_eth_int_handler(netdev->irq, netdev, NULL);
-	mv643xx_enable_irq(mp);
+
+	mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_UNMASK_ALL);
 }
 #endif
 
@@ -1441,7 +1379,7 @@ static int mv643xx_eth_probe(struct plat
 	 * Zero copy can only work if we use Discovery II memory. Else, we will
 	 * have to map the buffers to ISA memory which is only 16 MB
 	 */
-	dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_HW_CSUM;
+	dev->features = NETIF_F_SG | NETIF_F_IP_CSUM;
 #endif
 #endif
 
@@ -2054,6 +1992,196 @@ static int eth_port_uc_addr(unsigned int
 }
 
 /*
+ * The entries in each table are indexed by a hash of a packet's MAC
+ * address.  One bit in each entry determines whether the packet is
+ * accepted.  There are 4 entries (each 8 bits wide) in each register
+ * of the table.  The bits in each entry are defined as follows:
+ *	0	Accept=1, Drop=0
+ *	3-1	Queue			(ETH_Q0=0)
+ *	7-4	Reserved = 0;
+ */
+static void eth_port_set_filter_table_entry(int table, unsigned char entry)
+{
+	unsigned int table_reg;
+	unsigned int tbl_offset;
+	unsigned int reg_offset;
+
+	tbl_offset = (entry / 4) * 4;	/* Register offset of DA table entry */
+	reg_offset = entry % 4;		/* Entry offset within the register */
+
+	/* Set "accepts frame bit" at specified table entry */
+	table_reg = mv_read(table + tbl_offset);
+	table_reg |= 0x01 << (8 * reg_offset);
+	mv_write(table + tbl_offset, table_reg);
+}
+
+/*
+ * eth_port_mc_addr - Multicast address settings.
+ *
+ * The MV device supports multicast using two tables:
+ * 1) Special Multicast Table for MAC addresses of the form
+ *    0x01-00-5E-00-00-XX (where XX is between 0x00 and 0x_FF).
+ *    The MAC DA[7:0] bits are used as a pointer to the Special Multicast
+ *    Table entries in the DA-Filter table.
+ * 2) Other Multicast Table for multicast of another type. A CRC-8bit
+ *    is used as an index to the Other Multicast Table entries in the
+ *    DA-Filter table.  This function calculates the CRC-8bit value.
+ * In either case, eth_port_set_filter_table_entry() is then called
+ * to set to set the actual table entry.
+ */
+static void eth_port_mc_addr(unsigned int eth_port_num, unsigned char *p_addr)
+{
+	unsigned int mac_h;
+	unsigned int mac_l;
+	unsigned char crc_result = 0;
+	int table;
+	int mac_array[48];
+	int crc[8];
+	int i;
+
+	if ((p_addr[0] == 0x01) && (p_addr[1] == 0x00) &&
+	    (p_addr[2] == 0x5E) && (p_addr[3] == 0x00) && (p_addr[4] == 0x00)) {
+		table = MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE
+					(eth_port_num);
+		eth_port_set_filter_table_entry(table, p_addr[5]);
+		return;
+	}
+
+	/* Calculate CRC-8 out of the given address */
+	mac_h = (p_addr[0] << 8) | (p_addr[1]);
+	mac_l = (p_addr[2] << 24) | (p_addr[3] << 16) |
+			(p_addr[4] << 8) | (p_addr[5] << 0);
+
+	for (i = 0; i < 32; i++)
+		mac_array[i] = (mac_l >> i) & 0x1;
+	for (i = 32; i < 48; i++)
+		mac_array[i] = (mac_h >> (i - 32)) & 0x1;
+
+	crc[0] = mac_array[45] ^ mac_array[43] ^ mac_array[40] ^ mac_array[39] ^
+		 mac_array[35] ^ mac_array[34] ^ mac_array[31] ^ mac_array[30] ^
+		 mac_array[28] ^ mac_array[23] ^ mac_array[21] ^ mac_array[19] ^
+		 mac_array[18] ^ mac_array[16] ^ mac_array[14] ^ mac_array[12] ^
+		 mac_array[8]  ^ mac_array[7]  ^ mac_array[6]  ^ mac_array[0];
+
+	crc[1] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^ mac_array[43] ^
+		 mac_array[41] ^ mac_array[39] ^ mac_array[36] ^ mac_array[34] ^
+		 mac_array[32] ^ mac_array[30] ^ mac_array[29] ^ mac_array[28] ^
+		 mac_array[24] ^ mac_array[23] ^ mac_array[22] ^ mac_array[21] ^
+		 mac_array[20] ^ mac_array[18] ^ mac_array[17] ^ mac_array[16] ^
+		 mac_array[15] ^ mac_array[14] ^ mac_array[13] ^ mac_array[12] ^
+		 mac_array[9]  ^ mac_array[6]  ^ mac_array[1]  ^ mac_array[0];
+
+	crc[2] = mac_array[47] ^ mac_array[46] ^ mac_array[44] ^ mac_array[43] ^
+		 mac_array[42] ^ mac_array[39] ^ mac_array[37] ^ mac_array[34] ^
+		 mac_array[33] ^ mac_array[29] ^ mac_array[28] ^ mac_array[25] ^
+		 mac_array[24] ^ mac_array[22] ^ mac_array[17] ^ mac_array[15] ^
+		 mac_array[13] ^ mac_array[12] ^ mac_array[10] ^ mac_array[8]  ^
+		 mac_array[6]  ^ mac_array[2]  ^ mac_array[1]  ^ mac_array[0];
+
+	crc[3] = mac_array[47] ^ mac_array[45] ^ mac_array[44] ^ mac_array[43] ^
+		 mac_array[40] ^ mac_array[38] ^ mac_array[35] ^ mac_array[34] ^
+		 mac_array[30] ^ mac_array[29] ^ mac_array[26] ^ mac_array[25] ^
+		 mac_array[23] ^ mac_array[18] ^ mac_array[16] ^ mac_array[14] ^
+		 mac_array[13] ^ mac_array[11] ^ mac_array[9]  ^ mac_array[7]  ^
+		 mac_array[3]  ^ mac_array[2]  ^ mac_array[1];
+
+	crc[4] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^ mac_array[41] ^
+		 mac_array[39] ^ mac_array[36] ^ mac_array[35] ^ mac_array[31] ^
+		 mac_array[30] ^ mac_array[27] ^ mac_array[26] ^ mac_array[24] ^
+		 mac_array[19] ^ mac_array[17] ^ mac_array[15] ^ mac_array[14] ^
+		 mac_array[12] ^ mac_array[10] ^ mac_array[8]  ^ mac_array[4]  ^
+		 mac_array[3]  ^ mac_array[2];
+
+	crc[5] = mac_array[47] ^ mac_array[46] ^ mac_array[45] ^ mac_array[42] ^
+		 mac_array[40] ^ mac_array[37] ^ mac_array[36] ^ mac_array[32] ^
+		 mac_array[31] ^ mac_array[28] ^ mac_array[27] ^ mac_array[25] ^
+		 mac_array[20] ^ mac_array[18] ^ mac_array[16] ^ mac_array[15] ^
+		 mac_array[13] ^ mac_array[11] ^ mac_array[9]  ^ mac_array[5]  ^
+		 mac_array[4]  ^ mac_array[3];
+
+	crc[6] = mac_array[47] ^ mac_array[46] ^ mac_array[43] ^ mac_array[41] ^
+		 mac_array[38] ^ mac_array[37] ^ mac_array[33] ^ mac_array[32] ^
+		 mac_array[29] ^ mac_array[28] ^ mac_array[26] ^ mac_array[21] ^
+		 mac_array[19] ^ mac_array[17] ^ mac_array[16] ^ mac_array[14] ^
+		 mac_array[12] ^ mac_array[10] ^ mac_array[6]  ^ mac_array[5]  ^
+		 mac_array[4];
+
+	crc[7] = mac_array[47] ^ mac_array[44] ^ mac_array[42] ^ mac_array[39] ^
+		 mac_array[38] ^ mac_array[34] ^ mac_array[33] ^ mac_array[30] ^
+		 mac_array[29] ^ mac_array[27] ^ mac_array[22] ^ mac_array[20] ^
+		 mac_array[18] ^ mac_array[17] ^ mac_array[15] ^ mac_array[13] ^
+		 mac_array[11] ^ mac_array[7]  ^ mac_array[6]  ^ mac_array[5];
+
+	for (i = 0; i < 8; i++)
+		crc_result = crc_result | (crc[i] << i);
+
+	table = MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num);
+	eth_port_set_filter_table_entry(table, crc_result);
+}
+
+/*
+ * Set the entire multicast list based on dev->mc_list.
+ */
+static void eth_port_set_multicast_list(struct net_device *dev)
+{
+
+	struct dev_mc_list	*mc_list;
+	int			i;
+	int			table_index;
+	struct mv643xx_private	*mp = netdev_priv(dev);
+	unsigned int		eth_port_num = mp->port_num;
+
+	/* If the device is in promiscuous mode or in all multicast mode,
+	 * we will fully populate both multicast tables with accept.
+	 * This is guaranteed to yield a match on all multicast addresses...
+	 */
+	if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI)) {
+		for (table_index = 0; table_index <= 0xFC; table_index += 4) {
+			/* Set all entries in DA filter special multicast
+			 * table (Ex_dFSMT)
+			 * Set for ETH_Q0 for now
+			 * Bits
+			 * 0	  Accept=1, Drop=0
+			 * 3-1  Queue	 ETH_Q0=0
+			 * 7-4  Reserved = 0;
+			 */
+			mv_write(MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101);
+
+			/* Set all entries in DA filter other multicast
+			 * table (Ex_dFOMT)
+			 * Set for ETH_Q0 for now
+			 * Bits
+			 * 0	  Accept=1, Drop=0
+			 * 3-1  Queue	 ETH_Q0=0
+			 * 7-4  Reserved = 0;
+			 */
+			mv_write(MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101);
+		}
+		return;
+	}
+
+	/* We will clear out multicast tables every time we get the list.
+	 * Then add the entire new list...
+	 */
+	for (table_index = 0; table_index <= 0xFC; table_index += 4) {
+		/* Clear DA filter special multicast table (Ex_dFSMT) */
+		mv_write(MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE
+				(eth_port_num) + table_index, 0);
+
+		/* Clear DA filter other multicast table (Ex_dFOMT) */
+		mv_write(MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE
+				(eth_port_num) + table_index, 0);
+	}
+
+	/* Get pointer to net_device multicast list and add each one... */
+	for (i = 0, mc_list = dev->mc_list;
+			(i < 256) && (mc_list != NULL) && (i < dev->mc_count);
+			i++, mc_list = mc_list->next)
+		if (mc_list->dmi_addrlen == 6)
+			eth_port_mc_addr(eth_port_num, mc_list->dmi_addr);
+}
+
+/*
  * eth_port_init_mac_tables - Clear all entrance in the UC, SMC and OMC tables
  *
  * DESCRIPTION:
@@ -2080,11 +2208,11 @@ static void eth_port_init_mac_tables(uns
 
 	for (table_index = 0; table_index <= 0xFC; table_index += 4) {
 		/* Clear DA filter special multicast table (Ex_dFSMT) */
-		mv_write((MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE
-					(eth_port_num) + table_index), 0);
+		mv_write(MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE
+					(eth_port_num) + table_index, 0);
 		/* Clear DA filter other multicast table (Ex_dFOMT) */
-		mv_write((MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE
-					(eth_port_num) + table_index), 0);
+		mv_write(MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE
+					(eth_port_num) + table_index, 0);
 	}
 }
 
@@ -2629,23 +2757,27 @@ static ETH_FUNC_RET_STATUS eth_port_send
  *	Tx ring 'first' and 'used' indexes are updated.
  *
  * RETURN:
- *	ETH_ERROR in case the routine can not access Tx desc ring.
- *	ETH_RETRY in case there is transmission in process.
- *	ETH_END_OF_JOB if the routine has nothing to release.
- *	ETH_OK otherwise.
+ *	ETH_OK on success
+ *	ETH_ERROR otherwise.
  *
  */
 static ETH_FUNC_RET_STATUS eth_tx_return_desc(struct mv643xx_private *mp,
 						struct pkt_info *p_pkt_info)
 {
 	int tx_desc_used;
+	int tx_busy_desc;
+	struct eth_tx_desc *p_tx_desc_used;
+	unsigned int command_status;
+	unsigned long flags;
+	int err = ETH_OK;
+
+	spin_lock_irqsave(&mp->lock, flags);
+
 #ifdef MV643XX_CHECKSUM_OFFLOAD_TX
-	int tx_busy_desc = mp->tx_first_desc_q;
+	tx_busy_desc = mp->tx_first_desc_q;
 #else
-	int tx_busy_desc = mp->tx_curr_desc_q;
+	tx_busy_desc = mp->tx_curr_desc_q;
 #endif
-	struct eth_tx_desc *p_tx_desc_used;
-	unsigned int command_status;
 
 	/* Get the Tx Desc ring indexes */
 	tx_desc_used = mp->tx_used_desc_q;
@@ -2653,22 +2785,30 @@ static ETH_FUNC_RET_STATUS eth_tx_return
 	p_tx_desc_used = &mp->p_tx_desc_area[tx_desc_used];
 
 	/* Sanity check */
-	if (p_tx_desc_used == NULL)
-		return ETH_ERROR;
+	if (p_tx_desc_used == NULL) {
+		err = ETH_ERROR;
+		goto out;
+	}
 
 	/* Stop release. About to overlap the current available Tx descriptor */
-	if (tx_desc_used == tx_busy_desc && !mp->tx_resource_err)
-		return ETH_END_OF_JOB;
+	if (tx_desc_used == tx_busy_desc && !mp->tx_resource_err) {
+		err = ETH_ERROR;
+		goto out;
+	}
 
 	command_status = p_tx_desc_used->cmd_sts;
 
 	/* Still transmitting... */
-	if (command_status & (ETH_BUFFER_OWNED_BY_DMA))
-		return ETH_RETRY;
+	if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) {
+		err = ETH_ERROR;
+		goto out;
+	}
 
 	/* Pass the packet information to the caller */
 	p_pkt_info->cmd_sts = command_status;
 	p_pkt_info->return_info = mp->tx_skb[tx_desc_used];
+	p_pkt_info->buf_ptr = p_tx_desc_used->buf_ptr;
+	p_pkt_info->byte_cnt = p_tx_desc_used->byte_cnt;
 	mp->tx_skb[tx_desc_used] = NULL;
 
 	/* Update the next descriptor to release. */
@@ -2680,7 +2820,10 @@ static ETH_FUNC_RET_STATUS eth_tx_return
 	BUG_ON(mp->tx_ring_skbs == 0);
 	mp->tx_ring_skbs--;
 
-	return ETH_OK;
+out:
+	spin_unlock_irqrestore(&mp->lock, flags);
+
+	return err;
 }
 
 /*
@@ -2712,11 +2855,14 @@ static ETH_FUNC_RET_STATUS eth_port_rece
 	int rx_next_curr_desc, rx_curr_desc, rx_used_desc;
 	volatile struct eth_rx_desc *p_rx_desc;
 	unsigned int command_status;
+	unsigned long flags;
 
 	/* Do not process Rx ring in case of Rx ring resource error */
 	if (mp->rx_resource_err)
 		return ETH_QUEUE_FULL;
 
+	spin_lock_irqsave(&mp->lock, flags);
+
 	/* Get the Rx Desc ring 'curr and 'used' indexes */
 	rx_curr_desc = mp->rx_curr_desc_q;
 	rx_used_desc = mp->rx_used_desc_q;
@@ -2728,8 +2874,10 @@ static ETH_FUNC_RET_STATUS eth_port_rece
 	rmb();
 
 	/* Nothing to receive... */
-	if (command_status & (ETH_BUFFER_OWNED_BY_DMA))
+	if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) {
+		spin_unlock_irqrestore(&mp->lock, flags);
 		return ETH_END_OF_JOB;
+	}
 
 	p_pkt_info->byte_cnt = (p_rx_desc->byte_cnt) - RX_BUF_OFFSET;
 	p_pkt_info->cmd_sts = command_status;
@@ -2737,8 +2885,10 @@ static ETH_FUNC_RET_STATUS eth_port_rece
 	p_pkt_info->return_info = mp->rx_skb[rx_curr_desc];
 	p_pkt_info->l4i_chk = p_rx_desc->buf_size;
 
-	/* Clean the return info field to indicate that the packet has been */
-	/* moved to the upper layers					    */
+	/*
+	 * Clean the return info field to indicate that the
+	 * packet has been moved to the upper layers
+	 */
 	mp->rx_skb[rx_curr_desc] = NULL;
 
 	/* Update current index in data structure */
@@ -2749,6 +2899,8 @@ static ETH_FUNC_RET_STATUS eth_port_rece
 	if (rx_next_curr_desc == rx_used_desc)
 		mp->rx_resource_err = 1;
 
+	spin_unlock_irqrestore(&mp->lock, flags);
+
 	return ETH_OK;
 }
 
@@ -2777,6 +2929,9 @@ static ETH_FUNC_RET_STATUS eth_rx_return
 {
 	int used_rx_desc;	/* Where to return Rx resource */
 	volatile struct eth_rx_desc *p_used_rx_desc;
+	unsigned long flags;
+
+	spin_lock_irqsave(&mp->lock, flags);
 
 	/* Get 'used' Rx descriptor */
 	used_rx_desc = mp->rx_used_desc_q;
@@ -2800,6 +2955,8 @@ static ETH_FUNC_RET_STATUS eth_rx_return
 	/* Any Rx return cancels the Rx resource error status */
 	mp->rx_resource_err = 0;
 
+	spin_unlock_irqrestore(&mp->lock, flags);
+
 	return ETH_OK;
 }
 
@@ -2812,7 +2969,7 @@ struct mv643xx_stats {
 };
 
 #define MV643XX_STAT(m) sizeof(((struct mv643xx_private *)0)->m), \
-		      offsetof(struct mv643xx_private, m)
+					offsetof(struct mv643xx_private, m)
 
 static const struct mv643xx_stats mv643xx_gstrings_stats[] = {
 	{ "rx_packets", MV643XX_STAT(stats.rx_packets) },
@@ -2963,9 +3120,8 @@ mv643xx_get_settings(struct net_device *
 	return 0;
 }
 
-static void
-mv643xx_get_drvinfo(struct net_device *netdev,
-                       struct ethtool_drvinfo *drvinfo)
+static void mv643xx_get_drvinfo(struct net_device *netdev,
+				struct ethtool_drvinfo *drvinfo)
 {
 	strncpy(drvinfo->driver,  mv643xx_driver_name, 32);
 	strncpy(drvinfo->version, mv643xx_driver_version, 32);
@@ -2974,39 +3130,37 @@ mv643xx_get_drvinfo(struct net_device *n
 	drvinfo->n_stats = MV643XX_STATS_LEN;
 }
 
-static int 
-mv643xx_get_stats_count(struct net_device *netdev)
+static int mv643xx_get_stats_count(struct net_device *netdev)
 {
 	return MV643XX_STATS_LEN;
 }
 
-static void 
-mv643xx_get_ethtool_stats(struct net_device *netdev, 
-		struct ethtool_stats *stats, uint64_t *data)
+static void mv643xx_get_ethtool_stats(struct net_device *netdev,
+				struct ethtool_stats *stats, uint64_t *data)
 {
 	struct mv643xx_private *mp = netdev->priv;
 	int i;
 
 	eth_update_mib_counters(mp);
 
-	for(i = 0; i < MV643XX_STATS_LEN; i++) {
+	for (i = 0; i < MV643XX_STATS_LEN; i++) {
 		char *p = (char *)mp+mv643xx_gstrings_stats[i].stat_offset;	
-		data[i] = (mv643xx_gstrings_stats[i].sizeof_stat == 
+		data[i] = (mv643xx_gstrings_stats[i].sizeof_stat ==
 			sizeof(uint64_t)) ? *(uint64_t *)p : *(uint32_t *)p;
 	}
 }
 
-static void 
-mv643xx_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data)
+static void mv643xx_get_strings(struct net_device *netdev, uint32_t stringset,
+				uint8_t *data)
 {
 	int i;
 
 	switch(stringset) {
 	case ETH_SS_STATS:
 		for (i=0; i < MV643XX_STATS_LEN; i++) {
-			memcpy(data + i * ETH_GSTRING_LEN, 
-			mv643xx_gstrings_stats[i].stat_string,
-			ETH_GSTRING_LEN);
+			memcpy(data + i * ETH_GSTRING_LEN,
+					mv643xx_gstrings_stats[i].stat_string,
+					ETH_GSTRING_LEN);
 		}
 		break;
 	}
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 89c4678..49b597c 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -3586,7 +3586,7 @@ static int s2io_xmit(struct sk_buff *skb
 		txdp->Buffer_Pointer = (u64) pci_map_page
 		    (sp->pdev, frag->page, frag->page_offset,
 		     frag->size, PCI_DMA_TODEVICE);
-		txdp->Control_1 |= TXD_BUFFER0_SIZE(frag->size);
+		txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size);
 		if (skb_shinfo(skb)->ufo_size)
 			txdp->Control_1 |= TXD_UFO_EN;
 	}
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index b538e30..bf55a4c 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -3243,12 +3243,22 @@ static int __devinit skge_probe(struct p
 
 	pci_set_master(pdev);
 
-	if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK)))
+	if (sizeof(dma_addr_t) > sizeof(u32) &&
+	    !(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
 		using_dac = 1;
-	else if (!(err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {
-		printk(KERN_ERR PFX "%s no usable DMA configuration\n",
-		       pci_name(pdev));
-		goto err_out_free_regions;
+		err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+		if (err < 0) {
+			printk(KERN_ERR PFX "%s unable to obtain 64 bit DMA "
+			       "for consistent allocations\n", pci_name(pdev));
+			goto err_out_free_regions;
+		}
+	} else {
+		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		if (err) {
+			printk(KERN_ERR PFX "%s no usable DMA configuration\n",
+			       pci_name(pdev));
+			goto err_out_free_regions;
+		}
 	}
 
 #ifdef __BIG_ENDIAN
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index f5d697c..f8b973a 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -57,7 +57,7 @@
 #include "sky2.h"
 
 #define DRV_NAME		"sky2"
-#define DRV_VERSION		"0.11"
+#define DRV_VERSION		"0.13"
 #define PFX			DRV_NAME " "
 
 /*
@@ -75,6 +75,7 @@
 #define RX_LE_BYTES		(RX_LE_SIZE*sizeof(struct sky2_rx_le))
 #define RX_MAX_PENDING		(RX_LE_SIZE/2 - 2)
 #define RX_DEF_PENDING		RX_MAX_PENDING
+#define RX_SKB_ALIGN		8
 
 #define TX_RING_SIZE		512
 #define TX_DEF_PENDING		(TX_RING_SIZE - 1)
@@ -91,7 +92,7 @@
 static const u32 default_msg =
     NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK
     | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR
-    | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN | NETIF_MSG_INTR;
+    | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN;
 
 static int debug = -1;		/* defaults above */
 module_param(debug, int, 0);
@@ -624,13 +625,16 @@ static void sky2_mac_init(struct sky2_hw
 
 }
 
-static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, size_t len)
+/* Assign Ram Buffer allocation.
+ * start and end are in units of 4k bytes
+ * ram registers are in units of 64bit words
+ */
+static void sky2_ramset(struct sky2_hw *hw, u16 q, u8 startk, u8 endk)
 {
-	u32 end;
+	u32 start, end;
 
-	start /= 8;
-	len /= 8;
-	end = start + len - 1;
+	start = startk * 4096/8;
+	end = (endk * 4096/8) - 1;
 
 	sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
 	sky2_write32(hw, RB_ADDR(q, RB_START), start);
@@ -639,14 +643,19 @@ static void sky2_ramset(struct sky2_hw *
 	sky2_write32(hw, RB_ADDR(q, RB_RP), start);
 
 	if (q == Q_R1 || q == Q_R2) {
-		u32 rxup, rxlo;
+		u32 space = (endk - startk) * 4096/8;
+		u32 tp = space - space/4;
 
-		rxlo = len/2;
-		rxup = rxlo + len/4;
+		/* On receive queue's set the thresholds
+		 * give receiver priority when > 3/4 full
+		 * send pause when down to 2K
+		 */
+		sky2_write32(hw, RB_ADDR(q, RB_RX_UTHP), tp);
+		sky2_write32(hw, RB_ADDR(q, RB_RX_LTHP), space/2);
 
-		/* Set thresholds on receive queue's */
-		sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), rxup);
-		sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), rxlo);
+		tp = space - 2048/8;
+		sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp);
+		sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4);
 	} else {
 		/* Enable store & forward on Tx queue's because
 		 * Tx FIFO is only 1K on Yukon
@@ -695,9 +704,10 @@ static inline struct sky2_tx_le *get_tx_
  * This is a workaround code taken from SysKonnect sk98lin driver
  * to deal with chip bug on Yukon EC rev 0 in the wraparound case.
  */
-static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q,
+static void sky2_put_idx(struct sky2_hw *hw, unsigned q,
 				u16 idx, u16 *last, u16 size)
 {
+	wmb();
 	if (is_ec_a1(hw) && idx < *last) {
 		u16 hwget = sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_GET_IDX));
 
@@ -721,6 +731,7 @@ setnew:
 		sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx);
 	}
 	*last = idx;
+	mmiowb();
 }
 
 
@@ -734,11 +745,11 @@ static inline struct sky2_rx_le *sky2_ne
 /* Return high part of DMA address (could be 32 or 64 bit) */
 static inline u32 high32(dma_addr_t a)
 {
-	return (a >> 16) >> 16;
+	return sizeof(a) > sizeof(u32) ? (a >> 16) >> 16 : 0;
 }
 
 /* Build description to hardware about buffer */
-static inline void sky2_rx_add(struct sky2_port *sky2, dma_addr_t map)
+static void sky2_rx_add(struct sky2_port *sky2, dma_addr_t map)
 {
 	struct sky2_rx_le *le;
 	u32 hi = high32(map);
@@ -878,13 +889,13 @@ static void sky2_vlan_rx_register(struct
 	struct sky2_hw *hw = sky2->hw;
 	u16 port = sky2->port;
 
-	spin_lock(&sky2->tx_lock);
+	spin_lock_bh(&sky2->tx_lock);
 
 	sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_ON);
 	sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_ON);
 	sky2->vlgrp = grp;
 
-	spin_unlock(&sky2->tx_lock);
+	spin_unlock_bh(&sky2->tx_lock);
 }
 
 static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
@@ -893,27 +904,42 @@ static void sky2_vlan_rx_kill_vid(struct
 	struct sky2_hw *hw = sky2->hw;
 	u16 port = sky2->port;
 
-	spin_lock(&sky2->tx_lock);
+	spin_lock_bh(&sky2->tx_lock);
 
 	sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_OFF);
 	sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_OFF);
 	if (sky2->vlgrp)
 		sky2->vlgrp->vlan_devices[vid] = NULL;
 
-	spin_unlock(&sky2->tx_lock);
+	spin_unlock_bh(&sky2->tx_lock);
 }
 #endif
 
 /*
+ * It appears the hardware has a bug in the FIFO logic that
+ * cause it to hang if the FIFO gets overrun and the receive buffer
+ * is not aligned. ALso alloc_skb() won't align properly if slab
+ * debugging is enabled.
+ */
+static inline struct sk_buff *sky2_alloc_skb(unsigned int size, gfp_t gfp_mask)
+{
+	struct sk_buff *skb;
+
+	skb = alloc_skb(size + RX_SKB_ALIGN, gfp_mask);
+	if (likely(skb)) {
+		unsigned long p	= (unsigned long) skb->data;
+		skb_reserve(skb,
+			((p + RX_SKB_ALIGN - 1) & ~(RX_SKB_ALIGN - 1)) - p);
+	}
+
+	return skb;
+}
+
+/*
  * Allocate and setup receiver buffer pool.
  * In case of 64 bit dma, there are 2X as many list elements
  * available as ring entries
  * and need to reserve one list element so we don't wrap around.
- *
- * It appears the hardware has a bug in the FIFO logic that
- * cause it to hang if the FIFO gets overrun and the receive buffer
- * is not aligned.  This means we can't use skb_reserve to align
- * the IP header.
  */
 static int sky2_rx_start(struct sky2_port *sky2)
 {
@@ -929,7 +955,7 @@ static int sky2_rx_start(struct sky2_por
 	for (i = 0; i < sky2->rx_pending; i++) {
 		struct ring_info *re = sky2->rx_ring + i;
 
-		re->skb = dev_alloc_skb(sky2->rx_bufsize);
+		re->skb = sky2_alloc_skb(sky2->rx_bufsize, GFP_KERNEL);
 		if (!re->skb)
 			goto nomem;
 
@@ -986,19 +1012,19 @@ static int sky2_up(struct net_device *de
 
 	sky2_mac_init(hw, port);
 
-	/* Configure RAM buffers */
-	if (hw->chip_id == CHIP_ID_YUKON_FE ||
-	    (hw->chip_id == CHIP_ID_YUKON_EC && hw->chip_rev == 2))
-		ramsize = 4096;
-	else {
-		u8 e0 = sky2_read8(hw, B2_E_0);
-		ramsize = (e0 == 0) ? (128 * 1024) : (e0 * 4096);
-	}
+	/* Determine available ram buffer space (in 4K blocks).
+	 * Note: not sure about the FE setting below yet
+	 */
+	if (hw->chip_id == CHIP_ID_YUKON_FE)
+		ramsize = 4;
+	else
+		ramsize = sky2_read8(hw, B2_E_0);
+
+	/* Give transmitter one third (rounded up) */
+	rxspace = ramsize - (ramsize + 2) / 3;
 
-	/* 2/3 for Rx */
-	rxspace = (2 * ramsize) / 3;
 	sky2_ramset(hw, rxqaddr[port], 0, rxspace);
-	sky2_ramset(hw, txqaddr[port], rxspace, ramsize - rxspace);
+	sky2_ramset(hw, txqaddr[port], rxspace, ramsize);
 
 	/* Make sure SyncQ is disabled */
 	sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL),
@@ -1054,7 +1080,7 @@ static inline int tx_avail(const struct 
 }
 
 /* Estimate of number of transmit list elements required */
-static inline unsigned tx_le_req(const struct sk_buff *skb)
+static unsigned tx_le_req(const struct sk_buff *skb)
 {
 	unsigned count;
 
@@ -1090,6 +1116,10 @@ static int sky2_xmit_frame(struct sk_buf
 	u16 mss;
 	u8 ctrl;
 
+	/* No BH disabling for tx_lock here.  We are running in BH disabled
+	 * context and TX reclaim runs via poll inside of a software
+	 * interrupt, and no related locks in IRQ processing.
+	 */
 	if (!spin_trylock(&sky2->tx_lock))
 		return NETDEV_TX_LOCKED;
 
@@ -1099,8 +1129,9 @@ static int sky2_xmit_frame(struct sk_buf
 		 */
 		if (!netif_queue_stopped(dev)) {
 			netif_stop_queue(dev);
-			printk(KERN_WARNING PFX "%s: ring full when queue awake!\n",
-			       dev->name);
+			if (net_ratelimit())
+				printk(KERN_WARNING PFX "%s: ring full when queue awake!\n",
+				       dev->name);
 		}
 		spin_unlock(&sky2->tx_lock);
 
@@ -1199,7 +1230,7 @@ static int sky2_xmit_frame(struct sk_buf
 
 		mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset,
 				       frag->size, PCI_DMA_TODEVICE);
-		addr64 = (mapping >> 16) >> 16;
+		addr64 = high32(mapping);
 		if (addr64 != sky2->tx_addr64) {
 			le = get_tx_le(sky2);
 			le->tx.addr = cpu_to_le32(addr64);
@@ -1229,7 +1260,6 @@ static int sky2_xmit_frame(struct sk_buf
 		netif_stop_queue(dev);
 
 out_unlock:
-	mmiowb();
 	spin_unlock(&sky2->tx_lock);
 
 	dev->trans_start = jiffies;
@@ -1282,17 +1312,17 @@ static void sky2_tx_complete(struct sky2
 		dev_kfree_skb_any(skb);
 	}
 
-	spin_lock(&sky2->tx_lock);
 	sky2->tx_cons = put;
 	if (netif_queue_stopped(dev) && tx_avail(sky2) > MAX_SKB_TX_LE)
 		netif_wake_queue(dev);
-	spin_unlock(&sky2->tx_lock);
 }
 
 /* Cleanup all untransmitted buffers, assume transmitter not running */
 static void sky2_tx_clean(struct sky2_port *sky2)
 {
+	spin_lock_bh(&sky2->tx_lock);
 	sky2_tx_complete(sky2, sky2->tx_prod);
+	spin_unlock_bh(&sky2->tx_lock);
 }
 
 /* Network shutdown */
@@ -1582,28 +1612,40 @@ out:
 	local_irq_enable();
 }
 
+
+/* Transmit timeout is only called if we are running, carries is up
+ * and tx queue is full (stopped).
+ */
 static void sky2_tx_timeout(struct net_device *dev)
 {
 	struct sky2_port *sky2 = netdev_priv(dev);
 	struct sky2_hw *hw = sky2->hw;
 	unsigned txq = txqaddr[sky2->port];
+	u16 ridx;
+
+	/* Maybe we just missed an status interrupt */
+	spin_lock(&sky2->tx_lock);
+	ridx = sky2_read16(hw,
+			   sky2->port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX);
+	sky2_tx_complete(sky2, ridx);
+	spin_unlock(&sky2->tx_lock);
+
+	if (!netif_queue_stopped(dev)) {
+		if (net_ratelimit())
+			pr_info(PFX "transmit interrupt missed? recovered\n");
+		return;
+	}
 
 	if (netif_msg_timer(sky2))
 		printk(KERN_ERR PFX "%s: tx timeout\n", dev->name);
 
-	netif_stop_queue(dev);
-
 	sky2_write32(hw, Q_ADDR(txq, Q_CSR), BMU_STOP);
-	sky2_read32(hw, Q_ADDR(txq, Q_CSR));
-
 	sky2_write32(hw, Y2_QADDR(txq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
 
 	sky2_tx_clean(sky2);
 
 	sky2_qset(hw, txq);
 	sky2_prefetch_init(hw, txq, sky2->tx_le_map, TX_RING_SIZE - 1);
-
-	netif_wake_queue(dev);
 }
 
 
@@ -1713,7 +1755,7 @@ static struct sk_buff *sky2_receive(stru
 	} else {
 		struct sk_buff *nskb;
 
-		nskb = dev_alloc_skb(sky2->rx_bufsize);
+		nskb = sky2_alloc_skb(sky2->rx_bufsize, GFP_ATOMIC);
 		if (!nskb)
 			goto resubmit;
 
@@ -1745,7 +1787,7 @@ oversize:
 error:
 	++sky2->net_stats.rx_errors;
 
-	if (netif_msg_rx_err(sky2))
+	if (netif_msg_rx_err(sky2) && net_ratelimit())
 		printk(KERN_INFO PFX "%s: rx error, status 0x%x length %d\n",
 		       sky2->netdev->name, status, length);
 
@@ -1766,13 +1808,16 @@ error:
  */
 #define TX_NO_STATUS	0xffff
 
-static inline void sky2_tx_check(struct sky2_hw *hw, int port, u16 last)
+static void sky2_tx_check(struct sky2_hw *hw, int port, u16 last)
 {
 	if (last != TX_NO_STATUS) {
 		struct net_device *dev = hw->dev[port];
 		if (dev && netif_running(dev)) {
 			struct sky2_port *sky2 = netdev_priv(dev);
+
+			spin_lock(&sky2->tx_lock);
 			sky2_tx_complete(sky2, last);
+			spin_unlock(&sky2->tx_lock);
 		}
 	}
 }
@@ -1800,7 +1845,6 @@ static int sky2_poll(struct net_device *
 		struct sk_buff *skb;
 		u32 status;
 		u16 length;
-		u8 op;
 
 		le = hw->st_le + hw->st_idx;
 		hw->st_idx = (hw->st_idx + 1) % STATUS_RING_SIZE;
@@ -1814,10 +1858,8 @@ static int sky2_poll(struct net_device *
 		sky2 = netdev_priv(dev);
 		status = le32_to_cpu(le->status);
 		length = le16_to_cpu(le->length);
-		op = le->opcode & ~HW_OWNER;
-		le->opcode = 0;
 
-		switch (op) {
+		switch (le->opcode & ~HW_OWNER) {
 		case OP_RXSTAT:
 			skb = sky2_receive(sky2, length, status);
 			if (!skb)
@@ -1865,14 +1907,13 @@ static int sky2_poll(struct net_device *
 		default:
 			if (net_ratelimit())
 				printk(KERN_WARNING PFX
-				       "unknown status opcode 0x%x\n", op);
+				       "unknown status opcode 0x%x\n", le->opcode);
 			break;
 		}
 	}
 
 exit_loop:
 	sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
-	mmiowb();
 
 	sky2_tx_check(hw, 0, tx_done[0]);
 	sky2_tx_check(hw, 1, tx_done[1]);
@@ -1887,7 +1928,6 @@ exit_loop:
 		netif_rx_complete(dev0);
 		hw->intr_mask |= Y2_IS_STAT_BMU;
 		sky2_write32(hw, B0_IMSK, hw->intr_mask);
-		mmiowb();
 		return 0;
 	} else {
 		*budget -= work_done;
@@ -1900,35 +1940,42 @@ static void sky2_hw_error(struct sky2_hw
 {
 	struct net_device *dev = hw->dev[port];
 
-	printk(KERN_INFO PFX "%s: hw error interrupt status 0x%x\n",
-	       dev->name, status);
+	if (net_ratelimit())
+		printk(KERN_INFO PFX "%s: hw error interrupt status 0x%x\n",
+		       dev->name, status);
 
 	if (status & Y2_IS_PAR_RD1) {
-		printk(KERN_ERR PFX "%s: ram data read parity error\n",
-		       dev->name);
+		if (net_ratelimit())
+			printk(KERN_ERR PFX "%s: ram data read parity error\n",
+			       dev->name);
 		/* Clear IRQ */
 		sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_RD_PERR);
 	}
 
 	if (status & Y2_IS_PAR_WR1) {
-		printk(KERN_ERR PFX "%s: ram data write parity error\n",
-		       dev->name);
+		if (net_ratelimit())
+			printk(KERN_ERR PFX "%s: ram data write parity error\n",
+			       dev->name);
 
 		sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_WR_PERR);
 	}
 
 	if (status & Y2_IS_PAR_MAC1) {
-		printk(KERN_ERR PFX "%s: MAC parity error\n", dev->name);
+		if (net_ratelimit())
+			printk(KERN_ERR PFX "%s: MAC parity error\n", dev->name);
 		sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_PE);
 	}
 
 	if (status & Y2_IS_PAR_RX1) {
-		printk(KERN_ERR PFX "%s: RX parity error\n", dev->name);
+		if (net_ratelimit())
+			printk(KERN_ERR PFX "%s: RX parity error\n", dev->name);
 		sky2_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), BMU_CLR_IRQ_PAR);
 	}
 
 	if (status & Y2_IS_TCP_TXA1) {
-		printk(KERN_ERR PFX "%s: TCP segmentation error\n", dev->name);
+		if (net_ratelimit())
+			printk(KERN_ERR PFX "%s: TCP segmentation error\n",
+			       dev->name);
 		sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_CLR_IRQ_TCP);
 	}
 }
@@ -1944,8 +1991,9 @@ static void sky2_hw_intr(struct sky2_hw 
 		u16 pci_err;
 
 		pci_read_config_word(hw->pdev, PCI_STATUS, &pci_err);
-		printk(KERN_ERR PFX "%s: pci hw error (0x%x)\n",
-		       pci_name(hw->pdev), pci_err);
+		if (net_ratelimit())
+			printk(KERN_ERR PFX "%s: pci hw error (0x%x)\n",
+			       pci_name(hw->pdev), pci_err);
 
 		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
 		pci_write_config_word(hw->pdev, PCI_STATUS,
@@ -1959,8 +2007,9 @@ static void sky2_hw_intr(struct sky2_hw 
 
 		pci_read_config_dword(hw->pdev, PEX_UNC_ERR_STAT, &pex_err);
 
-		printk(KERN_ERR PFX "%s: pci express error (0x%x)\n",
-		       pci_name(hw->pdev), pex_err);
+		if (net_ratelimit())
+			printk(KERN_ERR PFX "%s: pci express error (0x%x)\n",
+			       pci_name(hw->pdev), pex_err);
 
 		/* clear the interrupt */
 		sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
@@ -2250,7 +2299,7 @@ static int sky2_reset(struct sky2_hw *hw
 	return 0;
 }
 
-static inline u32 sky2_supported_modes(const struct sky2_hw *hw)
+static u32 sky2_supported_modes(const struct sky2_hw *hw)
 {
 	u32 modes;
 	if (hw->copper) {
@@ -2995,7 +3044,7 @@ static __devinit struct net_device *sky2
 	return dev;
 }
 
-static inline void sky2_show_addr(struct net_device *dev)
+static void __devinit sky2_show_addr(struct net_device *dev)
 {
 	const struct sky2_port *sky2 = netdev_priv(dev);
 
@@ -3038,13 +3087,17 @@ static int __devinit sky2_probe(struct p
 		goto err_out_free_regions;
 	}
 
-	if (sizeof(dma_addr_t) > sizeof(u32)) {
-		err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
-		if (!err)
-			using_dac = 1;
-	}
+	if (sizeof(dma_addr_t) > sizeof(u32) &&
+	    !(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
+		using_dac = 1;
+		err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+		if (err < 0) {
+			printk(KERN_ERR PFX "%s unable to obtain 64 bit DMA "
+			       "for consistent allocations\n", pci_name(pdev));
+			goto err_out_free_regions;
+		}
 
-	if (!using_dac) {
+	} else {
 		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
 		if (err) {
 			printk(KERN_ERR PFX "%s no usable DMA configuration\n",
@@ -3052,6 +3105,7 @@ static int __devinit sky2_probe(struct p
 			goto err_out_free_regions;
 		}
 	}
+
 #ifdef __BIG_ENDIAN
 	/* byte swap descriptors in hardware */
 	{
@@ -3064,14 +3118,13 @@ static int __devinit sky2_probe(struct p
 #endif
 
 	err = -ENOMEM;
-	hw = kmalloc(sizeof(*hw), GFP_KERNEL);
+	hw = kzalloc(sizeof(*hw), GFP_KERNEL);
 	if (!hw) {
 		printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n",
 		       pci_name(pdev));
 		goto err_out_free_regions;
 	}
 
-	memset(hw, 0, sizeof(*hw));
 	hw->pdev = pdev;
 
 	hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000);
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index 0d765f1..1f5975a 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -22,7 +22,6 @@
  */
 
 #include <linux/config.h>
-
 #include <linux/compiler.h>
 #include <linux/crc32.h>
 #include <linux/delay.h>
@@ -30,6 +29,7 @@
 #include <linux/ethtool.h>
 #include <linux/firmware.h>
 #include <linux/if_vlan.h>
+#include <linux/in.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/ip.h>
@@ -43,6 +43,7 @@
 #include <linux/slab.h>
 #include <linux/tcp.h>
 #include <linux/types.h>
+#include <linux/vmalloc.h>
 #include <linux/wait.h>
 #include <linux/workqueue.h>
 #include <asm/bitops.h>
@@ -108,42 +109,6 @@ spider_net_write_reg(struct spider_net_c
 	writel(value, card->regs + reg);
 }
 
-/**
- * spider_net_write_reg_sync - writes to an SMMIO register of a card
- * @card: device structure
- * @reg: register to write to
- * @value: value to write into the specified SMMIO register
- *
- * Unlike spider_net_write_reg, this will also make sure the
- * data arrives on the card by reading the reg again.
- */
-static void
-spider_net_write_reg_sync(struct spider_net_card *card, u32 reg, u32 value)
-{
-	value = cpu_to_le32(value);
-	writel(value, card->regs + reg);
-	(void)readl(card->regs + reg);
-}
-
-/**
- * spider_net_rx_irq_off - switch off rx irq on this spider card
- * @card: device structure
- *
- * switches off rx irq by masking them out in the GHIINTnMSK register
- */
-static void
-spider_net_rx_irq_off(struct spider_net_card *card)
-{
-	u32 regvalue;
-	unsigned long flags;
-
-	spin_lock_irqsave(&card->intmask_lock, flags);
-	regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK);
-	regvalue &= ~SPIDER_NET_RXINT;
-	spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue);
-	spin_unlock_irqrestore(&card->intmask_lock, flags);
-}
-
 /** spider_net_write_phy - write to phy register
  * @netdev: adapter to be written to
  * @mii_id: id of MII
@@ -199,60 +164,33 @@ spider_net_read_phy(struct net_device *n
 }
 
 /**
- * spider_net_rx_irq_on - switch on rx irq on this spider card
- * @card: device structure
- *
- * switches on rx irq by enabling them in the GHIINTnMSK register
- */
-static void
-spider_net_rx_irq_on(struct spider_net_card *card)
-{
-	u32 regvalue;
-	unsigned long flags;
-
-	spin_lock_irqsave(&card->intmask_lock, flags);
-	regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK);
-	regvalue |= SPIDER_NET_RXINT;
-	spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue);
-	spin_unlock_irqrestore(&card->intmask_lock, flags);
-}
-
-/**
- * spider_net_tx_irq_off - switch off tx irq on this spider card
+ * spider_net_rx_irq_off - switch off rx irq on this spider card
  * @card: device structure
  *
- * switches off tx irq by masking them out in the GHIINTnMSK register
+ * switches off rx irq by masking them out in the GHIINTnMSK register
  */
 static void
-spider_net_tx_irq_off(struct spider_net_card *card)
+spider_net_rx_irq_off(struct spider_net_card *card)
 {
 	u32 regvalue;
-	unsigned long flags;
 
-	spin_lock_irqsave(&card->intmask_lock, flags);
-	regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK);
-	regvalue &= ~SPIDER_NET_TXINT;
-	spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue);
-	spin_unlock_irqrestore(&card->intmask_lock, flags);
+	regvalue = SPIDER_NET_INT0_MASK_VALUE & (~SPIDER_NET_RXINT);
+	spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, regvalue);
 }
 
 /**
- * spider_net_tx_irq_on - switch on tx irq on this spider card
+ * spider_net_rx_irq_on - switch on rx irq on this spider card
  * @card: device structure
  *
- * switches on tx irq by enabling them in the GHIINTnMSK register
+ * switches on rx irq by enabling them in the GHIINTnMSK register
  */
 static void
-spider_net_tx_irq_on(struct spider_net_card *card)
+spider_net_rx_irq_on(struct spider_net_card *card)
 {
 	u32 regvalue;
-	unsigned long flags;
 
-	spin_lock_irqsave(&card->intmask_lock, flags);
-	regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK);
-	regvalue |= SPIDER_NET_TXINT;
-	spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue);
-	spin_unlock_irqrestore(&card->intmask_lock, flags);
+	regvalue = SPIDER_NET_INT0_MASK_VALUE | SPIDER_NET_RXINT;
+	spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, regvalue);
 }
 
 /**
@@ -326,9 +264,8 @@ static enum spider_net_descr_status
 spider_net_get_descr_status(struct spider_net_descr *descr)
 {
 	u32 cmd_status;
-	rmb();
+
 	cmd_status = descr->dmac_cmd_status;
-	rmb();
 	cmd_status >>= SPIDER_NET_DESCR_IND_PROC_SHIFT;
 	/* no need to mask out any bits, as cmd_status is 32 bits wide only
 	 * (and unsigned) */
@@ -349,7 +286,6 @@ spider_net_set_descr_status(struct spide
 {
 	u32 cmd_status;
 	/* read the status */
-	mb();
 	cmd_status = descr->dmac_cmd_status;
 	/* clean the upper 4 bits */
 	cmd_status &= SPIDER_NET_DESCR_IND_PROC_MASKO;
@@ -357,7 +293,6 @@ spider_net_set_descr_status(struct spide
 	cmd_status |= ((u32)status)<<SPIDER_NET_DESCR_IND_PROC_SHIFT;
 	/* and write it back */
 	descr->dmac_cmd_status = cmd_status;
-	wmb();
 }
 
 /**
@@ -398,8 +333,9 @@ spider_net_init_chain(struct spider_net_
 {
 	int i;
 	struct spider_net_descr *descr;
+	dma_addr_t buf;
 
-	spin_lock_init(&card->chain_lock);
+	atomic_set(&card->rx_chain_refill,0);
 
 	descr = start_descr;
 	memset(descr, 0, sizeof(*descr) * no);
@@ -408,14 +344,14 @@ spider_net_init_chain(struct spider_net_
 	for (i=0; i<no; i++, descr++) {
 		spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE);
 
-		descr->bus_addr =
-			pci_map_single(card->pdev, descr,
-				       SPIDER_NET_DESCR_SIZE,
-				       PCI_DMA_BIDIRECTIONAL);
+		buf = pci_map_single(card->pdev, descr,
+				     SPIDER_NET_DESCR_SIZE,
+				     PCI_DMA_BIDIRECTIONAL);
 
-		if (descr->bus_addr == DMA_ERROR_CODE)
+		if (buf == DMA_ERROR_CODE)
 			goto iommu_error;
 
+		descr->bus_addr = buf;
 		descr->next = descr + 1;
 		descr->prev = descr - 1;
 
@@ -439,7 +375,8 @@ iommu_error:
 	for (i=0; i < no; i++, descr++)
 		if (descr->bus_addr)
 			pci_unmap_single(card->pdev, descr->bus_addr,
-					 SPIDER_NET_DESCR_SIZE, PCI_DMA_BIDIRECTIONAL);
+					 SPIDER_NET_DESCR_SIZE,
+					 PCI_DMA_BIDIRECTIONAL);
 	return -ENOMEM;
 }
 
@@ -459,7 +396,7 @@ spider_net_free_rx_chain_contents(struct
 		if (descr->skb) {
 			dev_kfree_skb(descr->skb);
 			pci_unmap_single(card->pdev, descr->buf_addr,
-					 SPIDER_NET_MAX_MTU,
+					 SPIDER_NET_MAX_FRAME,
 					 PCI_DMA_BIDIRECTIONAL);
 		}
 		descr = descr->next;
@@ -480,12 +417,13 @@ static int
 spider_net_prepare_rx_descr(struct spider_net_card *card,
 			    struct spider_net_descr *descr)
 {
+	dma_addr_t buf;
 	int error = 0;
 	int offset;
 	int bufsize;
 
 	/* we need to round up the buffer size to a multiple of 128 */
-	bufsize = (SPIDER_NET_MAX_MTU + SPIDER_NET_RXBUF_ALIGN - 1) &
+	bufsize = (SPIDER_NET_MAX_FRAME + SPIDER_NET_RXBUF_ALIGN - 1) &
 		(~(SPIDER_NET_RXBUF_ALIGN - 1));
 
 	/* and we need to have it 128 byte aligned, therefore we allocate a
@@ -493,10 +431,8 @@ spider_net_prepare_rx_descr(struct spide
 	/* allocate an skb */
 	descr->skb = dev_alloc_skb(bufsize + SPIDER_NET_RXBUF_ALIGN - 1);
 	if (!descr->skb) {
-		if (net_ratelimit())
-			if (netif_msg_rx_err(card))
-				pr_err("Not enough memory to allocate "
-					"rx buffer\n");
+		if (netif_msg_rx_err(card) && net_ratelimit())
+			pr_err("Not enough memory to allocate rx buffer\n");
 		return -ENOMEM;
 	}
 	descr->buf_size = bufsize;
@@ -510,12 +446,12 @@ spider_net_prepare_rx_descr(struct spide
 	if (offset)
 		skb_reserve(descr->skb, SPIDER_NET_RXBUF_ALIGN - offset);
 	/* io-mmu-map the skb */
-	descr->buf_addr = pci_map_single(card->pdev, descr->skb->data,
-					 SPIDER_NET_MAX_MTU,
-					 PCI_DMA_BIDIRECTIONAL);
-	if (descr->buf_addr == DMA_ERROR_CODE) {
+	buf = pci_map_single(card->pdev, descr->skb->data,
+			     SPIDER_NET_MAX_FRAME, PCI_DMA_BIDIRECTIONAL);
+	descr->buf_addr = buf;
+	if (buf == DMA_ERROR_CODE) {
 		dev_kfree_skb_any(descr->skb);
-		if (netif_msg_rx_err(card))
+		if (netif_msg_rx_err(card) && net_ratelimit())
 			pr_err("Could not iommu-map rx buffer\n");
 		spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE);
 	} else {
@@ -526,10 +462,10 @@ spider_net_prepare_rx_descr(struct spide
 }
 
 /**
- * spider_net_enable_rxctails - sets RX dmac chain tail addresses
+ * spider_net_enable_rxchtails - sets RX dmac chain tail addresses
  * @card: card structure
  *
- * spider_net_enable_rxctails sets the RX DMAC chain tail adresses in the
+ * spider_net_enable_rxchtails sets the RX DMAC chain tail adresses in the
  * chip by writing to the appropriate register. DMA is enabled in
  * spider_net_enable_rxdmac.
  */
@@ -551,6 +487,7 @@ spider_net_enable_rxchtails(struct spide
 static void
 spider_net_enable_rxdmac(struct spider_net_card *card)
 {
+	wmb();
 	spider_net_write_reg(card, SPIDER_NET_GDADMACCNTR,
 			     SPIDER_NET_DMA_RX_VALUE);
 }
@@ -559,32 +496,28 @@ spider_net_enable_rxdmac(struct spider_n
  * spider_net_refill_rx_chain - refills descriptors/skbs in the rx chains
  * @card: card structure
  *
- * refills descriptors in all chains (last used chain first): allocates skbs
- * and iommu-maps them.
+ * refills descriptors in the rx chain: allocates skbs and iommu-maps them.
  */
 static void
 spider_net_refill_rx_chain(struct spider_net_card *card)
 {
 	struct spider_net_descr_chain *chain;
-	int count = 0;
-	unsigned long flags;
 
 	chain = &card->rx_chain;
 
-	spin_lock_irqsave(&card->chain_lock, flags);
-	while (spider_net_get_descr_status(chain->head) ==
-				SPIDER_NET_DESCR_NOT_IN_USE) {
-		if (spider_net_prepare_rx_descr(card, chain->head))
-			break;
-		count++;
-		chain->head = chain->head->next;
-	}
-	spin_unlock_irqrestore(&card->chain_lock, flags);
+	/* one context doing the refill (and a second context seeing that
+	 * and omitting it) is ok. If called by NAPI, we'll be called again
+	 * as spider_net_decode_one_descr is called several times. If some
+	 * interrupt calls us, the NAPI is about to clean up anyway. */
+	if (atomic_inc_return(&card->rx_chain_refill) == 1)
+		while (spider_net_get_descr_status(chain->head) ==
+		       SPIDER_NET_DESCR_NOT_IN_USE) {
+			if (spider_net_prepare_rx_descr(card, chain->head))
+				break;
+			chain->head = chain->head->next;
+		}
 
-	/* could be optimized, only do that, if we know the DMA processing
-	 * has terminated */
-	if (count)
-		spider_net_enable_rxdmac(card);
+	atomic_dec(&card->rx_chain_refill);
 }
 
 /**
@@ -613,6 +546,7 @@ spider_net_alloc_rx_skbs(struct spider_n
 	/* this will allocate the rest of the rx buffers; if not, it's
 	 * business as usual later on */
 	spider_net_refill_rx_chain(card);
+	spider_net_enable_rxdmac(card);
 	return 0;
 
 error:
@@ -649,24 +583,30 @@ spider_net_release_tx_descr(struct spide
  * @card: adapter structure
  * @brutal: if set, don't care about whether descriptor seems to be in use
  *
- * releases the tx descriptors that spider has finished with (if non-brutal)
- * or simply release tx descriptors (if brutal)
+ * returns 0 if the tx ring is empty, otherwise 1.
+ *
+ * spider_net_release_tx_chain releases the tx descriptors that spider has
+ * finished with (if non-brutal) or simply release tx descriptors (if brutal).
+ * If some other context is calling this function, we return 1 so that we're
+ * scheduled again (if we were scheduled) and will not loose initiative.
  */
-static void
+static int
 spider_net_release_tx_chain(struct spider_net_card *card, int brutal)
 {
 	struct spider_net_descr_chain *tx_chain = &card->tx_chain;
 	enum spider_net_descr_status status;
 
-	spider_net_tx_irq_off(card);
+	if (atomic_inc_return(&card->tx_chain_release) != 1) {
+		atomic_dec(&card->tx_chain_release);
+		return 1;
+	}
 
-	/* no lock for chain needed, if this is only executed once at a time */
-again:
 	for (;;) {
 		status = spider_net_get_descr_status(tx_chain->tail);
 		switch (status) {
 		case SPIDER_NET_DESCR_CARDOWNED:
-			if (!brutal) goto out;
+			if (!brutal)
+				goto out;
 			/* fallthrough, if we release the descriptors
 			 * brutally (then we don't care about
 			 * SPIDER_NET_DESCR_CARDOWNED) */
@@ -693,25 +633,30 @@ again:
 		tx_chain->tail = tx_chain->tail->next;
 	}
 out:
+	atomic_dec(&card->tx_chain_release);
+
 	netif_wake_queue(card->netdev);
 
-	if (!brutal) {
-		/* switch on tx irqs (while we are still in the interrupt
-		 * handler, so we don't get an interrupt), check again
-		 * for done descriptors. This results in fewer interrupts */
-		spider_net_tx_irq_on(card);
-		status = spider_net_get_descr_status(tx_chain->tail);
-		switch (status) {
-			case SPIDER_NET_DESCR_RESPONSE_ERROR:
-			case SPIDER_NET_DESCR_PROTECTION_ERROR:
-			case SPIDER_NET_DESCR_FORCE_END:
-			case SPIDER_NET_DESCR_COMPLETE:
-				goto again;
-			default:
-				break;
-		}
-	}
+	if (status == SPIDER_NET_DESCR_CARDOWNED)
+		return 1;
+	return 0;
+}
 
+/**
+ * spider_net_cleanup_tx_ring - cleans up the TX ring
+ * @card: card structure
+ *
+ * spider_net_cleanup_tx_ring is called by the tx_timer (as we don't use
+ * interrupts to cleanup our TX ring) and returns sent packets to the stack
+ * by freeing them
+ */
+static void
+spider_net_cleanup_tx_ring(struct spider_net_card *card)
+{
+	if ( (spider_net_release_tx_chain(card, 0)) &&
+	      (card->netdev->flags & IFF_UP) ) {
+		mod_timer(&card->tx_timer, jiffies + SPIDER_NET_TX_TIMER);
+	}
 }
 
 /**
@@ -726,16 +671,22 @@ out:
 static u8
 spider_net_get_multicast_hash(struct net_device *netdev, __u8 *addr)
 {
-	/* FIXME: an addr of 01:00:5e:00:00:01 must result in 0xa9,
-	 * ff:ff:ff:ff:ff:ff must result in 0xfd */
 	u32 crc;
 	u8 hash;
+	char addr_for_crc[ETH_ALEN] = { 0, };
+	int i, bit;
 
-	crc = crc32_be(~0, addr, netdev->addr_len);
+	for (i = 0; i < ETH_ALEN * 8; i++) {
+		bit = (addr[i / 8] >> (i % 8)) & 1;
+		addr_for_crc[ETH_ALEN - 1 - i / 8] += bit << (7 - (i % 8));
+	}
+
+	crc = crc32_be(~0, addr_for_crc, netdev->addr_len);
 
 	hash = (crc >> 27);
 	hash <<= 3;
 	hash |= crc & 7;
+	hash &= 0xff;
 
 	return hash;
 }
@@ -821,9 +772,11 @@ spider_net_stop(struct net_device *netde
 {
 	struct spider_net_card *card = netdev_priv(netdev);
 
+	tasklet_kill(&card->rxram_full_tl);
 	netif_poll_disable(netdev);
 	netif_carrier_off(netdev);
 	netif_stop_queue(netdev);
+	del_timer_sync(&card->tx_timer);
 
 	/* disable/mask all interrupts */
 	spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0);
@@ -872,13 +825,15 @@ spider_net_get_next_tx_descr(struct spid
  * @skb: packet to consider
  *
  * fills out the command and status field of the descriptor structure,
- * depending on hardware checksum settings. This function assumes a wmb()
- * has executed before.
+ * depending on hardware checksum settings.
  */
 static void
 spider_net_set_txdescr_cmdstat(struct spider_net_descr *descr,
 			       struct sk_buff *skb)
 {
+	/* make sure the other fields in the descriptor are written */
+	wmb();
+
 	if (skb->ip_summed != CHECKSUM_HW) {
 		descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_NOCS;
 		return;
@@ -887,14 +842,13 @@ spider_net_set_txdescr_cmdstat(struct sp
 	/* is packet ip?
 	 * if yes: tcp? udp? */
 	if (skb->protocol == htons(ETH_P_IP)) {
-		if (skb->nh.iph->protocol == IPPROTO_TCP) {
+		if (skb->nh.iph->protocol == IPPROTO_TCP)
 			descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_TCPCS;
-		} else if (skb->nh.iph->protocol == IPPROTO_UDP) {
+		else if (skb->nh.iph->protocol == IPPROTO_UDP)
 			descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_UDPCS;
-		} else { /* the stack should checksum non-tcp and non-udp
-			    packets on his own: NETIF_F_IP_CSUM */
+		else /* the stack should checksum non-tcp and non-udp
+			packets on his own: NETIF_F_IP_CSUM */
 			descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_NOCS;
-		}
 	}
 }
 
@@ -914,23 +868,22 @@ spider_net_prepare_tx_descr(struct spide
 			    struct spider_net_descr *descr,
 			    struct sk_buff *skb)
 {
-	descr->buf_addr = pci_map_single(card->pdev, skb->data,
-					 skb->len, PCI_DMA_BIDIRECTIONAL);
-	if (descr->buf_addr == DMA_ERROR_CODE) {
-		if (netif_msg_tx_err(card))
+	dma_addr_t buf;
+
+	buf = pci_map_single(card->pdev, skb->data,
+			     skb->len, PCI_DMA_BIDIRECTIONAL);
+	if (buf == DMA_ERROR_CODE) {
+		if (netif_msg_tx_err(card) && net_ratelimit())
 			pr_err("could not iommu-map packet (%p, %i). "
 				  "Dropping packet\n", skb->data, skb->len);
 		return -ENOMEM;
 	}
 
+	descr->buf_addr = buf;
 	descr->buf_size = skb->len;
 	descr->skb = skb;
 	descr->data_status = 0;
 
-	/* make sure the above values are in memory before we change the
-	 * status */
-	wmb();
-
 	spider_net_set_txdescr_cmdstat(descr,skb);
 
 	return 0;
@@ -972,17 +925,12 @@ spider_net_xmit(struct sk_buff *skb, str
 	struct spider_net_descr *descr;
 	int result;
 
-	descr = spider_net_get_next_tx_descr(card);
+	spider_net_release_tx_chain(card, 0);
 
-	if (!descr) {
-		netif_stop_queue(netdev);
+	descr = spider_net_get_next_tx_descr(card);
 
-		descr = spider_net_get_next_tx_descr(card);
-		if (!descr)
-			goto error;
-		else
-			netif_start_queue(netdev);
-	}
+	if (!descr)
+		goto error;
 
 	result = spider_net_prepare_tx_descr(card, descr, skb);
 	if (result)
@@ -990,19 +938,25 @@ spider_net_xmit(struct sk_buff *skb, str
 
 	card->tx_chain.head = card->tx_chain.head->next;
 
-	/* make sure the status from spider_net_prepare_tx_descr is in
-	 * memory before we check out the previous descriptor */
-	wmb();
-
 	if (spider_net_get_descr_status(descr->prev) !=
-	    SPIDER_NET_DESCR_CARDOWNED)
-		spider_net_kick_tx_dma(card, descr);
+	    SPIDER_NET_DESCR_CARDOWNED) {
+		/* make sure the current descriptor is in memory. Then
+		 * kicking it on again makes sense, if the previous is not
+		 * card-owned anymore. Check the previous descriptor twice
+		 * to omit an mb() in heavy traffic cases */
+		mb();
+		if (spider_net_get_descr_status(descr->prev) !=
+		    SPIDER_NET_DESCR_CARDOWNED)
+			spider_net_kick_tx_dma(card, descr);
+	}
+
+	mod_timer(&card->tx_timer, jiffies + SPIDER_NET_TX_TIMER);
 
 	return NETDEV_TX_OK;
 
 error:
 	card->netdev_stats.tx_dropped++;
-	return NETDEV_TX_LOCKED;
+	return NETDEV_TX_BUSY;
 }
 
 /**
@@ -1027,6 +981,7 @@ spider_net_do_ioctl(struct net_device *n
  * spider_net_pass_skb_up - takes an skb from a descriptor and passes it on
  * @descr: descriptor to process
  * @card: card structure
+ * @napi: whether caller is in NAPI context
  *
  * returns 1 on success, 0 if no packet was passed to the stack
  *
@@ -1035,7 +990,7 @@ spider_net_do_ioctl(struct net_device *n
  */
 static int
 spider_net_pass_skb_up(struct spider_net_descr *descr,
-		       struct spider_net_card *card)
+		       struct spider_net_card *card, int napi)
 {
 	struct sk_buff *skb;
 	struct net_device *netdev;
@@ -1046,22 +1001,20 @@ spider_net_pass_skb_up(struct spider_net
 
 	netdev = card->netdev;
 
-	/* check for errors in the data_error flag */
-	if ((data_error & SPIDER_NET_DATA_ERROR_MASK) &&
-	    netif_msg_rx_err(card))
-		pr_err("error in received descriptor found, "
-		       "data_status=x%08x, data_error=x%08x\n",
-		       data_status, data_error);
-
-	/* prepare skb, unmap descriptor */
-	skb = descr->skb;
-	pci_unmap_single(card->pdev, descr->buf_addr, SPIDER_NET_MAX_MTU,
+	/* unmap descriptor */
+	pci_unmap_single(card->pdev, descr->buf_addr, SPIDER_NET_MAX_FRAME,
 			 PCI_DMA_BIDIRECTIONAL);
 
 	/* the cases we'll throw away the packet immediately */
-	if (data_error & SPIDER_NET_DESTROY_RX_FLAGS)
+	if (data_error & SPIDER_NET_DESTROY_RX_FLAGS) {
+		if (netif_msg_rx_err(card))
+			pr_err("error in received descriptor found, "
+			       "data_status=x%08x, data_error=x%08x\n",
+			       data_status, data_error);
 		return 0;
+	}
 
+	skb = descr->skb;
 	skb->dev = netdev;
 	skb_put(skb, descr->valid_size);
 
@@ -1073,14 +1026,14 @@ spider_net_pass_skb_up(struct spider_net
 
 	/* checksum offload */
 	if (card->options.rx_csum) {
-		if ( (data_status & SPIDER_NET_DATA_STATUS_CHK_MASK) &&
-		     (!(data_error & SPIDER_NET_DATA_ERROR_CHK_MASK)) )
+		if ( ( (data_status & SPIDER_NET_DATA_STATUS_CKSUM_MASK) ==
+		       SPIDER_NET_DATA_STATUS_CKSUM_MASK) &&
+		     !(data_error & SPIDER_NET_DATA_ERR_CKSUM_MASK))
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 		else
 			skb->ip_summed = CHECKSUM_NONE;
-	} else {
+	} else
 		skb->ip_summed = CHECKSUM_NONE;
-	}
 
 	if (data_status & SPIDER_NET_VLAN_PACKET) {
 		/* further enhancements: HW-accel VLAN
@@ -1089,7 +1042,10 @@ spider_net_pass_skb_up(struct spider_net
 	}
 
 	/* pass skb up to stack */
-	netif_receive_skb(skb);
+	if (napi)
+		netif_receive_skb(skb);
+	else
+		netif_rx_ni(skb);
 
 	/* update netdevice statistics */
 	card->netdev_stats.rx_packets++;
@@ -1099,16 +1055,18 @@ spider_net_pass_skb_up(struct spider_net
 }
 
 /**
- * spider_net_decode_descr - processes an rx descriptor
+ * spider_net_decode_one_descr - processes an rx descriptor
  * @card: card structure
+ * @napi: whether caller is in NAPI context
  *
  * returns 1 if a packet has been sent to the stack, otherwise 0
  *
  * processes an rx descriptor by iommu-unmapping the data buffer and passing
- * the packet up to the stack
+ * the packet up to the stack. This function is called in softirq
+ * context, e.g. either bottom half from interrupt or NAPI polling context
  */
 static int
-spider_net_decode_one_descr(struct spider_net_card *card)
+spider_net_decode_one_descr(struct spider_net_card *card, int napi)
 {
 	enum spider_net_descr_status status;
 	struct spider_net_descr *descr;
@@ -1122,17 +1080,19 @@ spider_net_decode_one_descr(struct spide
 
 	if (status == SPIDER_NET_DESCR_CARDOWNED) {
 		/* nothing in the descriptor yet */
-		return 0;
+		result=0;
+		goto out;
 	}
 
 	if (status == SPIDER_NET_DESCR_NOT_IN_USE) {
-		/* not initialized yet, I bet chain->tail == chain->head
-		 * and the ring is empty */
+		/* not initialized yet, the ring must be empty */
 		spider_net_refill_rx_chain(card);
-		return 0;
+		spider_net_enable_rxdmac(card);
+		result=0;
+		goto out;
 	}
 
-	/* descriptor definitively used -- move on head */
+	/* descriptor definitively used -- move on tail */
 	chain->tail = descr->next;
 
 	result = 0;
@@ -1143,6 +1103,9 @@ spider_net_decode_one_descr(struct spide
 			pr_err("%s: dropping RX descriptor with state %d\n",
 			       card->netdev->name, status);
 		card->netdev_stats.rx_dropped++;
+		pci_unmap_single(card->pdev, descr->buf_addr,
+				 SPIDER_NET_MAX_FRAME, PCI_DMA_BIDIRECTIONAL);
+		dev_kfree_skb_irq(descr->skb);
 		goto refill;
 	}
 
@@ -1155,12 +1118,13 @@ spider_net_decode_one_descr(struct spide
 	}
 
 	/* ok, we've got a packet in descr */
-	result = spider_net_pass_skb_up(descr, card);
+	result = spider_net_pass_skb_up(descr, card, napi);
 refill:
 	spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE);
 	/* change the descriptor state: */
-	spider_net_refill_rx_chain(card);
-
+	if (!napi)
+		spider_net_refill_rx_chain(card);
+out:
 	return result;
 }
 
@@ -1186,7 +1150,7 @@ spider_net_poll(struct net_device *netde
 	packets_to_do = min(*budget, netdev->quota);
 
 	while (packets_to_do) {
-		if (spider_net_decode_one_descr(card)) {
+		if (spider_net_decode_one_descr(card, 1)) {
 			packets_done++;
 			packets_to_do--;
 		} else {
@@ -1198,6 +1162,7 @@ spider_net_poll(struct net_device *netde
 
 	netdev->quota -= packets_done;
 	*budget -= packets_done;
+	spider_net_refill_rx_chain(card);
 
 	/* if all packets are in the stack, enable interrupts and return 0 */
 	/* if not, return 1 */
@@ -1342,6 +1307,24 @@ spider_net_enable_txdmac(struct spider_n
 }
 
 /**
+ * spider_net_handle_rxram_full - cleans up RX ring upon RX RAM full interrupt
+ * @card: card structure
+ *
+ * spider_net_handle_rxram_full empties the RX ring so that spider can put
+ * more packets in it and empty its RX RAM. This is called in bottom half
+ * context
+ */
+static void
+spider_net_handle_rxram_full(struct spider_net_card *card)
+{
+	while (spider_net_decode_one_descr(card, 0))
+		;
+	spider_net_enable_rxchtails(card);
+	spider_net_enable_rxdmac(card);
+	netif_rx_schedule(card->netdev);
+}
+
+/**
  * spider_net_handle_error_irq - handles errors raised by an interrupt
  * @card: card structure
  * @status_reg: interrupt status register 0 (GHIINT0STS)
@@ -1449,17 +1432,21 @@ spider_net_handle_error_irq(struct spide
 				switch (i)
 	{
 	case SPIDER_NET_GTMFLLINT:
-		if (netif_msg_intr(card))
+		if (netif_msg_intr(card) && net_ratelimit())
 			pr_err("Spider TX RAM full\n");
 		show_error = 0;
 		break;
+	case SPIDER_NET_GRFDFLLINT: /* fallthrough */
+	case SPIDER_NET_GRFCFLLINT: /* fallthrough */
+	case SPIDER_NET_GRFBFLLINT: /* fallthrough */
+	case SPIDER_NET_GRFAFLLINT: /* fallthrough */
 	case SPIDER_NET_GRMFLLINT:
-		if (netif_msg_intr(card))
+		if (netif_msg_intr(card) && net_ratelimit())
 			pr_err("Spider RX RAM full, incoming packets "
-			       "might be discarded !\n");
-		netif_rx_schedule(card->netdev);
-		spider_net_enable_rxchtails(card);
-		spider_net_enable_rxdmac(card);
+			       "might be discarded!\n");
+		spider_net_rx_irq_off(card);
+		tasklet_schedule(&card->rxram_full_tl);
+		show_error = 0;
 		break;
 
 	/* case SPIDER_NET_GTMSHTINT: problem, print a message */
@@ -1467,10 +1454,6 @@ spider_net_handle_error_irq(struct spide
 		/* allrighty. tx from previous descr ok */
 		show_error = 0;
 		break;
-	/* case SPIDER_NET_GRFDFLLINT: print a message down there */
-	/* case SPIDER_NET_GRFCFLLINT: print a message down there */
-	/* case SPIDER_NET_GRFBFLLINT: print a message down there */
-	/* case SPIDER_NET_GRFAFLLINT: print a message down there */
 
 	/* chain end */
 	case SPIDER_NET_GDDDCEINT: /* fallthrough */
@@ -1482,6 +1465,7 @@ spider_net_handle_error_irq(struct spide
 			       "restarting DMAC %c.\n",
 			       'D'+i-SPIDER_NET_GDDDCEINT);
 		spider_net_refill_rx_chain(card);
+		spider_net_enable_rxdmac(card);
 		show_error = 0;
 		break;
 
@@ -1492,6 +1476,7 @@ spider_net_handle_error_irq(struct spide
 	case SPIDER_NET_GDAINVDINT:
 		/* could happen when rx chain is full */
 		spider_net_refill_rx_chain(card);
+		spider_net_enable_rxdmac(card);
 		show_error = 0;
 		break;
 
@@ -1580,17 +1565,13 @@ spider_net_interrupt(int irq, void *ptr,
 	if (!status_reg)
 		return IRQ_NONE;
 
-	if (status_reg & SPIDER_NET_TXINT)
-		spider_net_release_tx_chain(card, 0);
-
 	if (status_reg & SPIDER_NET_RXINT ) {
 		spider_net_rx_irq_off(card);
 		netif_rx_schedule(netdev);
 	}
 
-	/* we do this after rx and tx processing, as we want the tx chain
-	 * processed to see, whether we should restart tx dma processing */
-	spider_net_handle_error_irq(card, status_reg);
+	if (status_reg & SPIDER_NET_ERRINT )
+		spider_net_handle_error_irq(card, status_reg);
 
 	/* clear interrupt sources */
 	spider_net_write_reg(card, SPIDER_NET_GHIINT0STS, status_reg);
@@ -1831,34 +1812,40 @@ spider_net_setup_phy(struct spider_net_c
 /**
  * spider_net_download_firmware - loads firmware into the adapter
  * @card: card structure
- * @firmware: firmware pointer
+ * @firmware_ptr: pointer to firmware data
  *
- * spider_net_download_firmware loads the firmware opened by
- * spider_net_init_firmware into the adapter.
+ * spider_net_download_firmware loads the firmware data into the
+ * adapter. It assumes the length etc. to be allright.
  */
-static void
+static int
 spider_net_download_firmware(struct spider_net_card *card,
-			     const struct firmware *firmware)
+			     u8 *firmware_ptr)
 {
 	int sequencer, i;
-	u32 *fw_ptr = (u32 *)firmware->data;
+	u32 *fw_ptr = (u32 *)firmware_ptr;
 
 	/* stop sequencers */
 	spider_net_write_reg(card, SPIDER_NET_GSINIT,
 			     SPIDER_NET_STOP_SEQ_VALUE);
 
-	for (sequencer = 0; sequencer < 6; sequencer++) {
+	for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS;
+	     sequencer++) {
 		spider_net_write_reg(card,
 				     SPIDER_NET_GSnPRGADR + sequencer * 8, 0);
-		for (i = 0; i < SPIDER_NET_FIRMWARE_LEN; i++) {
+		for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) {
 			spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT +
 					     sequencer * 8, *fw_ptr);
 			fw_ptr++;
 		}
 	}
 
+	if (spider_net_read_reg(card, SPIDER_NET_GSINIT))
+		return -EIO;
+
 	spider_net_write_reg(card, SPIDER_NET_GSINIT,
 			     SPIDER_NET_RUN_SEQ_VALUE);
+
+	return 0;
 }
 
 /**
@@ -1890,31 +1877,53 @@ spider_net_download_firmware(struct spid
 static int
 spider_net_init_firmware(struct spider_net_card *card)
 {
-	const struct firmware *firmware;
-	int err = -EIO;
+	struct firmware *firmware = NULL;
+	struct device_node *dn;
+	u8 *fw_prop = NULL;
+	int err = -ENOENT;
+	int fw_size;
+
+	if (request_firmware((const struct firmware **)&firmware,
+			     SPIDER_NET_FIRMWARE_NAME, &card->pdev->dev) == 0) {
+		if ( (firmware->size != SPIDER_NET_FIRMWARE_LEN) &&
+		     netif_msg_probe(card) ) {
+			pr_err("Incorrect size of spidernet firmware in " \
+			       "filesystem. Looking in host firmware...\n");
+			goto try_host_fw;
+		}
+		err = spider_net_download_firmware(card, firmware->data);
 
-	if (request_firmware(&firmware,
-			     SPIDER_NET_FIRMWARE_NAME, &card->pdev->dev) < 0) {
-		if (netif_msg_probe(card))
-			pr_err("Couldn't read in sequencer data file %s.\n",
-			       SPIDER_NET_FIRMWARE_NAME);
-		firmware = NULL;
-		goto out;
-	}
+		release_firmware(firmware);
+		if (err)
+			goto try_host_fw;
 
-	if (firmware->size != 6 * SPIDER_NET_FIRMWARE_LEN * sizeof(u32)) {
-		if (netif_msg_probe(card))
-			pr_err("Invalid size of sequencer data file %s.\n",
-			       SPIDER_NET_FIRMWARE_NAME);
-		goto out;
+		goto done;
 	}
 
-	spider_net_download_firmware(card, firmware);
+try_host_fw:
+	dn = pci_device_to_OF_node(card->pdev);
+	if (!dn)
+		goto out_err;
 
-	err = 0;
-out:
-	release_firmware(firmware);
+	fw_prop = (u8 *)get_property(dn, "firmware", &fw_size);
+	if (!fw_prop)
+		goto out_err;
+
+	if ( (fw_size != SPIDER_NET_FIRMWARE_LEN) &&
+	     netif_msg_probe(card) ) {
+		pr_err("Incorrect size of spidernet firmware in " \
+		       "host firmware\n");
+		goto done;
+	}
 
+	err = spider_net_download_firmware(card, fw_prop);
+
+done:
+	return err;
+out_err:
+	if (netif_msg_probe(card))
+		pr_err("Couldn't find spidernet firmware in filesystem " \
+		       "or host firmware\n");
 	return err;
 }
 
@@ -1934,10 +1943,11 @@ spider_net_workaround_rxramfull(struct s
 			     SPIDER_NET_CKRCTRL_RUN_VALUE);
 
 	/* empty sequencer data */
-	for (sequencer = 0; sequencer < 6; sequencer++) {
+	for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS;
+	     sequencer++) {
 		spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT +
 				     sequencer * 8, 0x0);
-		for (i = 0; i < SPIDER_NET_FIRMWARE_LEN; i++) {
+		for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) {
 			spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT +
 					     sequencer * 8, 0x0);
 		}
@@ -2061,7 +2071,15 @@ spider_net_setup_netdev(struct spider_ne
 	SET_NETDEV_DEV(netdev, &card->pdev->dev);
 
 	pci_set_drvdata(card->pdev, netdev);
-	spin_lock_init(&card->intmask_lock);
+
+	atomic_set(&card->tx_chain_release,0);
+	card->rxram_full_tl.data = (unsigned long) card;
+	card->rxram_full_tl.func =
+		(void (*)(unsigned long)) spider_net_handle_rxram_full;
+	init_timer(&card->tx_timer);
+	card->tx_timer.function =
+		(void (*)(unsigned long)) spider_net_cleanup_tx_ring;
+	card->tx_timer.data = (unsigned long) card;
 	netdev->irq = card->pdev->irq;
 
 	card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT;
diff --git a/drivers/net/spider_net.h b/drivers/net/spider_net.h
index 22b2f23..5922b52 100644
--- a/drivers/net/spider_net.h
+++ b/drivers/net/spider_net.h
@@ -33,25 +33,32 @@ extern struct ethtool_ops spider_net_eth
 
 extern char spider_net_driver_name[];
 
-#define SPIDER_NET_MAX_MTU			2308
+#define SPIDER_NET_MAX_FRAME			2312
+#define SPIDER_NET_MAX_MTU			2294
 #define SPIDER_NET_MIN_MTU			64
 
 #define SPIDER_NET_RXBUF_ALIGN			128
 
-#define SPIDER_NET_RX_DESCRIPTORS_DEFAULT	64
+#define SPIDER_NET_RX_DESCRIPTORS_DEFAULT	256
 #define SPIDER_NET_RX_DESCRIPTORS_MIN		16
-#define SPIDER_NET_RX_DESCRIPTORS_MAX		256
+#define SPIDER_NET_RX_DESCRIPTORS_MAX		512
 
-#define SPIDER_NET_TX_DESCRIPTORS_DEFAULT	64
+#define SPIDER_NET_TX_DESCRIPTORS_DEFAULT	256
 #define SPIDER_NET_TX_DESCRIPTORS_MIN		16
-#define SPIDER_NET_TX_DESCRIPTORS_MAX		256
+#define SPIDER_NET_TX_DESCRIPTORS_MAX		512
+
+#define SPIDER_NET_TX_TIMER			20
 
 #define SPIDER_NET_RX_CSUM_DEFAULT		1
 
-#define SPIDER_NET_WATCHDOG_TIMEOUT 5*HZ
-#define SPIDER_NET_NAPI_WEIGHT 64
+#define SPIDER_NET_WATCHDOG_TIMEOUT		50*HZ
+#define SPIDER_NET_NAPI_WEIGHT			64
 
-#define SPIDER_NET_FIRMWARE_LEN		1024
+#define SPIDER_NET_FIRMWARE_SEQS	6
+#define SPIDER_NET_FIRMWARE_SEQWORDS	1024
+#define SPIDER_NET_FIRMWARE_LEN		(SPIDER_NET_FIRMWARE_SEQS * \
+					 SPIDER_NET_FIRMWARE_SEQWORDS * \
+					 sizeof(u32))
 #define SPIDER_NET_FIRMWARE_NAME	"spider_fw.bin"
 
 /** spider_net SMMIO registers */
@@ -142,14 +149,12 @@ extern char spider_net_driver_name[];
 /** SCONFIG registers */
 #define SPIDER_NET_SCONFIG_IOACTE	0x00002810
 
-/** hardcoded register values */
-#define SPIDER_NET_INT0_MASK_VALUE	0x3f7fe3ff
-#define SPIDER_NET_INT1_MASK_VALUE	0xffffffff
+/** interrupt mask registers */
+#define SPIDER_NET_INT0_MASK_VALUE	0x3f7fe2c7
+#define SPIDER_NET_INT1_MASK_VALUE	0xffff7ff7
 /* no MAC aborts -> auto retransmission */
-#define SPIDER_NET_INT2_MASK_VALUE	0xfffffff1
+#define SPIDER_NET_INT2_MASK_VALUE	0xffef7ff1
 
-/* clear counter when interrupt sources are cleared
-#define SPIDER_NET_FRAMENUM_VALUE	0x0001f001 */
 /* we rely on flagged descriptor interrupts */
 #define SPIDER_NET_FRAMENUM_VALUE	0x00000000
 /* set this first, then the FRAMENUM_VALUE */
@@ -168,7 +173,7 @@ extern char spider_net_driver_name[];
 #if 0
 #define SPIDER_NET_WOL_VALUE		0x00000000
 #endif
-#define SPIDER_NET_IPSECINIT_VALUE	0x00f000f8
+#define SPIDER_NET_IPSECINIT_VALUE	0x6f716f71
 
 /* pause frames: automatic, no upper retransmission count */
 /* outside loopback mode: ETOMOD signal dont matter, not connected */
@@ -318,6 +323,10 @@ enum spider_net_int2_status {
 #define SPIDER_NET_RXINT	( (1 << SPIDER_NET_GDAFDCINT) | \
 				  (1 << SPIDER_NET_GRMFLLINT) )
 
+#define SPIDER_NET_ERRINT	( 0xffffffff & \
+				  (~SPIDER_NET_TXINT) & \
+				  (~SPIDER_NET_RXINT) )
+
 #define SPIDER_NET_GPREXEC		0x80000000
 #define SPIDER_NET_GPRDAT_MASK		0x0000ffff
 
@@ -358,9 +367,6 @@ enum spider_net_int2_status {
 /* descr ready, descr is in middle of chain, get interrupt on completion */
 #define SPIDER_NET_DMAC_RX_CARDOWNED	0xa0800000
 
-/* multicast is no problem */
-#define SPIDER_NET_DATA_ERROR_MASK	0xffffbfff
-
 enum spider_net_descr_status {
 	SPIDER_NET_DESCR_COMPLETE		= 0x00, /* used in rx and tx */
 	SPIDER_NET_DESCR_RESPONSE_ERROR		= 0x01, /* used in rx and tx */
@@ -373,9 +379,9 @@ enum spider_net_descr_status {
 
 struct spider_net_descr {
 	/* as defined by the hardware */
-	dma_addr_t buf_addr;
+	u32 buf_addr;
 	u32 buf_size;
-	dma_addr_t next_descr_addr;
+	u32 next_descr_addr;
 	u32 dmac_cmd_status;
 	u32 result_size;
 	u32 valid_size;	/* all zeroes for tx */
@@ -384,7 +390,7 @@ struct spider_net_descr {
 
 	/* used in the driver */
 	struct sk_buff *skb;
-	dma_addr_t bus_addr;
+	u32 bus_addr;
 	struct spider_net_descr *next;
 	struct spider_net_descr *prev;
 } __attribute__((aligned(32)));
@@ -396,21 +402,21 @@ struct spider_net_descr_chain {
 };
 
 /* descriptor data_status bits */
-#define SPIDER_NET_RXIPCHK		29
-#define SPIDER_NET_TCPUDPIPCHK		28
-#define SPIDER_NET_DATA_STATUS_CHK_MASK	(1 << SPIDER_NET_RXIPCHK | \
-					 1 << SPIDER_NET_TCPUDPIPCHK)
-
+#define SPIDER_NET_RX_IPCHK		29
+#define SPIDER_NET_RX_TCPCHK		28
 #define SPIDER_NET_VLAN_PACKET		21
+#define SPIDER_NET_DATA_STATUS_CKSUM_MASK ( (1 << SPIDER_NET_RX_IPCHK) | \
+					  (1 << SPIDER_NET_RX_TCPCHK) )
 
 /* descriptor data_error bits */
-#define SPIDER_NET_RXIPCHKERR		27
-#define SPIDER_NET_RXTCPCHKERR		26
-#define SPIDER_NET_DATA_ERROR_CHK_MASK	(1 << SPIDER_NET_RXIPCHKERR | \
-					 1 << SPIDER_NET_RXTCPCHKERR)
+#define SPIDER_NET_RX_IPCHKERR		27
+#define SPIDER_NET_RX_RXTCPCHKERR	28
+
+#define SPIDER_NET_DATA_ERR_CKSUM_MASK	(1 << SPIDER_NET_RX_IPCHKERR)
 
-/* the cases we don't pass the packet to the stack */
-#define SPIDER_NET_DESTROY_RX_FLAGS	0x70138000
+/* the cases we don't pass the packet to the stack.
+ * 701b8000 would be correct, but every packets gets that flag */
+#define SPIDER_NET_DESTROY_RX_FLAGS	0x700b8000
 
 #define SPIDER_NET_DESCR_SIZE		32
 
@@ -445,13 +451,16 @@ struct spider_net_card {
 
 	struct spider_net_descr_chain tx_chain;
 	struct spider_net_descr_chain rx_chain;
-	spinlock_t chain_lock;
+	atomic_t rx_chain_refill;
+	atomic_t tx_chain_release;
 
 	struct net_device_stats netdev_stats;
 
 	struct spider_net_options options;
 
 	spinlock_t intmask_lock;
+	struct tasklet_struct rxram_full_tl;
+	struct timer_list tx_timer;
 
 	struct work_struct tx_timeout_task;
 	atomic_t tx_timeout_task_counter;
diff --git a/drivers/net/spider_net_ethtool.c b/drivers/net/spider_net_ethtool.c
index d42e60b..a5bb0b7 100644
--- a/drivers/net/spider_net_ethtool.c
+++ b/drivers/net/spider_net_ethtool.c
@@ -113,6 +113,23 @@ spider_net_ethtool_set_rx_csum(struct ne
 	return 0;
 }
 
+static uint32_t
+spider_net_ethtool_get_tx_csum(struct net_device *netdev)
+{
+        return (netdev->features & NETIF_F_HW_CSUM) != 0;
+}
+
+static int
+spider_net_ethtool_set_tx_csum(struct net_device *netdev, uint32_t data)
+{
+        if (data)
+                netdev->features |= NETIF_F_HW_CSUM;
+        else
+                netdev->features &= ~NETIF_F_HW_CSUM;
+
+        return 0;
+}
+
 struct ethtool_ops spider_net_ethtool_ops = {
 	.get_settings		= spider_net_ethtool_get_settings,
 	.get_drvinfo		= spider_net_ethtool_get_drvinfo,
@@ -122,5 +139,7 @@ struct ethtool_ops spider_net_ethtool_op
 	.nway_reset		= spider_net_ethtool_nway_reset,
 	.get_rx_csum		= spider_net_ethtool_get_rx_csum,
 	.set_rx_csum		= spider_net_ethtool_set_rx_csum,
+	.get_tx_csum		= spider_net_ethtool_get_tx_csum,
+	.set_tx_csum		= spider_net_ethtool_set_tx_csum,
 };
 
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index eb86b05..f2d1daf 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -69,8 +69,8 @@
 
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"3.47"
-#define DRV_MODULE_RELDATE	"Dec 28, 2005"
+#define DRV_MODULE_VERSION	"3.48"
+#define DRV_MODULE_RELDATE	"Jan 16, 2006"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -1325,10 +1325,12 @@ static int tg3_set_power_state(struct tg
 		val &= ~((1 << 16) | (1 << 4) | (1 << 2) | (1 << 1) | 1);
 		tw32(0x7d00, val);
 		if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
-			tg3_nvram_lock(tp);
+			int err;
+
+			err = tg3_nvram_lock(tp);
 			tg3_halt_cpu(tp, RX_CPU_BASE);
-			tw32_f(NVRAM_SWARB, SWARB_REQ_CLR0);
-			tg3_nvram_unlock(tp);
+			if (!err)
+				tg3_nvram_unlock(tp);
 		}
 	}
 
@@ -4193,14 +4195,19 @@ static int tg3_nvram_lock(struct tg3 *tp
 	if (tp->tg3_flags & TG3_FLAG_NVRAM) {
 		int i;
 
-		tw32(NVRAM_SWARB, SWARB_REQ_SET1);
-		for (i = 0; i < 8000; i++) {
-			if (tr32(NVRAM_SWARB) & SWARB_GNT1)
-				break;
-			udelay(20);
+		if (tp->nvram_lock_cnt == 0) {
+			tw32(NVRAM_SWARB, SWARB_REQ_SET1);
+			for (i = 0; i < 8000; i++) {
+				if (tr32(NVRAM_SWARB) & SWARB_GNT1)
+					break;
+				udelay(20);
+			}
+			if (i == 8000) {
+				tw32(NVRAM_SWARB, SWARB_REQ_CLR1);
+				return -ENODEV;
+			}
 		}
-		if (i == 8000)
-			return -ENODEV;
+		tp->nvram_lock_cnt++;
 	}
 	return 0;
 }
@@ -4208,8 +4215,12 @@ static int tg3_nvram_lock(struct tg3 *tp
 /* tp->lock is held. */
 static void tg3_nvram_unlock(struct tg3 *tp)
 {
-	if (tp->tg3_flags & TG3_FLAG_NVRAM)
-		tw32_f(NVRAM_SWARB, SWARB_REQ_CLR1);
+	if (tp->tg3_flags & TG3_FLAG_NVRAM) {
+		if (tp->nvram_lock_cnt > 0)
+			tp->nvram_lock_cnt--;
+		if (tp->nvram_lock_cnt == 0)
+			tw32_f(NVRAM_SWARB, SWARB_REQ_CLR1);
+	}
 }
 
 /* tp->lock is held. */
@@ -4320,8 +4331,13 @@ static int tg3_chip_reset(struct tg3 *tp
 	void (*write_op)(struct tg3 *, u32, u32);
 	int i;
 
-	if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X))
+	if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) {
 		tg3_nvram_lock(tp);
+		/* No matching tg3_nvram_unlock() after this because
+		 * chip reset below will undo the nvram lock.
+		 */
+		tp->nvram_lock_cnt = 0;
+	}
 
 	/*
 	 * We must avoid the readl() that normally takes place.
@@ -4717,6 +4733,10 @@ static int tg3_halt_cpu(struct tg3 *tp, 
 		       (offset == RX_CPU_BASE ? "RX" : "TX"));
 		return -ENODEV;
 	}
+
+	/* Clear firmware's nvram arbitration. */
+	if (tp->tg3_flags & TG3_FLAG_NVRAM)
+		tw32(NVRAM_SWARB, SWARB_REQ_CLR0);
 	return 0;
 }
 
@@ -4736,7 +4756,7 @@ struct fw_info {
 static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_base,
 				 int cpu_scratch_size, struct fw_info *info)
 {
-	int err, i;
+	int err, lock_err, i;
 	void (*write_op)(struct tg3 *, u32, u32);
 
 	if (cpu_base == TX_CPU_BASE &&
@@ -4755,9 +4775,10 @@ static int tg3_load_firmware_cpu(struct 
 	/* It is possible that bootcode is still loading at this point.
 	 * Get the nvram lock first before halting the cpu.
 	 */
-	tg3_nvram_lock(tp);
+	lock_err = tg3_nvram_lock(tp);
 	err = tg3_halt_cpu(tp, cpu_base);
-	tg3_nvram_unlock(tp);
+	if (!lock_err)
+		tg3_nvram_unlock(tp);
 	if (err)
 		goto out;
 
@@ -8182,7 +8203,7 @@ static void tg3_self_test(struct net_dev
 		data[1] = 1;
 	}
 	if (etest->flags & ETH_TEST_FL_OFFLINE) {
-		int irq_sync = 0;
+		int err, irq_sync = 0;
 
 		if (netif_running(dev)) {
 			tg3_netif_stop(tp);
@@ -8192,11 +8213,12 @@ static void tg3_self_test(struct net_dev
 		tg3_full_lock(tp, irq_sync);
 
 		tg3_halt(tp, RESET_KIND_SUSPEND, 1);
-		tg3_nvram_lock(tp);
+		err = tg3_nvram_lock(tp);
 		tg3_halt_cpu(tp, RX_CPU_BASE);
 		if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
 			tg3_halt_cpu(tp, TX_CPU_BASE);
-		tg3_nvram_unlock(tp);
+		if (!err)
+			tg3_nvram_unlock(tp);
 
 		if (tg3_test_registers(tp) != 0) {
 			etest->flags |= ETH_TEST_FL_FAILED;
@@ -8588,7 +8610,11 @@ static void __devinit tg3_nvram_init(str
 	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) {
 		tp->tg3_flags |= TG3_FLAG_NVRAM;
 
-		tg3_nvram_lock(tp);
+		if (tg3_nvram_lock(tp)) {
+			printk(KERN_WARNING PFX "%s: Cannot get nvarm lock, "
+			       "tg3_nvram_init failed.\n", tp->dev->name);
+			return;
+		}
 		tg3_enable_nvram_access(tp);
 
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
@@ -8686,7 +8712,9 @@ static int tg3_nvram_read(struct tg3 *tp
 	if (offset > NVRAM_ADDR_MSK)
 		return -EINVAL;
 
-	tg3_nvram_lock(tp);
+	ret = tg3_nvram_lock(tp);
+	if (ret)
+		return ret;
 
 	tg3_enable_nvram_access(tp);
 
@@ -8785,10 +8813,6 @@ static int tg3_nvram_write_block_unbuffe
 
 		offset = offset + (pagesize - page_off);
 
-		/* Nvram lock released by tg3_nvram_read() above,
-		 * so need to get it again.
-		 */
-		tg3_nvram_lock(tp);
 		tg3_enable_nvram_access(tp);
 
 		/*
@@ -8925,7 +8949,9 @@ static int tg3_nvram_write_block(struct 
 	else {
 		u32 grc_mode;
 
-		tg3_nvram_lock(tp);
+		ret = tg3_nvram_lock(tp);
+		if (ret)
+			return ret;
 
 		tg3_enable_nvram_access(tp);
 		if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 890e163..e824330 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2275,6 +2275,7 @@ struct tg3 {
 	dma_addr_t			stats_mapping;
 	struct work_struct		reset_task;
 
+	int				nvram_lock_cnt;
 	u32				nvram_size;
 	u32				nvram_pagesize;
 	u32				nvram_jedecnum;
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index ee866fd..a4c7ae9 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -5668,13 +5668,13 @@ static int airo_set_freq(struct net_devi
 		int channel = fwrq->m;
 		/* We should do a better check than that,
 		 * based on the card capability !!! */
-		if((channel < 1) || (channel > 16)) {
+		if((channel < 1) || (channel > 14)) {
 			printk(KERN_DEBUG "%s: New channel value of %d is invalid!\n", dev->name, fwrq->m);
 			rc = -EINVAL;
 		} else {
 			readConfigRid(local, 1);
 			/* Yes ! We can set it !!! */
-			local->config.channelSet = (u16)(channel - 1);
+			local->config.channelSet = (u16) channel;
 			set_bit (FLAG_COMMIT, &local->flags);
 		}
 	}
@@ -5692,6 +5692,7 @@ static int airo_get_freq(struct net_devi
 {
 	struct airo_info *local = dev->priv;
 	StatusRid status_rid;		/* Card status info */
+	int ch;
 
 	readConfigRid(local, 1);
 	if ((local->config.opmode & 0xFF) == MODE_STA_ESS)
@@ -5699,16 +5700,14 @@ static int airo_get_freq(struct net_devi
 	else
 		readStatusRid(local, &status_rid, 1);
 
-#ifdef WEXT_USECHANNELS
-	fwrq->m = ((int)status_rid.channel) + 1;
-	fwrq->e = 0;
-#else
-	{
-		int f = (int)status_rid.channel;
-		fwrq->m = frequency_list[f] * 100000;
+	ch = (int)status_rid.channel;
+	if((ch > 0) && (ch < 15)) {
+		fwrq->m = frequency_list[ch - 1] * 100000;
 		fwrq->e = 1;
+	} else {
+		fwrq->m = ch;
+		fwrq->e = 0;
 	}
-#endif
 
 	return 0;
 }
@@ -5783,7 +5782,7 @@ static int airo_get_essid(struct net_dev
 	/* If none, we may want to get the one that was set */
 
 	/* Push it out ! */
-	dwrq->length = status_rid.SSIDlen + 1;
+	dwrq->length = status_rid.SSIDlen;
 	dwrq->flags = 1; /* active */
 
 	return 0;
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index f0ccfef..98a76f1 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -1718,11 +1718,11 @@ static int atmel_get_essid(struct net_de
 	if (priv->new_SSID_size != 0) {
 		memcpy(extra, priv->new_SSID, priv->new_SSID_size);
 		extra[priv->new_SSID_size] = '\0';
-		dwrq->length = priv->new_SSID_size + 1;
+		dwrq->length = priv->new_SSID_size;
 	} else {
 		memcpy(extra, priv->SSID, priv->SSID_size);
 		extra[priv->SSID_size] = '\0';
-		dwrq->length = priv->SSID_size + 1;
+		dwrq->length = priv->SSID_size;
 	}
 
 	dwrq->flags = !priv->connect_to_any_BSS; /* active */
diff --git a/drivers/net/wireless/hostap/Kconfig b/drivers/net/wireless/hostap/Kconfig
index 56f41c7..308f773 100644
--- a/drivers/net/wireless/hostap/Kconfig
+++ b/drivers/net/wireless/hostap/Kconfig
@@ -26,11 +26,25 @@ config HOSTAP_FIRMWARE
 	depends on HOSTAP
 	---help---
 	Configure Host AP driver to include support for firmware image
-	download. Current version supports only downloading to volatile, i.e.,
-	RAM memory. Flash upgrade is not yet supported.
+	download. This option by itself only enables downloading to the
+	volatile memory, i.e. the card RAM. This option is required to
+	support cards that don't have firmware in flash, such as D-Link
+	DWL-520 rev E and D-Link DWL-650 rev P.
+
+	Firmware image downloading needs a user space tool, prism2_srec.
+	It is available from http://hostap.epitest.fi/.
+
+config HOSTAP_FIRMWARE_NVRAM
+	bool "Support for non-volatile firmware download"
+	depends on HOSTAP_FIRMWARE
+	---help---
+	Allow Host AP driver to write firmware images to the non-volatile
+	card memory, i.e. flash memory that survives power cycling.
+	Enable this option if you want to be able to change card firmware
+	permanently.
 
-	Firmware image downloading needs user space tool, prism2_srec. It is
-	available from http://hostap.epitest.fi/.
+	Firmware image downloading needs a user space tool, prism2_srec.
+	It is available from http://hostap.epitest.fi/.
 
 config HOSTAP_PLX
 	tristate "Host AP driver for Prism2/2.5/3 in PLX9052 PCI adaptors"
@@ -61,7 +75,7 @@ config HOSTAP_PCI
 
 config HOSTAP_CS
 	tristate "Host AP driver for Prism2/2.5/3 PC Cards"
-	depends on PCMCIA!=n && HOSTAP
+	depends on PCMCIA && HOSTAP
 	---help---
 	Host AP driver's version for Prism2/2.5/3 PC Cards.
 
diff --git a/drivers/net/wireless/hostap/Makefile b/drivers/net/wireless/hostap/Makefile
index 353ccb9..b8e41a7 100644
--- a/drivers/net/wireless/hostap/Makefile
+++ b/drivers/net/wireless/hostap/Makefile
@@ -1,4 +1,5 @@
-hostap-y := hostap_main.o
+hostap-y := hostap_80211_rx.o hostap_80211_tx.o hostap_ap.o hostap_info.o \
+            hostap_ioctl.o hostap_main.o hostap_proc.o 
 obj-$(CONFIG_HOSTAP) += hostap.o
 
 obj-$(CONFIG_HOSTAP_CS) += hostap_cs.o
diff --git a/drivers/net/wireless/hostap/hostap.h b/drivers/net/wireless/hostap/hostap.h
index 5fac89b..5e63765 100644
--- a/drivers/net/wireless/hostap/hostap.h
+++ b/drivers/net/wireless/hostap/hostap.h
@@ -1,6 +1,15 @@
 #ifndef HOSTAP_H
 #define HOSTAP_H
 
+#include <linux/ethtool.h>
+
+#include "hostap_wlan.h"
+#include "hostap_ap.h"
+
+static const long freq_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
+				  2447, 2452, 2457, 2462, 2467, 2472, 2484 };
+#define FREQ_COUNT (sizeof(freq_list) / sizeof(freq_list[0]))
+
 /* hostap.c */
 
 extern struct proc_dir_entry *hostap_proc;
@@ -40,6 +49,26 @@ int prism2_update_comms_qual(struct net_
 int prism2_sta_send_mgmt(local_info_t *local, u8 *dst, u16 stype,
 			 u8 *body, size_t bodylen);
 int prism2_sta_deauth(local_info_t *local, u16 reason);
+int prism2_wds_add(local_info_t *local, u8 *remote_addr,
+		   int rtnl_locked);
+int prism2_wds_del(local_info_t *local, u8 *remote_addr,
+		   int rtnl_locked, int do_not_remove);
+
+
+/* hostap_ap.c */
+
+int ap_control_add_mac(struct mac_restrictions *mac_restrictions, u8 *mac);
+int ap_control_del_mac(struct mac_restrictions *mac_restrictions, u8 *mac);
+void ap_control_flush_macs(struct mac_restrictions *mac_restrictions);
+int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev, u8 *mac);
+void ap_control_kickall(struct ap_data *ap);
+void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
+			 struct ieee80211_crypt_data ***crypt);
+int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
+			   struct iw_quality qual[], int buf_size,
+			   int aplist);
+int prism2_ap_translate_scan(struct net_device *dev, char *buffer);
+int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param);
 
 
 /* hostap_proc.c */
@@ -54,4 +83,12 @@ void hostap_info_init(local_info_t *loca
 void hostap_info_process(local_info_t *local, struct sk_buff *skb);
 
 
+/* hostap_ioctl.c */
+
+extern const struct iw_handler_def hostap_iw_handler_def;
+extern struct ethtool_ops prism2_ethtool_ops;
+
+int hostap_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
+
+
 #endif /* HOSTAP_H */
diff --git a/drivers/net/wireless/hostap/hostap_80211.h b/drivers/net/wireless/hostap/hostap_80211.h
index bf506f5..1fc72fe 100644
--- a/drivers/net/wireless/hostap/hostap_80211.h
+++ b/drivers/net/wireless/hostap/hostap_80211.h
@@ -1,6 +1,9 @@
 #ifndef HOSTAP_80211_H
 #define HOSTAP_80211_H
 
+#include <linux/types.h>
+#include <net/ieee80211_crypt.h>
+
 struct hostap_ieee80211_mgmt {
 	u16 frame_control;
 	u16 duration;
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c
index 4b13b76..7e04dc9 100644
--- a/drivers/net/wireless/hostap/hostap_80211_rx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_rx.c
@@ -1,7 +1,18 @@
 #include <linux/etherdevice.h>
+#include <net/ieee80211_crypt.h>
 
 #include "hostap_80211.h"
 #include "hostap.h"
+#include "hostap_ap.h"
+
+/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
+/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
+static unsigned char rfc1042_header[] =
+{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
+/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
+static unsigned char bridge_tunnel_header[] =
+{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
+/* No encapsulation header if EtherType < 0x600 (=length) */
 
 void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
 			  struct hostap_80211_rx_status *rx_stats)
diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c
index 9d24f8a..4a85e63 100644
--- a/drivers/net/wireless/hostap/hostap_80211_tx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_tx.c
@@ -1,3 +1,18 @@
+#include "hostap_80211.h"
+#include "hostap_common.h"
+#include "hostap_wlan.h"
+#include "hostap.h"
+#include "hostap_ap.h"
+
+/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
+/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
+static unsigned char rfc1042_header[] =
+{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
+/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
+static unsigned char bridge_tunnel_header[] =
+{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
+/* No encapsulation header if EtherType < 0x600 (=length) */
+
 void hostap_dump_tx_80211(const char *name, struct sk_buff *skb)
 {
 	struct ieee80211_hdr_4addr *hdr;
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index 9da94ab..753a1de 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -16,6 +16,14 @@
  *   (8802.11: 5.5)
  */
 
+#include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <linux/random.h>
+
+#include "hostap_wlan.h"
+#include "hostap.h"
+#include "hostap_ap.h"
+
 static int other_ap_policy[MAX_PARM_DEVICES] = { AP_OTHER_AP_SKIP_ALL,
 						 DEF_INTS };
 module_param_array(other_ap_policy, int, NULL, 0444);
@@ -360,8 +368,7 @@ static int ap_control_proc_read(char *pa
 }
 
 
-static int ap_control_add_mac(struct mac_restrictions *mac_restrictions,
-			      u8 *mac)
+int ap_control_add_mac(struct mac_restrictions *mac_restrictions, u8 *mac)
 {
 	struct mac_entry *entry;
 
@@ -380,8 +387,7 @@ static int ap_control_add_mac(struct mac
 }
 
 
-static int ap_control_del_mac(struct mac_restrictions *mac_restrictions,
-			      u8 *mac)
+int ap_control_del_mac(struct mac_restrictions *mac_restrictions, u8 *mac)
 {
 	struct list_head *ptr;
 	struct mac_entry *entry;
@@ -433,7 +439,7 @@ static int ap_control_mac_deny(struct ma
 }
 
 
-static void ap_control_flush_macs(struct mac_restrictions *mac_restrictions)
+void ap_control_flush_macs(struct mac_restrictions *mac_restrictions)
 {
 	struct list_head *ptr, *n;
 	struct mac_entry *entry;
@@ -454,8 +460,7 @@ static void ap_control_flush_macs(struct
 }
 
 
-static int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev,
-			       u8 *mac)
+int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev, u8 *mac)
 {
 	struct sta_info *sta;
 	u16 resp;
@@ -486,7 +491,7 @@ static int ap_control_kick_mac(struct ap
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
 
 
-static void ap_control_kickall(struct ap_data *ap)
+void ap_control_kickall(struct ap_data *ap)
 {
 	struct list_head *ptr, *n;
 	struct sta_info *sta;
@@ -2321,9 +2326,9 @@ static void schedule_packet_send(local_i
 }
 
 
-static int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
-				  struct iw_quality qual[], int buf_size,
-				  int aplist)
+int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
+			   struct iw_quality qual[], int buf_size,
+			   int aplist)
 {
 	struct ap_data *ap = local->ap;
 	struct list_head *ptr;
@@ -2363,7 +2368,7 @@ static int prism2_ap_get_sta_qual(local_
 
 /* Translate our list of Access Points & Stations to a card independant
  * format that the Wireless Tools will understand - Jean II */
-static int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
+int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
 {
 	struct hostap_interface *iface;
 	local_info_t *local;
@@ -2608,8 +2613,7 @@ static int prism2_hostapd_sta_clear_stat
 }
 
 
-static int prism2_hostapd(struct ap_data *ap,
-			  struct prism2_hostapd_param *param)
+int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param)
 {
 	switch (param->cmd) {
 	case PRISM2_HOSTAPD_FLUSH:
@@ -3207,8 +3211,8 @@ void hostap_update_rates(local_info_t *l
 }
 
 
-static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
-				struct ieee80211_crypt_data ***crypt)
+void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
+			 struct ieee80211_crypt_data ***crypt)
 {
 	struct sta_info *sta;
 
diff --git a/drivers/net/wireless/hostap/hostap_ap.h b/drivers/net/wireless/hostap/hostap_ap.h
index 6d00df6..2fa2452 100644
--- a/drivers/net/wireless/hostap/hostap_ap.h
+++ b/drivers/net/wireless/hostap/hostap_ap.h
@@ -1,6 +1,8 @@
 #ifndef HOSTAP_AP_H
 #define HOSTAP_AP_H
 
+#include "hostap_80211.h"
+
 /* AP data structures for STAs */
 
 /* maximum number of frames to buffer per STA */
diff --git a/drivers/net/wireless/hostap/hostap_common.h b/drivers/net/wireless/hostap/hostap_common.h
index 6f4fa9d..0162400 100644
--- a/drivers/net/wireless/hostap/hostap_common.h
+++ b/drivers/net/wireless/hostap/hostap_common.h
@@ -1,6 +1,9 @@
 #ifndef HOSTAP_COMMON_H
 #define HOSTAP_COMMON_H
 
+#include <linux/types.h>
+#include <linux/if_ether.h>
+
 #define BIT(x) (1 << (x))
 
 #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
diff --git a/drivers/net/wireless/hostap/hostap_config.h b/drivers/net/wireless/hostap/hostap_config.h
index 7ed3425..c090a5a 100644
--- a/drivers/net/wireless/hostap/hostap_config.h
+++ b/drivers/net/wireless/hostap/hostap_config.h
@@ -21,15 +21,10 @@
 #define PRISM2_DOWNLOAD_SUPPORT
 #endif
 
-#ifdef PRISM2_DOWNLOAD_SUPPORT
-/* Allow writing firmware images into flash, i.e., to non-volatile storage.
- * Before you enable this option, you should make absolutely sure that you are
- * using prism2_srec utility that comes with THIS version of the driver!
- * In addition, please note that it is possible to kill your card with
- * non-volatile download if you are using incorrect image. This feature has not
- * been fully tested, so please be careful with it. */
-/* #define PRISM2_NON_VOLATILE_DOWNLOAD */
-#endif /* PRISM2_DOWNLOAD_SUPPORT */
+/* Allow kernel configuration to enable non-volatile download support. */
+#ifdef CONFIG_HOSTAP_FIRMWARE_NVRAM
+#define PRISM2_NON_VOLATILE_DOWNLOAD
+#endif
 
 /* Save low-level I/O for debugging. This should not be enabled in normal use.
  */
diff --git a/drivers/net/wireless/hostap/hostap_info.c b/drivers/net/wireless/hostap/hostap_info.c
index 5aa998f..50f72d8 100644
--- a/drivers/net/wireless/hostap/hostap_info.c
+++ b/drivers/net/wireless/hostap/hostap_info.c
@@ -1,5 +1,8 @@
 /* Host AP driver Info Frame processing (part of hostap.o module) */
 
+#include "hostap_wlan.h"
+#include "hostap.h"
+#include "hostap_ap.h"
 
 /* Called only as a tasklet (software IRQ) */
 static void prism2_info_commtallies16(local_info_t *local, unsigned char *buf,
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 2617d70..f3e0ce1 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -1,11 +1,13 @@
 /* ioctl() (mostly Linux Wireless Extensions) routines for Host AP driver */
 
-#ifdef in_atomic
-/* Get kernel_locked() for in_atomic() */
+#include <linux/types.h>
 #include <linux/smp_lock.h>
-#endif
 #include <linux/ethtool.h>
+#include <net/ieee80211_crypt.h>
 
+#include "hostap_wlan.h"
+#include "hostap.h"
+#include "hostap_ap.h"
 
 static struct iw_statistics *hostap_get_wireless_stats(struct net_device *dev)
 {
@@ -3910,7 +3912,7 @@ static void prism2_get_drvinfo(struct ne
 		 local->sta_fw_ver & 0xff);
 }
 
-static struct ethtool_ops prism2_ethtool_ops = {
+struct ethtool_ops prism2_ethtool_ops = {
 	.get_drvinfo = prism2_get_drvinfo
 };
 
@@ -3985,7 +3987,7 @@ static const iw_handler prism2_private_h
 	(iw_handler) prism2_ioctl_priv_readmif,		/* 3 */
 };
 
-static const struct iw_handler_def hostap_iw_handler_def =
+const struct iw_handler_def hostap_iw_handler_def =
 {
 	.num_standard	= sizeof(prism2_handler) / sizeof(iw_handler),
 	.num_private	= sizeof(prism2_private_handler) / sizeof(iw_handler),
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index 3d2ea61..8dd4c44 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -24,6 +24,7 @@
 #include <linux/kmod.h>
 #include <linux/rtnetlink.h>
 #include <linux/wireless.h>
+#include <linux/etherdevice.h>
 #include <net/iw_handler.h>
 #include <net/ieee80211.h>
 #include <net/ieee80211_crypt.h>
@@ -47,57 +48,6 @@ MODULE_VERSION(PRISM2_VERSION);
 #define PRISM2_MAX_MTU (PRISM2_MAX_FRAME_SIZE - (6 /* LLC */ + 8 /* WEP */))
 
 
-/* hostap.c */
-static int prism2_wds_add(local_info_t *local, u8 *remote_addr,
-			  int rtnl_locked);
-static int prism2_wds_del(local_info_t *local, u8 *remote_addr,
-			  int rtnl_locked, int do_not_remove);
-
-/* hostap_ap.c */
-static int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
-				  struct iw_quality qual[], int buf_size,
-				  int aplist);
-static int prism2_ap_translate_scan(struct net_device *dev, char *buffer);
-static int prism2_hostapd(struct ap_data *ap,
-			  struct prism2_hostapd_param *param);
-static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
-				struct ieee80211_crypt_data ***crypt);
-static void ap_control_kickall(struct ap_data *ap);
-#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
-static int ap_control_add_mac(struct mac_restrictions *mac_restrictions,
-			      u8 *mac);
-static int ap_control_del_mac(struct mac_restrictions *mac_restrictions,
-			      u8 *mac);
-static void ap_control_flush_macs(struct mac_restrictions *mac_restrictions);
-static int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev,
-			       u8 *mac);
-#endif /* !PRISM2_NO_KERNEL_IEEE80211_MGMT */
-
-
-static const long freq_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
-				  2447, 2452, 2457, 2462, 2467, 2472, 2484 };
-#define FREQ_COUNT (sizeof(freq_list) / sizeof(freq_list[0]))
-
-
-/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
-/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
-static unsigned char rfc1042_header[] =
-{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
-/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
-static unsigned char bridge_tunnel_header[] =
-{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
-/* No encapsulation header if EtherType < 0x600 (=length) */
-
-
-/* FIX: these could be compiled separately and linked together to hostap.o */
-#include "hostap_ap.c"
-#include "hostap_info.c"
-#include "hostap_ioctl.c"
-#include "hostap_proc.c"
-#include "hostap_80211_rx.c"
-#include "hostap_80211_tx.c"
-
-
 struct net_device * hostap_add_interface(struct local_info *local,
 					 int type, int rtnl_locked,
 					 const char *prefix,
@@ -196,8 +146,8 @@ static inline int prism2_wds_special_add
 }
 
 
-static int prism2_wds_add(local_info_t *local, u8 *remote_addr,
-			  int rtnl_locked)
+int prism2_wds_add(local_info_t *local, u8 *remote_addr,
+		   int rtnl_locked)
 {
 	struct net_device *dev;
 	struct list_head *ptr;
@@ -258,8 +208,8 @@ static int prism2_wds_add(local_info_t *
 }
 
 
-static int prism2_wds_del(local_info_t *local, u8 *remote_addr,
-			  int rtnl_locked, int do_not_remove)
+int prism2_wds_del(local_info_t *local, u8 *remote_addr,
+		   int rtnl_locked, int do_not_remove)
 {
 	unsigned long flags;
 	struct list_head *ptr;
diff --git a/drivers/net/wireless/hostap/hostap_proc.c b/drivers/net/wireless/hostap/hostap_proc.c
index a0a4cbd..d1d8ce0 100644
--- a/drivers/net/wireless/hostap/hostap_proc.c
+++ b/drivers/net/wireless/hostap/hostap_proc.c
@@ -1,5 +1,12 @@
 /* /proc routines for Host AP driver */
 
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <net/ieee80211_crypt.h>
+
+#include "hostap_wlan.h"
+#include "hostap.h"
+
 #define PROC_LIMIT (PAGE_SIZE - 80)
 
 
diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h
index cfd8015..87a54aa 100644
--- a/drivers/net/wireless/hostap/hostap_wlan.h
+++ b/drivers/net/wireless/hostap/hostap_wlan.h
@@ -1,6 +1,10 @@
 #ifndef HOSTAP_WLAN_H
 #define HOSTAP_WLAN_H
 
+#include <linux/wireless.h>
+#include <linux/netdevice.h>
+#include <net/iw_handler.h>
+
 #include "hostap_config.h"
 #include "hostap_common.h"
 
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 7518384..6290c9f 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -2201,6 +2201,17 @@ static int ipw2100_alloc_skb(struct ipw2
 #define SEARCH_SNAPSHOT 1
 
 #define SNAPSHOT_ADDR(ofs) (priv->snapshot[((ofs) >> 12) & 0xff] + ((ofs) & 0xfff))
+static void ipw2100_snapshot_free(struct ipw2100_priv *priv)
+{
+	int i;
+	if (!priv->snapshot[0])
+		return;
+	for (i = 0; i < 0x30; i++)
+		kfree(priv->snapshot[i]);
+	priv->snapshot[0] = NULL;
+}
+
+#ifdef CONFIG_IPW2100_DEBUG_C3
 static int ipw2100_snapshot_alloc(struct ipw2100_priv *priv)
 {
 	int i;
@@ -2221,16 +2232,6 @@ static int ipw2100_snapshot_alloc(struct
 	return 1;
 }
 
-static void ipw2100_snapshot_free(struct ipw2100_priv *priv)
-{
-	int i;
-	if (!priv->snapshot[0])
-		return;
-	for (i = 0; i < 0x30; i++)
-		kfree(priv->snapshot[i]);
-	priv->snapshot[0] = NULL;
-}
-
 static u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 * in_buf,
 				    size_t len, int mode)
 {
@@ -2269,6 +2270,7 @@ static u32 ipw2100_match_buf(struct ipw2
 
 	return ret;
 }
+#endif
 
 /*
  *
@@ -5735,70 +5737,6 @@ static struct net_device_stats *ipw2100_
 	return &priv->ieee->stats;
 }
 
-#if WIRELESS_EXT < 18
-/* Support for wpa_supplicant before WE-18, deprecated. */
-
-/* following definitions must match definitions in driver_ipw.c */
-
-#define IPW2100_IOCTL_WPA_SUPPLICANT		SIOCIWFIRSTPRIV+30
-
-#define IPW2100_CMD_SET_WPA_PARAM		1
-#define	IPW2100_CMD_SET_WPA_IE			2
-#define IPW2100_CMD_SET_ENCRYPTION		3
-#define IPW2100_CMD_MLME			4
-
-#define IPW2100_PARAM_WPA_ENABLED		1
-#define IPW2100_PARAM_TKIP_COUNTERMEASURES	2
-#define IPW2100_PARAM_DROP_UNENCRYPTED		3
-#define IPW2100_PARAM_PRIVACY_INVOKED		4
-#define IPW2100_PARAM_AUTH_ALGS			5
-#define IPW2100_PARAM_IEEE_802_1X		6
-
-#define IPW2100_MLME_STA_DEAUTH			1
-#define IPW2100_MLME_STA_DISASSOC		2
-
-#define IPW2100_CRYPT_ERR_UNKNOWN_ALG		2
-#define IPW2100_CRYPT_ERR_UNKNOWN_ADDR		3
-#define IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED	4
-#define IPW2100_CRYPT_ERR_KEY_SET_FAILED	5
-#define IPW2100_CRYPT_ERR_TX_KEY_SET_FAILED	6
-#define IPW2100_CRYPT_ERR_CARD_CONF_FAILED	7
-
-#define	IPW2100_CRYPT_ALG_NAME_LEN		16
-
-struct ipw2100_param {
-	u32 cmd;
-	u8 sta_addr[ETH_ALEN];
-	union {
-		struct {
-			u8 name;
-			u32 value;
-		} wpa_param;
-		struct {
-			u32 len;
-			u8 reserved[32];
-			u8 data[0];
-		} wpa_ie;
-		struct {
-			u32 command;
-			u32 reason_code;
-		} mlme;
-		struct {
-			u8 alg[IPW2100_CRYPT_ALG_NAME_LEN];
-			u8 set_tx;
-			u32 err;
-			u8 idx;
-			u8 seq[8];	/* sequence counter (set: RX, get: TX) */
-			u16 key_len;
-			u8 key[0];
-		} crypt;
-
-	} u;
-};
-
-/* end of driver_ipw.c code */
-#endif				/* WIRELESS_EXT < 18 */
-
 static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value)
 {
 	/* This is called when wpa_supplicant loads and closes the driver
@@ -5807,11 +5745,6 @@ static int ipw2100_wpa_enable(struct ipw
 	return 0;
 }
 
-#if WIRELESS_EXT < 18
-#define IW_AUTH_ALG_OPEN_SYSTEM			0x1
-#define IW_AUTH_ALG_SHARED_KEY			0x2
-#endif
-
 static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value)
 {
 
@@ -5855,360 +5788,6 @@ void ipw2100_wpa_assoc_frame(struct ipw2
 	ipw2100_set_wpa_ie(priv, &frame, 0);
 }
 
-#if WIRELESS_EXT < 18
-static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value)
-{
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_crypt_data *crypt;
-	unsigned long flags;
-	int ret = 0;
-
-	switch (name) {
-	case IPW2100_PARAM_WPA_ENABLED:
-		ret = ipw2100_wpa_enable(priv, value);
-		break;
-
-	case IPW2100_PARAM_TKIP_COUNTERMEASURES:
-		crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
-		if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
-			break;
-
-		flags = crypt->ops->get_flags(crypt->priv);
-
-		if (value)
-			flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
-		else
-			flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
-
-		crypt->ops->set_flags(flags, crypt->priv);
-
-		break;
-
-	case IPW2100_PARAM_DROP_UNENCRYPTED:{
-			/* See IW_AUTH_DROP_UNENCRYPTED handling for details */
-			struct ieee80211_security sec = {
-				.flags = SEC_ENABLED,
-				.enabled = value,
-			};
-			priv->ieee->drop_unencrypted = value;
-			/* We only change SEC_LEVEL for open mode. Others
-			 * are set by ipw_wpa_set_encryption.
-			 */
-			if (!value) {
-				sec.flags |= SEC_LEVEL;
-				sec.level = SEC_LEVEL_0;
-			} else {
-				sec.flags |= SEC_LEVEL;
-				sec.level = SEC_LEVEL_1;
-			}
-			if (priv->ieee->set_security)
-				priv->ieee->set_security(priv->ieee->dev, &sec);
-			break;
-		}
-
-	case IPW2100_PARAM_PRIVACY_INVOKED:
-		priv->ieee->privacy_invoked = value;
-		break;
-
-	case IPW2100_PARAM_AUTH_ALGS:
-		ret = ipw2100_wpa_set_auth_algs(priv, value);
-		break;
-
-	case IPW2100_PARAM_IEEE_802_1X:
-		priv->ieee->ieee802_1x = value;
-		break;
-
-	default:
-		printk(KERN_ERR DRV_NAME ": %s: Unknown WPA param: %d\n",
-		       dev->name, name);
-		ret = -EOPNOTSUPP;
-	}
-
-	return ret;
-}
-
-static int ipw2100_wpa_mlme(struct net_device *dev, int command, int reason)
-{
-
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
-	int ret = 0;
-
-	switch (command) {
-	case IPW2100_MLME_STA_DEAUTH:
-		// silently ignore
-		break;
-
-	case IPW2100_MLME_STA_DISASSOC:
-		ipw2100_disassociate_bssid(priv);
-		break;
-
-	default:
-		printk(KERN_ERR DRV_NAME ": %s: Unknown MLME request: %d\n",
-		       dev->name, command);
-		ret = -EOPNOTSUPP;
-	}
-
-	return ret;
-}
-
-static int ipw2100_wpa_set_wpa_ie(struct net_device *dev,
-				  struct ipw2100_param *param, int plen)
-{
-
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee = priv->ieee;
-	u8 *buf;
-
-	if (!ieee->wpa_enabled)
-		return -EOPNOTSUPP;
-
-	if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
-	    (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
-		return -EINVAL;
-
-	if (param->u.wpa_ie.len) {
-		buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
-		if (buf == NULL)
-			return -ENOMEM;
-
-		memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
-
-		kfree(ieee->wpa_ie);
-		ieee->wpa_ie = buf;
-		ieee->wpa_ie_len = param->u.wpa_ie.len;
-
-	} else {
-		kfree(ieee->wpa_ie);
-		ieee->wpa_ie = NULL;
-		ieee->wpa_ie_len = 0;
-	}
-
-	ipw2100_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
-
-	return 0;
-}
-
-/* implementation borrowed from hostap driver */
-
-static int ipw2100_wpa_set_encryption(struct net_device *dev,
-				      struct ipw2100_param *param,
-				      int param_len)
-{
-	int ret = 0;
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee = priv->ieee;
-	struct ieee80211_crypto_ops *ops;
-	struct ieee80211_crypt_data **crypt;
-
-	struct ieee80211_security sec = {
-		.flags = 0,
-	};
-
-	param->u.crypt.err = 0;
-	param->u.crypt.alg[IPW2100_CRYPT_ALG_NAME_LEN - 1] = '\0';
-
-	if (param_len !=
-	    (int)((char *)param->u.crypt.key - (char *)param) +
-	    param->u.crypt.key_len) {
-		IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len,
-			       param->u.crypt.key_len);
-		return -EINVAL;
-	}
-	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
-	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
-	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
-		if (param->u.crypt.idx >= WEP_KEYS)
-			return -EINVAL;
-		crypt = &ieee->crypt[param->u.crypt.idx];
-	} else {
-		return -EINVAL;
-	}
-
-	sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
-	if (strcmp(param->u.crypt.alg, "none") == 0) {
-		if (crypt) {
-			sec.enabled = 0;
-			sec.encrypt = 0;
-			sec.level = SEC_LEVEL_0;
-			sec.flags |= SEC_LEVEL;
-			ieee80211_crypt_delayed_deinit(ieee, crypt);
-		}
-		goto done;
-	}
-	sec.enabled = 1;
-	sec.encrypt = 1;
-
-	ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-	if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
-		request_module("ieee80211_crypt_wep");
-		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-	} else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
-		request_module("ieee80211_crypt_tkip");
-		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-	} else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
-		request_module("ieee80211_crypt_ccmp");
-		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-	}
-	if (ops == NULL) {
-		IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n",
-			       dev->name, param->u.crypt.alg);
-		param->u.crypt.err = IPW2100_CRYPT_ERR_UNKNOWN_ALG;
-		ret = -EINVAL;
-		goto done;
-	}
-
-	if (*crypt == NULL || (*crypt)->ops != ops) {
-		struct ieee80211_crypt_data *new_crypt;
-
-		ieee80211_crypt_delayed_deinit(ieee, crypt);
-
-		new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL);
-		if (new_crypt == NULL) {
-			ret = -ENOMEM;
-			goto done;
-		}
-		new_crypt->ops = ops;
-		if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
-			new_crypt->priv =
-			    new_crypt->ops->init(param->u.crypt.idx);
-
-		if (new_crypt->priv == NULL) {
-			kfree(new_crypt);
-			param->u.crypt.err =
-			    IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED;
-			ret = -EINVAL;
-			goto done;
-		}
-
-		*crypt = new_crypt;
-	}
-
-	if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
-	    (*crypt)->ops->set_key(param->u.crypt.key,
-				   param->u.crypt.key_len, param->u.crypt.seq,
-				   (*crypt)->priv) < 0) {
-		IPW_DEBUG_INFO("%s: key setting failed\n", dev->name);
-		param->u.crypt.err = IPW2100_CRYPT_ERR_KEY_SET_FAILED;
-		ret = -EINVAL;
-		goto done;
-	}
-
-	if (param->u.crypt.set_tx) {
-		ieee->tx_keyidx = param->u.crypt.idx;
-		sec.active_key = param->u.crypt.idx;
-		sec.flags |= SEC_ACTIVE_KEY;
-	}
-
-	if (ops->name != NULL) {
-
-		if (strcmp(ops->name, "WEP") == 0) {
-			memcpy(sec.keys[param->u.crypt.idx],
-			       param->u.crypt.key, param->u.crypt.key_len);
-			sec.key_sizes[param->u.crypt.idx] =
-			    param->u.crypt.key_len;
-			sec.flags |= (1 << param->u.crypt.idx);
-			sec.flags |= SEC_LEVEL;
-			sec.level = SEC_LEVEL_1;
-		} else if (strcmp(ops->name, "TKIP") == 0) {
-			sec.flags |= SEC_LEVEL;
-			sec.level = SEC_LEVEL_2;
-		} else if (strcmp(ops->name, "CCMP") == 0) {
-			sec.flags |= SEC_LEVEL;
-			sec.level = SEC_LEVEL_3;
-		}
-	}
-      done:
-	if (ieee->set_security)
-		ieee->set_security(ieee->dev, &sec);
-
-	/* Do not reset port if card is in Managed mode since resetting will
-	 * generate new IEEE 802.11 authentication which may end up in looping
-	 * with IEEE 802.1X.  If your hardware requires a reset after WEP
-	 * configuration (for example... Prism2), implement the reset_port in
-	 * the callbacks structures used to initialize the 802.11 stack. */
-	if (ieee->reset_on_keychange &&
-	    ieee->iw_mode != IW_MODE_INFRA &&
-	    ieee->reset_port && ieee->reset_port(dev)) {
-		IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name);
-		param->u.crypt.err = IPW2100_CRYPT_ERR_CARD_CONF_FAILED;
-		return -EINVAL;
-	}
-
-	return ret;
-}
-
-static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p)
-{
-
-	struct ipw2100_param *param;
-	int ret = 0;
-
-	IPW_DEBUG_IOCTL("wpa_supplicant: len=%d\n", p->length);
-
-	if (p->length < sizeof(struct ipw2100_param) || !p->pointer)
-		return -EINVAL;
-
-	param = (struct ipw2100_param *)kmalloc(p->length, GFP_KERNEL);
-	if (param == NULL)
-		return -ENOMEM;
-
-	if (copy_from_user(param, p->pointer, p->length)) {
-		kfree(param);
-		return -EFAULT;
-	}
-
-	switch (param->cmd) {
-
-	case IPW2100_CMD_SET_WPA_PARAM:
-		ret = ipw2100_wpa_set_param(dev, param->u.wpa_param.name,
-					    param->u.wpa_param.value);
-		break;
-
-	case IPW2100_CMD_SET_WPA_IE:
-		ret = ipw2100_wpa_set_wpa_ie(dev, param, p->length);
-		break;
-
-	case IPW2100_CMD_SET_ENCRYPTION:
-		ret = ipw2100_wpa_set_encryption(dev, param, p->length);
-		break;
-
-	case IPW2100_CMD_MLME:
-		ret = ipw2100_wpa_mlme(dev, param->u.mlme.command,
-				       param->u.mlme.reason_code);
-		break;
-
-	default:
-		printk(KERN_ERR DRV_NAME
-		       ": %s: Unknown WPA supplicant request: %d\n", dev->name,
-		       param->cmd);
-		ret = -EOPNOTSUPP;
-
-	}
-
-	if (ret == 0 && copy_to_user(p->pointer, param, p->length))
-		ret = -EFAULT;
-
-	kfree(param);
-	return ret;
-}
-
-static int ipw2100_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
-	struct iwreq *wrq = (struct iwreq *)rq;
-	int ret = -1;
-	switch (cmd) {
-	case IPW2100_IOCTL_WPA_SUPPLICANT:
-		ret = ipw2100_wpa_supplicant(dev, &wrq->u.data);
-		return ret;
-
-	default:
-		return -EOPNOTSUPP;
-	}
-
-	return -EOPNOTSUPP;
-}
-#endif				/* WIRELESS_EXT < 18 */
-
 static void ipw_ethtool_get_drvinfo(struct net_device *dev,
 				    struct ethtool_drvinfo *info)
 {
@@ -6337,9 +5916,6 @@ static struct net_device *ipw2100_alloc_
 	dev->open = ipw2100_open;
 	dev->stop = ipw2100_close;
 	dev->init = ipw2100_net_init;
-#if WIRELESS_EXT < 18
-	dev->do_ioctl = ipw2100_ioctl;
-#endif
 	dev->get_stats = ipw2100_stats;
 	dev->ethtool_ops = &ipw2100_ethtool_ops;
 	dev->tx_timeout = ipw2100_tx_timeout;
@@ -7538,11 +7114,17 @@ static int ipw2100_wx_set_txpow(struct n
 {
 	struct ipw2100_priv *priv = ieee80211_priv(dev);
 	int err = 0, value;
+	
+	if (ipw_radio_kill_sw(priv, wrqu->txpower.disabled))
+		return -EINPROGRESS;
 
 	if (priv->ieee->iw_mode != IW_MODE_ADHOC)
+		return 0;
+
+	if ((wrqu->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
 		return -EINVAL;
 
-	if (wrqu->txpower.disabled == 1 || wrqu->txpower.fixed == 0)
+	if (wrqu->txpower.fixed == 0)
 		value = IPW_TX_POWER_DEFAULT;
 	else {
 		if (wrqu->txpower.value < IPW_TX_POWER_MIN_DBM ||
@@ -7577,24 +7159,19 @@ static int ipw2100_wx_get_txpow(struct n
 
 	struct ipw2100_priv *priv = ieee80211_priv(dev);
 
-	if (priv->ieee->iw_mode != IW_MODE_ADHOC) {
-		wrqu->power.disabled = 1;
-		return 0;
-	}
+	wrqu->txpower.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
 
 	if (priv->tx_power == IPW_TX_POWER_DEFAULT) {
-		wrqu->power.fixed = 0;
-		wrqu->power.value = IPW_TX_POWER_MAX_DBM;
-		wrqu->power.disabled = 1;
+		wrqu->txpower.fixed = 0;
+		wrqu->txpower.value = IPW_TX_POWER_MAX_DBM;
 	} else {
-		wrqu->power.disabled = 0;
-		wrqu->power.fixed = 1;
-		wrqu->power.value = priv->tx_power;
+		wrqu->txpower.fixed = 1;
+		wrqu->txpower.value = priv->tx_power;
 	}
 
-	wrqu->power.flags = IW_TXPOW_DBM;
+	wrqu->txpower.flags = IW_TXPOW_DBM;
 
-	IPW_DEBUG_WX("GET TX Power -> %d \n", wrqu->power.value);
+	IPW_DEBUG_WX("GET TX Power -> %d \n", wrqu->txpower.value);
 
 	return 0;
 }
@@ -7855,7 +7432,6 @@ static int ipw2100_wx_get_power(struct n
 	return 0;
 }
 
-#if WIRELESS_EXT > 17
 /*
  * WE-18 WPA support
  */
@@ -8117,7 +7693,6 @@ static int ipw2100_wx_set_mlme(struct ne
 	}
 	return 0;
 }
-#endif				/* WIRELESS_EXT > 17 */
 
 /*
  *
@@ -8350,11 +7925,7 @@ static iw_handler ipw2100_wx_handlers[] 
 	NULL,			/* SIOCWIWTHRSPY */
 	ipw2100_wx_set_wap,	/* SIOCSIWAP */
 	ipw2100_wx_get_wap,	/* SIOCGIWAP */
-#if WIRELESS_EXT > 17
 	ipw2100_wx_set_mlme,	/* SIOCSIWMLME */
-#else
-	NULL,			/* -- hole -- */
-#endif
 	NULL,			/* SIOCGIWAPLIST -- deprecated */
 	ipw2100_wx_set_scan,	/* SIOCSIWSCAN */
 	ipw2100_wx_get_scan,	/* SIOCGIWSCAN */
@@ -8378,7 +7949,6 @@ static iw_handler ipw2100_wx_handlers[] 
 	ipw2100_wx_get_encode,	/* SIOCGIWENCODE */
 	ipw2100_wx_set_power,	/* SIOCSIWPOWER */
 	ipw2100_wx_get_power,	/* SIOCGIWPOWER */
-#if WIRELESS_EXT > 17
 	NULL,			/* -- hole -- */
 	NULL,			/* -- hole -- */
 	ipw2100_wx_set_genie,	/* SIOCSIWGENIE */
@@ -8388,7 +7958,6 @@ static iw_handler ipw2100_wx_handlers[] 
 	ipw2100_wx_set_encodeext,	/* SIOCSIWENCODEEXT */
 	ipw2100_wx_get_encodeext,	/* SIOCGIWENCODEEXT */
 	NULL,			/* SIOCSIWPMKSA */
-#endif
 };
 
 #define IPW2100_PRIV_SET_MONITOR	SIOCIWFIRSTPRIV
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 819be2b..14beab4 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -2456,7 +2456,7 @@ static void ipw_eeprom_init_sram(struct 
 	   copy.  Otherwise let the firmware know to perform the operation
 	   on it's own
 	 */
-	if ((priv->eeprom + EEPROM_VERSION) != 0) {
+	if (priv->eeprom[EEPROM_VERSION] != 0) {
 		IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n");
 
 		/* write the eeprom data to sram */
@@ -8012,6 +8012,10 @@ static int ipw_sw_reset(struct ipw_priv 
 	else
 		IPW_DEBUG_INFO("Auto adhoc creation disabled.\n");
 
+	priv->config &= ~CFG_STATIC_ESSID;
+	priv->essid_len = 0;
+	memset(priv->essid, 0, IW_ESSID_MAX_SIZE);
+
 	if (disable) {
 		priv->status |= STATUS_RF_KILL_SW;
 		IPW_DEBUG_INFO("Radio disabled.\n");
@@ -8936,14 +8940,12 @@ static int ipw_request_direct_scan(struc
 	IPW_DEBUG_HC("starting request direct scan!\n");
 
 	if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) {
-		err = wait_event_interruptible(priv->wait_state,
-					       !(priv->
-						 status & (STATUS_SCANNING |
-							   STATUS_SCAN_ABORTING)));
-		if (err) {
-			IPW_DEBUG_HC("aborting direct scan");
-			goto done;
-		}
+		/* We should not sleep here; otherwise we will block most
+		 * of the system (for instance, we hold rtnl_lock when we
+		 * get here).
+		 */
+		err = -EAGAIN;
+		goto done;
 	}
 	memset(&scan, 0, sizeof(scan));
 
@@ -11037,7 +11039,6 @@ static int ipw_pci_probe(struct pci_dev 
 	net_dev->set_multicast_list = ipw_net_set_multicast_list;
 	net_dev->set_mac_address = ipw_net_set_mac_address;
 	priv->wireless_data.spy_data = &priv->ieee->spy_data;
-	priv->wireless_data.ieee80211 = priv->ieee;
 	net_dev->wireless_data = &priv->wireless_data;
 	net_dev->wireless_handlers = &ipw_wx_handler_def;
 	net_dev->ethtool_ops = &ipw_ethtool_ops;
@@ -11123,8 +11124,8 @@ static void ipw_pci_remove(struct pci_de
 	/* Free MAC hash list for ADHOC */
 	for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) {
 		list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) {
-			kfree(list_entry(p, struct ipw_ibss_seq, list));
 			list_del(p);
+			kfree(list_entry(p, struct ipw_ibss_seq, list));
 		}
 	}
 
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index b664708..3c128b6 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -261,13 +261,13 @@ orinoco_cs_config(dev_link_t *link)
 		/* Note that the CIS values need to be rescaled */
 		if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
 			if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
-				DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n",  conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
+				DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, cfg CIS = %d)\n",  conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
 				if (!ignore_cis_vcc)
 					goto next_entry;
 			}
 		} else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
 			if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
-				DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n",  conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
+				DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, dflt CIS = %d)\n",  conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
 				if(!ignore_cis_vcc)
 					goto next_entry;
 			}
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 135a156..c5cd61c 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -748,7 +748,7 @@ prism54_get_essid(struct net_device *nde
 	if (essid->length) {
 		dwrq->flags = 1;	/* set ESSID to ON for Wireless Extensions */
 		/* if it is to big, trunk it */
-		dwrq->length = min(IW_ESSID_MAX_SIZE, essid->length + 1);
+		dwrq->length = min(IW_ESSID_MAX_SIZE, essid->length);
 	} else {
 		dwrq->flags = 0;
 		dwrq->length = 0;
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index 33d64d2..a8261d8 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -177,7 +177,7 @@ islpci_eth_transmit(struct sk_buff *skb,
 #endif
 
 			newskb->dev = skb->dev;
-			dev_kfree_skb(skb);
+			dev_kfree_skb_irq(skb);
 			skb = newskb;
 		}
 	}
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 319180c..7880d8c 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -1256,7 +1256,7 @@ static int ray_get_essid(struct net_devi
 	extra[IW_ESSID_MAX_SIZE] = '\0';
 
 	/* Push it out ! */
-	dwrq->length = strlen(extra) + 1;
+	dwrq->length = strlen(extra);
 	dwrq->flags = 1; /* active */
 
 	return 0;
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index 7e2039f..cf37362 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -2280,7 +2280,7 @@ static int wavelan_get_essid(struct net_
 	extra[IW_ESSID_MAX_SIZE] = '\0';
 
 	/* Set the length */
-	wrqu->data.length = strlen(extra) + 1;
+	wrqu->data.length = strlen(extra);
 
 	return 0;
 }
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig
index 2f1289e..222a1cc 100644
--- a/drivers/pci/hotplug/Kconfig
+++ b/drivers/pci/hotplug/Kconfig
@@ -11,8 +11,7 @@ config HOTPLUG_PCI
 	---help---
 	  Say Y here if you have a motherboard with a PCI Hotplug controller.
 	  This allows you to add and remove PCI cards while the machine is
-	  powered up and running.  The file system pcihpfs must be mounted
-	  in order to interact with any PCI Hotplug controllers.
+	  powered up and running.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called pci_hotplug.
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c
index 7e7f913..317457d 100644
--- a/drivers/pci/hotplug/acpiphp_ibm.c
+++ b/drivers/pci/hotplug/acpiphp_ibm.c
@@ -302,7 +302,7 @@ static int ibm_get_table_from_acpi(char 
 	}
 
 	package = (union acpi_object *) buffer.pointer;
-	if(!(package) ||
+	if (!(package) ||
 			(package->type != ACPI_TYPE_PACKAGE) ||
 			!(package->package.elements)) {
 		err("%s:  Invalid APCI object\n", __FUNCTION__);
@@ -405,7 +405,7 @@ static acpi_status __init ibm_find_acpi_
 	}
 	info.hardware_id.value[sizeof(info.hardware_id.value) - 1] = '\0';
 
-	if(info.current_status && (info.valid & ACPI_VALID_HID) &&
+	if (info.current_status && (info.valid & ACPI_VALID_HID) &&
 			(!strcmp(info.hardware_id.value, IBM_HARDWARE_ID1) ||
 			!strcmp(info.hardware_id.value, IBM_HARDWARE_ID2))) {
 		dbg("found hardware: %s, handle: %p\n", info.hardware_id.value,
@@ -449,13 +449,11 @@ static int __init ibm_acpiphp_init(void)
 	}
 
 	ibm_note.device = device;
-	status = acpi_install_notify_handler(
-			ibm_acpi_handle,
-			ACPI_DEVICE_NOTIFY,
-			ibm_handle_events,
+	status = acpi_install_notify_handler(ibm_acpi_handle,
+			ACPI_DEVICE_NOTIFY, ibm_handle_events,
 			&ibm_note);
 	if (ACPI_FAILURE(status)) {
-		err("%s:  Failed to register notification handler\n",
+		err("%s: Failed to register notification handler\n",
 				__FUNCTION__);
 		retval = -EBUSY;
 		goto init_cleanup;
@@ -482,14 +480,13 @@ static void __exit ibm_acpiphp_exit(void
 	if (acpiphp_unregister_attention(&ibm_attention_info))
 		err("%s: attention info deregistration failed", __FUNCTION__);
 
-	   status = acpi_remove_notify_handler(
+	status = acpi_remove_notify_handler(
 			   ibm_acpi_handle,
 			   ACPI_DEVICE_NOTIFY,
 			   ibm_handle_events);
-	   if (ACPI_FAILURE(status))
-		   err("%s:  Notification handler removal failed\n",
-				   __FUNCTION__);
-	// remove the /sys entries
+	if (ACPI_FAILURE(status))
+		err("%s: Notification handler removal failed\n", __FUNCTION__);
+	/* remove the /sys entries */
 	if (sysfs_remove_bin_file(sysdir, &ibm_apci_table_attr))
 		err("%s: removal of sysfs file apci_table failed\n",
 				__FUNCTION__);
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
index aabf1e7..dc59da6 100644
--- a/drivers/pci/hotplug/ibmphp_core.c
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -235,12 +235,12 @@ static int set_attention_status(struct h
 {
 	int rc = 0;
 	struct slot *pslot;
-	u8 cmd;
+	u8 cmd = 0x00;     /* avoid compiler warning */
 
 	debug("set_attention_status - Entry hotplug_slot[%lx] value[%x]\n",
 			(ulong) hotplug_slot, value);
 	ibmphp_lock_operations();
-	cmd = 0x00;     // avoid compiler warning
+
 
 	if (hotplug_slot) {
 		switch (value) {
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
index 7d93dba..3eefe2c 100644
--- a/drivers/pci/hotplug/rpadlpar_core.c
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -103,13 +103,13 @@ static struct slot *find_slot(struct dev
 	struct list_head *tmp, *n;
 	struct slot *slot;
 
-        list_for_each_safe(tmp, n, &rpaphp_slot_head) {
-                slot = list_entry(tmp, struct slot, rpaphp_slot_list);
-                if (slot->dn == dn)
-                        return slot;
-        }
+	list_for_each_safe(tmp, n, &rpaphp_slot_head) {
+		slot = list_entry(tmp, struct slot, rpaphp_slot_list);
+		if (slot->dn == dn)
+			return slot;
+	}
 
-        return NULL;
+	return NULL;
 }
 
 static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent,
@@ -126,9 +126,9 @@ static struct pci_dev *dlpar_find_new_de
 	return NULL;
 }
 
-static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn)
+static void dlpar_pci_add_bus(struct device_node *dn)
 {
-	struct pci_dn *pdn = dn->data;
+	struct pci_dn *pdn = PCI_DN(dn);
 	struct pci_controller *phb = pdn->phb;
 	struct pci_dev *dev = NULL;
 
@@ -139,52 +139,52 @@ static struct pci_dev *dlpar_pci_add_bus
 	if (!dev) {
 		printk(KERN_ERR "%s: failed to create pci dev for %s\n",
 				__FUNCTION__, dn->full_name);
-		return NULL;
+		return;
 	}
 
 	if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
 	    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
 		of_scan_pci_bridge(dn, dev);
 
-	rpaphp_init_new_devs(dev->subordinate);
+	pcibios_fixup_new_pci_devices(dev->subordinate,0);
 
 	/* Claim new bus resources */
 	pcibios_claim_one_bus(dev->bus);
 
 	/* ioremap() for child bus, which may or may not succeed */
-	(void) remap_bus_range(dev->bus);
+	remap_bus_range(dev->subordinate);
 
 	/* Add new devices to global lists.  Register in proc, sysfs. */
 	pci_bus_add_devices(phb->bus);
-
-	/* Confirm new bridge dev was created */
-	dev = dlpar_find_new_dev(phb->bus, dn);
-	if (dev) {
-		if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
-			printk(KERN_ERR "%s: unexpected header type %d\n",
-				__FUNCTION__, dev->hdr_type);
-			return NULL;
-		}
-	}
-
-	return dev;
 }
 
 static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
 {
 	struct pci_dev *dev;
+	struct pci_controller *phb;
 
-	if (rpaphp_find_pci_bus(dn))
+	if (pcibios_find_pci_bus(dn))
 		return -EINVAL;
 
 	/* Add pci bus */
-	dev = dlpar_pci_add_bus(dn);
+	dlpar_pci_add_bus(dn);
+
+	/* Confirm new bridge dev was created */
+	phb = PCI_DN(dn)->phb;
+	dev = dlpar_find_new_dev(phb->bus, dn);
+
 	if (!dev) {
 		printk(KERN_ERR "%s: unable to add bus %s\n", __FUNCTION__,
 			drc_name);
 		return -EIO;
 	}
 
+	if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
+		printk(KERN_ERR "%s: unexpected header type %d, unable to add bus %s\n",
+			__FUNCTION__, dev->hdr_type, drc_name);
+		return -EIO;
+	}
+
 	/* Add hotplug slot */
 	if (rpaphp_add_slot(dn)) {
 		printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
@@ -221,13 +221,13 @@ static int dlpar_remove_phb(char *drc_na
 	struct pci_dn *pdn;
 	int rc = 0;
 
-	if (!rpaphp_find_pci_bus(dn))
+	if (!pcibios_find_pci_bus(dn))
 		return -EINVAL;
 
 	slot = find_slot(dn);
 	if (slot) {
 		/* Remove hotplug slot */
-		if (rpaphp_remove_slot(slot)) {
+		if (rpaphp_deregister_slot(slot)) {
 			printk(KERN_ERR
 				"%s: unable to remove hotplug slot %s\n",
 				__FUNCTION__, drc_name);
@@ -366,21 +366,25 @@ int dlpar_remove_pci_slot(char *drc_name
 	struct pci_bus *bus;
 	struct slot *slot;
 
-	bus = rpaphp_find_pci_bus(dn);
+	bus = pcibios_find_pci_bus(dn);
 	if (!bus)
 		return -EINVAL;
 
 	slot = find_slot(dn);
 	if (slot) {
 		/* Remove hotplug slot */
-		if (rpaphp_remove_slot(slot)) {
+		if (rpaphp_deregister_slot(slot)) {
 			printk(KERN_ERR
 				"%s: unable to remove hotplug slot %s\n",
 				__FUNCTION__, drc_name);
 			return -EIO;
 		}
 	} else {
-		rpaphp_unconfig_pci_adapter(bus);
+		struct pci_dev *dev, *tmp;
+		list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
+			eeh_remove_bus_device(dev);
+			pci_remove_bus_device(dev);
+		}
 	}
 
 	if (unmap_bus_range(bus)) {
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
index 57ea71a..310b618 100644
--- a/drivers/pci/hotplug/rpaphp.h
+++ b/drivers/pci/hotplug/rpaphp.h
@@ -88,16 +88,10 @@ extern int num_slots;
 /* function prototypes */
 
 /* rpaphp_pci.c */
-extern struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn);
-extern int rpaphp_claim_resource(struct pci_dev *dev, int resource);
 extern int rpaphp_enable_pci_slot(struct slot *slot);
-extern int register_pci_slot(struct slot *slot);
+extern int rpaphp_register_pci_slot(struct slot *slot);
 extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value);
-extern void rpaphp_init_new_devs(struct pci_bus *bus);
-extern void rpaphp_eeh_init_nodes(struct device_node *dn);
-
-extern int rpaphp_config_pci_adapter(struct pci_bus *bus);
-extern int rpaphp_unconfig_pci_adapter(struct pci_bus *bus);
+extern int rpaphp_get_sensor_state(struct slot *slot, int *state);
 
 /* rpaphp_core.c */
 extern int rpaphp_add_slot(struct device_node *dn);
@@ -108,8 +102,8 @@ extern int rpaphp_get_drc_props(struct d
 /* rpaphp_slot.c */
 extern void dealloc_slot_struct(struct slot *slot);
 extern struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain);
-extern int register_slot(struct slot *slot);
-extern int deregister_slot(struct slot *slot);
+extern int rpaphp_register_slot(struct slot *slot);
+extern int rpaphp_deregister_slot(struct slot *slot);
 extern int rpaphp_get_power_status(struct slot *slot, u8 * value);
 extern int rpaphp_set_attention_status(struct slot *slot, u8 status);
 	
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
index cf075c3..6e79f56 100644
--- a/drivers/pci/hotplug/rpaphp_core.c
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -56,25 +56,6 @@ MODULE_LICENSE("GPL");
 
 module_param(debug, bool, 0644);
 
-static int enable_slot(struct hotplug_slot *slot);
-static int disable_slot(struct hotplug_slot *slot);
-static int set_attention_status(struct hotplug_slot *slot, u8 value);
-static int get_power_status(struct hotplug_slot *slot, u8 * value);
-static int get_attention_status(struct hotplug_slot *slot, u8 * value);
-static int get_adapter_status(struct hotplug_slot *slot, u8 * value);
-static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value);
-
-struct hotplug_slot_ops rpaphp_hotplug_slot_ops = {
-	.owner = THIS_MODULE,
-	.enable_slot = enable_slot,
-	.disable_slot = disable_slot,
-	.set_attention_status = set_attention_status,
-	.get_power_status = get_power_status,
-	.get_attention_status = get_attention_status,
-	.get_adapter_status = get_adapter_status,
-	.get_max_bus_speed = get_max_bus_speed,
-};
-
 static int rpaphp_get_attention_status(struct slot *slot)
 {
 	return slot->hotplug_slot->info->attention_status;
@@ -196,11 +177,6 @@ static int get_max_bus_speed(struct hotp
 	return 0;
 }
 
-int rpaphp_remove_slot(struct slot *slot)
-{
-	return deregister_slot(slot);
-}
-
 static int get_children_props(struct device_node *dn, int **drc_indexes,
 		int **drc_names, int **drc_types, int **drc_power_domains)
 {
@@ -307,13 +283,15 @@ static int is_php_dn(struct device_node 
 	return 0;
 }
 
-/****************************************************************
+/**
+ * rpaphp_add_slot -- add hotplug or dlpar slot
+ *
  *	rpaphp not only registers PCI hotplug slots(HOTPLUG), 
  *	but also logical DR slots(EMBEDDED).
  *	HOTPLUG slot: An adapter can be physically added/removed. 
  *	EMBEDDED slot: An adapter can be logically removed/added
  *		  from/to a partition with the slot.
- ***************************************************************/
+ */
 int rpaphp_add_slot(struct device_node *dn)
 {
 	struct slot *slot;
@@ -344,7 +322,7 @@ int rpaphp_add_slot(struct device_node *
 			dbg("Found drc-index:0x%x drc-name:%s drc-type:%s\n",
 					indexes[i + 1], name, type);
 
-			retval = register_pci_slot(slot);
+			retval = rpaphp_register_pci_slot(slot);
 		}
 	}
 exit:
@@ -393,53 +371,85 @@ static void __exit rpaphp_exit(void)
 	cleanup_slots();
 }
 
-static int enable_slot(struct hotplug_slot *hotplug_slot)
+static int __enable_slot(struct slot *slot)
 {
-	int retval = 0;
-	struct slot *slot = (struct slot *)hotplug_slot->private;
+	int state;
+	int retval;
 
-	if (slot->state == CONFIGURED) {
-		dbg("%s: %s is already enabled\n", __FUNCTION__, slot->name);
-		goto exit;
+	if (slot->state == CONFIGURED)
+		return 0;
+
+	retval = rpaphp_get_sensor_state(slot, &state);
+	if (retval)
+		return retval;
+
+	if (state == PRESENT) {
+		pcibios_add_pci_devices(slot->bus);
+		slot->state = CONFIGURED;
+	} else if (state == EMPTY) {
+		slot->state = EMPTY;
+	} else {
+		err("%s: slot[%s] is in invalid state\n", __FUNCTION__, slot->name);
+		slot->state = NOT_VALID;
+		return -EINVAL;
 	}
+	return 0;
+}
+
+static int enable_slot(struct hotplug_slot *hotplug_slot)
+{
+	int retval;
+	struct slot *slot = (struct slot *)hotplug_slot->private;
 
-	dbg("ENABLING SLOT %s\n", slot->name);
 	down(&rpaphp_sem);
-	retval = rpaphp_enable_pci_slot(slot);
+	retval = __enable_slot(slot);
 	up(&rpaphp_sem);
-exit:
-	dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
+
 	return retval;
 }
 
-static int disable_slot(struct hotplug_slot *hotplug_slot)
+static int __disable_slot(struct slot *slot)
 {
-	int retval = -EINVAL;
-	struct slot *slot = (struct slot *)hotplug_slot->private;
+	struct pci_dev *dev, *tmp;
 
-	dbg("%s - Entry: slot[%s]\n", __FUNCTION__, slot->name);
+	if (slot->state == NOT_CONFIGURED)
+		return -EINVAL;
 
-	if (slot->state == NOT_CONFIGURED) {
-		dbg("%s: %s is already disabled\n", __FUNCTION__, slot->name);
-		goto exit;
+	list_for_each_entry_safe(dev, tmp, &slot->bus->devices, bus_list) {
+		eeh_remove_bus_device(dev);
+		pci_remove_bus_device(dev);
 	}
 
-	dbg("DISABLING SLOT %s\n", slot->name);
+	slot->state = NOT_CONFIGURED;
+	return 0;
+}
+
+static int disable_slot(struct hotplug_slot *hotplug_slot)
+{
+	struct slot *slot = (struct slot *)hotplug_slot->private;
+	int retval;
+
 	down(&rpaphp_sem);
-	retval = rpaphp_unconfig_pci_adapter(slot->bus);
+	retval = __disable_slot (slot);
 	up(&rpaphp_sem);
-	slot->state = NOT_CONFIGURED;
-	info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__,
-	     slot->name);
-exit:
-	dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
+
 	return retval;
 }
 
+struct hotplug_slot_ops rpaphp_hotplug_slot_ops = {
+	.owner = THIS_MODULE,
+	.enable_slot = enable_slot,
+	.disable_slot = disable_slot,
+	.set_attention_status = set_attention_status,
+	.get_power_status = get_power_status,
+	.get_attention_status = get_attention_status,
+	.get_adapter_status = get_adapter_status,
+	.get_max_bus_speed = get_max_bus_speed,
+};
+
 module_init(rpaphp_init);
 module_exit(rpaphp_exit);
 
 EXPORT_SYMBOL_GPL(rpaphp_add_slot);
-EXPORT_SYMBOL_GPL(rpaphp_remove_slot);
 EXPORT_SYMBOL_GPL(rpaphp_slot_head);
 EXPORT_SYMBOL_GPL(rpaphp_get_drc_props);
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c
index 396b54b..6f6cbed 100644
--- a/drivers/pci/hotplug/rpaphp_pci.c
+++ b/drivers/pci/hotplug/rpaphp_pci.c
@@ -32,37 +32,7 @@
 #include "../pci.h"		/* for pci_add_new_bus */
 #include "rpaphp.h"
 
-static struct pci_bus *find_bus_among_children(struct pci_bus *bus,
-					struct device_node *dn)
-{
-	struct pci_bus *child = NULL;
-	struct list_head *tmp;
-	struct device_node *busdn;
-
-	busdn = pci_bus_to_OF_node(bus);
-	if (busdn == dn)
-		return bus;
-
-	list_for_each(tmp, &bus->children) {
-		child = find_bus_among_children(pci_bus_b(tmp), dn);
-		if (child)
-			break;
-	}
-	return child;
-}
-
-struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn)
-{
-	struct pci_dn *pdn = dn->data;
-
-	if (!pdn  || !pdn->phb || !pdn->phb->bus)
-		return NULL;
-
-	return find_bus_among_children(pdn->phb->bus, dn);
-}
-EXPORT_SYMBOL_GPL(rpaphp_find_pci_bus);
-
-static int rpaphp_get_sensor_state(struct slot *slot, int *state)
+int rpaphp_get_sensor_state(struct slot *slot, int *state)
 {
 	int rc;
 	int setlevel;
@@ -120,7 +90,7 @@ int rpaphp_get_pci_adapter_status(struct
 			/* config/unconfig adapter */
 			*value = slot->state;
 		} else {
-			bus = rpaphp_find_pci_bus(slot->dn);
+			bus = pcibios_find_pci_bus(slot->dn);
 			if (bus && !list_empty(&bus->devices))
 				*value = CONFIGURED;
 			else
@@ -131,140 +101,6 @@ exit:
 	return rc;
 }
 
-/* Must be called before pci_bus_add_devices */
-void rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
-{
-	struct pci_dev *dev;
-
-	list_for_each_entry(dev, &bus->devices, bus_list) {
-		/*
-		 * Skip already-present devices (which are on the
-		 * global device list.)
-		 */
-		if (list_empty(&dev->global_list)) {
-			int i;
-			
-			/* Need to setup IOMMU tables */
-			ppc_md.iommu_dev_setup(dev);
-
-			if(fix_bus)
-				pcibios_fixup_device_resources(dev, bus);
-			pci_read_irq_line(dev);
-			for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-				struct resource *r = &dev->resource[i];
-
-				if (r->parent || !r->start || !r->flags)
-					continue;
-				pci_claim_resource(dev, i);
-			}
-		}
-	}
-}
-
-static void rpaphp_eeh_add_bus_device(struct pci_bus *bus)
-{
-	struct pci_dev *dev;
-
-	list_for_each_entry(dev, &bus->devices, bus_list) {
-		eeh_add_device_late(dev);
-		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
-			struct pci_bus *subbus = dev->subordinate;
-			if (subbus)
-				rpaphp_eeh_add_bus_device (subbus);
-		}
-	}
-}
-
-static int rpaphp_pci_config_bridge(struct pci_dev *dev)
-{
-	u8 sec_busno;
-	struct pci_bus *child_bus;
-	struct pci_dev *child_dev;
-
-	dbg("Enter %s:  BRIDGE dev=%s\n", __FUNCTION__, pci_name(dev));
-
-	/* get busno of downstream bus */
-	pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno);
-		
-	/* add to children of PCI bridge dev->bus */
-	child_bus = pci_add_new_bus(dev->bus, dev, sec_busno);
-	if (!child_bus) {
-		err("%s: could not add second bus\n", __FUNCTION__);
-		return -EIO;
-	}
-	sprintf(child_bus->name, "PCI Bus #%02x", child_bus->number);
-	/* do pci_scan_child_bus */
-	pci_scan_child_bus(child_bus);
-
-	list_for_each_entry(child_dev, &child_bus->devices, bus_list) {
-		eeh_add_device_late(child_dev);
-	}
-
-	 /* fixup new pci devices without touching bus struct */
-	rpaphp_fixup_new_pci_devices(child_bus, 0);
-
-	/* Make the discovered devices available */
-	pci_bus_add_devices(child_bus);
-	return 0;
-}
-
-void rpaphp_init_new_devs(struct pci_bus *bus)
-{
-	rpaphp_fixup_new_pci_devices(bus, 0);
-	rpaphp_eeh_add_bus_device(bus);
-}
-EXPORT_SYMBOL_GPL(rpaphp_init_new_devs);
-
-/*****************************************************************************
- rpaphp_pci_config_slot() will  configure all devices under the
- given slot->dn and return the the first pci_dev.
- *****************************************************************************/
-static struct pci_dev *
-rpaphp_pci_config_slot(struct pci_bus *bus)
-{
-	struct device_node *dn = pci_bus_to_OF_node(bus);
-	struct pci_dev *dev = NULL;
-	int slotno;
-	int num;
-
-	dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name);
-	if (!dn || !dn->child)
-		return NULL;
-
-	if (_machine == PLATFORM_PSERIES_LPAR) {
-		of_scan_bus(dn, bus);
-		if (list_empty(&bus->devices)) {
-			err("%s: No new device found\n", __FUNCTION__);
-			return NULL;
-		}
-
-		rpaphp_init_new_devs(bus);
-		pci_bus_add_devices(bus);
-		dev = list_entry(&bus->devices, struct pci_dev, bus_list);
-	} else {
-		slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
-
-		/* pci_scan_slot should find all children */
-		num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
-		if (num) {
-			rpaphp_fixup_new_pci_devices(bus, 1);
-			pci_bus_add_devices(bus);
-		}
-		if (list_empty(&bus->devices)) {
-			err("%s: No new device found\n", __FUNCTION__);
-			return NULL;
-		}
-		list_for_each_entry(dev, &bus->devices, bus_list) {
-			if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
-				rpaphp_pci_config_bridge(dev);
-
-			rpaphp_eeh_add_bus_device(bus);
-		}
-	}
-
-	return dev;
-}
-
 static void print_slot_pci_funcs(struct pci_bus *bus)
 {
 	struct device_node *dn;
@@ -280,60 +116,6 @@ static void print_slot_pci_funcs(struct 
 	return;
 }
 
-int rpaphp_config_pci_adapter(struct pci_bus *bus)
-{
-	struct device_node *dn = pci_bus_to_OF_node(bus);
-	struct pci_dev *dev;
-	int rc = -ENODEV;
-
-	dbg("Entry %s: slot[%s]\n", __FUNCTION__, dn->full_name);
-	if (!dn)
-		goto exit;
-
-	eeh_add_device_tree_early(dn);
-	dev = rpaphp_pci_config_slot(bus);
-	if (!dev) {
-		err("%s: can't find any devices.\n", __FUNCTION__);
-		goto exit;
-	}
-	print_slot_pci_funcs(bus);
-	rc = 0;
-exit:
-	dbg("Exit %s:  rc=%d\n", __FUNCTION__, rc);
-	return rc;
-}
-EXPORT_SYMBOL_GPL(rpaphp_config_pci_adapter);
-
-static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev)
-{
-	eeh_remove_device(dev);
-	if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
-		struct pci_bus *bus = dev->subordinate;
-		struct list_head *ln;
-		if (!bus)
-			return; 
-		for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
-			struct pci_dev *pdev = pci_dev_b(ln);
-			if (pdev)
-				rpaphp_eeh_remove_bus_device(pdev);
-		}
-
-	}
-	return;
-}
-
-int rpaphp_unconfig_pci_adapter(struct pci_bus *bus)
-{
-	struct pci_dev *dev, *tmp;
-
-	list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
-		rpaphp_eeh_remove_bus_device(dev);
-		pci_remove_bus_device(dev);
-	}
-	return 0;
-}
-EXPORT_SYMBOL_GPL(rpaphp_unconfig_pci_adapter);
-
 static int setup_pci_hotplug_slot_info(struct slot *slot)
 {
 	struct hotplug_slot_info *hotplug_slot_info = slot->hotplug_slot->info;
@@ -370,7 +152,7 @@ static int setup_pci_slot(struct slot *s
 	struct pci_bus *bus;
 
 	BUG_ON(!dn);
-	bus = rpaphp_find_pci_bus(dn);
+	bus = pcibios_find_pci_bus(dn);
 	if (!bus) {
 		err("%s: no pci_bus for dn %s\n", __FUNCTION__, dn->full_name);
 		goto exit_rc;
@@ -395,10 +177,7 @@ static int setup_pci_slot(struct slot *s
 		if (slot->hotplug_slot->info->adapter_status == NOT_CONFIGURED) {
 			dbg("%s CONFIGURING pci adapter in slot[%s]\n",  
 				__FUNCTION__, slot->name);
-			if (rpaphp_config_pci_adapter(slot->bus)) {
-				err("%s: CONFIG pci adapter failed\n", __FUNCTION__);
-				goto exit_rc;		
-			}
+			pcibios_add_pci_devices(slot->bus);
 
 		} else if (slot->hotplug_slot->info->adapter_status != CONFIGURED) {
 			err("%s: slot[%s]'s adapter_status is NOT_VALID.\n",
@@ -420,7 +199,7 @@ exit_rc:
 	return -EINVAL;
 }
 
-int register_pci_slot(struct slot *slot)
+int rpaphp_register_pci_slot(struct slot *slot)
 {
 	int rc = -EINVAL;
 
@@ -428,42 +207,8 @@ int register_pci_slot(struct slot *slot)
 		goto exit_rc;
 	if (setup_pci_slot(slot))
 		goto exit_rc;
-	rc = register_slot(slot);
+	rc = rpaphp_register_slot(slot);
 exit_rc:
 	return rc;
 }
 
-int rpaphp_enable_pci_slot(struct slot *slot)
-{
-	int retval = 0, state;
-
-	retval = rpaphp_get_sensor_state(slot, &state);
-	if (retval)
-		goto exit;
-	dbg("%s: sensor state[%d]\n", __FUNCTION__, state);
-	/* if slot is not empty, enable the adapter */
-	if (state == PRESENT) {
-		dbg("%s : slot[%s] is occupied.\n", __FUNCTION__, slot->name);
-		retval = rpaphp_config_pci_adapter(slot->bus);
-		if (!retval) {
-			slot->state = CONFIGURED;
-			info("%s: devices in slot[%s] configured\n",
-					__FUNCTION__, slot->name);
-		} else {
-			slot->state = NOT_CONFIGURED;
-			dbg("%s: no pci_dev struct for adapter in slot[%s]\n",
-			    __FUNCTION__, slot->name);
-		}
-	} else if (state == EMPTY) {
-		dbg("%s : slot[%s] is empty\n", __FUNCTION__, slot->name);
-		slot->state = EMPTY;
-	} else {
-		err("%s: slot[%s] is in invalid state\n", __FUNCTION__,
-		    slot->name);
-		slot->state = NOT_VALID;
-		retval = -EINVAL;
-	}
-exit:
-	dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
-	return retval;
-}
diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c
index daa89ae..78943e0 100644
--- a/drivers/pci/hotplug/rpaphp_slot.c
+++ b/drivers/pci/hotplug/rpaphp_slot.c
@@ -35,16 +35,16 @@
 
 static ssize_t location_read_file (struct hotplug_slot *php_slot, char *buf)
 {
-        char *value;
-        int retval = -ENOENT;
+	char *value;
+	int retval = -ENOENT;
 	struct slot *slot = (struct slot *)php_slot->private;
 
 	if (!slot)
 		return retval;
 
-        value = slot->location;
-        retval = sprintf (buf, "%s\n", value);
-        return retval;
+	value = slot->location;
+	retval = sprintf (buf, "%s\n", value);
+	return retval;
 }
 
 static struct hotplug_slot_attribute hotplug_slot_attr_location = {
@@ -137,7 +137,7 @@ static int is_registered(struct slot *sl
 	return 0;
 }
 
-int deregister_slot(struct slot *slot)
+int rpaphp_deregister_slot(struct slot *slot)
 {
 	int retval = 0;
 	struct hotplug_slot *php_slot = slot->hotplug_slot;
@@ -159,8 +159,9 @@ int deregister_slot(struct slot *slot)
 	dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
 	return retval;
 }
+EXPORT_SYMBOL_GPL(rpaphp_deregister_slot);
 
-int register_slot(struct slot *slot)
+int rpaphp_register_slot(struct slot *slot)
 {
 	int retval;
 
@@ -169,7 +170,7 @@ int register_slot(struct slot *slot)
 		slot->power_domain, slot->type);
 	/* should not try to register the same slot twice */
 	if (is_registered(slot)) { /* should't be here */
-		err("register_slot: slot[%s] is already registered\n", slot->name);
+		err("rpaphp_register_slot: slot[%s] is already registered\n", slot->name);
 		rpaphp_release_slot(slot->hotplug_slot);
 		return -EAGAIN;
 	}	
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index ce0e9b6..7d6f521 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -95,6 +95,7 @@ struct controller {
 	u8 function;
 	u8 slot_device_offset;
 	u8 add_support;
+	u32 pcix_misc2_reg;	/* for amd pogo errata */
 	enum pci_bus_speed speed;
 	u32 first_slot;		/* First physical slot number */
 	u8 slot_bus;		/* Bus where the slots handled by this controller sit */
@@ -113,6 +114,26 @@ struct hotplug_params {
 
 /* Define AMD SHPC ID  */
 #define PCI_DEVICE_ID_AMD_GOLAM_7450	0x7450 
+#define PCI_DEVICE_ID_AMD_POGO_7458	0x7458
+
+/* AMD PCIX bridge registers */
+
+#define PCIX_MEM_BASE_LIMIT_OFFSET	0x1C
+#define PCIX_MISCII_OFFSET		0x48
+#define PCIX_MISC_BRIDGE_ERRORS_OFFSET	0x80
+
+/* AMD PCIX_MISCII masks and offsets */
+#define PERRNONFATALENABLE_MASK		0x00040000
+#define PERRFATALENABLE_MASK		0x00080000
+#define PERRFLOODENABLE_MASK		0x00100000
+#define SERRNONFATALENABLE_MASK		0x00200000
+#define SERRFATALENABLE_MASK		0x00400000
+
+/* AMD PCIX_MISC_BRIDGE_ERRORS masks and offsets */
+#define PERR_OBSERVED_MASK		0x00000001
+
+/* AMD PCIX_MEM_BASE_LIMIT masks */
+#define RSE_MASK			0x40000000
 
 #define INT_BUTTON_IGNORE		0
 #define INT_PRESENCE_ON			1
@@ -333,6 +354,79 @@ static inline int wait_for_ctrl_irq (str
 	return retval;
 }
 
+static inline void amd_pogo_errata_save_misc_reg(struct slot *p_slot)
+{
+	u32 pcix_misc2_temp;
+
+	/* save MiscII register */
+	pci_read_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, &pcix_misc2_temp);
+
+	p_slot->ctrl->pcix_misc2_reg = pcix_misc2_temp;
+
+	/* clear SERR/PERR enable bits */
+	pcix_misc2_temp &= ~SERRFATALENABLE_MASK;
+	pcix_misc2_temp &= ~SERRNONFATALENABLE_MASK;
+	pcix_misc2_temp &= ~PERRFLOODENABLE_MASK;
+	pcix_misc2_temp &= ~PERRFATALENABLE_MASK;
+	pcix_misc2_temp &= ~PERRNONFATALENABLE_MASK;
+	pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, pcix_misc2_temp);
+}
+
+static inline void amd_pogo_errata_restore_misc_reg(struct slot *p_slot)
+{
+	u32 pcix_misc2_temp;
+	u32 pcix_bridge_errors_reg;
+	u32 pcix_mem_base_reg;
+	u8  perr_set;
+	u8  rse_set;
+
+	/* write-one-to-clear Bridge_Errors[ PERR_OBSERVED ] */
+	pci_read_config_dword(p_slot->ctrl->pci_dev, PCIX_MISC_BRIDGE_ERRORS_OFFSET, &pcix_bridge_errors_reg);
+	perr_set = pcix_bridge_errors_reg & PERR_OBSERVED_MASK;
+	if (perr_set) {
+		dbg ("%s  W1C: Bridge_Errors[ PERR_OBSERVED = %08X]\n",__FUNCTION__ , perr_set);
+
+		pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MISC_BRIDGE_ERRORS_OFFSET, perr_set);
+	}
+
+	/* write-one-to-clear Memory_Base_Limit[ RSE ] */
+	pci_read_config_dword(p_slot->ctrl->pci_dev, PCIX_MEM_BASE_LIMIT_OFFSET, &pcix_mem_base_reg);
+	rse_set = pcix_mem_base_reg & RSE_MASK;
+	if (rse_set) {
+		dbg ("%s  W1C: Memory_Base_Limit[ RSE ]\n",__FUNCTION__ );
+
+		pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MEM_BASE_LIMIT_OFFSET, rse_set);
+	}
+	/* restore MiscII register */
+	pci_read_config_dword( p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, &pcix_misc2_temp );
+
+	if (p_slot->ctrl->pcix_misc2_reg & SERRFATALENABLE_MASK)
+		pcix_misc2_temp |= SERRFATALENABLE_MASK;
+	else
+		pcix_misc2_temp &= ~SERRFATALENABLE_MASK;
+
+	if (p_slot->ctrl->pcix_misc2_reg & SERRNONFATALENABLE_MASK)
+		pcix_misc2_temp |= SERRNONFATALENABLE_MASK;
+	else
+		pcix_misc2_temp &= ~SERRNONFATALENABLE_MASK;
+
+	if (p_slot->ctrl->pcix_misc2_reg & PERRFLOODENABLE_MASK)
+		pcix_misc2_temp |= PERRFLOODENABLE_MASK;
+	else
+		pcix_misc2_temp &= ~PERRFLOODENABLE_MASK;
+
+	if (p_slot->ctrl->pcix_misc2_reg & PERRFATALENABLE_MASK)
+		pcix_misc2_temp |= PERRFATALENABLE_MASK;
+	else
+		pcix_misc2_temp &= ~PERRFATALENABLE_MASK;
+
+	if (p_slot->ctrl->pcix_misc2_reg & PERRNONFATALENABLE_MASK)
+		pcix_misc2_temp |= PERRNONFATALENABLE_MASK;
+	else
+		pcix_misc2_temp &= ~PERRNONFATALENABLE_MASK;
+	pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, pcix_misc2_temp);
+}
+
 #define SLOT_NAME_SIZE 10
 
 static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index 25ccb0e..643252d 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -894,7 +894,17 @@ int shpchp_enable_slot (struct slot *p_s
 	dbg("%s: p_slot->pwr_save %x\n", __FUNCTION__, p_slot->pwr_save);
 	p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
 
-	rc = board_added(p_slot);
+	if(((p_slot->ctrl->pci_dev->vendor == PCI_VENDOR_ID_AMD) ||
+	    (p_slot->ctrl->pci_dev->device == PCI_DEVICE_ID_AMD_POGO_7458))
+	     && p_slot->ctrl->num_slots == 1) {
+		/* handle amd pogo errata; this must be done before enable  */
+		amd_pogo_errata_save_misc_reg(p_slot);
+		rc = board_added(p_slot);
+		/* handle amd pogo errata; this must be done after enable  */
+		amd_pogo_errata_restore_misc_reg(p_slot);
+	} else
+		rc = board_added(p_slot);
+
 	if (rc) {
 		p_slot->hpc_ops->get_adapter_status(p_slot,
 				&(p_slot->presence_save));
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 202b750..48723d6 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -137,6 +137,8 @@ static void set_msi_affinity(unsigned in
 		break;
 	}
 }
+#else
+#define set_msi_affinity NULL
 #endif /* CONFIG_SMP */
 
 static void mask_MSI_irq(unsigned int vector)
@@ -214,7 +216,7 @@ static struct hw_interrupt_type msix_irq
 	.disable	= mask_MSI_irq,
 	.ack		= mask_MSI_irq,
 	.end		= end_msi_irq_w_maskbit,
-	.set_affinity	= set_msi_irq_affinity
+	.set_affinity	= set_msi_affinity
 };
 
 /*
@@ -230,7 +232,7 @@ static struct hw_interrupt_type msi_irq_
 	.disable	= mask_MSI_irq,
 	.ack		= mask_MSI_irq,
 	.end		= end_msi_irq_w_maskbit,
-	.set_affinity	= set_msi_irq_affinity
+	.set_affinity	= set_msi_affinity
 };
 
 /*
@@ -246,7 +248,7 @@ static struct hw_interrupt_type msi_irq_
 	.disable	= do_nothing,
 	.ack		= do_nothing,
 	.end		= end_msi_irq_wo_maskbit,
-	.set_affinity	= set_msi_irq_affinity
+	.set_affinity	= set_msi_affinity
 };
 
 static void msi_data_init(struct msg_data *msi_data,
@@ -416,7 +418,9 @@ static void attach_msi_entry(struct msi_
 
 static void irq_handler_init(int cap_id, int pos, int mask)
 {
-	spin_lock(&irq_desc[pos].lock);
+	unsigned long flags;
+
+	spin_lock_irqsave(&irq_desc[pos].lock, flags);
 	if (cap_id == PCI_CAP_ID_MSIX)
 		irq_desc[pos].handler = &msix_irq_type;
 	else {
@@ -425,7 +429,7 @@ static void irq_handler_init(int cap_id,
 		else
 			irq_desc[pos].handler = &msi_irq_w_maskbit_type;
 	}
-	spin_unlock(&irq_desc[pos].lock);
+	spin_unlock_irqrestore(&irq_desc[pos].lock, flags);
 }
 
 static void enable_msi_mode(struct pci_dev *dev, int pos, int type)
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h
index 402136a..4ac52d4 100644
--- a/drivers/pci/msi.h
+++ b/drivers/pci/msi.h
@@ -22,12 +22,6 @@ extern int vector_irq[NR_VECTORS];
 extern void (*interrupt[NR_IRQS])(void);
 extern int pci_vector_resources(int last, int nr_released);
 
-#ifdef CONFIG_SMP
-#define set_msi_irq_affinity	set_msi_affinity
-#else
-#define set_msi_irq_affinity	NULL
-#endif
-
 /*
  * MSI-X Address Register
  */
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index d2a633e..d2d1879 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -163,6 +163,7 @@ int pci_bus_find_capability(struct pci_b
 	return __pci_bus_find_cap(bus, devfn, hdr_type & 0x7f, cap);
 }
 
+#if 0
 /**
  * pci_find_ext_capability - Find an extended capability
  * @dev: PCI device to query
@@ -210,6 +211,7 @@ int pci_find_ext_capability(struct pci_d
 
 	return 0;
 }
+#endif  /*  0  */
 
 /**
  * pci_find_parent_resource - return resource region of parent bus of given region
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 605f0df..dda6099 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1142,6 +1142,9 @@ static void __devinit quirk_intel_ide_co
 	case 0x27c4:
 		ich = 7;
 		break;
+	case 0x2828:	/* ICH8M */
+		ich = 8;
+		break;
 	default:
 		/* we do not handle this PCI device */
 		return;
@@ -1161,7 +1164,7 @@ static void __devinit quirk_intel_ide_co
 		else
 			return;			/* not in combined mode */
 	} else {
-		WARN_ON((ich != 6) && (ich != 7));
+		WARN_ON((ich != 6) && (ich != 7) && (ich != 8));
 		tmp &= 0x3;  /* interesting bits 1:0 */
 		if (tmp & (1 << 0))
 			comb = (1 << 2);	/* PATA port 0, SATA port 1 */
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 50d6685..ea9277b 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -112,6 +112,7 @@ pci_claim_resource(struct pci_dev *dev, 
 
 	return err;
 }
+EXPORT_SYMBOL_GPL(pci_claim_resource);
 
 int pci_assign_resource(struct pci_dev *dev, int resno)
 {
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c
index 0ecbe4e..aaa568a 100644
--- a/drivers/pnp/card.c
+++ b/drivers/pnp/card.c
@@ -363,7 +363,7 @@ static int card_resume(struct pnp_dev *d
 
 int pnp_register_card_driver(struct pnp_card_driver * drv)
 {
-	int count = 0;
+	int count;
 	struct list_head *pos, *temp;
 
 	drv->link.name = drv->name;
@@ -374,10 +374,15 @@ int pnp_register_card_driver(struct pnp_
 	drv->link.suspend = drv->suspend ? card_suspend : NULL;
 	drv->link.resume = drv->resume ? card_resume : NULL;
 
+	count = pnp_register_driver(&drv->link);
+	if (count < 0)
+		return count;
+
 	spin_lock(&pnp_lock);
 	list_add_tail(&drv->global_list, &pnp_card_drivers);
 	spin_unlock(&pnp_lock);
-	pnp_register_driver(&drv->link);
+
+	count = 0;
 
 	list_for_each_safe(pos,temp,&pnp_cards){
 		struct pnp_card *card = list_entry(pos, struct pnp_card, global_list);
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 816479a..f104577 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -27,12 +27,15 @@
 
 static int num = 0;
 
+/* We need only to blacklist devices that have already an acpi driver that
+ * can't use pnp layer. We don't need to blacklist device that are directly
+ * used by the kernel (PCI root, ...), as it is harmless and there were
+ * already present in pnpbios. But there is an exception for devices that
+ * have irqs (PIC, Timer) because we call acpi_register_gsi.
+ * Finaly only devices that have a CRS method need to be in this list.
+ */
 static char __initdata excluded_id_list[] =
-	"PNP0C0A," /* Battery */
-	"PNP0C0C,PNP0C0E,PNP0C0D," /* Button */
 	"PNP0C09," /* EC */
-	"PNP0C0B," /* Fan */
-	"PNP0A03," /* PCI root */
 	"PNP0C0F," /* Link device */
 	"PNP0000," /* PIC */
 	"PNP0100," /* Timer */
@@ -131,7 +134,8 @@ static int __init pnpacpi_add_device(str
 	struct pnp_id *dev_id;
 	struct pnp_dev *dev;
 
-	if (!ispnpidacpi(acpi_device_hid(device)) ||
+	status = acpi_get_handle(device->handle, "_CRS", &temp);
+	if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) ||
 		is_exclusive_device(device))
 		return 0;
 
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 416d30d..407b4ea 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr>
  * Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com>
- * 
+ *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
  * Free Software Foundation; either version 2, or (at your option) any
@@ -32,17 +32,17 @@
 /*
  * Allocated Resources
  */
-static int irq_flags(int edge_level, int active_high_low)
+static int irq_flags(int triggering, int polarity)
 {
 	int flag;
-	if (edge_level == ACPI_LEVEL_SENSITIVE) {
-		if(active_high_low == ACPI_ACTIVE_LOW)
+	if (triggering == ACPI_LEVEL_SENSITIVE) {
+		if(polarity == ACPI_ACTIVE_LOW)
 			flag = IORESOURCE_IRQ_LOWLEVEL;
 		else
 			flag = IORESOURCE_IRQ_HIGHLEVEL;
 	}
 	else {
-		if(active_high_low == ACPI_ACTIVE_LOW)
+		if(polarity == ACPI_ACTIVE_LOW)
 			flag = IORESOURCE_IRQ_LOWEDGE;
 		else
 			flag = IORESOURCE_IRQ_HIGHEDGE;
@@ -50,31 +50,31 @@ static int irq_flags(int edge_level, int
 	return flag;
 }
 
-static void decode_irq_flags(int flag, int *edge_level, int *active_high_low)
+static void decode_irq_flags(int flag, int *triggering, int *polarity)
 {
 	switch (flag) {
 	case IORESOURCE_IRQ_LOWLEVEL:
-		*edge_level = ACPI_LEVEL_SENSITIVE;
-		*active_high_low = ACPI_ACTIVE_LOW;
+		*triggering = ACPI_LEVEL_SENSITIVE;
+		*polarity = ACPI_ACTIVE_LOW;
 		break;
 	case IORESOURCE_IRQ_HIGHLEVEL:	
-		*edge_level = ACPI_LEVEL_SENSITIVE;
-		*active_high_low = ACPI_ACTIVE_HIGH;
+		*triggering = ACPI_LEVEL_SENSITIVE;
+		*polarity = ACPI_ACTIVE_HIGH;
 		break;
 	case IORESOURCE_IRQ_LOWEDGE:
-		*edge_level = ACPI_EDGE_SENSITIVE;
-		*active_high_low = ACPI_ACTIVE_LOW;
+		*triggering = ACPI_EDGE_SENSITIVE;
+		*polarity = ACPI_ACTIVE_LOW;
 		break;
 	case IORESOURCE_IRQ_HIGHEDGE:
-		*edge_level = ACPI_EDGE_SENSITIVE;
-		*active_high_low = ACPI_ACTIVE_HIGH;
+		*triggering = ACPI_EDGE_SENSITIVE;
+		*polarity = ACPI_ACTIVE_HIGH;
 		break;
 	}
 }
 
 static void
 pnpacpi_parse_allocated_irqresource(struct pnp_resource_table * res, u32 gsi,
-	int edge_level, int active_high_low)
+	int triggering, int polarity)
 {
 	int i = 0;
 	int irq;
@@ -89,7 +89,7 @@ pnpacpi_parse_allocated_irqresource(stru
 		return;
 
 	res->irq_resource[i].flags = IORESOURCE_IRQ;  // Also clears _UNSET flag
-	irq = acpi_register_gsi(gsi, edge_level, active_high_low);
+	irq = acpi_register_gsi(gsi, triggering, polarity);
 	if (irq < 0) {
 		res->irq_resource[i].flags |= IORESOURCE_DISABLED;
 		return;
@@ -163,77 +163,96 @@ static acpi_status pnpacpi_allocated_res
 	struct pnp_resource_table * res_table = (struct pnp_resource_table *)data;
 	int i;
 
-	switch (res->id) {
-	case ACPI_RSTYPE_IRQ:
+	switch (res->type) {
+	case ACPI_RESOURCE_TYPE_IRQ:
 		/*
 		 * Per spec, only one interrupt per descriptor is allowed in
 		 * _CRS, but some firmware violates this, so parse them all.
 		 */
-		for (i = 0; i < res->data.irq.number_of_interrupts; i++) {
+		for (i = 0; i < res->data.irq.interrupt_count; i++) {
 			pnpacpi_parse_allocated_irqresource(res_table,
 				res->data.irq.interrupts[i],
-				res->data.irq.edge_level,
-				res->data.irq.active_high_low);
+				res->data.irq.triggering,
+				res->data.irq.polarity);
 		}
 		break;
 
-	case ACPI_RSTYPE_EXT_IRQ:
-		for (i = 0; i < res->data.extended_irq.number_of_interrupts; i++) {
-			pnpacpi_parse_allocated_irqresource(res_table,
-				res->data.extended_irq.interrupts[i],
-				res->data.extended_irq.edge_level,
-				res->data.extended_irq.active_high_low);
-		}
-		break;
-	case ACPI_RSTYPE_DMA:
-		if (res->data.dma.number_of_channels > 0)
-			pnpacpi_parse_allocated_dmaresource(res_table, 
+	case ACPI_RESOURCE_TYPE_DMA:
+		if (res->data.dma.channel_count > 0)
+			pnpacpi_parse_allocated_dmaresource(res_table,
 					res->data.dma.channels[0]);
 		break;
-	case ACPI_RSTYPE_IO:
-		pnpacpi_parse_allocated_ioresource(res_table, 
-				res->data.io.min_base_address, 
-				res->data.io.range_length);
-		break;
-	case ACPI_RSTYPE_FIXED_IO:
-		pnpacpi_parse_allocated_ioresource(res_table, 
-				res->data.fixed_io.base_address, 
-				res->data.fixed_io.range_length);
-		break;
-	case ACPI_RSTYPE_MEM24:
-		pnpacpi_parse_allocated_memresource(res_table, 
-				res->data.memory24.min_base_address, 
-				res->data.memory24.range_length);
-		break;
-	case ACPI_RSTYPE_MEM32:
-		pnpacpi_parse_allocated_memresource(res_table, 
-				res->data.memory32.min_base_address, 
-				res->data.memory32.range_length);
-		break;
-	case ACPI_RSTYPE_FIXED_MEM32:
-		pnpacpi_parse_allocated_memresource(res_table, 
-				res->data.fixed_memory32.range_base_address, 
-				res->data.fixed_memory32.range_length);
-		break;
-	case ACPI_RSTYPE_ADDRESS16:
-		pnpacpi_parse_allocated_memresource(res_table, 
-				res->data.address16.min_address_range, 
+
+	case ACPI_RESOURCE_TYPE_IO:
+		pnpacpi_parse_allocated_ioresource(res_table,
+				res->data.io.minimum,
+				res->data.io.address_length);
+		break;
+
+	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
+	case ACPI_RESOURCE_TYPE_END_DEPENDENT:
+		break;
+
+	case ACPI_RESOURCE_TYPE_FIXED_IO:
+		pnpacpi_parse_allocated_ioresource(res_table,
+				res->data.fixed_io.address,
+				res->data.fixed_io.address_length);
+		break;
+
+	case ACPI_RESOURCE_TYPE_VENDOR:
+		break;
+
+	case ACPI_RESOURCE_TYPE_END_TAG:
+		break;
+
+	case ACPI_RESOURCE_TYPE_MEMORY24:
+		pnpacpi_parse_allocated_memresource(res_table,
+				res->data.memory24.minimum,
+				res->data.memory24.address_length);
+		break;
+	case ACPI_RESOURCE_TYPE_MEMORY32:
+		pnpacpi_parse_allocated_memresource(res_table,
+				res->data.memory32.minimum,
+				res->data.memory32.address_length);
+		break;
+	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
+		pnpacpi_parse_allocated_memresource(res_table,
+				res->data.fixed_memory32.address,
+				res->data.fixed_memory32.address_length);
+		break;
+	case ACPI_RESOURCE_TYPE_ADDRESS16:
+		pnpacpi_parse_allocated_memresource(res_table,
+				res->data.address16.minimum,
 				res->data.address16.address_length);
 		break;
-	case ACPI_RSTYPE_ADDRESS32:
-		pnpacpi_parse_allocated_memresource(res_table, 
-				res->data.address32.min_address_range, 
+	case ACPI_RESOURCE_TYPE_ADDRESS32:
+		pnpacpi_parse_allocated_memresource(res_table,
+				res->data.address32.minimum,
 				res->data.address32.address_length);
 		break;
-	case ACPI_RSTYPE_ADDRESS64:
-		pnpacpi_parse_allocated_memresource(res_table, 
-		res->data.address64.min_address_range, 
+	case ACPI_RESOURCE_TYPE_ADDRESS64:
+		pnpacpi_parse_allocated_memresource(res_table,
+		res->data.address64.minimum,
 		res->data.address64.address_length);
 		break;
-	case ACPI_RSTYPE_VENDOR:
+
+	case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
 		break;
+
+	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+		for (i = 0; i < res->data.extended_irq.interrupt_count; i++) {
+			pnpacpi_parse_allocated_irqresource(res_table,
+				res->data.extended_irq.interrupts[i],
+				res->data.extended_irq.triggering,
+				res->data.extended_irq.polarity);
+		}
+		break;
+
+	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
+		break;
+
 	default:
-		pnp_warn("PnPACPI: unknown resource type %d", res->id);
+		pnp_warn("PnPACPI: unknown resource type %d", res->type);
 		return AE_ERROR;
 	}
 			
@@ -253,13 +272,13 @@ static void pnpacpi_parse_dma_option(str
 	int i;
 	struct pnp_dma * dma;
 
-	if (p->number_of_channels == 0)
+	if (p->channel_count == 0)
 		return;
 	dma = kcalloc(1, sizeof(struct pnp_dma), GFP_KERNEL);
 	if (!dma)
 		return;
 
-	for(i = 0; i < p->number_of_channels; i++)
+	for(i = 0; i < p->channel_count; i++)
 		dma->map |= 1 << p->channels[i];
 	dma->flags = 0;
 	if (p->bus_master)
@@ -309,37 +328,37 @@ static void pnpacpi_parse_irq_option(str
 	int i;
 	struct pnp_irq * irq;
 	
-	if (p->number_of_interrupts == 0)
+	if (p->interrupt_count == 0)
 		return;
 	irq = kcalloc(1, sizeof(struct pnp_irq), GFP_KERNEL);
 	if (!irq)
 		return;
 
-	for(i = 0; i < p->number_of_interrupts; i++)
+	for(i = 0; i < p->interrupt_count; i++)
 		if (p->interrupts[i])
 			__set_bit(p->interrupts[i], irq->map);
-	irq->flags = irq_flags(p->edge_level, p->active_high_low);
+	irq->flags = irq_flags(p->triggering, p->polarity);
 
 	pnp_register_irq_resource(option, irq);
 	return;
 }
 
 static void pnpacpi_parse_ext_irq_option(struct pnp_option *option,
-	struct acpi_resource_ext_irq *p)
+	struct acpi_resource_extended_irq *p)
 {
 	int i;
 	struct pnp_irq * irq;
 
-	if (p->number_of_interrupts == 0)
+	if (p->interrupt_count == 0)
 		return;
 	irq = kcalloc(1, sizeof(struct pnp_irq), GFP_KERNEL);
 	if (!irq)
 		return;
 
-	for(i = 0; i < p->number_of_interrupts; i++)
+	for(i = 0; i < p->interrupt_count; i++)
 		if (p->interrupts[i])
 			__set_bit(p->interrupts[i], irq->map);
-	irq->flags = irq_flags(p->edge_level, p->active_high_low);
+	irq->flags = irq_flags(p->triggering, p->polarity);
 
 	pnp_register_irq_resource(option, irq);
 	return;
@@ -351,16 +370,16 @@ pnpacpi_parse_port_option(struct pnp_opt
 {
 	struct pnp_port * port;
 
-	if (io->range_length == 0)
+	if (io->address_length == 0)
 		return;
 	port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL);
 	if (!port)
 		return;
-	port->min = io->min_base_address;
-	port->max = io->max_base_address;
+	port->min = io->minimum;
+	port->max = io->maximum;
 	port->align = io->alignment;
-	port->size = io->range_length;
-	port->flags = ACPI_DECODE_16 == io->io_decode ? 
+	port->size = io->address_length;
+	port->flags = ACPI_DECODE_16 == io->io_decode ?
 		PNP_PORT_FLAG_16BITADDR : 0;
 	pnp_register_port_resource(option,port);
 	return;
@@ -372,13 +391,13 @@ pnpacpi_parse_fixed_port_option(struct p
 {
 	struct pnp_port * port;
 
-	if (io->range_length == 0)
+	if (io->address_length == 0)
 		return;
 	port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL);
 	if (!port)
 		return;
-	port->min = port->max = io->base_address;
-	port->size = io->range_length;
+	port->min = port->max = io->address;
+	port->size = io->address_length;
 	port->align = 0;
 	port->flags = PNP_PORT_FLAG_FIXED;
 	pnp_register_port_resource(option,port);
@@ -387,21 +406,21 @@ pnpacpi_parse_fixed_port_option(struct p
 
 static void
 pnpacpi_parse_mem24_option(struct pnp_option *option,
-	struct acpi_resource_mem24 *p)
+	struct acpi_resource_memory24 *p)
 {
 	struct pnp_mem * mem;
 
-	if (p->range_length == 0)
+	if (p->address_length == 0)
 		return;
 	mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
 	if (!mem)
 		return;
-	mem->min = p->min_base_address;
-	mem->max = p->max_base_address;
+	mem->min = p->minimum;
+	mem->max = p->maximum;
 	mem->align = p->alignment;
-	mem->size = p->range_length;
+	mem->size = p->address_length;
 
-	mem->flags = (ACPI_READ_WRITE_MEMORY == p->read_write_attribute) ?
+	mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
 			IORESOURCE_MEM_WRITEABLE : 0;
 
 	pnp_register_mem_resource(option,mem);
@@ -410,21 +429,21 @@ pnpacpi_parse_mem24_option(struct pnp_op
 
 static void
 pnpacpi_parse_mem32_option(struct pnp_option *option,
-	struct acpi_resource_mem32 *p)
+	struct acpi_resource_memory32 *p)
 {
 	struct pnp_mem * mem;
 
-	if (p->range_length == 0)
+	if (p->address_length == 0)
 		return;
 	mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
 	if (!mem)
 		return;
-	mem->min = p->min_base_address;
-	mem->max = p->max_base_address;
+	mem->min = p->minimum;
+	mem->max = p->maximum;
 	mem->align = p->alignment;
-	mem->size = p->range_length;
+	mem->size = p->address_length;
 
-	mem->flags = (ACPI_READ_WRITE_MEMORY == p->read_write_attribute) ?
+	mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
 			IORESOURCE_MEM_WRITEABLE : 0;
 
 	pnp_register_mem_resource(option,mem);
@@ -433,33 +452,72 @@ pnpacpi_parse_mem32_option(struct pnp_op
 
 static void
 pnpacpi_parse_fixed_mem32_option(struct pnp_option *option,
-	struct acpi_resource_fixed_mem32 *p)
+	struct acpi_resource_fixed_memory32 *p)
 {
 	struct pnp_mem * mem;
 
-	if (p->range_length == 0)
+	if (p->address_length == 0)
 		return;
 	mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
 	if (!mem)
 		return;
-	mem->min = mem->max = p->range_base_address;
-	mem->size = p->range_length;
+	mem->min = mem->max = p->address;
+	mem->size = p->address_length;
 	mem->align = 0;
 
-	mem->flags = (ACPI_READ_WRITE_MEMORY == p->read_write_attribute) ?
+	mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
 			IORESOURCE_MEM_WRITEABLE : 0;
 
 	pnp_register_mem_resource(option,mem);
 	return;
 }
 
+static void
+pnpacpi_parse_address_option(struct pnp_option *option, struct acpi_resource *r)
+{
+	struct acpi_resource_address64 addr, *p = &addr;
+	acpi_status status;
+	struct pnp_mem * mem;
+	struct pnp_port * port;
+
+	status = acpi_resource_to_address64(r, p);
+	if (!ACPI_SUCCESS(status)) {
+		pnp_warn("PnPACPI: failed to convert resource type %d", r->type);
+		return;
+	}
+
+	if (p->address_length == 0)
+		return;
+
+	if (p->resource_type == ACPI_MEMORY_RANGE) {
+		mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
+		if (!mem)
+			return;
+		mem->min = mem->max = p->minimum;
+		mem->size = p->address_length;
+		mem->align = 0;
+		mem->flags = (p->info.mem.write_protect ==
+		    ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE : 0;
+		pnp_register_mem_resource(option,mem);
+	} else if (p->resource_type == ACPI_IO_RANGE) {
+		port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL);
+		if (!port)
+			return;
+		port->min = port->max = p->minimum;
+		port->size = p->address_length;
+		port->align = 0;
+		port->flags = PNP_PORT_FLAG_FIXED;
+		pnp_register_port_resource(option,port);
+	}
+}
+
 struct acpipnp_parse_option_s {
 	struct pnp_option *option;
 	struct pnp_option *option_independent;
 	struct pnp_dev *dev;
 };
 
-static acpi_status pnpacpi_option_resource(struct acpi_resource *res, 
+static acpi_status pnpacpi_option_resource(struct acpi_resource *res,
 	void *data)
 {
 	int priority = 0;
@@ -467,35 +525,16 @@ static acpi_status pnpacpi_option_resour
 	struct pnp_dev *dev = parse_data->dev;
 	struct pnp_option *option = parse_data->option;
 
-	switch (res->id) {
-		case ACPI_RSTYPE_IRQ:
+	switch (res->type) {
+		case ACPI_RESOURCE_TYPE_IRQ:
 			pnpacpi_parse_irq_option(option, &res->data.irq);
 			break;
-		case ACPI_RSTYPE_EXT_IRQ:
-			pnpacpi_parse_ext_irq_option(option,
-				&res->data.extended_irq);
-			break;
-		case ACPI_RSTYPE_DMA:
+
+		case ACPI_RESOURCE_TYPE_DMA:
 			pnpacpi_parse_dma_option(option, &res->data.dma);	
 			break;
-		case ACPI_RSTYPE_IO:
-			pnpacpi_parse_port_option(option, &res->data.io);
-			break;
-		case ACPI_RSTYPE_FIXED_IO:
-			pnpacpi_parse_fixed_port_option(option,
-				&res->data.fixed_io);
-			break;
-		case ACPI_RSTYPE_MEM24:
-			pnpacpi_parse_mem24_option(option, &res->data.memory24);
-			break;
-		case ACPI_RSTYPE_MEM32:
-			pnpacpi_parse_mem32_option(option, &res->data.memory32);
-			break;
-		case ACPI_RSTYPE_FIXED_MEM32:
-			pnpacpi_parse_fixed_mem32_option(option,
-				&res->data.fixed_memory32);
-			break;
-		case ACPI_RSTYPE_START_DPF:
+
+		case ACPI_RESOURCE_TYPE_START_DEPENDENT:
 			switch (res->data.start_dpf.compatibility_priority) {
 				case ACPI_GOOD_CONFIGURATION:
 					priority = PNP_RES_PRIORITY_PREFERRED;
@@ -518,7 +557,8 @@ static acpi_status pnpacpi_option_resour
 				return AE_ERROR;
 			parse_data->option = option;	
 			break;
-		case ACPI_RSTYPE_END_DPF:
+
+		case ACPI_RESOURCE_TYPE_END_DEPENDENT:
 			/*only one EndDependentFn is allowed*/
 			if (!parse_data->option_independent) {
 				pnp_warn("PnPACPI: more than one EndDependentFn");
@@ -527,15 +567,59 @@ static acpi_status pnpacpi_option_resour
 			parse_data->option = parse_data->option_independent;
 			parse_data->option_independent = NULL;
 			break;
+
+		case ACPI_RESOURCE_TYPE_IO:
+			pnpacpi_parse_port_option(option, &res->data.io);
+			break;
+
+		case ACPI_RESOURCE_TYPE_FIXED_IO:
+			pnpacpi_parse_fixed_port_option(option,
+				&res->data.fixed_io);
+			break;
+
+		case ACPI_RESOURCE_TYPE_VENDOR:
+		case ACPI_RESOURCE_TYPE_END_TAG:
+			break;
+
+		case ACPI_RESOURCE_TYPE_MEMORY24:
+			pnpacpi_parse_mem24_option(option, &res->data.memory24);
+			break;
+
+		case ACPI_RESOURCE_TYPE_MEMORY32:
+			pnpacpi_parse_mem32_option(option, &res->data.memory32);
+			break;
+
+		case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
+			pnpacpi_parse_fixed_mem32_option(option,
+				&res->data.fixed_memory32);
+			break;
+
+		case ACPI_RESOURCE_TYPE_ADDRESS16:
+		case ACPI_RESOURCE_TYPE_ADDRESS32:
+		case ACPI_RESOURCE_TYPE_ADDRESS64:
+			pnpacpi_parse_address_option(option, res);
+			break;
+
+		case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
+			break;
+
+		case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+			pnpacpi_parse_ext_irq_option(option,
+				&res->data.extended_irq);
+			break;
+
+		case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
+			break;
+
 		default:
-			pnp_warn("PnPACPI: unknown resource type %d", res->id);
+			pnp_warn("PnPACPI: unknown resource type %d", res->type);
 			return AE_ERROR;
 	}
 			
 	return AE_OK;
 }
 
-acpi_status pnpacpi_parse_resource_option_data(acpi_handle handle, 
+acpi_status pnpacpi_parse_resource_option_data(acpi_handle handle,
 	struct pnp_dev *dev)
 {
 	acpi_status status;
@@ -546,7 +630,7 @@ acpi_status pnpacpi_parse_resource_optio
 		return AE_ERROR;
 	parse_data.option_independent = parse_data.option;
 	parse_data.dev = dev;
-	status = acpi_walk_resources(handle, METHOD_NAME__PRS, 
+	status = acpi_walk_resources(handle, METHOD_NAME__PRS,
 		pnpacpi_option_resource, &parse_data);
 
 	return status;
@@ -559,21 +643,24 @@ static acpi_status pnpacpi_count_resourc
 	void *data)
 {
 	int *res_cnt = (int *)data;
-	switch (res->id) {
-	case ACPI_RSTYPE_IRQ:
-	case ACPI_RSTYPE_EXT_IRQ:
-	case ACPI_RSTYPE_DMA:
-	case ACPI_RSTYPE_IO:
-	case ACPI_RSTYPE_FIXED_IO:
-	case ACPI_RSTYPE_MEM24:
-	case ACPI_RSTYPE_MEM32:
-	case ACPI_RSTYPE_FIXED_MEM32:
-#if 0
-	case ACPI_RSTYPE_ADDRESS16:
-	case ACPI_RSTYPE_ADDRESS32:
-	case ACPI_RSTYPE_ADDRESS64:
-#endif
+	switch (res->type) {
+	case ACPI_RESOURCE_TYPE_IRQ:
+	case ACPI_RESOURCE_TYPE_DMA:
+	case ACPI_RESOURCE_TYPE_IO:
+	case ACPI_RESOURCE_TYPE_FIXED_IO:
+	case ACPI_RESOURCE_TYPE_MEMORY24:
+	case ACPI_RESOURCE_TYPE_MEMORY32:
+	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
+	case ACPI_RESOURCE_TYPE_ADDRESS16:
+	case ACPI_RESOURCE_TYPE_ADDRESS32:
+	case ACPI_RESOURCE_TYPE_ADDRESS64:
+	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
 		(*res_cnt) ++;
+	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
+	case ACPI_RESOURCE_TYPE_END_DEPENDENT:
+	case ACPI_RESOURCE_TYPE_VENDOR:
+	case ACPI_RESOURCE_TYPE_END_TAG:
+	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
 	default:
 		return AE_OK;
 	}
@@ -584,22 +671,25 @@ static acpi_status pnpacpi_type_resource
 	void *data)
 {
 	struct acpi_resource **resource = (struct acpi_resource **)data;	
-	switch (res->id) {
-	case ACPI_RSTYPE_IRQ:
-	case ACPI_RSTYPE_EXT_IRQ:
-	case ACPI_RSTYPE_DMA:
-	case ACPI_RSTYPE_IO:
-	case ACPI_RSTYPE_FIXED_IO:
-	case ACPI_RSTYPE_MEM24:
-	case ACPI_RSTYPE_MEM32:
-	case ACPI_RSTYPE_FIXED_MEM32:
-#if 0
-	case ACPI_RSTYPE_ADDRESS16:
-	case ACPI_RSTYPE_ADDRESS32:
-	case ACPI_RSTYPE_ADDRESS64:
-#endif
-		(*resource)->id = res->id;
+	switch (res->type) {
+	case ACPI_RESOURCE_TYPE_IRQ:
+	case ACPI_RESOURCE_TYPE_DMA:
+	case ACPI_RESOURCE_TYPE_IO:
+	case ACPI_RESOURCE_TYPE_FIXED_IO:
+	case ACPI_RESOURCE_TYPE_MEMORY24:
+	case ACPI_RESOURCE_TYPE_MEMORY32:
+	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
+	case ACPI_RESOURCE_TYPE_ADDRESS16:
+	case ACPI_RESOURCE_TYPE_ADDRESS32:
+	case ACPI_RESOURCE_TYPE_ADDRESS64:
+	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+		(*resource)->type = res->type;
 		(*resource)++;
+	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
+	case ACPI_RESOURCE_TYPE_END_DEPENDENT:
+	case ACPI_RESOURCE_TYPE_VENDOR:
+	case ACPI_RESOURCE_TYPE_END_TAG:
+	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
 	default:
 		return AE_OK;
 	}
@@ -607,14 +697,14 @@ static acpi_status pnpacpi_type_resource
 	return AE_OK;
 }
 
-int pnpacpi_build_resource_template(acpi_handle handle, 
+int pnpacpi_build_resource_template(acpi_handle handle,
 	struct acpi_buffer *buffer)
 {
 	struct acpi_resource *resource;
 	int res_cnt = 0;
 	acpi_status status;
 
-	status = acpi_walk_resources(handle, METHOD_NAME__CRS, 
+	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
 		pnpacpi_count_resources, &res_cnt);
 	if (ACPI_FAILURE(status)) {
 		pnp_err("Evaluate _CRS failed");
@@ -628,7 +718,7 @@ int pnpacpi_build_resource_template(acpi
 		return -ENOMEM;
 	pnp_dbg("Res cnt %d", res_cnt);
 	resource = (struct acpi_resource *)buffer->pointer;
-	status = acpi_walk_resources(handle, METHOD_NAME__CRS, 
+	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
 		pnpacpi_type_resources, &resource);
 	if (ACPI_FAILURE(status)) {
 		kfree(buffer->pointer);
@@ -636,54 +726,54 @@ int pnpacpi_build_resource_template(acpi
 		return -EINVAL;
 	}
 	/* resource will pointer the end resource now */
-	resource->id = ACPI_RSTYPE_END_TAG;
+	resource->type = ACPI_RESOURCE_TYPE_END_TAG;
 
 	return 0;
 }
 
-static void pnpacpi_encode_irq(struct acpi_resource *resource, 
+static void pnpacpi_encode_irq(struct acpi_resource *resource,
 	struct resource *p)
 {
-	int edge_level, active_high_low;
+	int triggering, polarity;
 	
-	decode_irq_flags(p->flags & IORESOURCE_BITS, &edge_level, 
-		&active_high_low);
-	resource->id = ACPI_RSTYPE_IRQ;
+	decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering,
+		&polarity);
+	resource->type = ACPI_RESOURCE_TYPE_IRQ;
 	resource->length = sizeof(struct acpi_resource);
-	resource->data.irq.edge_level = edge_level;
-	resource->data.irq.active_high_low = active_high_low;
-	if (edge_level == ACPI_EDGE_SENSITIVE)
-		resource->data.irq.shared_exclusive = ACPI_EXCLUSIVE;
+	resource->data.irq.triggering = triggering;
+	resource->data.irq.polarity = polarity;
+	if (triggering == ACPI_EDGE_SENSITIVE)
+		resource->data.irq.sharable = ACPI_EXCLUSIVE;
 	else
-		resource->data.irq.shared_exclusive = ACPI_SHARED;
-	resource->data.irq.number_of_interrupts = 1;
+		resource->data.irq.sharable = ACPI_SHARED;
+	resource->data.irq.interrupt_count = 1;
 	resource->data.irq.interrupts[0] = p->start;
 }
 
 static void pnpacpi_encode_ext_irq(struct acpi_resource *resource,
 	struct resource *p)
 {
-	int edge_level, active_high_low;
+	int triggering, polarity;
 	
-	decode_irq_flags(p->flags & IORESOURCE_BITS, &edge_level, 
-		&active_high_low);
-	resource->id = ACPI_RSTYPE_EXT_IRQ;
+	decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering,
+		&polarity);
+	resource->type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ;
 	resource->length = sizeof(struct acpi_resource);
 	resource->data.extended_irq.producer_consumer = ACPI_CONSUMER;
-	resource->data.extended_irq.edge_level = edge_level;
-	resource->data.extended_irq.active_high_low = active_high_low;
-	if (edge_level == ACPI_EDGE_SENSITIVE)
-		resource->data.irq.shared_exclusive = ACPI_EXCLUSIVE;
+	resource->data.extended_irq.triggering = triggering;
+	resource->data.extended_irq.polarity = polarity;
+	if (triggering == ACPI_EDGE_SENSITIVE)
+		resource->data.irq.sharable = ACPI_EXCLUSIVE;
 	else
-		resource->data.irq.shared_exclusive = ACPI_SHARED;
-	resource->data.extended_irq.number_of_interrupts = 1;
+		resource->data.irq.sharable = ACPI_SHARED;
+	resource->data.extended_irq.interrupt_count = 1;
 	resource->data.extended_irq.interrupts[0] = p->start;
 }
 
 static void pnpacpi_encode_dma(struct acpi_resource *resource,
 	struct resource *p)
 {
-	resource->id = ACPI_RSTYPE_DMA;
+	resource->type = ACPI_RESOURCE_TYPE_DMA;
 	resource->length = sizeof(struct acpi_resource);
 	/* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */
 	if (p->flags & IORESOURCE_DMA_COMPATIBLE)
@@ -701,75 +791,75 @@ static void pnpacpi_encode_dma(struct ac
 	else if (p->flags & IORESOURCE_DMA_16BIT)
 		resource->data.dma.transfer = ACPI_TRANSFER_16;
 	resource->data.dma.bus_master = p->flags & IORESOURCE_DMA_MASTER;
-	resource->data.dma.number_of_channels = 1;
+	resource->data.dma.channel_count = 1;
 	resource->data.dma.channels[0] = p->start;
 }
 
 static void pnpacpi_encode_io(struct acpi_resource *resource,
 	struct resource *p)
 {
-	resource->id = ACPI_RSTYPE_IO;
+	resource->type = ACPI_RESOURCE_TYPE_IO;
 	resource->length = sizeof(struct acpi_resource);
 	/* Note: pnp_assign_port will copy pnp_port->flags into p->flags */
 	resource->data.io.io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR)?
-		ACPI_DECODE_16 : ACPI_DECODE_10; 
-	resource->data.io.min_base_address = p->start;
-	resource->data.io.max_base_address = p->end;
+		ACPI_DECODE_16 : ACPI_DECODE_10;
+	resource->data.io.minimum = p->start;
+	resource->data.io.maximum = p->end;
 	resource->data.io.alignment = 0; /* Correct? */
-	resource->data.io.range_length = p->end - p->start + 1;
+	resource->data.io.address_length = p->end - p->start + 1;
 }
 
 static void pnpacpi_encode_fixed_io(struct acpi_resource *resource,
 	struct resource *p)
 {
-	resource->id = ACPI_RSTYPE_FIXED_IO;
+	resource->type = ACPI_RESOURCE_TYPE_FIXED_IO;
 	resource->length = sizeof(struct acpi_resource);
-	resource->data.fixed_io.base_address = p->start;
-	resource->data.fixed_io.range_length = p->end - p->start + 1;
+	resource->data.fixed_io.address = p->start;
+	resource->data.fixed_io.address_length = p->end - p->start + 1;
 }
 
 static void pnpacpi_encode_mem24(struct acpi_resource *resource,
 	struct resource *p)
 {
-	resource->id = ACPI_RSTYPE_MEM24;
+	resource->type = ACPI_RESOURCE_TYPE_MEMORY24;
 	resource->length = sizeof(struct acpi_resource);
 	/* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */
-	resource->data.memory24.read_write_attribute =
+	resource->data.memory24.write_protect =
 		(p->flags & IORESOURCE_MEM_WRITEABLE) ?
 		ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
-	resource->data.memory24.min_base_address = p->start;
-	resource->data.memory24.max_base_address = p->end;
+	resource->data.memory24.minimum = p->start;
+	resource->data.memory24.maximum = p->end;
 	resource->data.memory24.alignment = 0;
-	resource->data.memory24.range_length = p->end - p->start + 1;
+	resource->data.memory24.address_length = p->end - p->start + 1;
 }
 
 static void pnpacpi_encode_mem32(struct acpi_resource *resource,
 	struct resource *p)
 {
-	resource->id = ACPI_RSTYPE_MEM32;
+	resource->type = ACPI_RESOURCE_TYPE_MEMORY32;
 	resource->length = sizeof(struct acpi_resource);
-	resource->data.memory32.read_write_attribute =
+	resource->data.memory32.write_protect =
 		(p->flags & IORESOURCE_MEM_WRITEABLE) ?
 		ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
-	resource->data.memory32.min_base_address = p->start;
-	resource->data.memory32.max_base_address = p->end;
+	resource->data.memory32.minimum = p->start;
+	resource->data.memory32.maximum = p->end;
 	resource->data.memory32.alignment = 0;
-	resource->data.memory32.range_length = p->end - p->start + 1;
+	resource->data.memory32.address_length = p->end - p->start + 1;
 }
 
 static void pnpacpi_encode_fixed_mem32(struct acpi_resource *resource,
 	struct resource *p)
 {
-	resource->id = ACPI_RSTYPE_FIXED_MEM32;
+	resource->type = ACPI_RESOURCE_TYPE_FIXED_MEMORY32;
 	resource->length = sizeof(struct acpi_resource);
-	resource->data.fixed_memory32.read_write_attribute =
+	resource->data.fixed_memory32.write_protect =
 		(p->flags & IORESOURCE_MEM_WRITEABLE) ?
 		ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
-	resource->data.fixed_memory32.range_base_address = p->start;
-	resource->data.fixed_memory32.range_length = p->end - p->start + 1;
+	resource->data.fixed_memory32.address = p->start;
+	resource->data.fixed_memory32.address_length = p->end - p->start + 1;
 }
 
-int pnpacpi_encode_resources(struct pnp_resource_table *res_table, 
+int pnpacpi_encode_resources(struct pnp_resource_table *res_table,
 	struct acpi_buffer *buffer)
 {
 	int i = 0;
@@ -780,58 +870,67 @@ int pnpacpi_encode_resources(struct pnp_
 
 	pnp_dbg("res cnt %d", res_cnt);
 	while (i < res_cnt) {
-		switch(resource->id) {
-		case ACPI_RSTYPE_IRQ:
+		switch(resource->type) {
+		case ACPI_RESOURCE_TYPE_IRQ:
 			pnp_dbg("Encode irq");
-			pnpacpi_encode_irq(resource, 
+			pnpacpi_encode_irq(resource,
 				&res_table->irq_resource[irq]);
 			irq++;
 			break;
 
-		case ACPI_RSTYPE_EXT_IRQ:
-			pnp_dbg("Encode ext irq");
-			pnpacpi_encode_ext_irq(resource, 
-				&res_table->irq_resource[irq]);
-			irq++;
-			break;
-		case ACPI_RSTYPE_DMA:
+		case ACPI_RESOURCE_TYPE_DMA:
 			pnp_dbg("Encode dma");
-			pnpacpi_encode_dma(resource, 
+			pnpacpi_encode_dma(resource,
 				&res_table->dma_resource[dma]);
 			dma ++;
 			break;
-		case ACPI_RSTYPE_IO:
+		case ACPI_RESOURCE_TYPE_IO:
 			pnp_dbg("Encode io");
-			pnpacpi_encode_io(resource, 
+			pnpacpi_encode_io(resource,
 				&res_table->port_resource[port]);
 			port ++;
 			break;
-		case ACPI_RSTYPE_FIXED_IO:
+		case ACPI_RESOURCE_TYPE_FIXED_IO:
 			pnp_dbg("Encode fixed io");
 			pnpacpi_encode_fixed_io(resource,
 				&res_table->port_resource[port]);
 			port ++;
 			break;
-		case ACPI_RSTYPE_MEM24:
+		case ACPI_RESOURCE_TYPE_MEMORY24:
 			pnp_dbg("Encode mem24");
 			pnpacpi_encode_mem24(resource,
 				&res_table->mem_resource[mem]);
 			mem ++;
 			break;
-		case ACPI_RSTYPE_MEM32:
+		case ACPI_RESOURCE_TYPE_MEMORY32:
 			pnp_dbg("Encode mem32");
 			pnpacpi_encode_mem32(resource,
 				&res_table->mem_resource[mem]);
 			mem ++;
 			break;
-		case ACPI_RSTYPE_FIXED_MEM32:
+		case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
 			pnp_dbg("Encode fixed mem32");
 			pnpacpi_encode_fixed_mem32(resource,
 				&res_table->mem_resource[mem]);
 			mem ++;
 			break;
+		case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+			pnp_dbg("Encode ext irq");
+			pnpacpi_encode_ext_irq(resource,
+				&res_table->irq_resource[irq]);
+			irq++;
+			break;
+		case ACPI_RESOURCE_TYPE_START_DEPENDENT:
+		case ACPI_RESOURCE_TYPE_END_DEPENDENT:
+		case ACPI_RESOURCE_TYPE_VENDOR:
+		case ACPI_RESOURCE_TYPE_END_TAG:
+		case ACPI_RESOURCE_TYPE_ADDRESS16:
+		case ACPI_RESOURCE_TYPE_ADDRESS32:
+		case ACPI_RESOURCE_TYPE_ADDRESS64:
+		case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
+		case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
 		default: /* other type */
-			pnp_warn("unknown resource type %d", resource->id);
+			pnp_warn("unknown resource type %d", resource->type);
 			return -EINVAL;
 		}
 		resource ++;
diff --git a/drivers/s390/Kconfig b/drivers/s390/Kconfig
index a86a650..721787c 100644
--- a/drivers/s390/Kconfig
+++ b/drivers/s390/Kconfig
@@ -51,6 +51,13 @@ config UNIX98_PTY_COUNT
 	  When not in use, each additional set of 256 PTYs occupy
 	  approximately 8 KB of kernel memory on 32-bit architectures.
 
+config HANGCHECK_TIMER
+	tristate "Hangcheck timer"
+	help
+	  The hangcheck-timer module detects when the system has gone
+	  out to lunch past a certain margin.  It can reboot the system
+	  or merely print a warning.
+
 source "drivers/char/watchdog/Kconfig"
 
 comment "S/390 character device drivers"
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index ef4c687..abdf1ee 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -7,7 +7,6 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
  *
- * $Revision: 1.172 $
  */
 
 #include <linux/config.h>
@@ -675,11 +674,8 @@ dasd_term_IO(struct dasd_ccw_req * cqr)
 		rc = ccw_device_clear(device->cdev, (long) cqr);
 		switch (rc) {
 		case 0:	/* termination successful */
-		        if (cqr->retries > 0) {
-				cqr->retries--;
-				cqr->status = DASD_CQR_CLEAR;
-			} else
-				cqr->status = DASD_CQR_FAILED;
+			cqr->retries--;
+			cqr->status = DASD_CQR_CLEAR;
 			cqr->stopclk = get_clock();
 			DBF_DEV_EVENT(DBF_DEBUG, device,
 				      "terminate cqr %p successful",
@@ -1308,7 +1304,7 @@ dasd_tasklet(struct dasd_device * device
 	/* Now call the callback function of requests with final status */
 	list_for_each_safe(l, n, &final_queue) {
 		cqr = list_entry(l, struct dasd_ccw_req, list);
-		list_del(&cqr->list);
+		list_del_init(&cqr->list);
 		if (cqr->callback != NULL)
 			(cqr->callback)(cqr, cqr->callback_data);
 	}
@@ -1393,7 +1389,9 @@ _wait_for_wakeup(struct dasd_ccw_req *cq
 
 	device = cqr->device;
 	spin_lock_irq(get_ccwdev_lock(device->cdev));
-	rc = cqr->status == DASD_CQR_DONE || cqr->status == DASD_CQR_FAILED;
+	rc = ((cqr->status == DASD_CQR_DONE ||
+	       cqr->status == DASD_CQR_FAILED) &&
+	      list_empty(&cqr->list));
 	spin_unlock_irq(get_ccwdev_lock(device->cdev));
 	return rc;
 }
@@ -1457,15 +1455,37 @@ dasd_sleep_on_interruptible(struct dasd_
 	while (!finished) {
 		rc = wait_event_interruptible(wait_q, _wait_for_wakeup(cqr));
 		if (rc != -ERESTARTSYS) {
-			/* Request status is either done or failed. */
-			rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0;
+			/* Request is final (done or failed) */
+			rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO;
 			break;
 		}
 		spin_lock_irq(get_ccwdev_lock(device->cdev));
-		if (cqr->status == DASD_CQR_IN_IO &&
-		    device->discipline->term_IO(cqr) == 0) {
-			list_del(&cqr->list);
+		switch (cqr->status) {
+		case DASD_CQR_IN_IO:
+                        /* terminate runnig cqr */
+			if (device->discipline->term_IO) {
+				cqr->retries = -1;
+				device->discipline->term_IO(cqr);
+				/*nished =
+				 * wait (non-interruptible) for final status
+				 * because signal ist still pending
+				 */
+				spin_unlock_irq(get_ccwdev_lock(device->cdev));
+				wait_event(wait_q, _wait_for_wakeup(cqr));
+				spin_lock_irq(get_ccwdev_lock(device->cdev));
+				rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO;
+				finished = 1;
+			}
+			break;
+		case DASD_CQR_QUEUED:
+			/* request  */
+			list_del_init(&cqr->list);
+			rc = -EIO;
 			finished = 1;
+			break;
+		default:
+			/* cqr with 'non-interruptable' status - just wait */
+			break;
 		}
 		spin_unlock_irq(get_ccwdev_lock(device->cdev));
 	}
diff --git a/drivers/s390/block/dasd_3370_erp.c b/drivers/s390/block/dasd_3370_erp.c
index 84565c8..1d11c2a 100644
--- a/drivers/s390/block/dasd_3370_erp.c
+++ b/drivers/s390/block/dasd_3370_erp.c
@@ -4,7 +4,6 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
  *
- * $Revision: 1.9 $
  */
 
 #define PRINTK_HEADER "dasd_erp(3370)"
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index c143ecb..4ee0f93 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -5,7 +5,6 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001
  *
- * $Revision: 1.36 $
  */
 
 #include <linux/timer.h>
diff --git a/drivers/s390/block/dasd_9336_erp.c b/drivers/s390/block/dasd_9336_erp.c
index 01e8717..dc86144 100644
--- a/drivers/s390/block/dasd_9336_erp.c
+++ b/drivers/s390/block/dasd_9336_erp.c
@@ -4,7 +4,6 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
  *
- * $Revision: 1.8 $
  */
 
 #define PRINTK_HEADER "dasd_erp(9336)"
diff --git a/drivers/s390/block/dasd_9343_erp.c b/drivers/s390/block/dasd_9343_erp.c
index 2a23b74..4a5b795 100644
--- a/drivers/s390/block/dasd_9343_erp.c
+++ b/drivers/s390/block/dasd_9343_erp.c
@@ -4,7 +4,6 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
  *
- * $Revision: 1.13 $
  */
 
 #define PRINTK_HEADER "dasd_erp(9343)"
diff --git a/drivers/s390/block/dasd_cmb.c b/drivers/s390/block/dasd_cmb.c
index 4f365bf..e88f73e 100644
--- a/drivers/s390/block/dasd_cmb.c
+++ b/drivers/s390/block/dasd_cmb.c
@@ -1,6 +1,4 @@
 /*
- * linux/drivers/s390/block/dasd_cmb.c ($Revision: 1.9 $)
- *
  * Linux on zSeries Channel Measurement Facility support
  *  (dasd device driver interface)
  *
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index caee16a..1629b27 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -11,7 +11,6 @@
  * functions may not be called from interrupt context. In particular
  * dasd_get_device is a no-no from interrupt context.
  *
- * $Revision: 1.43 $
  */
 
 #include <linux/config.h>
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index ba80fde..3f9d704 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -6,7 +6,6 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.53 $
  */
 
 #include <linux/config.h>
diff --git a/drivers/s390/block/dasd_diag.h b/drivers/s390/block/dasd_diag.h
index a4f80bd..38a4e55 100644
--- a/drivers/s390/block/dasd_diag.h
+++ b/drivers/s390/block/dasd_diag.h
@@ -6,7 +6,6 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.9 $
  */
 
 #define MDSK_WRITE_REQ 0x01
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 96eb482..822e2a2 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -7,7 +7,6 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.74 $
  */
 
 #include <linux/config.h>
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h
index b6888c6..bc3823d 100644
--- a/drivers/s390/block/dasd_eckd.h
+++ b/drivers/s390/block/dasd_eckd.h
@@ -5,7 +5,6 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.10 $
  */
 
 #ifndef DASD_ECKD_H
diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c
index 7cb98d2..8fd71ab 100644
--- a/drivers/s390/block/dasd_erp.c
+++ b/drivers/s390/block/dasd_erp.c
@@ -7,7 +7,6 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
  *
- * $Revision: 1.14 $
  */
 
 #include <linux/config.h>
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index 8ec75dc..9114569 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -4,7 +4,6 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.41 $
  */
 
 #include <linux/config.h>
diff --git a/drivers/s390/block/dasd_fba.h b/drivers/s390/block/dasd_fba.h
index 624f040..da1fa91 100644
--- a/drivers/s390/block/dasd_fba.h
+++ b/drivers/s390/block/dasd_fba.h
@@ -4,7 +4,6 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.6 $
  */
 
 #ifndef DASD_FBA_H
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index a601c9a..65dc844 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -9,7 +9,6 @@
  *
  * gendisk related functions for the dasd driver.
  *
- * $Revision: 1.51 $
  */
 
 #include <linux/config.h>
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index e4b4015..c20af98 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -6,7 +6,6 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.68 $
  */
 
 #ifndef DASD_INT_H
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index 9396fca..fafeeae 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -7,8 +7,6 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
  *
- * $Revision: 1.50 $
- *
  * i/o controls for the dasd driver.
  */
 #include <linux/config.h>
@@ -423,8 +421,15 @@ dasd_ioctl_information(struct block_devi
 	dasd_info->cu_model = cdev->id.cu_model;
 	dasd_info->dev_type = cdev->id.dev_type;
 	dasd_info->dev_model = cdev->id.dev_model;
-	dasd_info->open_count = atomic_read(&device->open_count);
 	dasd_info->status = device->state;
+	/*
+	 * The open_count is increased for every opener, that includes
+	 * the blkdev_get in dasd_scan_partitions.
+	 * This must be hidden from user-space.
+	 */
+	dasd_info->open_count = atomic_read(&device->open_count);
+	if (!device->bdev)
+		dasd_info->open_count++;
 	
 	/*
 	 * check if device is really formatted
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
index fff9020..2d5da3c 100644
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -9,7 +9,6 @@
  *
  * /proc interface for the dasd driver.
  *
- * $Revision: 1.33 $
  */
 
 #include <linux/config.h>
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 1f06091..606f6ad 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/interrupt.h>
+#include <linux/err.h>
 
 #include <linux/slab.h>
 #include <linux/bootmem.h>
@@ -864,7 +865,7 @@ con3215_init(void)
 	}
 
 	cdev = ccw_device_probe_console();
-	if (!cdev)
+	if (IS_ERR(cdev))
 		return -ENODEV;
 
 	raw3215[0] = raw = (struct raw3215_info *)
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
index c570a9f..ef607a1 100644
--- a/drivers/s390/char/con3270.c
+++ b/drivers/s390/char/con3270.c
@@ -15,6 +15,7 @@
 #include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/types.h>
+#include <linux/err.h>
 
 #include <asm/ccwdev.h>
 #include <asm/cio.h>
@@ -597,7 +598,7 @@ con3270_init(void)
 	}
 
 	cdev = ccw_device_probe_console();
-	if (!cdev)
+	if (IS_ERR(cdev))
 		return -ENODEV;
 	rp = raw3270_setup_console(cdev);
 	if (IS_ERR(rp))
diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c
index 5bda234..a317a12 100644
--- a/drivers/s390/char/keyboard.c
+++ b/drivers/s390/char/keyboard.c
@@ -440,7 +440,11 @@ do_kdgkb_ioctl(struct kbd_data *kbd, str
 			return -EPERM;
 		len = strnlen_user(u_kbs->kb_string,
 				   sizeof(u_kbs->kb_string) - 1);
-		p = kmalloc(len, GFP_KERNEL);
+		if (!len)
+			return -EFAULT;
+		if (len > sizeof(u_kbs->kb_string) - 1)
+			return -EINVAL;
+		p = kmalloc(len + 1, GFP_KERNEL);
 		if (!p)
 			return -ENOMEM;
 		if (copy_from_user(p, u_kbs->kb_string, len)) {
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c
index 20be88e..682039c 100644
--- a/drivers/s390/char/tape_34xx.c
+++ b/drivers/s390/char/tape_34xx.c
@@ -1357,7 +1357,7 @@ tape_34xx_init (void)
 	debug_set_level(TAPE_DBF_AREA, 6);
 #endif
 
-	DBF_EVENT(3, "34xx init: $Revision: 1.23 $\n");
+	DBF_EVENT(3, "34xx init\n");
 	/* Register driver for 3480/3490 tapes. */
 	rc = ccw_driver_register(&tape_34xx_driver);
 	if (rc)
@@ -1377,8 +1377,7 @@ tape_34xx_exit(void)
 
 MODULE_DEVICE_TABLE(ccw, tape_34xx_ids);
 MODULE_AUTHOR("(C) 2001-2002 IBM Deutschland Entwicklung GmbH");
-MODULE_DESCRIPTION("Linux on zSeries channel attached 3480 tape "
-		   "device driver ($Revision: 1.23 $)");
+MODULE_DESCRIPTION("Linux on zSeries channel attached 3480 tape device driver");
 MODULE_LICENSE("GPL");
 
 module_init(tape_34xx_init);
diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c
index fcaee44..b3569c8 100644
--- a/drivers/s390/char/tape_class.c
+++ b/drivers/s390/char/tape_class.c
@@ -1,6 +1,6 @@
 /*
  * (C) Copyright IBM Corp. 2004
- * tape_class.c ($Revision: 1.8 $)
+ * tape_class.c
  *
  * Tape class device support
  *
@@ -12,7 +12,7 @@
 MODULE_AUTHOR("Stefan Bader <shbader@de.ibm.com>");
 MODULE_DESCRIPTION(
 	"(C) Copyright IBM Corp. 2004   All Rights Reserved.\n"
-	"tape_class.c ($Revision: 1.8 $)"
+	"tape_class.c"
 );
 MODULE_LICENSE("GPL");
 
diff --git a/drivers/s390/char/tape_class.h b/drivers/s390/char/tape_class.h
index 33133ad..3d0ca05 100644
--- a/drivers/s390/char/tape_class.h
+++ b/drivers/s390/char/tape_class.h
@@ -1,6 +1,6 @@
 /*
  * (C) Copyright IBM Corp. 2004   All Rights Reserved.
- * tape_class.h ($Revision: 1.4 $)
+ * tape_class.h
  *
  * Tape class device support
  *
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index 8f486e1..4ea438c 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -1239,7 +1239,7 @@ tape_init (void)
 #ifdef DBF_LIKE_HELL
 	debug_set_level(TAPE_DBF_AREA, 6);
 #endif
-	DBF_EVENT(3, "tape init: ($Revision: 1.54 $)\n");
+	DBF_EVENT(3, "tape init\n");
 	tape_proc_init();
 	tapechar_init ();
 	tapeblock_init ();
@@ -1263,8 +1263,7 @@ tape_exit(void)
 
 MODULE_AUTHOR("(C) 2001 IBM Deutschland Entwicklung GmbH by Carsten Otte and "
 	      "Michael Holzheu (cotte@de.ibm.com,holzheu@de.ibm.com)");
-MODULE_DESCRIPTION("Linux on zSeries channel attached "
-		   "tape device driver ($Revision: 1.54 $)");
+MODULE_DESCRIPTION("Linux on zSeries channel attached tape device driver");
 MODULE_LICENSE("GPL");
 
 module_init(tape_init);
diff --git a/drivers/s390/cio/airq.c b/drivers/s390/cio/airq.c
index cd2cc28..5287631 100644
--- a/drivers/s390/cio/airq.c
+++ b/drivers/s390/cio/airq.c
@@ -2,8 +2,6 @@
  *  drivers/s390/cio/airq.c
  *   S/390 common I/O routines -- support for adapter interruptions
  *
- *   $Revision: 1.15 $
- *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
  *			      IBM Corporation
  *    Author(s): Ingo Adlung (adlung@de.ibm.com)
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c
index 72f27c1..cb8e2e6 100644
--- a/drivers/s390/cio/blacklist.c
+++ b/drivers/s390/cio/blacklist.c
@@ -1,7 +1,6 @@
 /*
  *  drivers/s390/cio/blacklist.c
  *   S/390 common I/O routines -- blacklisting of specific devices
- *   $Revision: 1.42 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
  *			      IBM Corporation
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 6c077ad..8013c8e 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -1,7 +1,6 @@
 /*
  *  drivers/s390/cio/ccwgroup.c
  *  bus driver for ccwgroup
- *   $Revision: 1.35 $
  *
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
  *                       IBM Corporation
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 2cbb724..92be75d 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -1,7 +1,6 @@
 /*
  *  drivers/s390/cio/chsc.c
  *   S/390 common I/O routines -- channel subsystem call
- *   $Revision: 1.128 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
  *			      IBM Corporation
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 6223b06..cbb86fa 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -1,7 +1,6 @@
 /*
  *  drivers/s390/cio/cio.c
  *   S/390 common I/O routines -- low level i/o calls
- *   $Revision: 1.140 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
  *			      IBM Corporation
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index 0b03714..07ef3f6 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/s390/cio/cmf.c ($Revision: 1.19 $)
+ * linux/drivers/s390/cio/cmf.c
  *
  * Linux on zSeries Channel Measurement Facility support
  *
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 5161087..1bbf231 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -1,7 +1,6 @@
 /*
  *  drivers/s390/cio/css.c
  *  driver for channel subsystem
- *   $Revision: 1.96 $
  *
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
  *			 IBM Corporation
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index a67e7e6..062fb10 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -1,7 +1,6 @@
 /*
  *  drivers/s390/cio/device.c
  *  bus driver for ccw devices
- *   $Revision: 1.140 $
  *
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
  *			 IBM Corporation
@@ -255,7 +254,7 @@ modalias_show (struct device *dev, struc
 	struct ccw_device_id *id = &(cdev->id);
 	int ret;
 
-	ret = sprintf(buf, "ccw:t%04Xm%02x",
+	ret = sprintf(buf, "ccw:t%04Xm%02X",
 			id->cu_type, id->cu_model);
 	if (id->dev_type != 0)
 		ret += sprintf(buf + ret, "dt%04Xdm%02X\n",
@@ -1013,7 +1012,7 @@ ccw_device_probe_console(void)
 	int ret;
 
 	if (xchg(&console_cdev_in_use, 1) != 0)
-		return NULL;
+		return ERR_PTR(-EBUSY);
 	sch = cio_probe_console();
 	if (IS_ERR(sch)) {
 		console_cdev_in_use = 0;
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index 8b02189..3a50b19 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -1,8 +1,6 @@
 /*
  *  drivers/s390/cio/device_ops.c
  *
- *   $Revision: 1.61 $
- *
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
  *			 IBM Corporation
  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index 77be2c3..45ce032 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -56,8 +56,6 @@
 #include "ioasm.h"
 #include "chsc.h"
 
-#define VERSION_QDIO_C "$Revision: 1.117 $"
-
 /****************** MODULE PARAMETER VARIABLES ********************/
 MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
 MODULE_DESCRIPTION("QDIO base support version 2, " \
@@ -66,8 +64,7 @@ MODULE_LICENSE("GPL");
 
 /******************** HERE WE GO ***********************************/
 
-static const char version[] = "QDIO base support version 2 ("
-	VERSION_QDIO_C "/" VERSION_QDIO_H  "/" VERSION_CIO_QDIO_H ")";
+static const char version[] = "QDIO base support version 2";
 
 #ifdef QDIO_PERFORMANCE_STATS
 static int proc_perf_file_registration;
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index fa385e7..ceb3ab3 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -5,8 +5,6 @@
 
 #include "schid.h"
 
-#define VERSION_CIO_QDIO_H "$Revision: 1.40 $"
-
 #ifdef CONFIG_QDIO_DEBUG
 #define QDIO_VERBOSE_LEVEL 9
 #else /* CONFIG_QDIO_DEBUG */
diff --git a/drivers/s390/crypto/z90common.h b/drivers/s390/crypto/z90common.h
index f87c785..dbbcda3 100644
--- a/drivers/s390/crypto/z90common.h
+++ b/drivers/s390/crypto/z90common.h
@@ -27,8 +27,6 @@
 #ifndef _Z90COMMON_H_
 #define _Z90COMMON_H_
 
-#define VERSION_Z90COMMON_H "$Revision: 1.17 $"
-
 
 #define RESPBUFFSIZE 256
 #define PCI_FUNC_KEY_DECRYPT 0x5044
diff --git a/drivers/s390/crypto/z90crypt.h b/drivers/s390/crypto/z90crypt.h
index 3a18443..5e6b1f5 100644
--- a/drivers/s390/crypto/z90crypt.h
+++ b/drivers/s390/crypto/z90crypt.h
@@ -29,8 +29,6 @@
 
 #include <linux/ioctl.h>
 
-#define VERSION_Z90CRYPT_H "$Revision: 1.2.2.4 $"
-
 #define z90crypt_VERSION 1
 #define z90crypt_RELEASE 3	// 2 = PCIXCC, 3 = rewrite for coding standards
 #define z90crypt_VARIANT 3	// 3 = CEX2A support
diff --git a/drivers/s390/crypto/z90hardware.c b/drivers/s390/crypto/z90hardware.c
index d7f7494..4141919 100644
--- a/drivers/s390/crypto/z90hardware.c
+++ b/drivers/s390/crypto/z90hardware.c
@@ -32,12 +32,6 @@
 #include "z90crypt.h"
 #include "z90common.h"
 
-#define VERSION_Z90HARDWARE_C "$Revision: 1.34 $"
-
-char z90hardware_version[] __initdata =
-	"z90hardware.o (" VERSION_Z90HARDWARE_C "/"
-	                  VERSION_Z90COMMON_H "/" VERSION_Z90CRYPT_H ")";
-
 struct cca_token_hdr {
 	unsigned char  token_identifier;
 	unsigned char  version;
diff --git a/drivers/s390/crypto/z90main.c b/drivers/s390/crypto/z90main.c
index 2f54d03..7d6f190 100644
--- a/drivers/s390/crypto/z90main.c
+++ b/drivers/s390/crypto/z90main.c
@@ -38,14 +38,6 @@
 #include "z90crypt.h"
 #include "z90common.h"
 
-#define VERSION_Z90MAIN_C "$Revision: 1.62 $"
-
-static char z90main_version[] __initdata =
-	"z90main.o (" VERSION_Z90MAIN_C "/"
-                      VERSION_Z90COMMON_H "/" VERSION_Z90CRYPT_H ")";
-
-extern char z90hardware_version[];
-
 /**
  * Defaults that may be modified.
  */
@@ -594,8 +586,6 @@ z90crypt_init_module(void)
 		PRINTKN("Version %d.%d.%d loaded, built on %s %s\n",
 			z90crypt_VERSION, z90crypt_RELEASE, z90crypt_VARIANT,
 			__DATE__, __TIME__);
-		PRINTKN("%s\n", z90main_version);
-		PRINTKN("%s\n", z90hardware_version);
 		PDEBUG("create_z90crypt (domain index %d) successful.\n",
 		       domain);
 	} else
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index e70af7f..a86436a 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -2,8 +2,6 @@
  *  drivers/s390/net/claw.c
  *    ESCON CLAW network driver
  *
- *    $Revision: 1.38 $ $Date: 2005/08/29 09:47:04 $
- *
  *  Linux for zSeries version
  *    Copyright (C) 2002,2005 IBM Corporation
  *  Author(s) Original code written by:
@@ -4391,14 +4389,7 @@ static int __init
 claw_init(void)
 {
 	int ret = 0;
-       printk(KERN_INFO "claw: starting driver "
-#ifdef MODULE
-                "module "
-#else
-                "compiled into kernel "
-#endif
-                " $Revision: 1.38 $ $Date: 2005/08/29 09:47:04 $ \n");
-
+	printk(KERN_INFO "claw: starting driver\n");
 
 #ifdef FUNCTRACE
         printk(KERN_INFO "claw: %s() enter \n",__FUNCTION__);
diff --git a/drivers/s390/net/claw.h b/drivers/s390/net/claw.h
index 3df7197..969be46 100644
--- a/drivers/s390/net/claw.h
+++ b/drivers/s390/net/claw.h
@@ -2,7 +2,7 @@
 *  Define constants                                    *
 *                                                      *
 ********************************************************/
-#define VERSION_CLAW_H "$Revision: 1.6 $"
+
 /*-----------------------------------------------------*
 *     CCW command codes for CLAW protocol              *
 *------------------------------------------------------*/
diff --git a/drivers/s390/net/ctcdbug.c b/drivers/s390/net/ctcdbug.c
index 0e2a8bb..e6e72de 100644
--- a/drivers/s390/net/ctcdbug.c
+++ b/drivers/s390/net/ctcdbug.c
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/ctcdbug.c ($Revision: 1.6 $)
+ * linux/drivers/s390/net/ctcdbug.c
  *
  * CTC / ESCON network driver - s390 dbf exploit.
  *
@@ -9,8 +9,6 @@
  *    Author(s): Original Code written by
  *			  Peter Tiedemann (ptiedem@de.ibm.com)
  *
- *    $Revision: 1.6 $	 $Date: 2005/05/11 08:10:17 $
- *
  * 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)
@@ -80,4 +78,3 @@ ctc_register_dbf_views(void)
 	return 0;
 }
 
-
diff --git a/drivers/s390/net/ctcdbug.h b/drivers/s390/net/ctcdbug.h
index 7d6afa1..413925e 100644
--- a/drivers/s390/net/ctcdbug.h
+++ b/drivers/s390/net/ctcdbug.h
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/ctcdbug.h ($Revision: 1.6 $)
+ * linux/drivers/s390/net/ctcdbug.h
  *
  * CTC / ESCON network driver - s390 dbf exploit.
  *
@@ -9,8 +9,6 @@
  *    Author(s): Original Code written by
  *			  Peter Tiedemann (ptiedem@de.ibm.com)
  *
- *    $Revision: 1.6 $	 $Date: 2005/05/11 08:10:17 $
- *
  * 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)
diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c
index 1901fee..af9f212 100644
--- a/drivers/s390/net/ctcmain.c
+++ b/drivers/s390/net/ctcmain.c
@@ -1,6 +1,4 @@
 /*
- * $Id: ctcmain.c,v 1.79 2006/01/11 11:32:18 cohuck Exp $
- *
  * CTC / ESCON network driver
  *
  * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
@@ -37,8 +35,6 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.79 $
- *
  */
 #undef DEBUG
 #include <linux/module.h>
@@ -248,22 +244,11 @@ static void
 print_banner(void)
 {
 	static int printed = 0;
-	char vbuf[] = "$Revision: 1.79 $";
-	char *version = vbuf;
 
 	if (printed)
 		return;
-	if ((version = strchr(version, ':'))) {
-		char *p = strchr(version + 1, '$');
-		if (p)
-			*p = '\0';
-	} else
-		version = " ??? ";
-	printk(KERN_INFO "CTC driver Version%s"
-#ifdef DEBUG
-		    " (DEBUG-VERSION, " __DATE__ __TIME__ ")"
-#endif
-		    " initialized\n", version);
+
+	printk(KERN_INFO "CTC driver initialized\n");
 	printed = 1;
 }
 
diff --git a/drivers/s390/net/ctcmain.h b/drivers/s390/net/ctcmain.h
index ba3605f..d2e835c 100644
--- a/drivers/s390/net/ctcmain.h
+++ b/drivers/s390/net/ctcmain.h
@@ -1,6 +1,4 @@
 /*
- * $Id: ctcmain.h,v 1.4 2005/03/24 09:04:17 mschwide Exp $
- *
  * CTC / ESCON network driver
  *
  * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
@@ -29,8 +27,6 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.4 $
- *
  */
 
 #ifndef _CTCMAIN_H_
diff --git a/drivers/s390/net/ctctty.c b/drivers/s390/net/ctctty.c
index 93d1725..5cdcdbf 100644
--- a/drivers/s390/net/ctctty.c
+++ b/drivers/s390/net/ctctty.c
@@ -1,6 +1,4 @@
 /*
- * $Id: ctctty.c,v 1.29 2005/04/05 08:50:44 mschwide Exp $
- *
  * CTC / ESCON network driver, tty interface.
  *
  * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
diff --git a/drivers/s390/net/ctctty.h b/drivers/s390/net/ctctty.h
index 84b2f8f..7254dc0 100644
--- a/drivers/s390/net/ctctty.h
+++ b/drivers/s390/net/ctctty.h
@@ -1,6 +1,4 @@
 /*
- * $Id: ctctty.h,v 1.4 2003/09/18 08:01:10 mschwide Exp $
- *
  * CTC / ESCON network driver, tty interface.
  *
  * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
diff --git a/drivers/s390/net/cu3088.c b/drivers/s390/net/cu3088.c
index 2014fb7..b125331 100644
--- a/drivers/s390/net/cu3088.c
+++ b/drivers/s390/net/cu3088.c
@@ -1,6 +1,4 @@
 /*
- * $Id: cu3088.c,v 1.38 2006/01/12 14:33:09 cohuck Exp $
- *
  * CTC / LCS ccw_device driver
  *
  * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
diff --git a/drivers/s390/net/fsm.c b/drivers/s390/net/fsm.c
index 24029bd..6caf5fa 100644
--- a/drivers/s390/net/fsm.c
+++ b/drivers/s390/net/fsm.c
@@ -1,6 +1,4 @@
 /**
- * $Id: fsm.c,v 1.6 2003/10/15 11:37:29 mschwide Exp $
- *
  * A generic FSM based on fsm used in isdn4linux
  *
  */
diff --git a/drivers/s390/net/fsm.h b/drivers/s390/net/fsm.h
index 5b98253..af679c1 100644
--- a/drivers/s390/net/fsm.h
+++ b/drivers/s390/net/fsm.h
@@ -1,5 +1,3 @@
-/* $Id: fsm.h,v 1.1.1.1 2002/03/13 19:33:09 mschwide Exp $
- */
 #ifndef _FSM_H_
 #define _FSM_H_
 
diff --git a/drivers/s390/net/iucv.c b/drivers/s390/net/iucv.c
index ea81773..760e77e 100644
--- a/drivers/s390/net/iucv.c
+++ b/drivers/s390/net/iucv.c
@@ -1,6 +1,4 @@
 /* 
- * $Id: iucv.c,v 1.47 2005/11/21 11:35:22 mschwide Exp $
- *
  * IUCV network driver
  *
  * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
@@ -29,8 +27,6 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.47 $
- *
  */
 
 /* #define DEBUG */
@@ -355,17 +351,7 @@ do { \
 static void
 iucv_banner(void)
 {
-	char vbuf[] = "$Revision: 1.47 $";
-	char *version = vbuf;
-
-	if ((version = strchr(version, ':'))) {
-		char *p = strchr(version + 1, '$');
-		if (p)
-			*p = '\0';
-	} else
-		version = " ??? ";
-	printk(KERN_INFO
-	       "IUCV lowlevel driver Version%s initialized\n", version);
+	printk(KERN_INFO "IUCV lowlevel driver initialized\n");
 }
 
 /**
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index da8c515..6229ba4 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -11,8 +11,6 @@
  *			  Frank Pavlic (fpavlic@de.ibm.com) and
  *		 	  Martin Schwidefsky <schwidefsky@de.ibm.com>
  *
- *    $Revision: 1.99 $	 $Date: 2005/05/11 08:10:17 $
- *
  * 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)
@@ -59,9 +57,8 @@
 /**
  * initialization string for output
  */
-#define VERSION_LCS_C  "$Revision: 1.99 $"
 
-static char version[] __initdata = "LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")";
+static char version[] __initdata = "LCS driver";
 static char debug_buffer[255];
 
 /**
diff --git a/drivers/s390/net/lcs.h b/drivers/s390/net/lcs.h
index a7f348e..08e60ad 100644
--- a/drivers/s390/net/lcs.h
+++ b/drivers/s390/net/lcs.h
@@ -6,8 +6,6 @@
 #include <linux/workqueue.h>
 #include <asm/ccwdev.h>
 
-#define VERSION_LCS_H "$Revision: 1.19 $"
-
 #define LCS_DBF_TEXT(level, name, text) \
 	do { \
 		debug_text_event(lcs_dbf_##name, level, text); \
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index ac4c4b8..71d3853 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -1,6 +1,4 @@
 /*
- * $Id: netiucv.c,v 1.69 2006/01/12 14:33:09 cohuck Exp $
- *
  * IUCV network driver
  *
  * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
@@ -31,8 +29,6 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: IUCV network driver $Revision: 1.69 $
- *
  */
 
 #undef DEBUG
@@ -2077,16 +2073,7 @@ DRIVER_ATTR(remove, 0200, NULL, remove_w
 static void
 netiucv_banner(void)
 {
-	char vbuf[] = "$Revision: 1.69 $";
-	char *version = vbuf;
-
-	if ((version = strchr(version, ':'))) {
-		char *p = strchr(version + 1, '$');
-		if (p)
-			*p = '\0';
-	} else
-		version = " ??? ";
-	PRINT_INFO("NETIUCV driver Version%s initialized\n", version);
+	PRINT_INFO("NETIUCV driver initialized\n");
 }
 
 static void __exit
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
index d238c7e..9a064d4 100644
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth.h
@@ -25,8 +25,6 @@
 
 #include "qeth_mpc.h"
 
-#define VERSION_QETH_H 		"$Revision: 1.152 $"
-
 #ifdef CONFIG_QETH_IPV6
 #define QETH_VERSION_IPV6 	":IPv6"
 #else
diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c
index f94f1f2..b023131 100644
--- a/drivers/s390/net/qeth_eddp.c
+++ b/drivers/s390/net/qeth_eddp.c
@@ -1,6 +1,5 @@
 /*
- *
- * linux/drivers/s390/net/qeth_eddp.c ($Revision: 1.13 $)
+ * linux/drivers/s390/net/qeth_eddp.c
  *
  * Enhanced Device Driver Packing (EDDP) support for the qeth driver.
  *
@@ -8,8 +7,6 @@
  *
  *    Author(s): Thomas Spatzier <tspat@de.ibm.com>
  *
- *    $Revision: 1.13 $	 $Date: 2005/05/04 20:19:18 $
- *
  */
 #include <linux/config.h>
 #include <linux/errno.h>
diff --git a/drivers/s390/net/qeth_eddp.h b/drivers/s390/net/qeth_eddp.h
index e1b5186..cae9ba2 100644
--- a/drivers/s390/net/qeth_eddp.h
+++ b/drivers/s390/net/qeth_eddp.h
@@ -1,14 +1,12 @@
 /*
- * linux/drivers/s390/net/qeth_eddp.c ($Revision: 1.5 $)
+ * linux/drivers/s390/net/qeth_eddp.h
  *
- * Header file for qeth enhanced device driver pakcing.
+ * Header file for qeth enhanced device driver packing.
  *
  * Copyright 2004 IBM Corporation
  *
  *    Author(s): Thomas Spatzier <tspat@de.ibm.com>
  *
- *    $Revision: 1.5 $	 $Date: 2005/03/24 09:04:18 $
- *
  */
 #ifndef __QETH_EDDP_H__
 #define __QETH_EDDP_H__
diff --git a/drivers/s390/net/qeth_fs.h b/drivers/s390/net/qeth_fs.h
index c0b4c8d..e422b41 100644
--- a/drivers/s390/net/qeth_fs.h
+++ b/drivers/s390/net/qeth_fs.h
@@ -12,11 +12,6 @@
 #ifndef __QETH_FS_H__
 #define __QETH_FS_H__
 
-#define VERSION_QETH_FS_H "$Revision: 1.10 $"
-
-extern const char *VERSION_QETH_PROC_C;
-extern const char *VERSION_QETH_SYS_C;
-
 #ifdef CONFIG_PROC_FS
 extern int
 qeth_create_procfs_entries(void);
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 97f927c..410abea 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -1,6 +1,5 @@
 /*
- *
- * linux/drivers/s390/net/qeth_main.c ($Revision: 1.251 $)
+ * linux/drivers/s390/net/qeth_main.c
  *
  * Linux on zSeries OSA Express and HiperSockets support
  *
@@ -12,8 +11,6 @@
  *			  Frank Pavlic (fpavlic@de.ibm.com) and
  *		 	  Thomas Spatzier <tspat@de.ibm.com>
  *
- *    $Revision: 1.251 $	 $Date: 2005/05/04 20:19:18 $
- *
  * 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)
@@ -73,7 +70,6 @@
 #include "qeth_eddp.h"
 #include "qeth_tso.h"
 
-#define VERSION_QETH_C "$Revision: 1.251 $"
 static const char *version = "qeth S/390 OSA-Express driver";
 
 /**
@@ -8626,12 +8622,7 @@ qeth_init(void)
 {
 	int rc=0;
 
-	PRINT_INFO("loading %s (%s/%s/%s/%s/%s/%s/%s %s %s)\n",
-		   version, VERSION_QETH_C, VERSION_QETH_H,
-		   VERSION_QETH_MPC_H, VERSION_QETH_MPC_C,
-		   VERSION_QETH_FS_H, VERSION_QETH_PROC_C,
-		   VERSION_QETH_SYS_C, QETH_VERSION_IPV6,
-		   QETH_VERSION_VLAN);
+	PRINT_INFO("loading %s\n", version);
 
 	INIT_LIST_HEAD(&qeth_card_list.list);
 	INIT_LIST_HEAD(&qeth_notify_list);
diff --git a/drivers/s390/net/qeth_mpc.c b/drivers/s390/net/qeth_mpc.c
index 5f8754a..77c8320 100644
--- a/drivers/s390/net/qeth_mpc.c
+++ b/drivers/s390/net/qeth_mpc.c
@@ -11,8 +11,6 @@
 #include <asm/cio.h>
 #include "qeth_mpc.h"
 
-const char *VERSION_QETH_MPC_C = "$Revision: 1.13 $";
-
 unsigned char IDX_ACTIVATE_READ[]={
 	0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00,
 	0x19,0x01,0x01,0x80, 0x00,0x00,0x00,0x00,
diff --git a/drivers/s390/net/qeth_mpc.h b/drivers/s390/net/qeth_mpc.h
index 864cec5..011c410 100644
--- a/drivers/s390/net/qeth_mpc.h
+++ b/drivers/s390/net/qeth_mpc.h
@@ -14,10 +14,6 @@
 
 #include <asm/qeth.h>
 
-#define VERSION_QETH_MPC_H "$Revision: 1.46 $"
-
-extern const char *VERSION_QETH_MPC_C;
-
 #define IPA_PDU_HEADER_SIZE	0x40
 #define QETH_IPA_PDU_LEN_TOTAL(buffer) (buffer+0x0e)
 #define QETH_IPA_PDU_LEN_PDU1(buffer) (buffer+0x26)
diff --git a/drivers/s390/net/qeth_proc.c b/drivers/s390/net/qeth_proc.c
index 7bf3509..3c6339d 100644
--- a/drivers/s390/net/qeth_proc.c
+++ b/drivers/s390/net/qeth_proc.c
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/qeth_fs.c ($Revision: 1.16 $)
+ * linux/drivers/s390/net/qeth_fs.c
  *
  * Linux on zSeries OSA Express and HiperSockets support
  * This file contains code related to procfs.
@@ -21,8 +21,6 @@
 #include "qeth_mpc.h"
 #include "qeth_fs.h"
 
-const char *VERSION_QETH_PROC_C = "$Revision: 1.16 $";
-
 /***** /proc/qeth *****/
 #define QETH_PROCFILE_NAME "qeth"
 static struct proc_dir_entry *qeth_procfile;
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c
index 0ea185f..c1831f5 100644
--- a/drivers/s390/net/qeth_sys.c
+++ b/drivers/s390/net/qeth_sys.c
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.60 $)
+ * linux/drivers/s390/net/qeth_sys.c
  *
  * Linux on zSeries OSA Express and HiperSockets support
  * This file contains code related to sysfs.
@@ -20,8 +20,6 @@
 #include "qeth_mpc.h"
 #include "qeth_fs.h"
 
-const char *VERSION_QETH_SYS_C = "$Revision: 1.60 $";
-
 /*****************************************************************************/
 /*                                                                           */
 /*          /sys-fs stuff UNDER DEVELOPMENT !!!                              */
diff --git a/drivers/s390/net/qeth_tso.h b/drivers/s390/net/qeth_tso.h
index 3c50b6f..1286dde 100644
--- a/drivers/s390/net/qeth_tso.h
+++ b/drivers/s390/net/qeth_tso.h
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/s390/net/qeth_tso.h ($Revision: 1.8 $)
+ * linux/drivers/s390/net/qeth_tso.h
  *
  * Header file for qeth TCP Segmentation Offload support.
  *
@@ -7,8 +7,6 @@
  *
  *    Author(s): Frank Pavlic <fpavlic@de.ibm.com>
  *
- *    $Revision: 1.8 $	 $Date: 2005/05/04 20:19:18 $
- *
  */
 #ifndef __QETH_TSO_H__
 #define __QETH_TSO_H__
diff --git a/drivers/s390/s390_rdev.c b/drivers/s390/s390_rdev.c
index 206518c..e3f6471 100644
--- a/drivers/s390/s390_rdev.c
+++ b/drivers/s390/s390_rdev.c
@@ -1,7 +1,6 @@
 /*
  *  drivers/s390/s390_rdev.c
  *  s390 root device
- *   $Revision: 1.4 $
  *
  *    Copyright (C) 2002, 2005 IBM Deutschland Entwicklung GmbH,
  *			 IBM Corporation
diff --git a/drivers/s390/s390mach.h b/drivers/s390/s390mach.h
index d9ea7ed..7abb42a 100644
--- a/drivers/s390/s390mach.h
+++ b/drivers/s390/s390mach.h
@@ -90,15 +90,16 @@ struct crw {
 
 static inline int stcrw(struct crw *pcrw )
 {
-        int ccode;
+	int ccode;
 
-        __asm__ __volatile__(
-                "STCRW 0(%1)\n\t"
-                "IPM %0\n\t"
-                "SRL %0,28\n\t"
-                : "=d" (ccode) : "a" (pcrw)
-                : "cc", "1" );
-        return ccode;
+	__asm__ __volatile__(
+		"stcrw 0(%2)\n\t"
+		"ipm %0\n\t"
+		"srl %0,28\n\t"
+		: "=d" (ccode), "=m" (*pcrw)
+		: "a" (pcrw)
+		: "cc" );
+	return ccode;
 }
 
 #endif /* __s390mach */
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 167fef3..95b92f3 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -29,8 +29,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define ZFCP_AUX_REVISION "$Revision: 1.145 $"
-
 #include "zfcp_ext.h"
 
 /* accumulated log level (module parameter) */
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index 0fc4638..241136d 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -27,8 +27,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define ZFCP_CCW_C_REVISION "$Revision: 1.58 $"
-
 #include "zfcp_ext.h"
 
 #define ZFCP_LOG_AREA                   ZFCP_LOG_AREA_CONFIG
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index 9559971..4d7d47c 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -23,8 +23,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define ZFCP_DBF_REVISION "$Revision$"
-
 #include <asm/debug.h>
 #include <linux/ctype.h>
 #include "zfcp_ext.h"
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 9bb5110..e260d19 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -34,8 +34,6 @@
 #ifndef ZFCP_DEF_H
 #define ZFCP_DEF_H
 
-#define ZFCP_DEF_REVISION "$Revision: 1.111 $"
-
 /*************************** INCLUDES *****************************************/
 
 #include <linux/init.h>
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index c065cb8..da947e6 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -31,8 +31,6 @@
 
 #define ZFCP_LOG_AREA			ZFCP_LOG_AREA_ERP
 
-#define ZFCP_ERP_REVISION "$Revision: 1.86 $"
-
 #include "zfcp_ext.h"
 
 static int zfcp_erp_adisc(struct zfcp_port *);
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index c378226..c1ba7cf 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -32,8 +32,6 @@
 #ifndef ZFCP_EXT_H
 #define ZFCP_EXT_H
 
-#define ZFCP_EXT_REVISION "$Revision: 1.62 $"
-
 #include "zfcp_def.h"
 
 extern struct zfcp_data zfcp_data;
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index cbfab09..9f0cb3d 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -30,8 +30,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define ZFCP_FSF_C_REVISION "$Revision: 1.92 $"
-
 #include "zfcp_ext.h"
 
 static int zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *);
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index d719f66..1c32751 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -29,8 +29,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define ZFCP_QDIO_C_REVISION "$Revision: 1.20 $"
-
 #include "zfcp_ext.h"
 
 static inline void zfcp_qdio_sbal_limit(struct zfcp_fsf_req *, int);
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 3c2cbcc..e080375 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -31,8 +31,6 @@
 
 #define ZFCP_LOG_AREA			ZFCP_LOG_AREA_SCSI
 
-#define ZFCP_SCSI_REVISION "$Revision: 1.74 $"
-
 #include "zfcp_ext.h"
 
 static void zfcp_scsi_slave_destroy(struct scsi_device *sdp);
diff --git a/drivers/s390/scsi/zfcp_sysfs_adapter.c b/drivers/s390/scsi/zfcp_sysfs_adapter.c
index 9f26225..dfc0737 100644
--- a/drivers/s390/scsi/zfcp_sysfs_adapter.c
+++ b/drivers/s390/scsi/zfcp_sysfs_adapter.c
@@ -27,8 +27,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define ZFCP_SYSFS_ADAPTER_C_REVISION "$Revision: 1.38 $"
-
 #include "zfcp_ext.h"
 
 #define ZFCP_LOG_AREA                   ZFCP_LOG_AREA_CONFIG
diff --git a/drivers/s390/scsi/zfcp_sysfs_driver.c b/drivers/s390/scsi/zfcp_sysfs_driver.c
index 77a5e2d..6622d55 100644
--- a/drivers/s390/scsi/zfcp_sysfs_driver.c
+++ b/drivers/s390/scsi/zfcp_sysfs_driver.c
@@ -27,8 +27,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define ZFCP_SYSFS_DRIVER_C_REVISION "$Revision: 1.17 $"
-
 #include "zfcp_ext.h"
 
 #define ZFCP_LOG_AREA                   ZFCP_LOG_AREA_CONFIG
diff --git a/drivers/s390/scsi/zfcp_sysfs_port.c b/drivers/s390/scsi/zfcp_sysfs_port.c
index 3924eb3..f401d42 100644
--- a/drivers/s390/scsi/zfcp_sysfs_port.c
+++ b/drivers/s390/scsi/zfcp_sysfs_port.c
@@ -28,8 +28,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define ZFCP_SYSFS_PORT_C_REVISION "$Revision: 1.47 $"
-
 #include "zfcp_ext.h"
 
 #define ZFCP_LOG_AREA                   ZFCP_LOG_AREA_CONFIG
diff --git a/drivers/s390/scsi/zfcp_sysfs_unit.c b/drivers/s390/scsi/zfcp_sysfs_unit.c
index 2f50815..ad5dfb8 100644
--- a/drivers/s390/scsi/zfcp_sysfs_unit.c
+++ b/drivers/s390/scsi/zfcp_sysfs_unit.c
@@ -28,8 +28,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define ZFCP_SYSFS_UNIT_C_REVISION "$Revision: 1.30 $"
-
 #include "zfcp_ext.h"
 
 #define ZFCP_LOG_AREA                   ZFCP_LOG_AREA_CONFIG
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index d113290..a800fb5 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -276,6 +276,20 @@ static const struct pci_device_id ahci_p
 	  board_ahci }, /* ESB2 */
 	{ PCI_VENDOR_ID_INTEL, 0x27c6, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 	  board_ahci }, /* ICH7-M DH */
+	{ PCI_VENDOR_ID_INTEL, 0x2821, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  board_ahci }, /* ICH8 */
+	{ PCI_VENDOR_ID_INTEL, 0x2822, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  board_ahci }, /* ICH8 */
+	{ PCI_VENDOR_ID_INTEL, 0x2824, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  board_ahci }, /* ICH8 */
+	{ PCI_VENDOR_ID_INTEL, 0x2829, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  board_ahci }, /* ICH8M */
+	{ PCI_VENDOR_ID_INTEL, 0x282a, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  board_ahci }, /* ICH8M */
+	{ 0x197b, 0x2360, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  board_ahci }, /* JMicron JMB360 */
+	{ 0x197b, 0x2363, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  board_ahci }, /* JMicron JMB363 */
 	{ }	/* terminate list */
 };
 
@@ -792,7 +806,6 @@ static int ahci_host_init(struct ata_pro
 	struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
 	void __iomem *mmio = probe_ent->mmio_base;
 	u32 tmp, cap_save;
-	u16 tmp16;
 	unsigned int i, j, using_dac;
 	int rc;
 	void __iomem *port_mmio;
@@ -826,9 +839,13 @@ static int ahci_host_init(struct ata_pro
 	writel(0xf, mmio + HOST_PORTS_IMPL);
 	(void) readl(mmio + HOST_PORTS_IMPL);	/* flush */
 
-	pci_read_config_word(pdev, 0x92, &tmp16);
-	tmp16 |= 0xf;
-	pci_write_config_word(pdev, 0x92, tmp16);
+	if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
+		u16 tmp16;
+
+		pci_read_config_word(pdev, 0x92, &tmp16);
+		tmp16 |= 0xf;
+		pci_write_config_word(pdev, 0x92, tmp16);
+	}
 
 	hpriv->cap = readl(mmio + HOST_CAP);
 	hpriv->port_map = readl(mmio + HOST_PORTS_IMPL);
@@ -1072,6 +1089,10 @@ static int ahci_init_one (struct pci_dev
 	if (have_msi)
 		hpriv->flags |= AHCI_FLAG_MSI;
 
+	/* JMicron-specific fixup: make sure we're in AHCI mode */
+	if (pdev->vendor == 0x197b)
+		pci_write_config_byte(pdev, 0x41, 0xa1);
+
 	/* initialize adapter */
 	rc = ahci_host_init(probe_ent);
 	if (rc)
diff --git a/drivers/scsi/aic7xxx/Kconfig.aic79xx b/drivers/scsi/aic7xxx/Kconfig.aic79xx
index 69ed77f..7955ebe 100644
--- a/drivers/scsi/aic7xxx/Kconfig.aic79xx
+++ b/drivers/scsi/aic7xxx/Kconfig.aic79xx
@@ -37,13 +37,13 @@ config AIC79XX_CMDS_PER_DEVICE
 config AIC79XX_RESET_DELAY_MS
 	int "Initial bus reset delay in milli-seconds"
 	depends on SCSI_AIC79XX
-	default "15000"
+	default "5000"
 	---help---
 	The number of milliseconds to delay after an initial bus reset.
 	The bus settle delay following all error recovery actions is
 	dictated by the SCSI layer and is not affected by this value.
 
-	Default: 15000 (15 seconds)
+	Default: 5000 (5 seconds)
 
 config AIC79XX_BUILD_FIRMWARE
 	bool "Build Adapter Firmware with Kernel Build"
diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h
index 2cfdbef..1d11f7e 100644
--- a/drivers/scsi/aic7xxx/aic79xx.h
+++ b/drivers/scsi/aic7xxx/aic79xx.h
@@ -37,7 +37,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#108 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#109 $
  *
  * $FreeBSD$
  */
@@ -222,6 +222,7 @@ typedef enum {
 typedef enum {
 	AHD_FENONE		= 0x00000,
 	AHD_WIDE  		= 0x00001,/* Wide Channel */
+	AHD_AIC79XXB_SLOWCRC    = 0x00002,/* SLOWCRC bit should be set */
 	AHD_MULTI_FUNC		= 0x00100,/* Multi-Function/Channel Device */
 	AHD_TARGETMODE		= 0x01000,/* Has tested target mode support */
 	AHD_MULTIROLE		= 0x02000,/* Space for two roles at a time */
diff --git a/drivers/scsi/aic7xxx/aic79xx.reg b/drivers/scsi/aic7xxx/aic79xx.reg
index 3a32047..be14e2e 100644
--- a/drivers/scsi/aic7xxx/aic79xx.reg
+++ b/drivers/scsi/aic7xxx/aic79xx.reg
@@ -1,7 +1,7 @@
 /*
  * Aic79xx register and scratch ram definitions.
  *
- * Copyright (c) 1994-2001 Justin T. Gibbs.
+ * Copyright (c) 1994-2001, 2004 Justin T. Gibbs.
  * Copyright (c) 2000-2002 Adaptec Inc.
  * All rights reserved.
  *
@@ -39,7 +39,7 @@
  *
  * $FreeBSD$
  */
-VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#76 $"
+VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#77 $"
 
 /*
  * This file is processed by the aic7xxx_asm utility for use in assembling
@@ -3715,8 +3715,9 @@ scratch_ram {
 
 	SEQ_FLAGS2 {
 		size		1
-		field	TARGET_MSG_PENDING	  0x02
-		field	SELECTOUT_QFROZEN	  0x04
+		field	PENDING_MK_MESSAGE	0x01
+		field	TARGET_MSG_PENDING	0x02
+		field	SELECTOUT_QFROZEN	0x04
 	}
 
 	ALLOCFIFO_SCBPTR {
@@ -3777,6 +3778,26 @@ scratch_ram {
 	CMDSIZE_TABLE {
 		size		8
 	}
+	/*
+	 * When an SCB with the MK_MESSAGE flag is
+	 * queued to the controller, it cannot enter
+	 * the waiting for selection list until the
+	 * selections for any previously queued
+	 * commands to that target complete.  During
+	 * the wait, the MK_MESSAGE SCB is queued
+	 * here.
+	 */
+	MK_MESSAGE_SCB {
+		size		2
+	}
+	/*
+	 * Saved SCSIID of MK_MESSAGE_SCB to avoid
+	 * an extra SCBPTR operation when deciding
+	 * if the MK_MESSAGE_SCB can be run.
+	 */
+	MK_MESSAGE_SCSIID {
+		size		1
+	}
 }
 
 /************************* Hardware SCB Definition ****************************/
diff --git a/drivers/scsi/aic7xxx/aic79xx.seq b/drivers/scsi/aic7xxx/aic79xx.seq
index bef1f9d..58bc175 100644
--- a/drivers/scsi/aic7xxx/aic79xx.seq
+++ b/drivers/scsi/aic7xxx/aic79xx.seq
@@ -1,7 +1,7 @@
 /*
  * Adaptec U320 device driver firmware for Linux and FreeBSD.
  *
- * Copyright (c) 1994-2001 Justin T. Gibbs.
+ * Copyright (c) 1994-2001, 2004 Justin T. Gibbs.
  * Copyright (c) 2000-2002 Adaptec Inc.
  * All rights reserved.
  *
@@ -40,7 +40,7 @@
  * $FreeBSD$
  */
 
-VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#119 $"
+VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#120 $"
 PATCH_ARG_LIST = "struct ahd_softc *ahd"
 PREFIX = "ahd_"
 
@@ -110,10 +110,8 @@ check_waiting_list:
 	 * one last time.
 	 */
 	test	SSTAT0, SELDO jnz select_out;
-END_CRITICAL;
 	call	start_selection;
 idle_loop_checkbus:
-BEGIN_CRITICAL;
 	test	SSTAT0, SELDO jnz select_out;
 END_CRITICAL;
 	test	SSTAT0, SELDI jnz select_in;
@@ -294,7 +292,6 @@ fetch_new_scb_inprog:
 	test	CCSCBCTL, ARRDONE jz return;
 fetch_new_scb_done:
 	and	CCSCBCTL, ~(CCARREN|CCSCBEN);
-	bmov	REG0, SCBPTR, 2;
 	clr	A;
 	add	CMDS_PENDING, 1;
 	adc	CMDS_PENDING[1], A;
@@ -316,43 +313,117 @@ fetch_new_scb_done:
 	clr	SCB_FIFO_USE_COUNT;
 	/* Update the next SCB address to download. */
 	bmov	NEXT_QUEUED_SCB_ADDR, SCB_NEXT_SCB_BUSADDR, 4;
+	/*
+	 * NULL out the SCB links since these fields
+	 * occupy the same location as SCB_NEXT_SCB_BUSADDR.
+	 */
 	mvi	SCB_NEXT[1], SCB_LIST_NULL;
 	mvi	SCB_NEXT2[1], SCB_LIST_NULL;
 	/* Increment our position in the QINFIFO. */
 	mov	NONE, SNSCB_QOFF;
+
 	/*
-	 * SCBs that want to send messages are always
-	 * queued independently.  This ensures that they
-	 * are at the head of the SCB list to select out
-	 * to a target and we will see the MK_MESSAGE flag.
+	 * Save SCBID of this SCB in REG0 since
+	 * SCBPTR will be clobbered during target
+	 * list updates.  We also record the SCB's
+	 * flags so that we can refer to them even
+	 * after SCBPTR has been changed.
+	 */
+	bmov	REG0, SCBPTR, 2;
+	mov	A, SCB_CONTROL;
+
+	/*
+	 * Find the tail SCB of the execution queue
+	 * for this target.
 	 */
-	test	SCB_CONTROL, MK_MESSAGE jnz first_new_target_scb;
 	shr	SINDEX, 3, SCB_SCSIID;
 	and	SINDEX, ~0x1;
 	mvi	SINDEX[1], (WAITING_SCB_TAILS >> 8);
 	bmov	DINDEX, SINDEX, 2;
 	bmov	SCBPTR, SINDIR, 2;
+
+	/*
+	 * Update the tail to point to the new SCB.
+	 */
 	bmov	DINDIR, REG0, 2;
+
+	/*
+	 * If the queue was empty, queue this SCB as
+	 * the first for this target.
+	 */
 	cmp	SCBPTR[1], SCB_LIST_NULL je first_new_target_scb;
+
+	/*
+	 * SCBs that want to send messages must always be
+	 * at the head of their per-target queue so that
+	 * ATN can be asserted even if the current
+	 * negotiation agreement is packetized.  If the
+	 * target queue is empty, the SCB can be queued
+	 * immediately.  If the queue is not empty, we must
+	 * wait for it to empty before entering this SCB
+	 * into the waiting for selection queue.  Otherwise
+	 * our batching and round-robin selection scheme 
+	 * could allow commands to be queued out of order.
+	 * To simplify the implementation, we stop pulling
+	 * new commands from the host until the MK_MESSAGE
+	 * SCB can be queued to the waiting for selection
+	 * list.
+	 */
+	test	A, MK_MESSAGE jz batch_scb; 
+
+	/*
+	 * If the last SCB is also a MK_MESSAGE SCB, then
+	 * order is preserved even if we batch.
+	 */
+	test	SCB_CONTROL, MK_MESSAGE jz batch_scb; 
+
+	/*
+	 * Defer this SCB and stop fetching new SCBs until
+	 * it can be queued.  Since the SCB_SCSIID of the
+	 * tail SCB must be the same as that of the newly
+	 * queued SCB, there is no need to restore the SCBID
+	 * here.
+	 */
+	or	SEQ_FLAGS2, PENDING_MK_MESSAGE;
+	bmov	MK_MESSAGE_SCB, REG0, 2;
+	mov	MK_MESSAGE_SCSIID, SCB_SCSIID ret;
+
+batch_scb:
+	/*
+	 * Otherwise just update the previous tail SCB to
+	 * point to the new tail.
+	 */
 	bmov	SCB_NEXT, REG0, 2 ret;
+
 first_new_target_scb:
+	/*
+	 * Append SCB to the tail of the waiting for
+	 * selection list.
+	 */
 	cmp	WAITING_TID_HEAD[1], SCB_LIST_NULL je first_new_scb;
 	bmov	SCBPTR, WAITING_TID_TAIL, 2;
 	bmov	SCB_NEXT2, REG0, 2;
 	bmov	WAITING_TID_TAIL, REG0, 2 ret;
 first_new_scb:
+	/*
+	 * Whole list is empty, so the head of
+	 * the list must be initialized too.
+	 */
 	bmov	WAITING_TID_HEAD, REG0, 2;
 	bmov	WAITING_TID_TAIL, REG0, 2 ret;
 END_CRITICAL;
 
 scbdma_idle:
 	/*
-	 * Give precedence to downloading new SCBs to execute
-	 * unless select-outs are currently frozen.
+	 * Don't bother downloading new SCBs to execute
+	 * if select-outs are currently frozen or we have
+	 * a MK_MESSAGE SCB waiting to enter the queue.
 	 */
-	test	SEQ_FLAGS2, SELECTOUT_QFROZEN jnz . + 2;
+	test	SEQ_FLAGS2, SELECTOUT_QFROZEN|PENDING_MK_MESSAGE
+		jnz scbdma_no_new_scbs;
 BEGIN_CRITICAL;
 	test	QOFF_CTLSTA, NEW_SCB_AVAIL jnz fetch_new_scb;
+scbdma_no_new_scbs:
 	cmp	COMPLETE_DMA_SCB_HEAD[1], SCB_LIST_NULL jne dma_complete_scb;
 	cmp	COMPLETE_SCB_HEAD[1], SCB_LIST_NULL je return;
 	/* FALLTHROUGH */
@@ -671,27 +742,41 @@ curscb_ww_done:
 	}
 
 	/*
-	 * Requeue any SCBs not sent, to the tail of the waiting Q.
+	 * The whole list made it.  Clear our tail pointer to indicate
+	 * that the per-target selection queue is now empty.
 	 */
-	cmp	SCB_NEXT[1], SCB_LIST_NULL je select_out_list_done;
+	cmp	SCB_NEXT[1], SCB_LIST_NULL je select_out_clear_tail;
 
 	/*
+	 * Requeue any SCBs not sent, to the tail of the waiting Q.
 	 * We know that neither the per-TID list nor the list of
-	 * TIDs is empty.  Use this knowledge to our advantage.
+	 * TIDs is empty.  Use this knowledge to our advantage and
+	 * queue the remainder to the tail of the global execution
+	 * queue.
 	 */
 	bmov	REG0, SCB_NEXT, 2;
+select_out_queue_remainder:
 	bmov	SCBPTR, WAITING_TID_TAIL, 2;
 	bmov	SCB_NEXT2, REG0, 2;
 	bmov	WAITING_TID_TAIL, REG0, 2;
 	jmp	select_out_inc_tid_q;
 
-select_out_list_done:
+select_out_clear_tail:
 	/*
-	 * The whole list made it.  Just clear our TID's tail pointer
-	 * unless we were queued independently due to our need to
-	 * send a message.
+	 * Queue any pending MK_MESSAGE SCB for this target now
+	 * that the queue is empty.
+	 */
+	test	SEQ_FLAGS2, PENDING_MK_MESSAGE jz select_out_no_mk_message_scb;
+	mov	A, MK_MESSAGE_SCSIID;
+	cmp	SCB_SCSIID, A jne select_out_no_mk_message_scb;
+	and	SEQ_FLAGS2, ~PENDING_MK_MESSAGE;
+	bmov	REG0, MK_MESSAGE_SCB, 2;
+	jmp select_out_queue_remainder;
+
+select_out_no_mk_message_scb:
+	/*
+	 * Clear this target's execution tail and increment the queue.
 	 */
-	test	SCB_CONTROL, MK_MESSAGE jnz select_out_inc_tid_q;
 	shr	DINDEX, 3, SCB_SCSIID;
 	or	DINDEX, 1;	/* Want only the second byte */
 	mvi	DINDEX[1], ((WAITING_SCB_TAILS) >> 8);
@@ -703,8 +788,8 @@ select_out_inc_tid_q:
 	mvi	WAITING_TID_TAIL[1], SCB_LIST_NULL;
 	bmov	SCBPTR, CURRSCB, 2;
 	mvi	CLRSINT0, CLRSELDO;
-	test	LQOSTAT2, LQOPHACHGOUTPKT jnz unexpected_nonpkt_phase;
-	test	LQOSTAT1, LQOPHACHGINPKT jnz unexpected_nonpkt_phase;
+	test	LQOSTAT2, LQOPHACHGOUTPKT jnz unexpected_nonpkt_mode_cleared;
+	test	LQOSTAT1, LQOPHACHGINPKT jnz unexpected_nonpkt_mode_cleared;
 
 	/*
 	 * If this is a packetized connection, return to our
@@ -2127,6 +2212,18 @@ SET_DST_MODE	M_DFF0;
 	mvi	DFFSXFRCTL, CLRCHN;
 unexpected_nonpkt_mode_cleared:
 	mvi	CLRSINT2, CLRNONPACKREQ;
+	if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) {
+		/*
+		 * Test to ensure that the bus has not
+		 * already gone free prior to clearing
+		 * any stale busfree status.  This avoids
+		 * a window whereby a busfree just after
+		 * a selection could be missed.
+		 */
+		test	SCSISIGI, BSYI jz . + 2;
+		mvi	CLRSINT1,CLRBUSFREE;
+		or	SIMODE1, ENBUSFREE;
+	}
 	test	SCSIPHASE, ~(MSG_IN_PHASE|MSG_OUT_PHASE) jnz illegal_phase;
 	SET_SEQINTCODE(ENTERING_NONPACK)
 	jmp	ITloop;
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c
index db8f5ce..342f779 100644
--- a/drivers/scsi/aic7xxx/aic79xx_core.c
+++ b/drivers/scsi/aic7xxx/aic79xx_core.c
@@ -37,7 +37,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#247 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#250 $
  */
 
 #ifdef __linux__
@@ -197,7 +197,8 @@ static int		ahd_search_scb_list(struct a
 					    char channel, int lun, u_int tag,
 					    role_t role, uint32_t status,
 					    ahd_search_action action,
-					    u_int *list_head, u_int tid);
+					    u_int *list_head, u_int *list_tail,
+					    u_int tid);
 static void		ahd_stitch_tid_list(struct ahd_softc *ahd,
 					    u_int tid_prev, u_int tid_cur,
 					    u_int tid_next);
@@ -1660,7 +1661,8 @@ ahd_handle_scsiint(struct ahd_softc *ahd
 		 * so just clear the error.
 		 */
 		ahd_outb(ahd, CLRLQIINT1, CLRLQICRCI_NLQ);
-	} else if ((status & BUSFREE) != 0) {
+	} else if ((status & BUSFREE) != 0
+		|| (lqistat1 & LQOBUSFREE) != 0) {
 		u_int lqostat1;
 		int   restart;
 		int   clear_fifo;
@@ -2025,10 +2027,6 @@ ahd_handle_pkt_busfree(struct ahd_softc 
 		u_int waiting_t;
 		u_int next;
 
-		if ((busfreetime & BUSFREE_LQO) == 0)
-			printf("%s: Warning, BUSFREE time is 0x%x.  "
-			       "Expected BUSFREE_LQO.\n",
-			       ahd_name(ahd), busfreetime);
 		/*
 		 * The LQO manager detected an unexpected busfree
 		 * either:
@@ -2251,8 +2249,14 @@ ahd_handle_nonpkt_busfree(struct ahd_sof
 			struct ahd_tmode_tstate *tstate;
 
 			/*
-			 * PPR Rejected.  Try non-ppr negotiation
-			 * and retry command.
+			 * PPR Rejected.
+			 *
+			 * If the previous negotiation was packetized,
+			 * this could be because the device has been
+			 * reset without our knowledge.  Force our
+			 * current negotiation to async and retry the
+			 * negotiation.  Otherwise retry the command
+			 * with non-ppr negotiation.
 			 */
 #ifdef AHD_DEBUG
 			if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
@@ -2261,11 +2265,34 @@ ahd_handle_nonpkt_busfree(struct ahd_sof
 			tinfo = ahd_fetch_transinfo(ahd, devinfo.channel,
 						    devinfo.our_scsiid,
 						    devinfo.target, &tstate);
-			tinfo->curr.transport_version = 2;
-			tinfo->goal.transport_version = 2;
-			tinfo->goal.ppr_options = 0;
-			ahd_qinfifo_requeue_tail(ahd, scb);
-			printerror = 0;
+			if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ)!=0) {
+				ahd_set_width(ahd, &devinfo,
+					      MSG_EXT_WDTR_BUS_8_BIT,
+					      AHD_TRANS_CUR,
+					      /*paused*/TRUE);
+				ahd_set_syncrate(ahd, &devinfo,
+						/*period*/0, /*offset*/0,
+						/*ppr_options*/0,
+						AHD_TRANS_CUR,
+						/*paused*/TRUE);
+				/*
+				 * The expect PPR busfree handler below
+				 * will effect the retry and necessary
+				 * abort.
+				 */
+			} else {
+				tinfo->curr.transport_version = 2;
+				tinfo->goal.transport_version = 2;
+				tinfo->goal.ppr_options = 0;
+				/*
+				 * Remove any SCBs in the waiting for selection
+				 * queue that may also be for this target so
+				 * that command ordering is preserved.
+				 */
+				ahd_freeze_devq(ahd, scb);
+				ahd_qinfifo_requeue_tail(ahd, scb);
+				printerror = 0;
+			}
 		} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE)
 			&& ppr_busfree == 0) {
 			/*
@@ -2280,6 +2307,12 @@ ahd_handle_nonpkt_busfree(struct ahd_sof
 				      MSG_EXT_WDTR_BUS_8_BIT,
 				      AHD_TRANS_CUR|AHD_TRANS_GOAL,
 				      /*paused*/TRUE);
+			/*
+			 * Remove any SCBs in the waiting for selection
+			 * queue that may also be for this target so that
+			 * command ordering is preserved.
+			 */
+			ahd_freeze_devq(ahd, scb);
 			ahd_qinfifo_requeue_tail(ahd, scb);
 			printerror = 0;
 		} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE)
@@ -2297,6 +2330,12 @@ ahd_handle_nonpkt_busfree(struct ahd_sof
 					/*ppr_options*/0,
 					AHD_TRANS_CUR|AHD_TRANS_GOAL,
 					/*paused*/TRUE);
+			/*
+			 * Remove any SCBs in the waiting for selection
+			 * queue that may also be for this target so that
+			 * command ordering is preserved.
+			 */
+			ahd_freeze_devq(ahd, scb);
 			ahd_qinfifo_requeue_tail(ahd, scb);
 			printerror = 0;
 		} else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0
@@ -2369,14 +2408,14 @@ ahd_handle_nonpkt_busfree(struct ahd_sof
 			 */
 			printf("%s: ", ahd_name(ahd));
 		}
-		if (lastphase != P_BUSFREE)
-			ahd_force_renegotiation(ahd, &devinfo);
 		printf("Unexpected busfree %s, %d SCBs aborted, "
 		       "PRGMCNT == 0x%x\n",
 		       ahd_lookup_phase_entry(lastphase)->phasemsg,
 		       aborted,
 		       ahd_inw(ahd, PRGMCNT));
 		ahd_dump_card_state(ahd);
+		if (lastphase != P_BUSFREE)
+			ahd_force_renegotiation(ahd, &devinfo);
 	}
 	/* Always restart the sequencer. */
 	return (1);
@@ -3293,6 +3332,15 @@ ahd_update_neg_table(struct ahd_softc *a
 		con_opts |= WIDEXFER;
 
 	/*
+	 * Slow down our CRC interval to be
+	 * compatible with packetized U320 devices
+	 * that can't handle a CRC at full speed
+	 */
+	if (ahd->features & AHD_AIC79XXB_SLOWCRC) {
+		con_opts |= ENSLOWCRC;
+	}
+
+	/*
 	 * During packetized transfers, the target will
 	 * give us the oportunity to send command packets
 	 * without us asserting attention.
@@ -3315,7 +3363,6 @@ ahd_update_pending_scbs(struct ahd_softc
 {
 	struct		scb *pending_scb;
 	int		pending_scb_count;
-	u_int		scb_tag;
 	int		paused;
 	u_int		saved_scbptr;
 	ahd_mode_state	saved_modes;
@@ -3333,7 +3380,6 @@ ahd_update_pending_scbs(struct ahd_softc
 	pending_scb_count = 0;
 	LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) {
 		struct ahd_devinfo devinfo;
-		struct hardware_scb *pending_hscb;
 		struct ahd_initiator_tinfo *tinfo;
 		struct ahd_tmode_tstate *tstate;
 
@@ -3341,11 +3387,10 @@ ahd_update_pending_scbs(struct ahd_softc
 		tinfo = ahd_fetch_transinfo(ahd, devinfo.channel,
 					    devinfo.our_scsiid,
 					    devinfo.target, &tstate);
-		pending_hscb = pending_scb->hscb;
 		if ((tstate->auto_negotiate & devinfo.target_mask) == 0
 		 && (pending_scb->flags & SCB_AUTO_NEGOTIATE) != 0) {
 			pending_scb->flags &= ~SCB_AUTO_NEGOTIATE;
-			pending_hscb->control &= ~MK_MESSAGE;
+			pending_scb->hscb->control &= ~MK_MESSAGE;
 		}
 		ahd_sync_scb(ahd, pending_scb,
 			     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
@@ -3377,18 +3422,15 @@ ahd_update_pending_scbs(struct ahd_softc
 		ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
 	saved_scbptr = ahd_get_scbptr(ahd);
 	/* Ensure that the hscbs down on the card match the new information */
-	for (scb_tag = 0; scb_tag < ahd->scb_data.maxhscbs; scb_tag++) {
-		struct	hardware_scb *pending_hscb;
+	LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) {
+		u_int	scb_tag;
 		u_int	control;
 
-		pending_scb = ahd_lookup_scb(ahd, scb_tag);
-		if (pending_scb == NULL)
-			continue;
+		scb_tag = SCB_GET_TAG(pending_scb);
 		ahd_set_scbptr(ahd, scb_tag);
-		pending_hscb = pending_scb->hscb;
 		control = ahd_inb_scbram(ahd, SCB_CONTROL);
 		control &= ~MK_MESSAGE;
-		control |= pending_hscb->control & MK_MESSAGE;
+		control |= pending_scb->hscb->control & MK_MESSAGE;
 		ahd_outb(ahd, SCB_CONTROL, control);
 	}
 	ahd_set_scbptr(ahd, saved_scbptr);
@@ -6500,13 +6542,14 @@ ahd_chip_init(struct ahd_softc *ahd)
 			      | ENLQIOVERI_LQ|ENLQIOVERI_NLQ);
 	ahd_outb(ahd, LQOMODE0, ENLQOATNLQ|ENLQOATNPKT|ENLQOTCRC);
 	/*
-	 * An interrupt from LQOBUSFREE is made redundant by the
-	 * BUSFREE interrupt.  We choose to have the sequencer catch
-	 * LQOPHCHGINPKT errors manually for the command phase at the
-	 * start of a packetized selection case.
-	ahd_outb(ahd, LQOMODE1, ENLQOBUSFREE|ENLQOPHACHGINPKT);
+	 * We choose to have the sequencer catch LQOPHCHGINPKT errors
+	 * manually for the command phase at the start of a packetized
+	 * selection case.  ENLQOBUSFREE should be made redundant by
+	 * the BUSFREE interrupt, but it seems that some LQOBUSFREE
+	 * events fail to assert the BUSFREE interrupt so we must
+	 * also enable LQOBUSFREE interrupts.
 	 */
-	ahd_outb(ahd, LQOMODE1, 0);
+	ahd_outb(ahd, LQOMODE1, ENLQOBUSFREE);
 
 	/*
 	 * Setup sequencer interrupt handlers.
@@ -6617,6 +6660,8 @@ ahd_chip_init(struct ahd_softc *ahd)
 	/* We don't have any waiting selections */
 	ahd_outw(ahd, WAITING_TID_HEAD, SCB_LIST_NULL);
 	ahd_outw(ahd, WAITING_TID_TAIL, SCB_LIST_NULL);
+	ahd_outw(ahd, MK_MESSAGE_SCB, SCB_LIST_NULL);
+	ahd_outw(ahd, MK_MESSAGE_SCSIID, 0xFF);
 	for (i = 0; i < AHD_NUM_TARGETS; i++)
 		ahd_outw(ahd, WAITING_SCB_TAILS + (2 * i), SCB_LIST_NULL);
 
@@ -6704,6 +6749,18 @@ ahd_chip_init(struct ahd_softc *ahd)
 
 	ahd_loadseq(ahd);
 	ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
+
+	if (ahd->features & AHD_AIC79XXB_SLOWCRC) {
+		u_int negodat3 = ahd_inb(ahd, NEGCONOPTS);
+
+		negodat3 |= ENSLOWCRC;
+		ahd_outb(ahd, NEGCONOPTS, negodat3);
+		negodat3 = ahd_inb(ahd, NEGCONOPTS);
+		if (!(negodat3 & ENSLOWCRC))
+			printf("aic79xx: failed to set the SLOWCRC bit\n");
+		else
+			printf("aic79xx: SLOWCRC bit set\n");
+	}
 }
 
 /*
@@ -7260,12 +7317,28 @@ ahd_reset_cmds_pending(struct ahd_softc 
 	ahd->flags &= ~AHD_UPDATE_PEND_CMDS;
 }
 
+void
+ahd_done_with_status(struct ahd_softc *ahd, struct scb *scb, uint32_t status)
+{
+	cam_status ostat;
+	cam_status cstat;
+
+	ostat = ahd_get_transaction_status(scb);
+	if (ostat == CAM_REQ_INPROG)
+		ahd_set_transaction_status(scb, status);
+	cstat = ahd_get_transaction_status(scb);
+	if (cstat != CAM_REQ_CMP)
+		ahd_freeze_scb(scb);
+	ahd_done(ahd, scb);
+}
+
 int
 ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel,
 		   int lun, u_int tag, role_t role, uint32_t status,
 		   ahd_search_action action)
 {
 	struct scb	*scb;
+	struct scb	*mk_msg_scb;
 	struct scb	*prev_scb;
 	ahd_mode_state	 saved_modes;
 	u_int		 qinstart;
@@ -7274,6 +7347,7 @@ ahd_search_qinfifo(struct ahd_softc *ahd
 	u_int		 tid_next;
 	u_int		 tid_prev;
 	u_int		 scbid;
+	u_int		 seq_flags2;
 	u_int		 savedscbptr;
 	uint32_t	 busaddr;
 	int		 found;
@@ -7329,23 +7403,10 @@ ahd_search_qinfifo(struct ahd_softc *ahd
 			found++;
 			switch (action) {
 			case SEARCH_COMPLETE:
-			{
-				cam_status ostat;
-				cam_status cstat;
-
-				ostat = ahd_get_transaction_status(scb);
-				if (ostat == CAM_REQ_INPROG)
-					ahd_set_transaction_status(scb,
-								   status);
-				cstat = ahd_get_transaction_status(scb);
-				if (cstat != CAM_REQ_CMP)
-					ahd_freeze_scb(scb);
 				if ((scb->flags & SCB_ACTIVE) == 0)
 					printf("Inactive SCB in qinfifo\n");
-				ahd_done(ahd, scb);
-
+				ahd_done_with_status(ahd, scb, status);
 				/* FALLTHROUGH */
-			}
 			case SEARCH_REMOVE:
 				break;
 			case SEARCH_PRINT:
@@ -7375,21 +7436,24 @@ ahd_search_qinfifo(struct ahd_softc *ahd
 	 * looking for matches.
 	 */
 	ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
+	seq_flags2 = ahd_inb(ahd, SEQ_FLAGS2);
+	if ((seq_flags2 & PENDING_MK_MESSAGE) != 0) {
+		scbid = ahd_inw(ahd, MK_MESSAGE_SCB);
+		mk_msg_scb = ahd_lookup_scb(ahd, scbid);
+	} else
+		mk_msg_scb = NULL;
 	savedscbptr = ahd_get_scbptr(ahd);
 	tid_next = ahd_inw(ahd, WAITING_TID_HEAD);
 	tid_prev = SCB_LIST_NULL;
 	targets = 0;
 	for (scbid = tid_next; !SCBID_IS_NULL(scbid); scbid = tid_next) {
 		u_int tid_head;
+		u_int tid_tail;
 
-		/*
-		 * We limit based on the number of SCBs since
-		 * MK_MESSAGE SCBs are not in the per-tid lists.
-		 */
 		targets++;
-		if (targets > AHD_SCB_MAX) {
+		if (targets > AHD_NUM_TARGETS)
 			panic("TID LIST LOOP");
-		}
+
 		if (scbid >= ahd->scb_data.numscbs) {
 			printf("%s: Waiting TID List inconsistency. "
 			       "SCB index == 0x%x, yet numscbs == 0x%x.",
@@ -7419,8 +7483,71 @@ ahd_search_qinfifo(struct ahd_softc *ahd
 		tid_head = scbid;
 		found += ahd_search_scb_list(ahd, target, channel,
 					     lun, tag, role, status,
-					     action, &tid_head,
+					     action, &tid_head, &tid_tail,
 					     SCB_GET_TARGET(ahd, scb));
+		/*
+		 * Check any MK_MESSAGE SCB that is still waiting to
+		 * enter this target's waiting for selection queue.
+		 */
+		if (mk_msg_scb != NULL
+		 && ahd_match_scb(ahd, mk_msg_scb, target, channel,
+				  lun, tag, role)) {
+
+			/*
+			 * We found an scb that needs to be acted on.
+			 */
+			found++;
+			switch (action) {
+			case SEARCH_COMPLETE:
+				if ((mk_msg_scb->flags & SCB_ACTIVE) == 0)
+					printf("Inactive SCB pending MK_MSG\n");
+				ahd_done_with_status(ahd, mk_msg_scb, status);
+				/* FALLTHROUGH */
+			case SEARCH_REMOVE:
+			{
+				u_int tail_offset;
+
+				printf("Removing MK_MSG scb\n");
+
+				/*
+				 * Reset our tail to the tail of the
+				 * main per-target list.
+				 */
+				tail_offset = WAITING_SCB_TAILS
+				    + (2 * SCB_GET_TARGET(ahd, mk_msg_scb));
+				ahd_outw(ahd, tail_offset, tid_tail);
+
+				seq_flags2 &= ~PENDING_MK_MESSAGE;
+				ahd_outb(ahd, SEQ_FLAGS2, seq_flags2);
+				ahd_outw(ahd, CMDS_PENDING,
+					 ahd_inw(ahd, CMDS_PENDING)-1);
+				mk_msg_scb = NULL;
+				break;
+			}
+			case SEARCH_PRINT:
+				printf(" 0x%x", SCB_GET_TAG(scb));
+				/* FALLTHROUGH */
+			case SEARCH_COUNT:
+				break;
+			}
+		}
+
+		if (mk_msg_scb != NULL
+		 && SCBID_IS_NULL(tid_head)
+		 && ahd_match_scb(ahd, scb, target, channel, CAM_LUN_WILDCARD,
+				  SCB_LIST_NULL, ROLE_UNKNOWN)) {
+
+			/*
+			 * When removing the last SCB for a target
+			 * queue with a pending MK_MESSAGE scb, we
+			 * must queue the MK_MESSAGE scb.
+			 */
+			printf("Queueing mk_msg_scb\n");
+			tid_head = ahd_inw(ahd, MK_MESSAGE_SCB);
+			seq_flags2 &= ~PENDING_MK_MESSAGE;
+			ahd_outb(ahd, SEQ_FLAGS2, seq_flags2);
+			mk_msg_scb = NULL;
+		}
 		if (tid_head != scbid)
 			ahd_stitch_tid_list(ahd, tid_prev, tid_head, tid_next);
 		if (!SCBID_IS_NULL(tid_head))
@@ -7428,6 +7555,8 @@ ahd_search_qinfifo(struct ahd_softc *ahd
 		if (action == SEARCH_PRINT)
 			printf(")\n");
 	}
+
+	/* Restore saved state. */
 	ahd_set_scbptr(ahd, savedscbptr);
 	ahd_restore_modes(ahd, saved_modes);
 	return (found);
@@ -7436,7 +7565,8 @@ ahd_search_qinfifo(struct ahd_softc *ahd
 static int
 ahd_search_scb_list(struct ahd_softc *ahd, int target, char channel,
 		    int lun, u_int tag, role_t role, uint32_t status,
-		    ahd_search_action action, u_int *list_head, u_int tid)
+		    ahd_search_action action, u_int *list_head, 
+		    u_int *list_tail, u_int tid)
 {
 	struct	scb *scb;
 	u_int	scbid;
@@ -7448,6 +7578,7 @@ ahd_search_scb_list(struct ahd_softc *ah
 	found = 0;
 	prev = SCB_LIST_NULL;
 	next = *list_head;
+	*list_tail = SCB_LIST_NULL;
 	for (scbid = next; !SCBID_IS_NULL(scbid); scbid = next) {
 		if (scbid >= ahd->scb_data.numscbs) {
 			printf("%s:SCB List inconsistency. "
@@ -7463,6 +7594,7 @@ ahd_search_scb_list(struct ahd_softc *ah
 			panic("Waiting List traversal\n");
 		}
 		ahd_set_scbptr(ahd, scbid);
+		*list_tail = scbid;
 		next = ahd_inw_scbram(ahd, SCB_NEXT);
 		if (ahd_match_scb(ahd, scb, target, channel,
 				  lun, SCB_LIST_NULL, role) == 0) {
@@ -7472,24 +7604,14 @@ ahd_search_scb_list(struct ahd_softc *ah
 		found++;
 		switch (action) {
 		case SEARCH_COMPLETE:
-		{
-			cam_status ostat;
-			cam_status cstat;
-
-			ostat = ahd_get_transaction_status(scb);
-			if (ostat == CAM_REQ_INPROG)
-				ahd_set_transaction_status(scb, status);
-			cstat = ahd_get_transaction_status(scb);
-			if (cstat != CAM_REQ_CMP)
-				ahd_freeze_scb(scb);
 			if ((scb->flags & SCB_ACTIVE) == 0)
 				printf("Inactive SCB in Waiting List\n");
-			ahd_done(ahd, scb);
+			ahd_done_with_status(ahd, scb, status);
 			/* FALLTHROUGH */
-		}
 		case SEARCH_REMOVE:
 			ahd_rem_wscb(ahd, scbid, prev, next, tid);
-			if (prev == SCB_LIST_NULL)
+			*list_tail = prev;
+			if (SCBID_IS_NULL(prev))
 				*list_head = next;
 			break;
 		case SEARCH_PRINT:
@@ -7558,14 +7680,17 @@ ahd_rem_wscb(struct ahd_softc *ahd, u_in
 	}
 
 	/*
-	 * SCBs that had MK_MESSAGE set in them will not
-	 * be queued to the per-target lists, so don't
-	 * blindly clear the tail pointer.
+	 * SCBs that have MK_MESSAGE set in them may
+	 * cause the tail pointer to be updated without
+	 * setting the next pointer of the previous tail.
+	 * Only clear the tail if the removed SCB was
+	 * the tail.
 	 */
 	tail_offset = WAITING_SCB_TAILS + (2 * tid);
 	if (SCBID_IS_NULL(next)
 	 && ahd_inw(ahd, tail_offset) == scbid)
 		ahd_outw(ahd, tail_offset, prev);
+
 	ahd_add_scb_to_free_list(ahd, scbid);
 	return (next);
 }
@@ -8148,11 +8273,6 @@ ahd_handle_scsi_status(struct ahd_softc 
 		ahd_setup_data_scb(ahd, scb);
 		scb->flags |= SCB_SENSE;
 		ahd_queue_scb(ahd, scb);
-		/*
-		 * Ensure we have enough time to actually
-		 * retrieve the sense.
-		 */
-		ahd_scb_timer_reset(scb, 5 * 1000000);
 		break;
 	}
 	case SCSI_STATUS_OK:
@@ -8793,6 +8913,9 @@ ahd_dump_card_state(struct ahd_softc *ah
 	 * Mode independent registers.
 	 */
 	cur_col = 0;
+	ahd_intstat_print(ahd_inb(ahd, INTSTAT), &cur_col, 50);
+	ahd_seloid_print(ahd_inb(ahd, SELOID), &cur_col, 50);
+	ahd_selid_print(ahd_inb(ahd, SELID), &cur_col, 50);
 	ahd_hs_mailbox_print(ahd_inb(ahd, LOCAL_HS_MAILBOX), &cur_col, 50);
 	ahd_intctl_print(ahd_inb(ahd, INTCTL), &cur_col, 50);
 	ahd_seqintstat_print(ahd_inb(ahd, SEQINTSTAT), &cur_col, 50);
@@ -8808,6 +8931,12 @@ ahd_dump_card_state(struct ahd_softc *ah
 	ahd_seqintctl_print(ahd_inb(ahd, SEQINTCTL), &cur_col, 50);
 	ahd_seq_flags_print(ahd_inb(ahd, SEQ_FLAGS), &cur_col, 50);
 	ahd_seq_flags2_print(ahd_inb(ahd, SEQ_FLAGS2), &cur_col, 50);
+	ahd_qfreeze_count_print(ahd_inw(ahd, QFREEZE_COUNT), &cur_col, 50);
+	ahd_kernel_qfreeze_count_print(ahd_inw(ahd, KERNEL_QFREEZE_COUNT),
+				       &cur_col, 50);
+	ahd_mk_message_scb_print(ahd_inw(ahd, MK_MESSAGE_SCB), &cur_col, 50);
+	ahd_mk_message_scsiid_print(ahd_inb(ahd, MK_MESSAGE_SCSIID),
+				    &cur_col, 50);
 	ahd_sstat0_print(ahd_inb(ahd, SSTAT0), &cur_col, 50);
 	ahd_sstat1_print(ahd_inb(ahd, SSTAT1), &cur_col, 50);
 	ahd_sstat2_print(ahd_inb(ahd, SSTAT2), &cur_col, 50);
@@ -8915,7 +9044,7 @@ ahd_dump_card_state(struct ahd_softc *ah
 
 		ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i);
 		fifo_scbptr = ahd_get_scbptr(ahd);
-		printf("\n%s: FIFO%d %s, LONGJMP == 0x%x, SCB 0x%x\n",
+		printf("\n\n%s: FIFO%d %s, LONGJMP == 0x%x, SCB 0x%x\n",
 		       ahd_name(ahd), i,
 		       (dffstat & (FIFO0FREE << i)) ? "Free" : "Active",
 		       ahd_inw(ahd, LONGJMP_ADDR), fifo_scbptr);
@@ -8970,6 +9099,9 @@ ahd_dump_card_state(struct ahd_softc *ah
 	printf("%s: OS_SPACE_CNT = 0x%x MAXCMDCNT = 0x%x\n",
 	       ahd_name(ahd), ahd_inb(ahd, OS_SPACE_CNT),
 	       ahd_inb(ahd, MAXCMDCNT));
+	printf("%s: SAVED_SCSIID = 0x%x SAVED_LUN = 0x%x\n",
+	       ahd_name(ahd), ahd_inb(ahd, SAVED_SCSIID),
+	       ahd_inb(ahd, SAVED_LUN));
 	ahd_simode0_print(ahd_inb(ahd, SIMODE0), &cur_col, 50);
 	printf("\n");
 	ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
diff --git a/drivers/scsi/aic7xxx/aic79xx_inline.h b/drivers/scsi/aic7xxx/aic79xx_inline.h
index 91c4f7f..8ad3ce9 100644
--- a/drivers/scsi/aic7xxx/aic79xx_inline.h
+++ b/drivers/scsi/aic7xxx/aic79xx_inline.h
@@ -37,7 +37,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#58 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#59 $
  *
  * $FreeBSD$
  */
@@ -804,9 +804,10 @@ ahd_queue_scb(struct ahd_softc *ahd, str
 		uint64_t host_dataptr;
 
 		host_dataptr = ahd_le64toh(scb->hscb->dataptr);
-		printf("%s: Queueing SCB 0x%x bus addr 0x%x - 0x%x%x/0x%x\n",
+		printf("%s: Queueing SCB %d:0x%x bus addr 0x%x - 0x%x%x/0x%x\n",
 		       ahd_name(ahd),
-		       SCB_GET_TAG(scb), ahd_le32toh(scb->hscb->hscb_busaddr),
+		       SCB_GET_TAG(scb), scb->hscb->scsiid,
+		       ahd_le32toh(scb->hscb->hscb_busaddr),
 		       (u_int)((host_dataptr >> 32) & 0xFFFFFFFF),
 		       (u_int)(host_dataptr & 0xFFFFFFFF),
 		       ahd_le32toh(scb->hscb->datacnt));
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 2567e29..7254ea5 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -314,6 +314,21 @@ static uint32_t aic79xx_seltime;
  */
 uint32_t aic79xx_periodic_otag;
 
+/* Some storage boxes are using an LSI chip which has a bug making it
+ * impossible to use aic79xx Rev B chip in 320 speeds.  The following
+ * storage boxes have been reported to be buggy:
+ * EonStor 3U 16-Bay: U16U-G3A3
+ * EonStor 2U 12-Bay: U12U-G3A3
+ * SentinelRAID: 2500F R5 / R6
+ * SentinelRAID: 2500F R1
+ * SentinelRAID: 2500F/1500F
+ * SentinelRAID: 150F
+ * 
+ * To get around this LSI bug, you can set your board to 160 mode
+ * or you can enable the SLOWCRC bit.
+ */
+uint32_t aic79xx_slowcrc;
+
 /*
  * Module information and settable options.
  */
@@ -343,6 +358,7 @@ MODULE_PARM_DESC(aic79xx,
 "	amplitude:<int>		Set the signal amplitude (0-7).\n"
 "	seltime:<int>		Selection Timeout:\n"
 "				(0/256ms,1/128ms,2/64ms,3/32ms)\n"
+"	slowcrc			Turn on the SLOWCRC bit (Rev B only)\n"		 
 "\n"
 "	Sample /etc/modprobe.conf line:\n"
 "		Enable verbose logging\n"
@@ -1003,6 +1019,7 @@ aic79xx_setup(char *s)
 		{ "slewrate", NULL },
 		{ "precomp", NULL },
 		{ "amplitude", NULL },
+		{ "slowcrc", &aic79xx_slowcrc },
 	};
 
 	end = strchr(s, '\0');
@@ -1072,7 +1089,6 @@ ahd_linux_register_host(struct ahd_softc
 		return (ENOMEM);
 
 	*((struct ahd_softc **)host->hostdata) = ahd;
-	ahd_lock(ahd, &s);
 	ahd->platform_data->host = host;
 	host->can_queue = AHD_MAX_QUEUE;
 	host->cmd_per_lun = 2;
@@ -1083,7 +1099,9 @@ ahd_linux_register_host(struct ahd_softc
 	host->max_lun = AHD_NUM_LUNS;
 	host->max_channel = 0;
 	host->sg_tablesize = AHD_NSEG;
+	ahd_lock(ahd, &s);
 	ahd_set_unit(ahd, ahd_linux_unit++);
+	ahd_unlock(ahd, &s);
 	sprintf(buf, "scsi%d", host->host_no);
 	new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
 	if (new_name != NULL) {
@@ -1093,7 +1111,6 @@ ahd_linux_register_host(struct ahd_softc
 	host->unique_id = ahd->unit;
 	ahd_linux_initialize_scsi_bus(ahd);
 	ahd_intr_enable(ahd, TRUE);
-	ahd_unlock(ahd, &s);
 
 	host->transportt = ahd_linux_transport_template;
 
@@ -1127,6 +1144,7 @@ ahd_linux_initialize_scsi_bus(struct ahd
 {
 	u_int target_id;
 	u_int numtarg;
+	unsigned long s;
 
 	target_id = 0;
 	numtarg = 0;
@@ -1139,6 +1157,8 @@ ahd_linux_initialize_scsi_bus(struct ahd
 	else
 		numtarg = (ahd->features & AHD_WIDE) ? 16 : 8;
 
+	ahd_lock(ahd, &s);
+
 	/*
 	 * Force negotiation to async for all targets that
 	 * will not see an initial bus reset.
@@ -1155,16 +1175,12 @@ ahd_linux_initialize_scsi_bus(struct ahd
 		ahd_update_neg_request(ahd, &devinfo, tstate,
 				       tinfo, AHD_NEG_ALWAYS);
 	}
+	ahd_unlock(ahd, &s);
 	/* Give the bus some time to recover */
 	if ((ahd->flags & AHD_RESET_BUS_A) != 0) {
 		ahd_freeze_simq(ahd);
-		init_timer(&ahd->platform_data->reset_timer);
-		ahd->platform_data->reset_timer.data = (u_long)ahd;
-		ahd->platform_data->reset_timer.expires =
-		    jiffies + (AIC79XX_RESET_DELAY * HZ)/1000;
-		ahd->platform_data->reset_timer.function =
-		    (ahd_linux_callback_t *)ahd_release_simq;
-		add_timer(&ahd->platform_data->reset_timer);
+		msleep(AIC79XX_RESET_DELAY);
+		ahd_release_simq(ahd);
 	}
 }
 
@@ -2033,6 +2049,9 @@ ahd_linux_sem_timeout(u_long arg)
 void
 ahd_freeze_simq(struct ahd_softc *ahd)
 {
+	unsigned long s;
+
+	ahd_lock(ahd, &s);
 	ahd->platform_data->qfrozen++;
 	if (ahd->platform_data->qfrozen == 1) {
 		scsi_block_requests(ahd->platform_data->host);
@@ -2040,6 +2059,7 @@ ahd_freeze_simq(struct ahd_softc *ahd)
 					CAM_LUN_WILDCARD, SCB_LIST_NULL,
 					ROLE_INITIATOR, CAM_REQUEUE_REQ);
 	}
+	ahd_unlock(ahd, &s);
 }
 
 void
@@ -2344,8 +2364,9 @@ done:
 			       ahd_name(ahd), dev->active);
 			retval = FAILED;
 		}
-	}
-	ahd_unlock(ahd, &flags);
+	} else
+		ahd_unlock(ahd, &flags);
+
 	return (retval);
 }
 
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
index cb74fcc..9cb1013 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h
@@ -36,7 +36,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#137 $
+ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#166 $
  *
  */
 #ifndef _AIC79XX_LINUX_H_
@@ -228,7 +228,6 @@ typedef struct timer_list ahd_timer_t;
 typedef void ahd_linux_callback_t (u_long);  
 static __inline void ahd_timer_reset(ahd_timer_t *timer, int usec,
 				     ahd_callback_t *func, void *arg);
-static __inline void ahd_scb_timer_reset(struct scb *scb, u_int usec);
 
 static __inline void
 ahd_timer_reset(ahd_timer_t *timer, int usec, ahd_callback_t *func, void *arg)
@@ -243,12 +242,6 @@ ahd_timer_reset(ahd_timer_t *timer, int 
 	add_timer(timer);
 }
 
-static __inline void
-ahd_scb_timer_reset(struct scb *scb, u_int usec)
-{
-	mod_timer(&scb->io_ctx->eh_timeout, jiffies + (usec * HZ)/1000000);
-}
-
 /***************************** SMP support ************************************/
 #include <linux/spinlock.h>
 
@@ -389,7 +382,6 @@ struct ahd_platform_data {
 
 	spinlock_t		 spin_lock;
 	u_int			 qfrozen;
-	struct timer_list	 reset_timer;
 	struct semaphore	 eh_sem;
 	struct Scsi_Host        *host;		/* pointer to scsi host */
 #define AHD_LINUX_NOIRQ	((uint32_t)~0)
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
index bf360ae..ebbf7e4 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
@@ -220,10 +220,10 @@ ahd_linux_pci_reserve_io_regions(struct 
 	*base2 = pci_resource_start(ahd->dev_softc, 3);
 	if (*base == 0 || *base2 == 0)
 		return (ENOMEM);
-	if (request_region(*base, 256, "aic79xx") == 0)
+	if (!request_region(*base, 256, "aic79xx"))
 		return (ENOMEM);
-	if (request_region(*base2, 256, "aic79xx") == 0) {
-		release_region(*base2, 256);
+	if (!request_region(*base2, 256, "aic79xx")) {
+		release_region(*base, 256);
 		return (ENOMEM);
 	}
 	return (0);
@@ -237,7 +237,7 @@ ahd_linux_pci_reserve_mem_region(struct 
 	u_long	start;
 	u_long	base_page;
 	u_long	base_offset;
-	int	error;
+	int	error = 0;
 
 	if (aic79xx_allow_memio == 0)
 		return (ENOMEM);
@@ -245,16 +245,15 @@ ahd_linux_pci_reserve_mem_region(struct 
 	if ((ahd->bugs & AHD_PCIX_MMAPIO_BUG) != 0)
 		return (ENOMEM);
 
-	error = 0;
 	start = pci_resource_start(ahd->dev_softc, 1);
 	base_page = start & PAGE_MASK;
 	base_offset = start - base_page;
 	if (start != 0) {
 		*bus_addr = start;
-		if (request_mem_region(start, 0x1000, "aic79xx") == 0)
+		if (!request_mem_region(start, 0x1000, "aic79xx"))
 			error = ENOMEM;
-		if (error == 0) {
-			*maddr = ioremap_nocache(base_page, base_offset + 256);
+		if (!error) {
+			*maddr = ioremap_nocache(base_page, base_offset + 512);
 			if (*maddr == NULL) {
 				error = ENOMEM;
 				release_mem_region(start, 0x1000);
@@ -344,7 +343,7 @@ ahd_pci_map_int(struct ahd_softc *ahd)
 
 	error = request_irq(ahd->dev_softc->irq, ahd_linux_isr,
 			    SA_SHIRQ, "aic79xx", ahd);
-	if (error == 0)
+	if (!error)
 		ahd->platform_data->irq = ahd->dev_softc->irq;
 	
 	return (-error);
diff --git a/drivers/scsi/aic7xxx/aic79xx_pci.c b/drivers/scsi/aic7xxx/aic79xx_pci.c
index 196a634..757242e 100644
--- a/drivers/scsi/aic7xxx/aic79xx_pci.c
+++ b/drivers/scsi/aic7xxx/aic79xx_pci.c
@@ -38,7 +38,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#89 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#92 $
  */
 
 #ifdef __linux__
@@ -950,12 +950,19 @@ ahd_aic790X_setup(struct ahd_softc *ahd)
 		if ((ahd->flags & AHD_HP_BOARD) == 0)
 			AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVA);
 	} else {
+		/* This is revision B and newer. */
+		extern uint32_t aic79xx_slowcrc;
 		u_int devconfig1;
 
 		ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS
-			      |  AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY;
+			      |  AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY
+			      |  AHD_BUSFREEREV_BUG;
 		ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_EARLY_REQ_BUG;
 
+		/* If the user requested the the SLOWCRC bit to be set. */
+		if (aic79xx_slowcrc)
+			ahd->features |= AHD_AIC79XXB_SLOWCRC;
+
 		/*
 		 * Some issues have been resolved in the 7901B.
 		 */
diff --git a/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped b/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped
index 8763b15..2068e00 100644
--- a/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped
+++ b/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped
@@ -2,8 +2,8 @@
  * DO NOT EDIT - This file is automatically generated
  *		 from the following source files:
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#119 $
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#76 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#120 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#77 $
  */
 typedef int (ahd_reg_print_t)(u_int, u_int *, u_int);
 typedef struct ahd_reg_parse_entry {
@@ -2204,6 +2204,20 @@ ahd_reg_print_t ahd_cmdsize_table_print;
 #endif
 
 #if AIC_DEBUG_REGISTERS
+ahd_reg_print_t ahd_mk_message_scb_print;
+#else
+#define ahd_mk_message_scb_print(regvalue, cur_col, wrap) \
+    ahd_print_register(NULL, 0, "MK_MESSAGE_SCB", 0x160, regvalue, cur_col, wrap)
+#endif
+
+#if AIC_DEBUG_REGISTERS
+ahd_reg_print_t ahd_mk_message_scsiid_print;
+#else
+#define ahd_mk_message_scsiid_print(regvalue, cur_col, wrap) \
+    ahd_print_register(NULL, 0, "MK_MESSAGE_SCSIID", 0x162, regvalue, cur_col, wrap)
+#endif
+
+#if AIC_DEBUG_REGISTERS
 ahd_reg_print_t ahd_scb_base_print;
 #else
 #define ahd_scb_base_print(regvalue, cur_col, wrap) \
@@ -3638,6 +3652,7 @@ ahd_reg_print_t ahd_scb_disconnected_lis
 #define	SEQ_FLAGS2      		0x14d
 #define		SELECTOUT_QFROZEN	0x04
 #define		TARGET_MSG_PENDING	0x02
+#define		PENDING_MK_MESSAGE	0x01
 
 #define	ALLOCFIFO_SCBPTR		0x14e
 
@@ -3655,6 +3670,10 @@ ahd_reg_print_t ahd_scb_disconnected_lis
 
 #define	CMDSIZE_TABLE   		0x158
 
+#define	MK_MESSAGE_SCB  		0x160
+
+#define	MK_MESSAGE_SCSIID		0x162
+
 #define	SCB_BASE        		0x180
 
 #define	SCB_RESIDUAL_DATACNT		0x180
@@ -3800,5 +3819,5 @@ ahd_reg_print_t ahd_scb_disconnected_lis
 
 
 /* Exported Labels */
-#define	LABEL_seq_isr 	0x285
-#define	LABEL_timer_isr	0x281
+#define	LABEL_seq_isr 	0x28f
+#define	LABEL_timer_isr	0x28b
diff --git a/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped b/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped
index a4137c9..db38a61 100644
--- a/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped
+++ b/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped
@@ -2,8 +2,8 @@
  * DO NOT EDIT - This file is automatically generated
  *		 from the following source files:
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#118 $
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#75 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#120 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#77 $
  */
 
 #include "aic79xx_osm.h"
@@ -3382,6 +3382,7 @@ ahd_initiator_tag_print(u_int regvalue, 
 }
 
 static ahd_reg_parse_entry_t SEQ_FLAGS2_parse_table[] = {
+	{ "PENDING_MK_MESSAGE",	0x01, 0x01 },
 	{ "TARGET_MSG_PENDING",	0x02, 0x02 },
 	{ "SELECTOUT_QFROZEN",	0x04, 0x04 }
 };
@@ -3389,7 +3390,7 @@ static ahd_reg_parse_entry_t SEQ_FLAGS2_
 int
 ahd_seq_flags2_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-	return (ahd_print_register(SEQ_FLAGS2_parse_table, 2, "SEQ_FLAGS2",
+	return (ahd_print_register(SEQ_FLAGS2_parse_table, 3, "SEQ_FLAGS2",
 	    0x14d, regvalue, cur_col, wrap));
 }
 
@@ -3450,6 +3451,20 @@ ahd_cmdsize_table_print(u_int regvalue, 
 }
 
 int
+ahd_mk_message_scb_print(u_int regvalue, u_int *cur_col, u_int wrap)
+{
+	return (ahd_print_register(NULL, 0, "MK_MESSAGE_SCB",
+	    0x160, regvalue, cur_col, wrap));
+}
+
+int
+ahd_mk_message_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap)
+{
+	return (ahd_print_register(NULL, 0, "MK_MESSAGE_SCSIID",
+	    0x162, regvalue, cur_col, wrap));
+}
+
+int
 ahd_scb_base_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
 	return (ahd_print_register(NULL, 0, "SCB_BASE",
diff --git a/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped b/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped
index b1e5365..11bed07 100644
--- a/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped
+++ b/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped
@@ -2,17 +2,17 @@
  * DO NOT EDIT - This file is automatically generated
  *		 from the following source files:
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#119 $
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#76 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#120 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#77 $
  */
 static uint8_t seqprog[] = {
 	0xff, 0x02, 0x06, 0x78,
-	0x00, 0xea, 0x64, 0x59,
+	0x00, 0xea, 0x6e, 0x59,
 	0x01, 0xea, 0x04, 0x30,
 	0xff, 0x04, 0x0c, 0x78,
-	0x19, 0xea, 0x64, 0x59,
+	0x19, 0xea, 0x6e, 0x59,
 	0x19, 0xea, 0x04, 0x00,
-	0x33, 0xea, 0x5e, 0x59,
+	0x33, 0xea, 0x68, 0x59,
 	0x33, 0xea, 0x00, 0x00,
 	0x60, 0x3a, 0x3a, 0x68,
 	0x04, 0x4d, 0x35, 0x78,
@@ -33,15 +33,15 @@ static uint8_t seqprog[] = {
 	0xff, 0xea, 0x62, 0x02,
 	0x00, 0xe2, 0x3a, 0x40,
 	0xff, 0x21, 0x3b, 0x70,
-	0x40, 0x4b, 0xaa, 0x69,
-	0x00, 0xe2, 0x68, 0x59,
-	0x40, 0x4b, 0xaa, 0x69,
-	0x20, 0x4b, 0x96, 0x69,
+	0x40, 0x4b, 0xb4, 0x69,
+	0x00, 0xe2, 0x72, 0x59,
+	0x40, 0x4b, 0xb4, 0x69,
+	0x20, 0x4b, 0xa0, 0x69,
 	0xfc, 0x42, 0x44, 0x78,
 	0x10, 0x40, 0x44, 0x78,
-	0x00, 0xe2, 0xfc, 0x5d,
+	0x00, 0xe2, 0x10, 0x5e,
 	0x20, 0x4d, 0x48, 0x78,
-	0x00, 0xe2, 0xfc, 0x5d,
+	0x00, 0xe2, 0x10, 0x5e,
 	0x30, 0x3f, 0xc0, 0x09,
 	0x30, 0xe0, 0x50, 0x60,
 	0x7f, 0x4a, 0x94, 0x08,
@@ -51,7 +51,7 @@ static uint8_t seqprog[] = {
 	0x00, 0xe2, 0x76, 0x58,
 	0x00, 0xe2, 0x86, 0x58,
 	0x00, 0xe2, 0x06, 0x40,
-	0x33, 0xea, 0x5e, 0x59,
+	0x33, 0xea, 0x68, 0x59,
 	0x33, 0xea, 0x00, 0x00,
 	0x01, 0x52, 0x84, 0x78,
 	0x02, 0x58, 0x50, 0x31,
@@ -59,26 +59,26 @@ static uint8_t seqprog[] = {
 	0xff, 0x97, 0x6f, 0x78,
 	0x50, 0x4b, 0x6a, 0x68,
 	0xbf, 0x3a, 0x74, 0x08,
-	0x14, 0xea, 0x64, 0x59,
+	0x14, 0xea, 0x6e, 0x59,
 	0x14, 0xea, 0x04, 0x00,
 	0x08, 0x92, 0x25, 0x03,
 	0xff, 0x90, 0x5f, 0x68,
-	0x00, 0xe2, 0x76, 0x5b,
+	0x00, 0xe2, 0x8a, 0x5b,
 	0x00, 0xe2, 0x5e, 0x40,
-	0x00, 0xea, 0x5e, 0x59,
+	0x00, 0xea, 0x68, 0x59,
 	0x01, 0xea, 0x00, 0x30,
 	0x80, 0xf9, 0x7e, 0x68,
-	0x00, 0xe2, 0x5c, 0x59,
-	0x11, 0xea, 0x5e, 0x59,
+	0x00, 0xe2, 0x66, 0x59,
+	0x11, 0xea, 0x68, 0x59,
 	0x11, 0xea, 0x00, 0x00,
-	0x80, 0xf9, 0x5c, 0x79,
+	0x80, 0xf9, 0x66, 0x79,
 	0xff, 0xea, 0xd4, 0x0d,
-	0x22, 0xea, 0x5e, 0x59,
+	0x22, 0xea, 0x68, 0x59,
 	0x22, 0xea, 0x00, 0x00,
 	0x10, 0x16, 0x90, 0x78,
 	0x10, 0x16, 0x2c, 0x00,
 	0x01, 0x0b, 0xae, 0x32,
-	0x18, 0xad, 0x12, 0x79,
+	0x18, 0xad, 0x1c, 0x79,
 	0x04, 0xad, 0xdc, 0x68,
 	0x80, 0xad, 0x84, 0x78,
 	0x10, 0xad, 0xaa, 0x78,
@@ -118,7 +118,6 @@ static uint8_t seqprog[] = {
 	0x80, 0x18, 0x30, 0x04,
 	0x40, 0xad, 0x84, 0x78,
 	0xe7, 0xad, 0x5a, 0x09,
-	0x02, 0xa8, 0x40, 0x31,
 	0xff, 0xea, 0xc0, 0x09,
 	0x01, 0x54, 0xa9, 0x1a,
 	0x00, 0x55, 0xab, 0x22,
@@ -128,24 +127,30 @@ static uint8_t seqprog[] = {
 	0xff, 0xea, 0x5a, 0x03,
 	0xff, 0xea, 0x5e, 0x03,
 	0x01, 0x10, 0xd4, 0x31,
-	0x10, 0x92, 0x07, 0x69,
+	0x02, 0xa8, 0x40, 0x31,
+	0x01, 0x92, 0xc1, 0x31,
 	0x3d, 0x93, 0xc5, 0x29,
 	0xfe, 0xe2, 0xc4, 0x09,
 	0x01, 0xea, 0xc6, 0x01,
 	0x02, 0xe2, 0xc8, 0x31,
 	0x02, 0xec, 0x50, 0x31,
 	0x02, 0xa0, 0xda, 0x31,
-	0xff, 0xa9, 0x06, 0x71,
+	0xff, 0xa9, 0x10, 0x71,
+	0x10, 0xe0, 0x0e, 0x79,
+	0x10, 0x92, 0x0f, 0x79,
+	0x01, 0x4d, 0x9b, 0x02,
+	0x02, 0xa0, 0xc0, 0x32,
+	0x01, 0x93, 0xc5, 0x36,
 	0x02, 0xa0, 0x58, 0x37,
-	0xff, 0x21, 0x0f, 0x71,
+	0xff, 0x21, 0x19, 0x71,
 	0x02, 0x22, 0x51, 0x31,
 	0x02, 0xa0, 0x5c, 0x33,
 	0x02, 0xa0, 0x44, 0x36,
 	0x02, 0xa0, 0x40, 0x32,
 	0x02, 0xa0, 0x44, 0x36,
-	0x04, 0x4d, 0x17, 0x69,
-	0x40, 0x16, 0x48, 0x69,
-	0xff, 0x2d, 0x4d, 0x61,
+	0x05, 0x4d, 0x21, 0x69,
+	0x40, 0x16, 0x52, 0x69,
+	0xff, 0x2d, 0x57, 0x61,
 	0xff, 0x29, 0x85, 0x70,
 	0x02, 0x28, 0x55, 0x32,
 	0x01, 0xea, 0x5a, 0x01,
@@ -159,22 +164,22 @@ static uint8_t seqprog[] = {
 	0x01, 0x56, 0xad, 0x1a,
 	0xff, 0x54, 0xa9, 0x1a,
 	0xff, 0x55, 0xab, 0x22,
-	0xff, 0x8d, 0x41, 0x71,
-	0x80, 0xac, 0x40, 0x71,
-	0x20, 0x16, 0x40, 0x69,
+	0xff, 0x8d, 0x4b, 0x71,
+	0x80, 0xac, 0x4a, 0x71,
+	0x20, 0x16, 0x4a, 0x69,
 	0x00, 0xac, 0xc4, 0x19,
-	0x07, 0xe2, 0x40, 0xf9,
+	0x07, 0xe2, 0x4a, 0xf9,
 	0x02, 0x8c, 0x51, 0x31,
-	0x00, 0xe2, 0x24, 0x41,
+	0x00, 0xe2, 0x2e, 0x41,
 	0x01, 0xac, 0x08, 0x31,
 	0x09, 0xea, 0x5a, 0x01,
 	0x02, 0x8c, 0x51, 0x32,
 	0xff, 0xea, 0x1a, 0x07,
 	0x04, 0x24, 0xf9, 0x30,
-	0x1d, 0xea, 0x52, 0x41,
+	0x1d, 0xea, 0x5c, 0x41,
 	0x02, 0x2c, 0x51, 0x31,
 	0x04, 0xa8, 0xf9, 0x30,
-	0x19, 0xea, 0x52, 0x41,
+	0x19, 0xea, 0x5c, 0x41,
 	0x06, 0xea, 0x08, 0x81,
 	0x01, 0xe2, 0x5a, 0x35,
 	0x02, 0xf2, 0xf0, 0x31,
@@ -190,27 +195,27 @@ static uint8_t seqprog[] = {
 	0x02, 0x20, 0xb9, 0x30,
 	0x02, 0x20, 0x51, 0x31,
 	0x4c, 0x93, 0xd7, 0x28,
-	0x10, 0x92, 0x77, 0x79,
+	0x10, 0x92, 0x81, 0x79,
 	0x01, 0x6b, 0xc0, 0x30,
 	0x02, 0x64, 0xc8, 0x00,
 	0x40, 0x3a, 0x74, 0x04,
 	0x00, 0xe2, 0x76, 0x58,
-	0x33, 0xea, 0x5e, 0x59,
+	0x33, 0xea, 0x68, 0x59,
 	0x33, 0xea, 0x00, 0x00,
 	0x30, 0x3f, 0xc0, 0x09,
-	0x30, 0xe0, 0x78, 0x61,
-	0x20, 0x3f, 0x8e, 0x69,
-	0x10, 0x3f, 0x78, 0x79,
+	0x30, 0xe0, 0x82, 0x61,
+	0x20, 0x3f, 0x98, 0x69,
+	0x10, 0x3f, 0x82, 0x79,
 	0x02, 0xea, 0x7e, 0x00,
-	0x00, 0xea, 0x5e, 0x59,
+	0x00, 0xea, 0x68, 0x59,
 	0x01, 0xea, 0x00, 0x30,
 	0x02, 0x4e, 0x51, 0x35,
 	0x01, 0xea, 0x7e, 0x00,
-	0x11, 0xea, 0x5e, 0x59,
+	0x11, 0xea, 0x68, 0x59,
 	0x11, 0xea, 0x00, 0x00,
 	0x02, 0x4e, 0x51, 0x35,
 	0xc0, 0x4a, 0x94, 0x00,
-	0x04, 0x41, 0x9c, 0x79,
+	0x04, 0x41, 0xa6, 0x79,
 	0x08, 0xea, 0x98, 0x00,
 	0x08, 0x57, 0xae, 0x00,
 	0x08, 0x3c, 0x78, 0x00,
@@ -218,12 +223,12 @@ static uint8_t seqprog[] = {
 	0x0f, 0x67, 0xc0, 0x09,
 	0x00, 0x3a, 0x75, 0x02,
 	0x20, 0xea, 0x96, 0x00,
-	0x00, 0xe2, 0x14, 0x42,
+	0x00, 0xe2, 0x28, 0x42,
 	0xc0, 0x4a, 0x94, 0x00,
-	0x40, 0x3a, 0xc8, 0x69,
+	0x40, 0x3a, 0xd2, 0x69,
 	0x02, 0x55, 0x06, 0x68,
-	0x02, 0x56, 0xc8, 0x69,
-	0xff, 0x5b, 0xc8, 0x61,
+	0x02, 0x56, 0xd2, 0x69,
+	0xff, 0x5b, 0xd2, 0x61,
 	0x02, 0x20, 0x51, 0x31,
 	0x80, 0xea, 0xb2, 0x01,
 	0x44, 0xea, 0x00, 0x00,
@@ -231,40 +236,45 @@ static uint8_t seqprog[] = {
 	0x33, 0xea, 0x00, 0x00,
 	0xff, 0xea, 0xb2, 0x09,
 	0xff, 0xe0, 0xc0, 0x19,
-	0xff, 0xe0, 0xca, 0x79,
+	0xff, 0xe0, 0xd4, 0x79,
 	0x02, 0xac, 0x51, 0x31,
-	0x00, 0xe2, 0xc0, 0x41,
+	0x00, 0xe2, 0xca, 0x41,
 	0x02, 0x5e, 0x50, 0x31,
 	0x02, 0xa8, 0xb8, 0x30,
 	0x02, 0x5c, 0x50, 0x31,
-	0xff, 0xad, 0xdb, 0x71,
+	0xff, 0xad, 0xe5, 0x71,
 	0x02, 0xac, 0x41, 0x31,
 	0x02, 0x22, 0x51, 0x31,
 	0x02, 0xa0, 0x5c, 0x33,
 	0x02, 0xa0, 0x44, 0x32,
-	0x00, 0xe2, 0xe4, 0x41,
-	0x10, 0x92, 0xe5, 0x69,
+	0x00, 0xe2, 0xf8, 0x41,
+	0x01, 0x4d, 0xf1, 0x79,
+	0x01, 0x62, 0xc1, 0x31,
+	0x00, 0x93, 0xf1, 0x61,
+	0xfe, 0x4d, 0x9b, 0x0a,
+	0x02, 0x60, 0x41, 0x31,
+	0x00, 0xe2, 0xdc, 0x41,
 	0x3d, 0x93, 0xc9, 0x29,
 	0x01, 0xe4, 0xc8, 0x01,
 	0x01, 0xea, 0xca, 0x01,
 	0xff, 0xea, 0xda, 0x01,
 	0x02, 0x20, 0x51, 0x31,
 	0x02, 0xae, 0x41, 0x32,
-	0xff, 0x21, 0xed, 0x61,
+	0xff, 0x21, 0x01, 0x62,
 	0xff, 0xea, 0x46, 0x02,
 	0x02, 0x5c, 0x50, 0x31,
 	0x40, 0xea, 0x96, 0x00,
-	0x02, 0x56, 0x04, 0x6e,
-	0x01, 0x55, 0x04, 0x6e,
-	0x10, 0x92, 0xf9, 0x79,
-	0x10, 0x40, 0x02, 0x6a,
-	0x01, 0x56, 0x02, 0x7a,
+	0x02, 0x56, 0x20, 0x6e,
+	0x01, 0x55, 0x20, 0x6e,
+	0x10, 0x92, 0x0d, 0x7a,
+	0x10, 0x40, 0x16, 0x6a,
+	0x01, 0x56, 0x16, 0x7a,
 	0xff, 0x97, 0x07, 0x78,
-	0x13, 0xea, 0x64, 0x59,
+	0x13, 0xea, 0x6e, 0x59,
 	0x13, 0xea, 0x04, 0x00,
 	0x00, 0xe2, 0x06, 0x40,
 	0xbf, 0x3a, 0x74, 0x08,
-	0x04, 0x41, 0x08, 0x7a,
+	0x04, 0x41, 0x1c, 0x7a,
 	0x08, 0xea, 0x98, 0x00,
 	0x08, 0x57, 0xae, 0x00,
 	0x01, 0x93, 0x75, 0x32,
@@ -272,108 +282,108 @@ static uint8_t seqprog[] = {
 	0x40, 0xea, 0x72, 0x02,
 	0x08, 0x3c, 0x78, 0x00,
 	0x80, 0xea, 0x6e, 0x02,
-	0x00, 0xe2, 0xe2, 0x5b,
+	0x00, 0xe2, 0xf6, 0x5b,
 	0x01, 0x3c, 0xc1, 0x31,
-	0x9f, 0xe0, 0x84, 0x7c,
-	0x80, 0xe0, 0x28, 0x72,
-	0xa0, 0xe0, 0x64, 0x72,
-	0xc0, 0xe0, 0x5a, 0x72,
-	0xe0, 0xe0, 0x94, 0x72,
-	0x01, 0xea, 0x64, 0x59,
+	0x9f, 0xe0, 0x98, 0x7c,
+	0x80, 0xe0, 0x3c, 0x72,
+	0xa0, 0xe0, 0x78, 0x72,
+	0xc0, 0xe0, 0x6e, 0x72,
+	0xe0, 0xe0, 0xa8, 0x72,
+	0x01, 0xea, 0x6e, 0x59,
 	0x01, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0x14, 0x42,
-	0x80, 0x39, 0x2f, 0x7a,
-	0x03, 0xea, 0x64, 0x59,
+	0x00, 0xe2, 0x28, 0x42,
+	0x80, 0x39, 0x43, 0x7a,
+	0x03, 0xea, 0x6e, 0x59,
 	0x03, 0xea, 0x04, 0x00,
-	0xee, 0x00, 0x36, 0x6a,
+	0xee, 0x00, 0x4a, 0x6a,
 	0x05, 0xea, 0xb4, 0x00,
-	0x33, 0xea, 0x5e, 0x59,
+	0x33, 0xea, 0x68, 0x59,
 	0x33, 0xea, 0x00, 0x00,
 	0x02, 0xa8, 0x9c, 0x32,
-	0x00, 0xe2, 0x7e, 0x59,
+	0x00, 0xe2, 0x88, 0x59,
 	0xef, 0x96, 0xd5, 0x19,
-	0x00, 0xe2, 0x46, 0x52,
+	0x00, 0xe2, 0x5a, 0x52,
 	0x09, 0x80, 0xe1, 0x30,
 	0x02, 0xea, 0x36, 0x00,
 	0xa8, 0xea, 0x32, 0x00,
-	0x00, 0xe2, 0x4c, 0x42,
+	0x00, 0xe2, 0x60, 0x42,
 	0x01, 0x96, 0xd1, 0x30,
 	0x10, 0x80, 0x89, 0x31,
 	0x20, 0xea, 0x32, 0x00,
 	0xbf, 0x39, 0x73, 0x0a,
-	0x10, 0x4c, 0x56, 0x6a,
-	0x20, 0x19, 0x4e, 0x6a,
-	0x20, 0x19, 0x52, 0x6a,
-	0x02, 0x4d, 0x14, 0x6a,
+	0x10, 0x4c, 0x6a, 0x6a,
+	0x20, 0x19, 0x62, 0x6a,
+	0x20, 0x19, 0x66, 0x6a,
+	0x02, 0x4d, 0x28, 0x6a,
 	0x40, 0x39, 0x73, 0x02,
-	0x00, 0xe2, 0x14, 0x42,
-	0x80, 0x39, 0xd5, 0x6a,
+	0x00, 0xe2, 0x28, 0x42,
+	0x80, 0x39, 0xe9, 0x6a,
 	0x01, 0x44, 0x10, 0x33,
 	0x08, 0x92, 0x25, 0x03,
-	0x00, 0xe2, 0x14, 0x42,
+	0x00, 0xe2, 0x28, 0x42,
 	0x10, 0xea, 0x80, 0x00,
 	0x01, 0x37, 0xc5, 0x31,
-	0x80, 0xe2, 0x80, 0x62,
-	0x10, 0x92, 0xa5, 0x6a,
+	0x80, 0xe2, 0x94, 0x62,
+	0x10, 0x92, 0xb9, 0x6a,
 	0xc0, 0x94, 0xc5, 0x01,
-	0x40, 0x92, 0x71, 0x6a,
+	0x40, 0x92, 0x85, 0x6a,
 	0xbf, 0xe2, 0xc4, 0x09,
-	0x20, 0x92, 0x85, 0x7a,
+	0x20, 0x92, 0x99, 0x7a,
 	0x01, 0xe2, 0x88, 0x30,
-	0x00, 0xe2, 0xe2, 0x5b,
-	0xa0, 0x3c, 0x8d, 0x62,
+	0x00, 0xe2, 0xf6, 0x5b,
+	0xa0, 0x3c, 0xa1, 0x62,
 	0x23, 0x92, 0x89, 0x08,
-	0x00, 0xe2, 0xe2, 0x5b,
-	0xa0, 0x3c, 0x8d, 0x62,
-	0x00, 0xa8, 0x84, 0x42,
-	0xff, 0xe2, 0x84, 0x62,
-	0x00, 0xe2, 0xa4, 0x42,
+	0x00, 0xe2, 0xf6, 0x5b,
+	0xa0, 0x3c, 0xa1, 0x62,
+	0x00, 0xa8, 0x98, 0x42,
+	0xff, 0xe2, 0x98, 0x62,
+	0x00, 0xe2, 0xb8, 0x42,
 	0x40, 0xea, 0x98, 0x00,
 	0x01, 0xe2, 0x88, 0x30,
-	0x00, 0xe2, 0xe2, 0x5b,
-	0xa0, 0x3c, 0x63, 0x72,
+	0x00, 0xe2, 0xf6, 0x5b,
+	0xa0, 0x3c, 0x77, 0x72,
 	0x40, 0xea, 0x98, 0x00,
 	0x01, 0x37, 0x95, 0x32,
 	0x08, 0xea, 0x6e, 0x02,
-	0x00, 0xe2, 0x14, 0x42,
-	0xe0, 0xea, 0xfe, 0x5b,
-	0x80, 0xe0, 0xe0, 0x6a,
-	0x04, 0xe0, 0x92, 0x73,
-	0x02, 0xe0, 0xc4, 0x73,
-	0x00, 0xea, 0x3e, 0x73,
-	0x03, 0xe0, 0xd4, 0x73,
-	0x23, 0xe0, 0xb6, 0x72,
-	0x08, 0xe0, 0xdc, 0x72,
-	0x00, 0xe2, 0xe2, 0x5b,
-	0x07, 0xea, 0x64, 0x59,
+	0x00, 0xe2, 0x28, 0x42,
+	0xe0, 0xea, 0x12, 0x5c,
+	0x80, 0xe0, 0xf4, 0x6a,
+	0x04, 0xe0, 0xa6, 0x73,
+	0x02, 0xe0, 0xd8, 0x73,
+	0x00, 0xea, 0x52, 0x73,
+	0x03, 0xe0, 0xe8, 0x73,
+	0x23, 0xe0, 0xca, 0x72,
+	0x08, 0xe0, 0xf0, 0x72,
+	0x00, 0xe2, 0xf6, 0x5b,
+	0x07, 0xea, 0x6e, 0x59,
 	0x07, 0xea, 0x04, 0x00,
-	0x08, 0x48, 0x15, 0x72,
-	0x04, 0x48, 0xb3, 0x62,
+	0x08, 0x48, 0x29, 0x72,
+	0x04, 0x48, 0xc7, 0x62,
 	0x01, 0x49, 0x89, 0x30,
-	0x00, 0xe2, 0xa4, 0x42,
+	0x00, 0xe2, 0xb8, 0x42,
 	0x01, 0x44, 0xd4, 0x31,
-	0x00, 0xe2, 0xa4, 0x42,
+	0x00, 0xe2, 0xb8, 0x42,
 	0x01, 0x00, 0x6c, 0x32,
-	0x33, 0xea, 0x5e, 0x59,
+	0x33, 0xea, 0x68, 0x59,
 	0x33, 0xea, 0x00, 0x00,
 	0x4c, 0x3a, 0xc1, 0x28,
 	0x01, 0x64, 0xc0, 0x31,
-	0x00, 0x36, 0x5f, 0x59,
+	0x00, 0x36, 0x69, 0x59,
 	0x01, 0x36, 0x01, 0x30,
-	0x01, 0xe0, 0xda, 0x7a,
-	0xa0, 0xea, 0xf4, 0x5b,
-	0x01, 0xa0, 0xda, 0x62,
-	0x01, 0x84, 0xcf, 0x7a,
-	0x01, 0x95, 0xdd, 0x6a,
-	0x05, 0xea, 0x64, 0x59,
+	0x01, 0xe0, 0xee, 0x7a,
+	0xa0, 0xea, 0x08, 0x5c,
+	0x01, 0xa0, 0xee, 0x62,
+	0x01, 0x84, 0xe3, 0x7a,
+	0x01, 0x95, 0xf1, 0x6a,
+	0x05, 0xea, 0x6e, 0x59,
 	0x05, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0xdc, 0x42,
-	0x03, 0xea, 0x64, 0x59,
+	0x00, 0xe2, 0xf0, 0x42,
+	0x03, 0xea, 0x6e, 0x59,
 	0x03, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0xdc, 0x42,
-	0x07, 0xea, 0x06, 0x5c,
+	0x00, 0xe2, 0xf0, 0x42,
+	0x07, 0xea, 0x1a, 0x5c,
 	0x01, 0x44, 0xd4, 0x31,
-	0x00, 0xe2, 0x14, 0x42,
+	0x00, 0xe2, 0x28, 0x42,
 	0x3f, 0xe0, 0x76, 0x0a,
 	0xc0, 0x3a, 0xc1, 0x09,
 	0x00, 0x3b, 0x51, 0x01,
@@ -384,54 +394,54 @@ static uint8_t seqprog[] = {
 	0x01, 0xea, 0xc6, 0x01,
 	0x02, 0xe2, 0xc8, 0x31,
 	0x02, 0xec, 0x40, 0x31,
-	0xff, 0xa1, 0xfc, 0x72,
+	0xff, 0xa1, 0x10, 0x73,
 	0x02, 0xe8, 0xda, 0x31,
 	0x02, 0xa0, 0x50, 0x31,
-	0x00, 0xe2, 0x1e, 0x43,
+	0x00, 0xe2, 0x32, 0x43,
 	0x80, 0x39, 0x73, 0x02,
 	0x01, 0x44, 0xd4, 0x31,
-	0x00, 0xe2, 0xe2, 0x5b,
+	0x00, 0xe2, 0xf6, 0x5b,
 	0x01, 0x39, 0x73, 0x02,
-	0xe0, 0x3c, 0x39, 0x63,
+	0xe0, 0x3c, 0x4d, 0x63,
 	0x02, 0x39, 0x73, 0x02,
-	0x20, 0x46, 0x32, 0x63,
+	0x20, 0x46, 0x46, 0x63,
 	0xff, 0xea, 0x52, 0x09,
-	0xa8, 0xea, 0xf4, 0x5b,
-	0x04, 0x92, 0x19, 0x7b,
+	0xa8, 0xea, 0x08, 0x5c,
+	0x04, 0x92, 0x2d, 0x7b,
 	0x01, 0x3a, 0xc1, 0x31,
-	0x00, 0x93, 0x19, 0x63,
+	0x00, 0x93, 0x2d, 0x63,
 	0x01, 0x3b, 0xc1, 0x31,
-	0x00, 0x94, 0x23, 0x73,
+	0x00, 0x94, 0x37, 0x73,
 	0x01, 0xa9, 0x52, 0x11,
-	0xff, 0xa9, 0x0e, 0x6b,
-	0x00, 0xe2, 0x32, 0x43,
+	0xff, 0xa9, 0x22, 0x6b,
+	0x00, 0xe2, 0x46, 0x43,
 	0x10, 0x39, 0x73, 0x02,
-	0x04, 0x92, 0x33, 0x7b,
+	0x04, 0x92, 0x47, 0x7b,
 	0xfb, 0x92, 0x25, 0x0b,
 	0xff, 0xea, 0x72, 0x0a,
-	0x01, 0xa4, 0x2d, 0x6b,
+	0x01, 0xa4, 0x41, 0x6b,
 	0x02, 0xa8, 0x9c, 0x32,
-	0x00, 0xe2, 0x7e, 0x59,
-	0x10, 0x92, 0xdd, 0x7a,
-	0xff, 0xea, 0x06, 0x5c,
-	0x00, 0xe2, 0xdc, 0x42,
-	0x04, 0xea, 0x64, 0x59,
+	0x00, 0xe2, 0x88, 0x59,
+	0x10, 0x92, 0xf1, 0x7a,
+	0xff, 0xea, 0x1a, 0x5c,
+	0x00, 0xe2, 0xf0, 0x42,
+	0x04, 0xea, 0x6e, 0x59,
 	0x04, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0xdc, 0x42,
-	0x04, 0xea, 0x64, 0x59,
+	0x00, 0xe2, 0xf0, 0x42,
+	0x04, 0xea, 0x6e, 0x59,
 	0x04, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0x14, 0x42,
-	0x08, 0x92, 0xd5, 0x7a,
-	0xc0, 0x39, 0x49, 0x7b,
-	0x80, 0x39, 0xd5, 0x6a,
-	0xff, 0x88, 0x49, 0x6b,
-	0x40, 0x39, 0xd5, 0x6a,
-	0x10, 0x92, 0x4f, 0x7b,
-	0x0a, 0xea, 0x64, 0x59,
+	0x00, 0xe2, 0x28, 0x42,
+	0x08, 0x92, 0xe9, 0x7a,
+	0xc0, 0x39, 0x5d, 0x7b,
+	0x80, 0x39, 0xe9, 0x6a,
+	0xff, 0x88, 0x5d, 0x6b,
+	0x40, 0x39, 0xe9, 0x6a,
+	0x10, 0x92, 0x63, 0x7b,
+	0x0a, 0xea, 0x6e, 0x59,
 	0x0a, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0x6e, 0x5b,
-	0x00, 0xe2, 0xae, 0x43,
-	0x50, 0x4b, 0x56, 0x6b,
+	0x00, 0xe2, 0x82, 0x5b,
+	0x00, 0xe2, 0xc2, 0x43,
+	0x50, 0x4b, 0x6a, 0x6b,
 	0xbf, 0x3a, 0x74, 0x08,
 	0x01, 0xe0, 0xf4, 0x31,
 	0xff, 0xea, 0xc0, 0x09,
@@ -441,31 +451,31 @@ static uint8_t seqprog[] = {
 	0x01, 0xfa, 0xc0, 0x35,
 	0x02, 0xa8, 0x90, 0x32,
 	0x02, 0xea, 0xb4, 0x00,
-	0x33, 0xea, 0x5e, 0x59,
+	0x33, 0xea, 0x68, 0x59,
 	0x33, 0xea, 0x00, 0x00,
 	0x02, 0x48, 0x51, 0x31,
 	0xff, 0x90, 0x85, 0x68,
-	0xff, 0x88, 0x7b, 0x6b,
-	0x01, 0xa4, 0x77, 0x6b,
-	0x02, 0xa4, 0x7f, 0x6b,
-	0x01, 0x84, 0x7f, 0x7b,
+	0xff, 0x88, 0x8f, 0x6b,
+	0x01, 0xa4, 0x8b, 0x6b,
+	0x02, 0xa4, 0x93, 0x6b,
+	0x01, 0x84, 0x93, 0x7b,
 	0x02, 0x28, 0x19, 0x33,
 	0x02, 0xa8, 0x50, 0x36,
-	0xff, 0x88, 0x7f, 0x73,
-	0x00, 0xe2, 0x52, 0x5b,
+	0xff, 0x88, 0x93, 0x73,
+	0x00, 0xe2, 0x66, 0x5b,
 	0x02, 0xa8, 0x20, 0x33,
 	0x04, 0xa4, 0x49, 0x03,
 	0xff, 0xea, 0x1a, 0x03,
-	0xff, 0x2d, 0x8b, 0x63,
+	0xff, 0x2d, 0x9f, 0x63,
 	0x02, 0xa8, 0x58, 0x32,
 	0x02, 0xa8, 0x5c, 0x36,
 	0x02, 0xa8, 0x40, 0x31,
 	0x02, 0x2e, 0x51, 0x31,
 	0x02, 0xa0, 0x18, 0x33,
 	0x02, 0xa0, 0x5c, 0x36,
-	0xc0, 0x39, 0xd5, 0x6a,
+	0xc0, 0x39, 0xe9, 0x6a,
 	0x04, 0x92, 0x25, 0x03,
-	0x20, 0x92, 0xaf, 0x6b,
+	0x20, 0x92, 0xc3, 0x6b,
 	0x02, 0xa8, 0x40, 0x31,
 	0xc0, 0x3a, 0xc1, 0x09,
 	0x00, 0x3b, 0x51, 0x01,
@@ -480,60 +490,60 @@ static uint8_t seqprog[] = {
 	0xf7, 0x57, 0xae, 0x08,
 	0x08, 0xea, 0x98, 0x00,
 	0x01, 0x44, 0xd4, 0x31,
-	0xee, 0x00, 0xb8, 0x6b,
+	0xee, 0x00, 0xcc, 0x6b,
 	0x02, 0xea, 0xb4, 0x00,
 	0xc0, 0xea, 0x72, 0x02,
-	0x09, 0x4c, 0xba, 0x7b,
+	0x09, 0x4c, 0xce, 0x7b,
 	0x01, 0xea, 0x78, 0x02,
 	0x08, 0x4c, 0x06, 0x68,
-	0x0b, 0xea, 0x64, 0x59,
+	0x0b, 0xea, 0x6e, 0x59,
 	0x0b, 0xea, 0x04, 0x00,
 	0x01, 0x44, 0xd4, 0x31,
-	0x20, 0x39, 0x15, 0x7a,
-	0x00, 0xe2, 0xcc, 0x5b,
-	0x00, 0xe2, 0x14, 0x42,
-	0x01, 0x84, 0xd1, 0x7b,
+	0x20, 0x39, 0x29, 0x7a,
+	0x00, 0xe2, 0xe0, 0x5b,
+	0x00, 0xe2, 0x28, 0x42,
+	0x01, 0x84, 0xe5, 0x7b,
 	0x01, 0xa4, 0x49, 0x07,
 	0x08, 0x60, 0x30, 0x33,
 	0x08, 0x80, 0x41, 0x37,
 	0xdf, 0x39, 0x73, 0x0a,
-	0xee, 0x00, 0xde, 0x6b,
+	0xee, 0x00, 0xf2, 0x6b,
 	0x05, 0xea, 0xb4, 0x00,
-	0x33, 0xea, 0x5e, 0x59,
+	0x33, 0xea, 0x68, 0x59,
 	0x33, 0xea, 0x00, 0x00,
-	0x00, 0xe2, 0x7e, 0x59,
-	0x00, 0xe2, 0xdc, 0x42,
-	0xff, 0x42, 0xee, 0x6b,
-	0x01, 0x41, 0xe2, 0x6b,
-	0x02, 0x41, 0xe2, 0x7b,
-	0xff, 0x42, 0xee, 0x6b,
-	0x01, 0x41, 0xe2, 0x6b,
-	0x02, 0x41, 0xe2, 0x7b,
-	0xff, 0x42, 0xee, 0x7b,
-	0x04, 0x4c, 0xe2, 0x6b,
+	0x00, 0xe2, 0x88, 0x59,
+	0x00, 0xe2, 0xf0, 0x42,
+	0xff, 0x42, 0x02, 0x6c,
+	0x01, 0x41, 0xf6, 0x6b,
+	0x02, 0x41, 0xf6, 0x7b,
+	0xff, 0x42, 0x02, 0x6c,
+	0x01, 0x41, 0xf6, 0x6b,
+	0x02, 0x41, 0xf6, 0x7b,
+	0xff, 0x42, 0x02, 0x7c,
+	0x04, 0x4c, 0xf6, 0x6b,
 	0xe0, 0x41, 0x78, 0x0e,
 	0x01, 0x44, 0xd4, 0x31,
-	0xff, 0x42, 0xf6, 0x7b,
-	0x04, 0x4c, 0xf6, 0x6b,
+	0xff, 0x42, 0x0a, 0x7c,
+	0x04, 0x4c, 0x0a, 0x6c,
 	0xe0, 0x41, 0x78, 0x0a,
-	0xe0, 0x3c, 0x15, 0x62,
+	0xe0, 0x3c, 0x29, 0x62,
 	0xff, 0xea, 0xca, 0x09,
 	0x01, 0xe2, 0xc8, 0x31,
 	0x01, 0x46, 0xda, 0x35,
 	0x01, 0x44, 0xd4, 0x35,
 	0x10, 0xea, 0x80, 0x00,
 	0x01, 0xe2, 0x6e, 0x36,
-	0x04, 0xa6, 0x0e, 0x7c,
+	0x04, 0xa6, 0x22, 0x7c,
 	0xff, 0xea, 0x5a, 0x09,
 	0xff, 0xea, 0x4c, 0x0d,
-	0x01, 0xa6, 0x3a, 0x6c,
+	0x01, 0xa6, 0x4e, 0x6c,
 	0x10, 0xad, 0x84, 0x78,
-	0x80, 0xad, 0x32, 0x6c,
+	0x80, 0xad, 0x46, 0x6c,
 	0x08, 0xad, 0x84, 0x68,
-	0x20, 0x19, 0x26, 0x7c,
+	0x20, 0x19, 0x3a, 0x7c,
 	0x80, 0xea, 0xb2, 0x01,
 	0x11, 0x00, 0x00, 0x10,
-	0x02, 0xa6, 0x22, 0x7c,
+	0x02, 0xa6, 0x36, 0x7c,
 	0xff, 0xea, 0xb2, 0x0d,
 	0x11, 0x00, 0x00, 0x10,
 	0xff, 0xea, 0xb2, 0x09,
@@ -561,7 +571,7 @@ static uint8_t seqprog[] = {
 	0x00, 0x86, 0x0d, 0x23,
 	0x00, 0x87, 0x0f, 0x23,
 	0x01, 0x84, 0xc5, 0x31,
-	0x80, 0x83, 0x5d, 0x7c,
+	0x80, 0x83, 0x71, 0x7c,
 	0x02, 0xe2, 0xc4, 0x01,
 	0xff, 0xea, 0x4c, 0x09,
 	0x01, 0xe2, 0x36, 0x30,
@@ -572,75 +582,75 @@ static uint8_t seqprog[] = {
 	0xfe, 0xa6, 0x4c, 0x0d,
 	0x0b, 0x98, 0xe1, 0x30,
 	0xfd, 0xa4, 0x49, 0x09,
-	0x80, 0xa3, 0x71, 0x7c,
+	0x80, 0xa3, 0x85, 0x7c,
 	0x02, 0xa4, 0x48, 0x01,
 	0x01, 0xa4, 0x36, 0x30,
 	0xa8, 0xea, 0x32, 0x00,
 	0xfd, 0xa4, 0x49, 0x0b,
 	0x05, 0xa3, 0x07, 0x33,
-	0x80, 0x83, 0x7d, 0x6c,
+	0x80, 0x83, 0x91, 0x6c,
 	0x02, 0xea, 0x4c, 0x05,
 	0xff, 0xea, 0x4c, 0x0d,
-	0x00, 0xe2, 0x56, 0x59,
-	0x02, 0xa6, 0x10, 0x6c,
+	0x00, 0xe2, 0x60, 0x59,
+	0x02, 0xa6, 0x24, 0x6c,
 	0x80, 0xf9, 0xf2, 0x05,
-	0xc0, 0x39, 0x8b, 0x7c,
-	0x03, 0xea, 0x64, 0x59,
+	0xc0, 0x39, 0x9f, 0x7c,
+	0x03, 0xea, 0x6e, 0x59,
 	0x03, 0xea, 0x04, 0x00,
-	0x20, 0x39, 0xaf, 0x7c,
-	0x01, 0x84, 0x95, 0x6c,
-	0x06, 0xea, 0x64, 0x59,
+	0x20, 0x39, 0xc3, 0x7c,
+	0x01, 0x84, 0xa9, 0x6c,
+	0x06, 0xea, 0x6e, 0x59,
 	0x06, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0xb2, 0x44,
+	0x00, 0xe2, 0xc6, 0x44,
 	0x01, 0x00, 0x6c, 0x32,
-	0xee, 0x00, 0x9e, 0x6c,
+	0xee, 0x00, 0xb2, 0x6c,
 	0x05, 0xea, 0xb4, 0x00,
-	0x33, 0xea, 0x5e, 0x59,
+	0x33, 0xea, 0x68, 0x59,
 	0x33, 0xea, 0x00, 0x00,
 	0x80, 0x3d, 0x7a, 0x00,
-	0xfc, 0x42, 0xa0, 0x7c,
+	0xfc, 0x42, 0xb4, 0x7c,
 	0x7f, 0x3d, 0x7a, 0x08,
-	0x00, 0x36, 0x5f, 0x59,
+	0x00, 0x36, 0x69, 0x59,
 	0x01, 0x36, 0x01, 0x30,
-	0x09, 0xea, 0x64, 0x59,
+	0x09, 0xea, 0x6e, 0x59,
 	0x09, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0x14, 0x42,
-	0x01, 0xa4, 0x95, 0x6c,
-	0x00, 0xe2, 0x68, 0x5c,
+	0x00, 0xe2, 0x28, 0x42,
+	0x01, 0xa4, 0xa9, 0x6c,
+	0x00, 0xe2, 0x7c, 0x5c,
 	0x20, 0x39, 0x73, 0x02,
 	0x01, 0x00, 0x6c, 0x32,
-	0x02, 0xa6, 0xba, 0x7c,
-	0x00, 0xe2, 0x7e, 0x5c,
+	0x02, 0xa6, 0xce, 0x7c,
+	0x00, 0xe2, 0x92, 0x5c,
 	0x00, 0xe2, 0x76, 0x58,
 	0x00, 0xe2, 0x86, 0x58,
 	0x00, 0xe2, 0x5a, 0x58,
-	0x00, 0x36, 0x5f, 0x59,
+	0x00, 0x36, 0x69, 0x59,
 	0x01, 0x36, 0x01, 0x30,
-	0x20, 0x19, 0xba, 0x6c,
-	0x00, 0xe2, 0xea, 0x5c,
-	0x04, 0x19, 0xd4, 0x6c,
+	0x20, 0x19, 0xce, 0x6c,
+	0x00, 0xe2, 0xfe, 0x5c,
+	0x04, 0x19, 0xe8, 0x6c,
 	0x02, 0x19, 0x32, 0x00,
-	0x01, 0x84, 0xd5, 0x7c,
-	0x01, 0x1b, 0xce, 0x7c,
-	0x01, 0x1a, 0xd4, 0x6c,
-	0x00, 0xe2, 0x84, 0x44,
-	0x80, 0x4b, 0xda, 0x6c,
-	0x01, 0x4c, 0xd6, 0x7c,
-	0x03, 0x42, 0x84, 0x6c,
-	0x00, 0xe2, 0x0a, 0x5c,
+	0x01, 0x84, 0xe9, 0x7c,
+	0x01, 0x1b, 0xe2, 0x7c,
+	0x01, 0x1a, 0xe8, 0x6c,
+	0x00, 0xe2, 0x98, 0x44,
+	0x80, 0x4b, 0xee, 0x6c,
+	0x01, 0x4c, 0xea, 0x7c,
+	0x03, 0x42, 0x98, 0x6c,
+	0x00, 0xe2, 0x1e, 0x5c,
 	0x80, 0xf9, 0xf2, 0x01,
-	0x04, 0x39, 0x15, 0x7a,
-	0x00, 0xe2, 0x14, 0x42,
-	0x08, 0x5d, 0xf2, 0x6c,
+	0x04, 0x39, 0x29, 0x7a,
+	0x00, 0xe2, 0x28, 0x42,
+	0x08, 0x5d, 0x06, 0x6d,
 	0x00, 0xe2, 0x76, 0x58,
-	0x00, 0x36, 0x5f, 0x59,
+	0x00, 0x36, 0x69, 0x59,
 	0x01, 0x36, 0x01, 0x30,
-	0x02, 0x1b, 0xe2, 0x7c,
-	0x08, 0x5d, 0xf0, 0x7c,
+	0x02, 0x1b, 0xf6, 0x7c,
+	0x08, 0x5d, 0x04, 0x7d,
 	0x03, 0x68, 0x00, 0x37,
 	0x01, 0x84, 0x09, 0x07,
-	0x80, 0x1b, 0xfc, 0x7c,
-	0x80, 0x84, 0xfd, 0x6c,
+	0x80, 0x1b, 0x10, 0x7d,
+	0x80, 0x84, 0x11, 0x6d,
 	0xff, 0x85, 0x0b, 0x1b,
 	0xff, 0x86, 0x0d, 0x23,
 	0xff, 0x87, 0x0f, 0x23,
@@ -652,161 +662,164 @@ static uint8_t seqprog[] = {
 	0xf9, 0xd9, 0xb2, 0x0d,
 	0x01, 0xd9, 0xb2, 0x05,
 	0x01, 0x52, 0x48, 0x31,
-	0x20, 0xa4, 0x26, 0x7d,
-	0x20, 0x5b, 0x26, 0x7d,
-	0x80, 0xf9, 0x34, 0x7d,
+	0x20, 0xa4, 0x3a, 0x7d,
+	0x20, 0x5b, 0x3a, 0x7d,
+	0x80, 0xf9, 0x48, 0x7d,
 	0x02, 0xea, 0xb4, 0x00,
 	0x11, 0x00, 0x00, 0x10,
-	0x04, 0x19, 0x40, 0x7d,
+	0x04, 0x19, 0x54, 0x7d,
 	0xdf, 0x19, 0x32, 0x08,
-	0x60, 0x5b, 0x40, 0x6d,
-	0x01, 0x4c, 0x1a, 0x7d,
+	0x60, 0x5b, 0x54, 0x6d,
+	0x01, 0x4c, 0x2e, 0x7d,
 	0x20, 0x19, 0x32, 0x00,
 	0x01, 0xd9, 0xb2, 0x05,
 	0x02, 0xea, 0xb4, 0x00,
 	0x01, 0xd9, 0xb2, 0x05,
-	0x10, 0x5b, 0x38, 0x6d,
-	0x08, 0x5b, 0x42, 0x6d,
-	0x20, 0x5b, 0x32, 0x6d,
-	0x02, 0x5b, 0x62, 0x6d,
-	0x0e, 0xea, 0x64, 0x59,
+	0x10, 0x5b, 0x4c, 0x6d,
+	0x08, 0x5b, 0x56, 0x6d,
+	0x20, 0x5b, 0x46, 0x6d,
+	0x02, 0x5b, 0x76, 0x6d,
+	0x0e, 0xea, 0x6e, 0x59,
 	0x0e, 0xea, 0x04, 0x00,
-	0x80, 0xf9, 0x22, 0x6d,
+	0x80, 0xf9, 0x36, 0x6d,
 	0xdf, 0x5c, 0xb8, 0x08,
 	0x01, 0xd9, 0xb2, 0x05,
-	0x01, 0xa4, 0x1d, 0x6e,
-	0x00, 0xe2, 0x68, 0x5c,
-	0x00, 0xe2, 0x6c, 0x5d,
+	0x01, 0xa4, 0x37, 0x6e,
+	0x00, 0xe2, 0x7c, 0x5c,
+	0x00, 0xe2, 0x80, 0x5d,
 	0x01, 0x90, 0x21, 0x1b,
 	0x01, 0xd9, 0xb2, 0x05,
-	0x00, 0xe2, 0x52, 0x5b,
+	0x00, 0xe2, 0x66, 0x5b,
 	0xf3, 0x96, 0xd5, 0x19,
-	0x00, 0xe2, 0x50, 0x55,
-	0x80, 0x96, 0x51, 0x6d,
-	0x0f, 0xea, 0x64, 0x59,
+	0x00, 0xe2, 0x64, 0x55,
+	0x80, 0x96, 0x65, 0x6d,
+	0x0f, 0xea, 0x6e, 0x59,
 	0x0f, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0x58, 0x45,
+	0x00, 0xe2, 0x6c, 0x45,
 	0x04, 0x8c, 0xe1, 0x30,
 	0x01, 0xea, 0xf2, 0x00,
 	0x02, 0xea, 0x36, 0x00,
 	0xa8, 0xea, 0x32, 0x00,
-	0xff, 0x97, 0x5f, 0x7d,
-	0x14, 0xea, 0x64, 0x59,
+	0xff, 0x97, 0x73, 0x7d,
+	0x14, 0xea, 0x6e, 0x59,
 	0x14, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0xce, 0x5d,
+	0x00, 0xe2, 0xe2, 0x5d,
 	0x01, 0xd9, 0xb2, 0x05,
 	0x09, 0x80, 0xe1, 0x30,
 	0x02, 0xea, 0x36, 0x00,
 	0xa8, 0xea, 0x32, 0x00,
-	0x00, 0xe2, 0xc6, 0x5d,
+	0x00, 0xe2, 0xda, 0x5d,
 	0x01, 0xd9, 0xb2, 0x05,
-	0x02, 0xa6, 0x7c, 0x7d,
-	0x00, 0xe2, 0x56, 0x59,
-	0x20, 0x5b, 0x8a, 0x6d,
-	0xfc, 0x42, 0x76, 0x7d,
-	0x10, 0x40, 0x78, 0x6d,
-	0x20, 0x4d, 0x7a, 0x7d,
-	0x08, 0x5d, 0x8a, 0x6d,
-	0x02, 0xa6, 0x10, 0x6c,
-	0x00, 0xe2, 0x56, 0x59,
-	0x20, 0x5b, 0x8a, 0x6d,
-	0x01, 0x1b, 0xaa, 0x6d,
-	0xfc, 0x42, 0x86, 0x7d,
-	0x10, 0x40, 0x88, 0x6d,
+	0x02, 0xa6, 0x90, 0x7d,
+	0x00, 0xe2, 0x60, 0x59,
+	0x20, 0x5b, 0x9e, 0x6d,
+	0xfc, 0x42, 0x8a, 0x7d,
+	0x10, 0x40, 0x8c, 0x6d,
+	0x20, 0x4d, 0x8e, 0x7d,
+	0x08, 0x5d, 0x9e, 0x6d,
+	0x02, 0xa6, 0x24, 0x6c,
+	0x00, 0xe2, 0x60, 0x59,
+	0x20, 0x5b, 0x9e, 0x6d,
+	0x01, 0x1b, 0xbe, 0x6d,
+	0xfc, 0x42, 0x9a, 0x7d,
+	0x10, 0x40, 0x9c, 0x6d,
 	0x20, 0x4d, 0x84, 0x78,
 	0x08, 0x5d, 0x84, 0x78,
 	0x02, 0x19, 0x32, 0x00,
 	0x01, 0x5b, 0x40, 0x31,
-	0x00, 0xe2, 0xea, 0x5c,
-	0x00, 0xe2, 0xcc, 0x5b,
+	0x00, 0xe2, 0xfe, 0x5c,
+	0x00, 0xe2, 0xe0, 0x5b,
 	0x20, 0xea, 0xb6, 0x00,
-	0x00, 0xe2, 0x0a, 0x5c,
+	0x00, 0xe2, 0x1e, 0x5c,
 	0x20, 0x5c, 0xb8, 0x00,
-	0x04, 0x19, 0xa0, 0x6d,
-	0x01, 0x1a, 0xa0, 0x6d,
-	0x00, 0xe2, 0x56, 0x59,
+	0x04, 0x19, 0xb4, 0x6d,
+	0x01, 0x1a, 0xb4, 0x6d,
+	0x00, 0xe2, 0x60, 0x59,
 	0x01, 0x1a, 0x84, 0x78,
 	0x80, 0xf9, 0xf2, 0x01,
-	0x20, 0xa0, 0x04, 0x7e,
+	0x20, 0xa0, 0x18, 0x7e,
 	0xff, 0x90, 0x21, 0x1b,
-	0x08, 0x92, 0x63, 0x6b,
+	0x08, 0x92, 0x77, 0x6b,
 	0x02, 0xea, 0xb4, 0x04,
 	0x01, 0xa4, 0x49, 0x03,
-	0x40, 0x5b, 0xba, 0x6d,
-	0x00, 0xe2, 0x56, 0x59,
-	0x40, 0x5b, 0xba, 0x6d,
-	0x04, 0x5d, 0x1e, 0x7e,
-	0x01, 0x1a, 0x1e, 0x7e,
+	0x40, 0x5b, 0xce, 0x6d,
+	0x00, 0xe2, 0x60, 0x59,
+	0x40, 0x5b, 0xce, 0x6d,
+	0x04, 0x5d, 0x38, 0x7e,
+	0x01, 0x1a, 0x38, 0x7e,
 	0x20, 0x4d, 0x84, 0x78,
-	0x40, 0x5b, 0x04, 0x7e,
-	0x04, 0x5d, 0x1e, 0x7e,
-	0x01, 0x1a, 0x1e, 0x7e,
+	0x40, 0x5b, 0x18, 0x7e,
+	0x04, 0x5d, 0x38, 0x7e,
+	0x01, 0x1a, 0x38, 0x7e,
 	0x80, 0xf9, 0xf2, 0x01,
 	0xff, 0x90, 0x21, 0x1b,
-	0x08, 0x92, 0x63, 0x6b,
+	0x08, 0x92, 0x77, 0x6b,
 	0x02, 0xea, 0xb4, 0x04,
-	0x00, 0xe2, 0x56, 0x59,
+	0x00, 0xe2, 0x60, 0x59,
 	0x01, 0x1b, 0x84, 0x78,
 	0x80, 0xf9, 0xf2, 0x01,
 	0x02, 0xea, 0xb4, 0x04,
-	0x00, 0xe2, 0x56, 0x59,
-	0x01, 0x1b, 0xe2, 0x6d,
-	0x40, 0x5b, 0xf0, 0x7d,
-	0x01, 0x1b, 0xe2, 0x6d,
+	0x00, 0xe2, 0x60, 0x59,
+	0x01, 0x1b, 0xf6, 0x6d,
+	0x40, 0x5b, 0x04, 0x7e,
+	0x01, 0x1b, 0xf6, 0x6d,
 	0x02, 0x19, 0x32, 0x00,
 	0x01, 0x1a, 0x84, 0x78,
 	0x80, 0xf9, 0xf2, 0x01,
 	0xff, 0xea, 0x10, 0x03,
 	0x08, 0x92, 0x25, 0x03,
-	0x00, 0xe2, 0x62, 0x43,
-	0x01, 0x1a, 0xec, 0x7d,
-	0x40, 0x5b, 0xe8, 0x7d,
-	0x01, 0x1a, 0xd6, 0x6d,
+	0x00, 0xe2, 0x76, 0x43,
+	0x01, 0x1a, 0x00, 0x7e,
+	0x40, 0x5b, 0xfc, 0x7d,
+	0x01, 0x1a, 0xea, 0x6d,
 	0xfc, 0x42, 0x84, 0x78,
-	0x01, 0x1a, 0xf0, 0x6d,
-	0x10, 0xea, 0x64, 0x59,
+	0x01, 0x1a, 0x04, 0x6e,
+	0x10, 0xea, 0x6e, 0x59,
 	0x10, 0xea, 0x04, 0x00,
 	0xfc, 0x42, 0x84, 0x78,
-	0x10, 0x40, 0xf6, 0x6d,
+	0x10, 0x40, 0x0a, 0x6e,
 	0x20, 0x4d, 0x84, 0x78,
-	0x40, 0x5b, 0xd6, 0x6d,
+	0x40, 0x5b, 0xea, 0x6d,
 	0x01, 0x1a, 0x84, 0x78,
 	0x01, 0x90, 0x21, 0x1b,
 	0x30, 0x3f, 0xc0, 0x09,
 	0x30, 0xe0, 0x84, 0x60,
 	0x40, 0x4b, 0x84, 0x68,
 	0xff, 0xea, 0x52, 0x01,
-	0xee, 0x00, 0x0c, 0x6e,
+	0xee, 0x00, 0x20, 0x6e,
 	0x80, 0xf9, 0xf2, 0x01,
 	0xff, 0x90, 0x21, 0x1b,
 	0x02, 0xea, 0xb4, 0x00,
 	0x20, 0xea, 0x9a, 0x00,
-	0xf3, 0x42, 0x16, 0x6e,
-	0x12, 0xea, 0x64, 0x59,
+	0x04, 0x41, 0x26, 0x7e,
+	0x08, 0xea, 0x98, 0x00,
+	0x08, 0x57, 0xae, 0x00,
+	0xf3, 0x42, 0x30, 0x6e,
+	0x12, 0xea, 0x6e, 0x59,
 	0x12, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0x14, 0x42,
-	0x0d, 0xea, 0x64, 0x59,
+	0x00, 0xe2, 0x28, 0x42,
+	0x0d, 0xea, 0x6e, 0x59,
 	0x0d, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0x14, 0x42,
+	0x00, 0xe2, 0x28, 0x42,
 	0x01, 0x90, 0x21, 0x1b,
-	0x11, 0xea, 0x64, 0x59,
+	0x11, 0xea, 0x6e, 0x59,
 	0x11, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0x52, 0x5b,
+	0x00, 0xe2, 0x66, 0x5b,
 	0x08, 0x5a, 0xb4, 0x00,
-	0x00, 0xe2, 0x44, 0x5e,
+	0x00, 0xe2, 0x5e, 0x5e,
 	0xa8, 0xea, 0x32, 0x00,
-	0x00, 0xe2, 0x56, 0x59,
-	0x80, 0x1a, 0x32, 0x7e,
-	0x00, 0xe2, 0x44, 0x5e,
+	0x00, 0xe2, 0x60, 0x59,
+	0x80, 0x1a, 0x4c, 0x7e,
+	0x00, 0xe2, 0x5e, 0x5e,
 	0x80, 0x19, 0x32, 0x00,
-	0x40, 0x5b, 0x38, 0x6e,
-	0x08, 0x5a, 0x38, 0x7e,
+	0x40, 0x5b, 0x52, 0x6e,
+	0x08, 0x5a, 0x52, 0x7e,
 	0x20, 0x4d, 0x84, 0x78,
 	0x02, 0x84, 0x09, 0x03,
-	0x40, 0x5b, 0x04, 0x7e,
+	0x40, 0x5b, 0x18, 0x7e,
 	0xff, 0x90, 0x21, 0x1b,
 	0x80, 0xf9, 0xf2, 0x01,
-	0x08, 0x92, 0x63, 0x6b,
+	0x08, 0x92, 0x77, 0x6b,
 	0x02, 0xea, 0xb4, 0x04,
 	0x01, 0x40, 0xe1, 0x30,
 	0x05, 0x41, 0xe3, 0x98,
@@ -1039,138 +1052,138 @@ static struct patch {
 	{ ahd_patch0_func, 64, 1, 1 },
 	{ ahd_patch2_func, 67, 1, 2 },
 	{ ahd_patch0_func, 68, 1, 1 },
-	{ ahd_patch4_func, 116, 1, 1 },
-	{ ahd_patch2_func, 175, 3, 1 },
-	{ ahd_patch1_func, 178, 2, 1 },
-	{ ahd_patch5_func, 180, 1, 1 },
-	{ ahd_patch2_func, 189, 1, 2 },
-	{ ahd_patch0_func, 190, 1, 1 },
-	{ ahd_patch6_func, 191, 2, 2 },
-	{ ahd_patch0_func, 193, 6, 3 },
-	{ ahd_patch2_func, 196, 1, 2 },
-	{ ahd_patch0_func, 197, 1, 1 },
-	{ ahd_patch2_func, 200, 1, 2 },
-	{ ahd_patch0_func, 201, 1, 1 },
-	{ ahd_patch3_func, 203, 1, 1 },
-	{ ahd_patch7_func, 204, 3, 1 },
-	{ ahd_patch3_func, 213, 1, 1 },
-	{ ahd_patch5_func, 214, 16, 2 },
-	{ ahd_patch0_func, 230, 1, 1 },
-	{ ahd_patch8_func, 250, 2, 1 },
-	{ ahd_patch1_func, 254, 1, 2 },
-	{ ahd_patch0_func, 255, 1, 1 },
-	{ ahd_patch7_func, 258, 3, 1 },
-	{ ahd_patch1_func, 273, 1, 2 },
-	{ ahd_patch0_func, 274, 1, 1 },
-	{ ahd_patch1_func, 277, 1, 2 },
-	{ ahd_patch0_func, 278, 1, 1 },
-	{ ahd_patch2_func, 281, 1, 2 },
-	{ ahd_patch0_func, 282, 1, 1 },
-	{ ahd_patch9_func, 295, 2, 2 },
-	{ ahd_patch0_func, 297, 1, 1 },
-	{ ahd_patch1_func, 339, 1, 2 },
-	{ ahd_patch0_func, 340, 1, 1 },
-	{ ahd_patch2_func, 348, 1, 2 },
-	{ ahd_patch0_func, 349, 1, 1 },
-	{ ahd_patch2_func, 352, 1, 2 },
-	{ ahd_patch0_func, 353, 1, 1 },
-	{ ahd_patch1_func, 359, 1, 2 },
-	{ ahd_patch0_func, 360, 1, 1 },
-	{ ahd_patch1_func, 362, 1, 2 },
+	{ ahd_patch4_func, 115, 1, 1 },
+	{ ahd_patch2_func, 180, 3, 1 },
+	{ ahd_patch1_func, 183, 2, 1 },
+	{ ahd_patch5_func, 185, 1, 1 },
+	{ ahd_patch2_func, 194, 1, 2 },
+	{ ahd_patch0_func, 195, 1, 1 },
+	{ ahd_patch6_func, 196, 2, 2 },
+	{ ahd_patch0_func, 198, 6, 3 },
+	{ ahd_patch2_func, 201, 1, 2 },
+	{ ahd_patch0_func, 202, 1, 1 },
+	{ ahd_patch2_func, 205, 1, 2 },
+	{ ahd_patch0_func, 206, 1, 1 },
+	{ ahd_patch3_func, 208, 1, 1 },
+	{ ahd_patch7_func, 209, 3, 1 },
+	{ ahd_patch3_func, 218, 1, 1 },
+	{ ahd_patch5_func, 219, 16, 2 },
+	{ ahd_patch0_func, 235, 1, 1 },
+	{ ahd_patch8_func, 260, 2, 1 },
+	{ ahd_patch1_func, 264, 1, 2 },
+	{ ahd_patch0_func, 265, 1, 1 },
+	{ ahd_patch7_func, 268, 3, 1 },
+	{ ahd_patch1_func, 283, 1, 2 },
+	{ ahd_patch0_func, 284, 1, 1 },
+	{ ahd_patch1_func, 287, 1, 2 },
+	{ ahd_patch0_func, 288, 1, 1 },
+	{ ahd_patch2_func, 291, 1, 2 },
+	{ ahd_patch0_func, 292, 1, 1 },
+	{ ahd_patch9_func, 305, 2, 2 },
+	{ ahd_patch0_func, 307, 1, 1 },
+	{ ahd_patch1_func, 349, 1, 2 },
+	{ ahd_patch0_func, 350, 1, 1 },
+	{ ahd_patch2_func, 358, 1, 2 },
+	{ ahd_patch0_func, 359, 1, 1 },
+	{ ahd_patch2_func, 362, 1, 2 },
 	{ ahd_patch0_func, 363, 1, 1 },
-	{ ahd_patch10_func, 382, 1, 1 },
-	{ ahd_patch10_func, 385, 1, 1 },
-	{ ahd_patch10_func, 387, 1, 1 },
-	{ ahd_patch10_func, 399, 1, 1 },
-	{ ahd_patch1_func, 409, 1, 2 },
-	{ ahd_patch0_func, 410, 1, 1 },
-	{ ahd_patch1_func, 412, 1, 2 },
-	{ ahd_patch0_func, 413, 1, 1 },
-	{ ahd_patch1_func, 421, 1, 2 },
-	{ ahd_patch0_func, 422, 1, 1 },
-	{ ahd_patch2_func, 435, 1, 2 },
-	{ ahd_patch0_func, 436, 1, 1 },
-	{ ahd_patch11_func, 472, 1, 1 },
-	{ ahd_patch1_func, 480, 1, 2 },
-	{ ahd_patch0_func, 481, 1, 1 },
-	{ ahd_patch2_func, 493, 1, 2 },
-	{ ahd_patch0_func, 494, 1, 1 },
-	{ ahd_patch12_func, 497, 6, 2 },
-	{ ahd_patch0_func, 503, 1, 1 },
-	{ ahd_patch13_func, 524, 7, 1 },
-	{ ahd_patch14_func, 533, 1, 1 },
-	{ ahd_patch15_func, 542, 1, 1 },
-	{ ahd_patch16_func, 543, 1, 2 },
-	{ ahd_patch0_func, 544, 1, 1 },
-	{ ahd_patch17_func, 547, 1, 1 },
-	{ ahd_patch16_func, 548, 1, 1 },
-	{ ahd_patch18_func, 559, 1, 2 },
-	{ ahd_patch0_func, 560, 1, 1 },
-	{ ahd_patch1_func, 579, 1, 2 },
-	{ ahd_patch0_func, 580, 1, 1 },
-	{ ahd_patch1_func, 583, 1, 2 },
-	{ ahd_patch0_func, 584, 1, 1 },
-	{ ahd_patch2_func, 589, 1, 2 },
+	{ ahd_patch1_func, 369, 1, 2 },
+	{ ahd_patch0_func, 370, 1, 1 },
+	{ ahd_patch1_func, 372, 1, 2 },
+	{ ahd_patch0_func, 373, 1, 1 },
+	{ ahd_patch10_func, 392, 1, 1 },
+	{ ahd_patch10_func, 395, 1, 1 },
+	{ ahd_patch10_func, 397, 1, 1 },
+	{ ahd_patch10_func, 409, 1, 1 },
+	{ ahd_patch1_func, 419, 1, 2 },
+	{ ahd_patch0_func, 420, 1, 1 },
+	{ ahd_patch1_func, 422, 1, 2 },
+	{ ahd_patch0_func, 423, 1, 1 },
+	{ ahd_patch1_func, 431, 1, 2 },
+	{ ahd_patch0_func, 432, 1, 1 },
+	{ ahd_patch2_func, 445, 1, 2 },
+	{ ahd_patch0_func, 446, 1, 1 },
+	{ ahd_patch11_func, 482, 1, 1 },
+	{ ahd_patch1_func, 490, 1, 2 },
+	{ ahd_patch0_func, 491, 1, 1 },
+	{ ahd_patch2_func, 503, 1, 2 },
+	{ ahd_patch0_func, 504, 1, 1 },
+	{ ahd_patch12_func, 507, 6, 2 },
+	{ ahd_patch0_func, 513, 1, 1 },
+	{ ahd_patch13_func, 534, 7, 1 },
+	{ ahd_patch14_func, 543, 1, 1 },
+	{ ahd_patch15_func, 552, 1, 1 },
+	{ ahd_patch16_func, 553, 1, 2 },
+	{ ahd_patch0_func, 554, 1, 1 },
+	{ ahd_patch17_func, 557, 1, 1 },
+	{ ahd_patch16_func, 558, 1, 1 },
+	{ ahd_patch18_func, 569, 1, 2 },
+	{ ahd_patch0_func, 570, 1, 1 },
+	{ ahd_patch1_func, 589, 1, 2 },
 	{ ahd_patch0_func, 590, 1, 1 },
-	{ ahd_patch2_func, 594, 1, 2 },
-	{ ahd_patch0_func, 595, 1, 1 },
-	{ ahd_patch1_func, 596, 1, 2 },
-	{ ahd_patch0_func, 597, 1, 1 },
-	{ ahd_patch2_func, 608, 1, 2 },
-	{ ahd_patch0_func, 609, 1, 1 },
-	{ ahd_patch19_func, 613, 1, 1 },
-	{ ahd_patch20_func, 618, 1, 1 },
-	{ ahd_patch21_func, 619, 2, 1 },
-	{ ahd_patch20_func, 623, 1, 2 },
-	{ ahd_patch0_func, 624, 1, 1 },
-	{ ahd_patch2_func, 627, 1, 2 },
-	{ ahd_patch0_func, 628, 1, 1 },
-	{ ahd_patch2_func, 643, 1, 2 },
-	{ ahd_patch0_func, 644, 1, 1 },
-	{ ahd_patch13_func, 645, 14, 1 },
-	{ ahd_patch1_func, 663, 1, 2 },
-	{ ahd_patch0_func, 664, 1, 1 },
-	{ ahd_patch13_func, 665, 1, 1 },
-	{ ahd_patch1_func, 677, 1, 2 },
-	{ ahd_patch0_func, 678, 1, 1 },
-	{ ahd_patch1_func, 685, 1, 2 },
-	{ ahd_patch0_func, 686, 1, 1 },
-	{ ahd_patch19_func, 709, 1, 1 },
-	{ ahd_patch19_func, 747, 1, 1 },
-	{ ahd_patch1_func, 758, 1, 2 },
-	{ ahd_patch0_func, 759, 1, 1 },
-	{ ahd_patch1_func, 776, 1, 2 },
-	{ ahd_patch0_func, 777, 1, 1 },
-	{ ahd_patch1_func, 779, 1, 2 },
-	{ ahd_patch0_func, 780, 1, 1 },
-	{ ahd_patch1_func, 783, 1, 2 },
-	{ ahd_patch0_func, 784, 1, 1 },
-	{ ahd_patch22_func, 786, 1, 2 },
-	{ ahd_patch0_func, 787, 2, 1 },
-	{ ahd_patch23_func, 790, 4, 2 },
-	{ ahd_patch0_func, 794, 1, 1 },
-	{ ahd_patch23_func, 802, 11, 1 }
+	{ ahd_patch1_func, 593, 1, 2 },
+	{ ahd_patch0_func, 594, 1, 1 },
+	{ ahd_patch2_func, 599, 1, 2 },
+	{ ahd_patch0_func, 600, 1, 1 },
+	{ ahd_patch2_func, 604, 1, 2 },
+	{ ahd_patch0_func, 605, 1, 1 },
+	{ ahd_patch1_func, 606, 1, 2 },
+	{ ahd_patch0_func, 607, 1, 1 },
+	{ ahd_patch2_func, 618, 1, 2 },
+	{ ahd_patch0_func, 619, 1, 1 },
+	{ ahd_patch19_func, 623, 1, 1 },
+	{ ahd_patch20_func, 628, 1, 1 },
+	{ ahd_patch21_func, 629, 2, 1 },
+	{ ahd_patch20_func, 633, 1, 2 },
+	{ ahd_patch0_func, 634, 1, 1 },
+	{ ahd_patch2_func, 637, 1, 2 },
+	{ ahd_patch0_func, 638, 1, 1 },
+	{ ahd_patch2_func, 653, 1, 2 },
+	{ ahd_patch0_func, 654, 1, 1 },
+	{ ahd_patch13_func, 655, 14, 1 },
+	{ ahd_patch1_func, 673, 1, 2 },
+	{ ahd_patch0_func, 674, 1, 1 },
+	{ ahd_patch13_func, 675, 1, 1 },
+	{ ahd_patch1_func, 687, 1, 2 },
+	{ ahd_patch0_func, 688, 1, 1 },
+	{ ahd_patch1_func, 695, 1, 2 },
+	{ ahd_patch0_func, 696, 1, 1 },
+	{ ahd_patch19_func, 719, 1, 1 },
+	{ ahd_patch19_func, 757, 1, 1 },
+	{ ahd_patch1_func, 768, 1, 2 },
+	{ ahd_patch0_func, 769, 1, 1 },
+	{ ahd_patch7_func, 785, 3, 1 },
+	{ ahd_patch1_func, 789, 1, 2 },
+	{ ahd_patch0_func, 790, 1, 1 },
+	{ ahd_patch1_func, 792, 1, 2 },
+	{ ahd_patch0_func, 793, 1, 1 },
+	{ ahd_patch1_func, 796, 1, 2 },
+	{ ahd_patch0_func, 797, 1, 1 },
+	{ ahd_patch22_func, 799, 1, 2 },
+	{ ahd_patch0_func, 800, 2, 1 },
+	{ ahd_patch23_func, 803, 4, 2 },
+	{ ahd_patch0_func, 807, 1, 1 },
+	{ ahd_patch23_func, 815, 11, 1 }
 };
 
 static struct cs {
 	uint16_t	begin;
 	uint16_t	end;
 } critical_sections[] = {
-	{ 17, 28 },
-	{ 29, 30 },
+	{ 17, 30 },
 	{ 47, 58 },
 	{ 61, 63 },
 	{ 65, 66 },
 	{ 72, 92 },
-	{ 110, 137 },
-	{ 138, 175 },
-	{ 180, 188 },
-	{ 213, 264 },
-	{ 425, 433 },
-	{ 443, 445 },
-	{ 448, 457 },
-	{ 709, 739 },
-	{ 749, 753 }
+	{ 110, 142 },
+	{ 143, 180 },
+	{ 185, 193 },
+	{ 218, 274 },
+	{ 435, 443 },
+	{ 453, 455 },
+	{ 458, 467 },
+	{ 719, 749 },
+	{ 759, 763 }
 };
 
 static const int num_critical_sections = sizeof(critical_sections)
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm.c b/drivers/scsi/aic7xxx/aicasm/aicasm.c
index f936b69..9241027 100644
--- a/drivers/scsi/aic7xxx/aicasm/aicasm.c
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm.c
@@ -37,7 +37,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#22 $
+ * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#23 $
  *
  * $FreeBSD$
  */
@@ -609,10 +609,10 @@ output_listing(char *ifilename)
 
 		while (line < cur_instr->srcline) {
 			fgets(buf, sizeof(buf), ifile);
-				fprintf(listfile, "\t\t%s", buf);
+				fprintf(listfile, "             \t%s", buf);
 				line++;
 		}
-		fprintf(listfile, "%03x %02x%02x%02x%02x", instrptr,
+		fprintf(listfile, "%04x %02x%02x%02x%02x", instrptr,
 #ifdef __LITTLE_ENDIAN
 			cur_instr->format.bytes[0],
 			cur_instr->format.bytes[1],
@@ -624,14 +624,23 @@ output_listing(char *ifilename)
 			cur_instr->format.bytes[1],
 			cur_instr->format.bytes[0]);
 #endif
-		fgets(buf, sizeof(buf), ifile);
-		fprintf(listfile, "\t%s", buf);
-		line++;
+		/*
+		 * Macro expansions can cause several instructions
+		 * to be output for a single source line.  Only
+		 * advance the line once in these cases.
+		 */
+		if (line == cur_instr->srcline) {
+			fgets(buf, sizeof(buf), ifile);
+			fprintf(listfile, "\t%s", buf);
+			line++;
+		} else {
+			fprintf(listfile, "\n");
+		}
 		instrptr++;
 	}
 	/* Dump the remainder of the file */
 	while(fgets(buf, sizeof(buf), ifile) != NULL)
-		fprintf(listfile, "\t\t%s", buf);
+		fprintf(listfile, "             %s", buf);
 
 	fclose(ifile);
 }
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
index 67e046d..c328596 100644
--- a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
@@ -38,7 +38,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#29 $
+ * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#30 $
  *
  * $FreeBSD$
  */
@@ -157,6 +157,8 @@ static int  is_download_const(expression
 
 %token T_END_CS
 
+%token T_PAD_PAGE
+
 %token T_FIELD
 
 %token T_ENUM
@@ -189,6 +191,10 @@ static int  is_download_const(expression
 
 %token <value> T_OR
 
+/* 16 bit extensions */
+%token <value> T_OR16 T_AND16 T_XOR16 T_ADD16
+%token <value> T_ADC16 T_MVI16 T_TEST16 T_CMP16 T_CMPXCHG
+
 %token T_RET
 
 %token T_NOP
@@ -207,7 +213,7 @@ static int  is_download_const(expression
 
 %type <expression> expression immediate immediate_or_a
 
-%type <value> export ret f1_opcode f2_opcode jmp_jc_jnc_call jz_jnz je_jne
+%type <value> export ret f1_opcode f2_opcode f4_opcode jmp_jc_jnc_call jz_jnz je_jne
 
 %type <value> mode_value mode_list macro_arglist
 
@@ -1304,6 +1310,15 @@ f2_opcode:
 |	T_ROR { $$ = AIC_OP_ROR; }
 ;
 
+f4_opcode:
+	T_OR16	{ $$ = AIC_OP_OR16; }
+|	T_AND16 { $$ = AIC_OP_AND16; }
+|	T_XOR16 { $$ = AIC_OP_XOR16; }
+|	T_ADD16 { $$ = AIC_OP_ADD16; }
+|	T_ADC16 { $$ = AIC_OP_ADC16; }
+|	T_MVI16 { $$ = AIC_OP_MVI16; }
+;
+
 code:
 	f2_opcode destination ',' expression opt_source ret ';'
 	{
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h b/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h
index e64f802..9df9e2c 100644
--- a/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h
@@ -37,13 +37,14 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#11 $
+ * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#12 $
  *
  * $FreeBSD$
  */
 
 #include <asm/byteorder.h>
 
+/* 8bit ALU logic operations */
 struct ins_format1 {
 #ifdef __LITTLE_ENDIAN
 	uint32_t	immediate	: 8,
@@ -62,6 +63,7 @@ struct ins_format1 {
 #endif
 };
 
+/* 8bit ALU shift/rotate operations */
 struct ins_format2 {
 #ifdef __LITTLE_ENDIAN
 	uint32_t	shift_control	: 8,
@@ -80,6 +82,7 @@ struct ins_format2 {
 #endif
 };
 
+/* 8bit branch control operations */
 struct ins_format3 {
 #ifdef __LITTLE_ENDIAN
 	uint32_t	immediate	: 8,
@@ -96,10 +99,68 @@ struct ins_format3 {
 #endif
 };
 
+/* 16bit ALU logic operations */
+struct ins_format4 {
+#ifdef __LITTLE_ENDIAN
+	uint32_t	opcode_ext	: 8,
+			source		: 9,
+			destination	: 9,
+			ret		: 1,
+			opcode		: 4,
+			parity		: 1;
+#else
+	uint32_t	parity		: 1,
+			opcode		: 4,
+			ret		: 1,
+			destination	: 9,
+			source		: 9,
+			opcode_ext	: 8;
+#endif
+};
+
+/* 16bit branch control operations */
+struct ins_format5 {
+#ifdef __LITTLE_ENDIAN
+	uint32_t	opcode_ext	: 8,
+			source		: 9,
+			address		: 10,
+			opcode		: 4,
+			parity		: 1;
+#else
+	uint32_t	parity		: 1,
+			opcode		: 4,
+			address		: 10,
+			source		: 9,
+			opcode_ext	: 8;
+#endif
+};
+
+/*  Far branch operations */
+struct ins_format6 {
+#ifdef __LITTLE_ENDIAN
+	uint32_t	page		: 3,
+			opcode_ext	: 5,
+			source		: 9,
+			address		: 10,
+			opcode		: 4,
+			parity		: 1;
+#else
+	uint32_t	parity		: 1,
+			opcode		: 4,
+			address		: 10,
+			source		: 9,
+			opcode_ext	: 5,
+			page		: 3;
+#endif
+};
+
 union ins_formats {
 		struct ins_format1 format1;
 		struct ins_format2 format2;
 		struct ins_format3 format3;
+		struct ins_format4 format4;
+		struct ins_format5 format5;
+		struct ins_format6 format6;
 		uint8_t		   bytes[4];
 		uint32_t	   integer;
 };
@@ -118,6 +179,8 @@ struct instruction {
 #define	AIC_OP_ROL	0x5
 #define	AIC_OP_BMOV	0x6
 
+#define	AIC_OP_MVI16	0x7
+
 #define	AIC_OP_JMP	0x8
 #define AIC_OP_JC	0x9
 #define AIC_OP_JNC	0xa
@@ -131,3 +194,26 @@ struct instruction {
 #define	AIC_OP_SHL	0x10
 #define	AIC_OP_SHR	0x20
 #define	AIC_OP_ROR	0x30
+
+/* 16bit Ops. Low byte main opcode.  High byte extended opcode. */ 
+#define	AIC_OP_OR16	0x8005
+#define	AIC_OP_AND16	0x8105
+#define	AIC_OP_XOR16	0x8205
+#define	AIC_OP_ADD16	0x8305
+#define	AIC_OP_ADC16	0x8405
+#define AIC_OP_JNE16	0x8805
+#define AIC_OP_JNZ16	0x8905
+#define AIC_OP_JE16	0x8C05
+#define AIC_OP_JZ16	0x8B05
+#define AIC_OP_JMP16	0x9005
+#define AIC_OP_JC16	0x9105
+#define AIC_OP_JNC16	0x9205
+#define AIC_OP_CALL16	0x9305
+#define AIC_OP_CALL16	0x9305
+
+/* Page extension is low three bits of second opcode byte. */
+#define AIC_OP_JMPF	0xA005
+#define AIC_OP_CALLF	0xB005
+#define AIC_OP_JCF	0xC005
+#define AIC_OP_JNCF	0xD005
+#define AIC_OP_CMPXCHG	0xE005
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l b/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l
index 45c0b23..7c3983f 100644
--- a/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l
@@ -38,7 +38,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#19 $
+ * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#20 $
  *
  * $FreeBSD$
  */
@@ -132,7 +132,7 @@ if[ \t]*\(		{
 						*string_buf_ptr++ = *yptr++;
 				}
 			}
-
+else			{ return T_ELSE; }
 VERSION			{ return T_VERSION; }
 PREFIX			{ return T_PREFIX; }
 PATCH_ARG_LIST		{ return T_PATCH_ARG_LIST; }
@@ -173,10 +173,6 @@ RW|RO|WO		{
 					yylval.value = WO;
 				 return T_MODE;
 			}
-BEGIN_CRITICAL		{ return T_BEGIN_CS; }
-END_CRITICAL		{ return T_END_CS; }
-SET_SRC_MODE		{ return T_SET_SRC_MODE; }
-SET_DST_MODE		{ return T_SET_DST_MODE; }
 field			{ return T_FIELD; }
 enum			{ return T_ENUM; }
 mask			{ return T_MASK; }
@@ -192,6 +188,13 @@ none			{ return T_NONE; }
 sindex			{ return T_SINDEX; }
 A			{ return T_A; }
 
+	/* Instruction Formatting */
+PAD_PAGE		{ return T_PAD_PAGE; }
+BEGIN_CRITICAL		{ return T_BEGIN_CS; }
+END_CRITICAL		{ return T_END_CS; }
+SET_SRC_MODE		{ return T_SET_SRC_MODE; }
+SET_DST_MODE		{ return T_SET_DST_MODE; }
+
 	/* Opcodes */
 shl			{ return T_SHL; }
 shr			{ return T_SHR; }
@@ -223,7 +226,17 @@ and			{ return T_AND;	}
 or			{ return T_OR;	}
 ret			{ return T_RET; }
 nop			{ return T_NOP; }
-else			{ return T_ELSE; }
+
+	/* ARP2 16bit extensions */
+or16			{ return T_OR16; }
+and16			{ return T_AND16; }
+xor16			{ return T_XOR16; }
+add16			{ return T_ADD16; }
+adc16			{ return T_ADC16; }
+mvi16			{ return T_MVI16; }
+test16			{ return T_TEST16; }
+cmp16			{ return T_CMP16; }
+cmpxchg			{ return T_CMPXCHG; }
 
 	/* Allowed Symbols */
 \<\<			{ return T_EXPR_LSHIFT; }
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 557788e..fc3ca05 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -157,6 +157,9 @@ static const struct pci_device_id piix_p
 	{ 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
 	{ 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
 	{ 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+	{ 0x8086, 0x2820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+	{ 0x8086, 0x2825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+	{ 0x8086, 0x2828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
 
 	{ }	/* terminate list */
 };
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index c8a32cf..cbf8252 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -246,6 +246,7 @@ struct ScsiReqBlk {
 	 * total_xfer_length in xferred. These values are restored in
 	 * pci_unmap_srb_sense. This is the only place xferred is used.
 	 */
+	unsigned char *virt_addr_req;	/* Saved virtual address of the request buffer */
 	u32 xferred;		        /* Saved copy of total_xfer_length */
 
 	u16 state;
@@ -2017,7 +2018,7 @@ static void sg_update_list(struct ScsiRe
 	sg_verify_length(srb);
 
 	/* we need the corresponding virtual address */
-	if (!segment) {
+	if (!segment || (srb->flag & AUTO_REQSENSE)) {
 		srb->virt_addr += xferred;
 		return;
 	}
@@ -3318,6 +3319,7 @@ static void pci_unmap_srb_sense(struct A
 	    srb->segment_x[DC395x_MAX_SG_LISTENTRY - 1].address;
 	srb->segment_x[0].length =
 	    srb->segment_x[DC395x_MAX_SG_LISTENTRY - 1].length;
+	srb->virt_addr = srb->virt_addr_req;
 }
 
 
@@ -3711,6 +3713,8 @@ static void request_sense(struct Adapter
 	srb->xferred = srb->total_xfer_length;
 	/* srb->segment_x : a one entry of S/G list table */
 	srb->total_xfer_length = sizeof(cmd->sense_buffer);
+	srb->virt_addr_req = srb->virt_addr;
+	srb->virt_addr = cmd->sense_buffer;
 	srb->segment_x[0].length = sizeof(cmd->sense_buffer);
 	/* Map sense buffer */
 	srb->segment_x[0].address =
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index 822b9fa..eaefedd 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -87,7 +87,7 @@ static int max_channel = 3;
 static int init_timeout = 5;
 static int max_requests = 50;
 
-#define IBMVSCSI_VERSION "1.5.7"
+#define IBMVSCSI_VERSION "1.5.8"
 
 MODULE_DESCRIPTION("IBM Virtual SCSI");
 MODULE_AUTHOR("Dave Boutcher");
@@ -534,7 +534,6 @@ static int map_data_for_srp_cmd(struct s
 static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
 				   struct ibmvscsi_host_data *hostdata)
 {
-	struct scsi_cmnd *cmnd;
 	u64 *crq_as_u64 = (u64 *) &evt_struct->crq;
 	int rc;
 
@@ -544,19 +543,8 @@ static int ibmvscsi_send_srp_event(struc
 	 * can handle more requests (can_queue) when we actually can't
 	 */
 	if ((evt_struct->crq.format == VIOSRP_SRP_FORMAT) &&
-	    (atomic_dec_if_positive(&hostdata->request_limit) < 0)) {
-		/* See if the adapter is disabled */
-		if (atomic_read(&hostdata->request_limit) < 0)
-			goto send_error;
-	
-		printk(KERN_WARNING 
-		       "ibmvscsi: Warning, request_limit exceeded\n");
-		unmap_cmd_data(&evt_struct->iu.srp.cmd,
-			       evt_struct,
-			       hostdata->dev);
-		free_event_struct(&hostdata->pool, evt_struct);
-		return SCSI_MLQUEUE_HOST_BUSY;
-	}
+	    (atomic_dec_if_positive(&hostdata->request_limit) < 0))
+		goto send_error;
 
 	/* Copy the IU into the transfer area */
 	*evt_struct->xfer_iu = evt_struct->iu;
@@ -572,7 +560,7 @@ static int ibmvscsi_send_srp_event(struc
 	     ibmvscsi_send_crq(hostdata, crq_as_u64[0], crq_as_u64[1])) != 0) {
 		list_del(&evt_struct->list);
 
-		printk(KERN_ERR "ibmvscsi: failed to send event struct rc %d\n",
+		printk(KERN_ERR "ibmvscsi: send error %d\n",
 		       rc);
 		goto send_error;
 	}
@@ -582,14 +570,8 @@ static int ibmvscsi_send_srp_event(struc
  send_error:
 	unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev);
 
-	if ((cmnd = evt_struct->cmnd) != NULL) {
-		cmnd->result = DID_ERROR << 16;
-		evt_struct->cmnd_done(cmnd);
-	} else if (evt_struct->done)
-		evt_struct->done(evt_struct);
-	
 	free_event_struct(&hostdata->pool, evt_struct);
-	return 0;
+ 	return SCSI_MLQUEUE_HOST_BUSY;
 }
 
 /**
@@ -802,7 +784,8 @@ static void login_rsp(struct srp_event_s
 	case SRP_LOGIN_RSP_TYPE:	/* it worked! */
 		break;
 	case SRP_LOGIN_REJ_TYPE:	/* refused! */
-		printk(KERN_INFO "ibmvscsi: SRP_LOGIN_REQ rejected\n");
+		printk(KERN_INFO "ibmvscsi: SRP_LOGIN_REJ reason %u\n",
+		       evt_struct->xfer_iu->srp.login_rej.reason);
 		/* Login failed.  */
 		atomic_set(&hostdata->request_limit, -1);
 		return;
@@ -834,6 +817,9 @@ static void login_rsp(struct srp_event_s
 		return;
 	}
 
+	/* If we had any pending I/Os, kick them */
+	scsi_unblock_requests(hostdata->host);
+
 	send_mad_adapter_info(hostdata);
 	return;
 }
@@ -862,6 +848,7 @@ static int send_srp_login(struct ibmvscs
 			  init_timeout * HZ);
 
 	login = &evt_struct->iu.srp.login_req;
+	memset(login, 0x00, sizeof(struct srp_login_req));
 	login->type = SRP_LOGIN_REQ_TYPE;
 	login->max_requested_initiator_to_target_iulen = sizeof(union srp_iu);
 	login->required_buffer_formats = 0x0006;
@@ -1122,7 +1109,7 @@ static int ibmvscsi_eh_device_reset_hand
  * purge_requests: Our virtual adapter just shut down.  purge any sent requests
  * @hostdata:    the adapter
  */
-static void purge_requests(struct ibmvscsi_host_data *hostdata)
+static void purge_requests(struct ibmvscsi_host_data *hostdata, int error_code)
 {
 	struct srp_event_struct *tmp_evt, *pos;
 	unsigned long flags;
@@ -1131,7 +1118,7 @@ static void purge_requests(struct ibmvsc
 	list_for_each_entry_safe(tmp_evt, pos, &hostdata->sent, list) {
 		list_del(&tmp_evt->list);
 		if (tmp_evt->cmnd) {
-			tmp_evt->cmnd->result = (DID_ERROR << 16);
+			tmp_evt->cmnd->result = (error_code << 16);
 			unmap_cmd_data(&tmp_evt->iu.srp.cmd, 
 				       tmp_evt,	
 				       tmp_evt->hostdata->dev);
@@ -1186,12 +1173,30 @@ void ibmvscsi_handle_crq(struct viosrp_c
 			printk(KERN_ERR "ibmvscsi: unknown crq message type\n");
 		}
 		return;
-	case 0xFF:		/* Hypervisor telling us the connection is closed */
-		printk(KERN_INFO "ibmvscsi: Virtual adapter failed!\n");
+	case 0xFF:	/* Hypervisor telling us the connection is closed */
+		scsi_block_requests(hostdata->host);
+		if (crq->format == 0x06) {
+			/* We need to re-setup the interpartition connection */
+			printk(KERN_INFO
+			       "ibmvscsi: Re-enabling adapter!\n");
+			purge_requests(hostdata, DID_REQUEUE);
+			if (ibmvscsi_reenable_crq_queue(&hostdata->queue,
+							hostdata) == 0)
+				if (ibmvscsi_send_crq(hostdata,
+						      0xC001000000000000LL, 0))
+					printk(KERN_ERR
+					       "ibmvscsi: transmit error after"
+					       " enable\n");
+		} else {
+			printk(KERN_INFO
+			       "ibmvscsi: Virtual adapter failed rc %d!\n",
+			       crq->format);
 
-		atomic_set(&hostdata->request_limit, -1);
-		purge_requests(hostdata);
-		ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata);
+			atomic_set(&hostdata->request_limit, -1);
+			purge_requests(hostdata, DID_ERROR);
+			ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata);
+		}
+		scsi_unblock_requests(hostdata->host);
 		return;
 	case 0x80:		/* real payload */
 		break;
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h
index 5b0edd1..4550d71 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.h
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.h
@@ -103,6 +103,9 @@ void ibmvscsi_release_crq_queue(struct c
 int ibmvscsi_reset_crq_queue(struct crq_queue *queue,
 			      struct ibmvscsi_host_data *hostdata);
 
+int ibmvscsi_reenable_crq_queue(struct crq_queue *queue,
+				struct ibmvscsi_host_data *hostdata);
+
 void ibmvscsi_handle_crq(struct viosrp_crq *crq,
 			 struct ibmvscsi_host_data *hostdata);
 int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata,
diff --git a/drivers/scsi/ibmvscsi/iseries_vscsi.c b/drivers/scsi/ibmvscsi/iseries_vscsi.c
index ce15d9e..7eed0b0 100644
--- a/drivers/scsi/ibmvscsi/iseries_vscsi.c
+++ b/drivers/scsi/ibmvscsi/iseries_vscsi.c
@@ -124,6 +124,19 @@ int ibmvscsi_reset_crq_queue(struct crq_
 }
 
 /**
+ * reenable_crq_queue: - reenables a crq after a failure
+ * @queue:	crq_queue to initialize and register
+ * @hostdata:	ibmvscsi_host_data of host
+ *
+ * no-op for iSeries
+ */
+int ibmvscsi_reenable_crq_queue(struct crq_queue *queue,
+				struct ibmvscsi_host_data *hostdata)
+{
+	return 0;
+}
+
+/**
  * ibmvscsi_send_crq: - Send a CRQ
  * @hostdata:	the adapter
  * @word1:	the first 64 bits of the data
diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c
index 75db2f5..f47dd87 100644
--- a/drivers/scsi/ibmvscsi/rpa_vscsi.c
+++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c
@@ -281,6 +281,28 @@ int ibmvscsi_init_crq_queue(struct crq_q
 }
 
 /**
+ * reenable_crq_queue: - reenables a crq after
+ * @queue:	crq_queue to initialize and register
+ * @hostdata:	ibmvscsi_host_data of host
+ *
+ */
+int ibmvscsi_reenable_crq_queue(struct crq_queue *queue,
+				 struct ibmvscsi_host_data *hostdata)
+{
+	int rc;
+	struct vio_dev *vdev = to_vio_dev(hostdata->dev);
+
+	/* Re-enable the CRQ */
+	do {
+		rc = plpar_hcall_norets(H_ENABLE_CRQ, vdev->unit_address);
+	} while ((rc == H_InProgress) || (rc == H_Busy) || (H_isLongBusy(rc)));
+
+	if (rc)
+		printk(KERN_ERR "ibmvscsi: Error %d enabling adapter\n", rc);
+	return rc;
+}
+
+/**
  * reset_crq_queue: - resets a crq after a failure
  * @queue:	crq_queue to initialize and register
  * @hostdata:	ibmvscsi_host_data of host
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 3c688ef..0cf0e4c 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -751,9 +751,8 @@ static void idescsi_setup (ide_drive_t *
 	idescsi_add_settings(drive);
 }
 
-static int ide_scsi_remove(struct device *dev)
+static void ide_scsi_remove(ide_drive_t *drive)
 {
-	ide_drive_t *drive = to_ide_device(dev);
 	struct Scsi_Host *scsihost = drive->driver_data;
 	struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost);
 	struct gendisk *g = scsi->disk;
@@ -768,11 +767,9 @@ static int ide_scsi_remove(struct device
 
 	scsi_remove_host(scsihost);
 	ide_scsi_put(scsi);
-
-	return 0;
 }
 
-static int ide_scsi_probe(struct device *);
+static int ide_scsi_probe(ide_drive_t *);
 
 #ifdef CONFIG_PROC_FS
 static ide_proc_entry_t idescsi_proc[] = {
@@ -788,9 +785,9 @@ static ide_driver_t idescsi_driver = {
 		.owner		= THIS_MODULE,
 		.name		= "ide-scsi",
 		.bus		= &ide_bus_type,
-		.probe		= ide_scsi_probe,
-		.remove		= ide_scsi_remove,
 	},
+	.probe			= ide_scsi_probe,
+	.remove			= ide_scsi_remove,
 	.version		= IDESCSI_VERSION,
 	.media			= ide_scsi,
 	.supports_dsc_overlap	= 0,
@@ -1119,9 +1116,8 @@ static struct scsi_host_template idescsi
 	.proc_name		= "ide-scsi",
 };
 
-static int ide_scsi_probe(struct device *dev)
+static int ide_scsi_probe(ide_drive_t *drive)
 {
-	ide_drive_t *drive = to_ide_device(dev);
 	idescsi_scsi_t *idescsi;
 	struct Scsi_Host *host;
 	struct gendisk *g;
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index e5e1ca4..86c5461 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -3499,6 +3499,7 @@ ips_map_status(ips_ha_t * ha, ips_scb_t 
 	int device_error;
 	uint32_t transfer_len;
 	IPS_DCDB_TABLE_TAPE *tapeDCDB;
+	IPS_SCSI_INQ_DATA inquiryData;
 
 	METHOD_TRACE("ips_map_status", 1);
 
@@ -3557,13 +3558,13 @@ ips_map_status(ips_ha_t * ha, ips_scb_t 
 				errcode = DID_OK;
 
 				/* Restrict access to physical DASD */
-				if ((scb->scsi_cmd->cmnd[0] == INQUIRY) &&
-				    ((((char *) scb->scsi_cmd->
-				       buffer)[0] & 0x1f) == TYPE_DISK)) {
-					/* underflow -- no error               */
-					/* restrict access to physical DASD    */
-					errcode = DID_TIME_OUT;
-					break;
+				if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
+				    ips_scmd_buf_read(scb->scsi_cmd, 
+                                      &inquiryData, sizeof (inquiryData));
+ 				    if ((inquiryData.DeviceType & 0x1f) == TYPE_DISK) {
+				        errcode = DID_TIME_OUT;
+				        break;
+				    }
 				}
 			} else
 				errcode = DID_ERROR;
@@ -4135,6 +4136,7 @@ ips_chkstatus(ips_ha_t * ha, IPS_STATUS 
 	uint8_t basic_status;
 	uint8_t ext_status;
 	int errcode;
+	IPS_SCSI_INQ_DATA inquiryData;
 
 	METHOD_TRACE("ips_chkstatus", 1);
 
@@ -4255,11 +4257,11 @@ ips_chkstatus(ips_ha_t * ha, IPS_STATUS 
 			scb->scsi_cmd->result = errcode << 16;
 		} else {	/* bus == 0 */
 			/* restrict access to physical drives */
-			if ((scb->scsi_cmd->cmnd[0] == INQUIRY) &&
-			    ((((char *) scb->scsi_cmd->buffer)[0] & 0x1f) ==
-			     TYPE_DISK)) {
-
-				scb->scsi_cmd->result = DID_TIME_OUT << 16;
+			if (scb->scsi_cmd->cmnd[0] == INQUIRY) { 
+			    ips_scmd_buf_read(scb->scsi_cmd, 
+                                  &inquiryData, sizeof (inquiryData));
+			    if ((inquiryData.DeviceType & 0x1f) == TYPE_DISK) 
+			        scb->scsi_cmd->result = DID_TIME_OUT << 16;
 			}
 		}		/* else */
 	} else {		/* recovered error / success */
@@ -5012,7 +5014,7 @@ ips_init_copperhead(ips_ha_t * ha)
 				break;
 
 			/* Delay for 1 Second */
-			MDELAY(IPS_ONE_SEC);
+			msleep(IPS_ONE_SEC);
 		}
 
 		if (j >= 45)
@@ -5038,7 +5040,7 @@ ips_init_copperhead(ips_ha_t * ha)
 				break;
 
 			/* Delay for 1 Second */
-			MDELAY(IPS_ONE_SEC);
+			msleep(IPS_ONE_SEC);
 		}
 
 		if (j >= 240)
@@ -5056,7 +5058,7 @@ ips_init_copperhead(ips_ha_t * ha)
 			break;
 
 		/* Delay for 1 Second */
-		MDELAY(IPS_ONE_SEC);
+		msleep(IPS_ONE_SEC);
 	}
 
 	if (i >= 240)
@@ -5106,7 +5108,7 @@ ips_init_copperhead_memio(ips_ha_t * ha)
 				break;
 
 			/* Delay for 1 Second */
-			MDELAY(IPS_ONE_SEC);
+			msleep(IPS_ONE_SEC);
 		}
 
 		if (j >= 45)
@@ -5132,7 +5134,7 @@ ips_init_copperhead_memio(ips_ha_t * ha)
 				break;
 
 			/* Delay for 1 Second */
-			MDELAY(IPS_ONE_SEC);
+			msleep(IPS_ONE_SEC);
 		}
 
 		if (j >= 240)
@@ -5150,7 +5152,7 @@ ips_init_copperhead_memio(ips_ha_t * ha)
 			break;
 
 		/* Delay for 1 Second */
-		MDELAY(IPS_ONE_SEC);
+		msleep(IPS_ONE_SEC);
 	}
 
 	if (i >= 240)
@@ -5202,7 +5204,7 @@ ips_init_morpheus(ips_ha_t * ha)
 			break;
 
 		/* Delay for 1 Second */
-		MDELAY(IPS_ONE_SEC);
+		msleep(IPS_ONE_SEC);
 	}
 
 	if (i >= 45) {
@@ -5228,7 +5230,7 @@ ips_init_morpheus(ips_ha_t * ha)
 			if (Post != 0x4F00)
 				break;
 			/* Delay for 1 Second */
-			MDELAY(IPS_ONE_SEC);
+			msleep(IPS_ONE_SEC);
 		}
 
 		if (i >= 120) {
@@ -5258,7 +5260,7 @@ ips_init_morpheus(ips_ha_t * ha)
 			break;
 
 		/* Delay for 1 Second */
-		MDELAY(IPS_ONE_SEC);
+		msleep(IPS_ONE_SEC);
 	}
 
 	if (i >= 240) {
@@ -5318,12 +5320,12 @@ ips_reset_copperhead(ips_ha_t * ha)
 		outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR);
 
 		/* Delay for 1 Second */
-		MDELAY(IPS_ONE_SEC);
+		msleep(IPS_ONE_SEC);
 
 		outb(0, ha->io_addr + IPS_REG_SCPR);
 
 		/* Delay for 1 Second */
-		MDELAY(IPS_ONE_SEC);
+		msleep(IPS_ONE_SEC);
 
 		if ((*ha->func.init) (ha))
 			break;
@@ -5363,12 +5365,12 @@ ips_reset_copperhead_memio(ips_ha_t * ha
 		writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR);
 
 		/* Delay for 1 Second */
-		MDELAY(IPS_ONE_SEC);
+		msleep(IPS_ONE_SEC);
 
 		writeb(0, ha->mem_ptr + IPS_REG_SCPR);
 
 		/* Delay for 1 Second */
-		MDELAY(IPS_ONE_SEC);
+		msleep(IPS_ONE_SEC);
 
 		if ((*ha->func.init) (ha))
 			break;
@@ -5409,7 +5411,7 @@ ips_reset_morpheus(ips_ha_t * ha)
 		writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR);
 
 		/* Delay for 5 Seconds */
-		MDELAY(5 * IPS_ONE_SEC);
+		msleep(5 * IPS_ONE_SEC);
 
 		/* Do a PCI config read to wait for adapter */
 		pci_read_config_byte(ha->pcidev, 4, &junk);
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 99bae83..46c4cdb 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -611,6 +611,10 @@ int ata_rwcmd_protocol(struct ata_queued
 	if (dev->flags & ATA_DFLAG_PIO) {
 		tf->protocol = ATA_PROT_PIO;
 		index = dev->multi_count ? 0 : 8;
+	} else if (lba48 && (qc->ap->flags & ATA_FLAG_PIO_LBA48)) {
+		/* Unable to use DMA due to host limitation */
+		tf->protocol = ATA_PROT_PIO;
+		index = dev->multi_count ? 0 : 4;
 	} else {
 		tf->protocol = ATA_PROT_DMA;
 		index = 16;
@@ -1051,18 +1055,22 @@ static unsigned int ata_pio_modes(const 
 {
 	u16 modes;
 
-	/* Usual case. Word 53 indicates word 88 is valid */
-	if (adev->id[ATA_ID_FIELD_VALID] & (1 << 2)) {
+	/* Usual case. Word 53 indicates word 64 is valid */
+	if (adev->id[ATA_ID_FIELD_VALID] & (1 << 1)) {
 		modes = adev->id[ATA_ID_PIO_MODES] & 0x03;
 		modes <<= 3;
 		modes |= 0x7;
 		return modes;
 	}
 
-	/* If word 88 isn't valid then Word 51 holds the PIO timing number
-	   for the maximum. Turn it into a mask and return it */
-	modes = (2 << (adev->id[ATA_ID_OLD_PIO_MODES] & 0xFF)) - 1 ;
+	/* If word 64 isn't valid then Word 51 high byte holds the PIO timing
+	   number for the maximum. Turn it into a mask and return it */
+	modes = (2 << ((adev->id[ATA_ID_OLD_PIO_MODES] >> 8) & 0xFF)) - 1 ;
 	return modes;
+	/* But wait.. there's more. Design your standards by committee and
+	   you too can get a free iordy field to process. However its the 
+	   speeds not the modes that are supported... Note drivers using the
+	   timing API will get this right anyway */
 }
 
 struct ata_exec_internal_arg {
@@ -1165,6 +1173,39 @@ ata_exec_internal(struct ata_port *ap, s
 }
 
 /**
+ *	ata_pio_need_iordy	-	check if iordy needed
+ *	@adev: ATA device
+ *
+ *	Check if the current speed of the device requires IORDY. Used
+ *	by various controllers for chip configuration.
+ */
+
+unsigned int ata_pio_need_iordy(const struct ata_device *adev)
+{
+	int pio;
+	int speed = adev->pio_mode - XFER_PIO_0;
+
+	if (speed < 2)
+		return 0;
+	if (speed > 2)
+		return 1;
+		
+	/* If we have no drive specific rule, then PIO 2 is non IORDY */
+
+	if (adev->id[ATA_ID_FIELD_VALID] & 2) {	/* EIDE */
+		pio = adev->id[ATA_ID_EIDE_PIO];
+		/* Is the speed faster than the drive allows non IORDY ? */
+		if (pio) {
+			/* This is cycle times not frequency - watch the logic! */
+			if (pio > 240)	/* PIO2 is 240nS per cycle */
+				return 1;
+			return 0;
+		}
+	}
+	return 0;
+}
+
+/**
  *	ata_dev_identify - obtain IDENTIFY x DEVICE page
  *	@ap: port on which device we wish to probe resides
  *	@device: device bus address, starting at zero
@@ -1415,7 +1456,7 @@ void ata_dev_config(struct ata_port *ap,
 		ap->udma_mask &= ATA_UDMA5;
 		ap->host->max_sectors = ATA_MAX_SECTORS;
 		ap->host->hostt->max_sectors = ATA_MAX_SECTORS;
-		ap->device->flags |= ATA_DFLAG_LOCK_SECTORS;
+		ap->device[i].flags |= ATA_DFLAG_LOCK_SECTORS;
 	}
 
 	if (ap->ops->dev_config)
@@ -3056,10 +3097,21 @@ static void ata_pio_data_xfer(struct ata
 static void ata_data_xfer(struct ata_port *ap, unsigned char *buf,
 			  unsigned int buflen, int do_write)
 {
-	if (ap->flags & ATA_FLAG_MMIO)
-		ata_mmio_data_xfer(ap, buf, buflen, do_write);
-	else
-		ata_pio_data_xfer(ap, buf, buflen, do_write);
+	/* Make the crap hardware pay the costs not the good stuff */
+	if (unlikely(ap->flags & ATA_FLAG_IRQ_MASK)) {
+		unsigned long flags;
+		local_irq_save(flags);
+		if (ap->flags & ATA_FLAG_MMIO)
+			ata_mmio_data_xfer(ap, buf, buflen, do_write);
+		else
+			ata_pio_data_xfer(ap, buf, buflen, do_write);
+		local_irq_restore(flags);
+	} else {
+		if (ap->flags & ATA_FLAG_MMIO)
+			ata_mmio_data_xfer(ap, buf, buflen, do_write);
+		else
+			ata_pio_data_xfer(ap, buf, buflen, do_write);
+	}
 }
 
 /**
@@ -5122,6 +5174,7 @@ EXPORT_SYMBOL_GPL(ata_dev_id_string);
 EXPORT_SYMBOL_GPL(ata_dev_config);
 EXPORT_SYMBOL_GPL(ata_scsi_simulate);
 
+EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
 EXPORT_SYMBOL_GPL(ata_timing_compute);
 EXPORT_SYMBOL_GPL(ata_timing_merge);
 
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index cfbceb5..07b1e7c 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -1700,6 +1700,31 @@ static unsigned int ata_msense_rw_recove
 	return sizeof(def_rw_recovery_mpage);
 }
 
+/*
+ * We can turn this into a real blacklist if it's needed, for now just
+ * blacklist any Maxtor BANC1G10 revision firmware
+ */
+static int ata_dev_supports_fua(u16 *id)
+{
+	unsigned char model[41], fw[9];
+
+	if (!ata_id_has_fua(id))
+		return 0;
+
+	model[40] = '\0';
+	fw[8] = '\0';
+
+	ata_dev_id_string(id, model, ATA_ID_PROD_OFS, sizeof(model) - 1);
+	ata_dev_id_string(id, fw, ATA_ID_FW_REV_OFS, sizeof(fw) - 1);
+
+	if (strncmp(model, "Maxtor", 6))
+		return 1;
+	if (strncmp(fw, "BANC1G10", 8))
+		return 1;
+
+	return 0; /* blacklisted */
+}
+
 /**
  *	ata_scsiop_mode_sense - Simulate MODE SENSE 6, 10 commands
  *	@args: device IDENTIFY data / SCSI command of interest.
@@ -1797,7 +1822,7 @@ unsigned int ata_scsiop_mode_sense(struc
 		return 0;
 
 	dpofua = 0;
-	if (ata_id_has_fua(args->id) && dev->flags & ATA_DFLAG_LBA48 &&
+	if (ata_dev_supports_fua(args->id) && dev->flags & ATA_DFLAG_LBA48 &&
 	    (!(dev->flags & ATA_DFLAG_PIO) || dev->multi_count))
 		dpofua = 1 << 4;
 
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 511ed52..a487f41 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -10,7 +10,7 @@
  *	   2 of the License, or (at your option) any later version.
  *
  * FILE		: megaraid_sas.c
- * Version	: v00.00.02.00-rc4
+ * Version	: v00.00.02.02
  *
  * Authors:
  * 	Sreenivas Bagalkote	<Sreenivas.Bagalkote@lsil.com>
@@ -55,13 +55,13 @@ static struct pci_device_id megasas_pci_
 
 	{
 	 PCI_VENDOR_ID_LSI_LOGIC,
-	 PCI_DEVICE_ID_LSI_SAS1064R,
+	 PCI_DEVICE_ID_LSI_SAS1064R, // xscale IOP
 	 PCI_ANY_ID,
 	 PCI_ANY_ID,
 	 },
 	{
 	 PCI_VENDOR_ID_DELL,
-	 PCI_DEVICE_ID_DELL_PERC5,
+	 PCI_DEVICE_ID_DELL_PERC5, // xscale IOP
 	 PCI_ANY_ID,
 	 PCI_ANY_ID,
 	 },
@@ -119,12 +119,18 @@ megasas_return_cmd(struct megasas_instan
 	spin_unlock_irqrestore(&instance->cmd_pool_lock, flags);
 }
 
+
+/**
+*	The following functions are defined for xscale 
+*	(deviceid : 1064R, PERC5) controllers
+*/
+
 /**
- * megasas_enable_intr -	Enables interrupts
+ * megasas_enable_intr_xscale -	Enables interrupts
  * @regs:			MFI register set
  */
 static inline void
-megasas_enable_intr(struct megasas_register_set __iomem * regs)
+megasas_enable_intr_xscale(struct megasas_register_set __iomem * regs)
 {
 	writel(1, &(regs)->outbound_intr_mask);
 
@@ -133,13 +139,73 @@ megasas_enable_intr(struct megasas_regis
 }
 
 /**
+ * megasas_read_fw_status_reg_xscale - returns the current FW status value
+ * @regs:			MFI register set
+ */
+static u32
+megasas_read_fw_status_reg_xscale(struct megasas_register_set __iomem * regs)
+{
+	return readl(&(regs)->outbound_msg_0);
+}
+/**
+ * megasas_clear_interrupt_xscale -	Check & clear interrupt
+ * @regs:				MFI register set
+ */
+static int 
+megasas_clear_intr_xscale(struct megasas_register_set __iomem * regs)
+{
+	u32 status;
+	/*
+	 * Check if it is our interrupt
+	 */
+	status = readl(&regs->outbound_intr_status);
+
+	if (!(status & MFI_OB_INTR_STATUS_MASK)) {
+		return 1;
+	}
+
+	/*
+	 * Clear the interrupt by writing back the same value
+	 */
+	writel(status, &regs->outbound_intr_status);
+
+	return 0;
+}
+
+/**
+ * megasas_fire_cmd_xscale -	Sends command to the FW
+ * @frame_phys_addr :		Physical address of cmd
+ * @frame_count :		Number of frames for the command
+ * @regs :			MFI register set
+ */
+static inline void 
+megasas_fire_cmd_xscale(dma_addr_t frame_phys_addr,u32 frame_count, struct megasas_register_set __iomem *regs)
+{
+	writel((frame_phys_addr >> 3)|(frame_count),
+	       &(regs)->inbound_queue_port);
+}
+
+static struct megasas_instance_template megasas_instance_template_xscale = {
+
+	.fire_cmd = megasas_fire_cmd_xscale,
+	.enable_intr = megasas_enable_intr_xscale,
+	.clear_intr = megasas_clear_intr_xscale,
+	.read_fw_status_reg = megasas_read_fw_status_reg_xscale,
+};
+
+/**
+*	This is the end of set of functions & definitions specific 
+*	to xscale (deviceid : 1064R, PERC5) controllers
+*/
+
+/**
  * megasas_disable_intr -	Disables interrupts
  * @regs:			MFI register set
  */
 static inline void
 megasas_disable_intr(struct megasas_register_set __iomem * regs)
 {
-	u32 mask = readl(&regs->outbound_intr_mask) & (~0x00000001);
+	u32 mask = 0x1f; 
 	writel(mask, &regs->outbound_intr_mask);
 
 	/* Dummy readl to force pci flush */
@@ -167,8 +233,7 @@ megasas_issue_polled(struct megasas_inst
 	/*
 	 * Issue the frame using inbound queue port
 	 */
-	writel(cmd->frame_phys_addr >> 3,
-	       &instance->reg_set->inbound_queue_port);
+	instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
 
 	/*
 	 * Wait for cmd_status to change
@@ -198,8 +263,7 @@ megasas_issue_blocked_cmd(struct megasas
 {
 	cmd->cmd_status = ENODATA;
 
-	writel(cmd->frame_phys_addr >> 3,
-	       &instance->reg_set->inbound_queue_port);
+	instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
 
 	wait_event(instance->int_cmd_wait_q, (cmd->cmd_status != ENODATA));
 
@@ -242,8 +306,7 @@ megasas_issue_blocked_abort_cmd(struct m
 	cmd->sync_cmd = 1;
 	cmd->cmd_status = 0xFF;
 
-	writel(cmd->frame_phys_addr >> 3,
-	       &instance->reg_set->inbound_queue_port);
+	instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
 
 	/*
 	 * Wait for this cmd to complete
@@ -558,112 +621,29 @@ megasas_build_ldio(struct megasas_instan
 }
 
 /**
- * megasas_build_cmd -	Prepares a command packet
- * @instance:		Adapter soft state
- * @scp:		SCSI command
- * @frame_count:	[OUT] Number of frames used to prepare this command
+ * megasas_is_ldio -		Checks if the cmd is for logical drive
+ * @scmd:			SCSI command
+ *	
+ * Called by megasas_queue_command to find out if the command to be queued
+ * is a logical drive command	
  */
-static struct megasas_cmd *megasas_build_cmd(struct megasas_instance
-						    *instance,
-						    struct scsi_cmnd *scp,
-						    int *frame_count)
+static inline int megasas_is_ldio(struct scsi_cmnd *cmd)
 {
-	u32 logical_cmd;
-	struct megasas_cmd *cmd;
-
-	/*
-	 * Find out if this is logical or physical drive command.
-	 */
-	logical_cmd = MEGASAS_IS_LOGICAL(scp);
-
-	/*
-	 * Logical drive command
-	 */
-	if (logical_cmd) {
-
-		if (scp->device->id >= MEGASAS_MAX_LD) {
-			scp->result = DID_BAD_TARGET << 16;
-			return NULL;
-		}
-
-		switch (scp->cmnd[0]) {
-
-		case READ_10:
-		case WRITE_10:
-		case READ_12:
-		case WRITE_12:
-		case READ_6:
-		case WRITE_6:
-		case READ_16:
-		case WRITE_16:
-			/*
-			 * Fail for LUN > 0
-			 */
-			if (scp->device->lun) {
-				scp->result = DID_BAD_TARGET << 16;
-				return NULL;
-			}
-
-			cmd = megasas_get_cmd(instance);
-
-			if (!cmd) {
-				scp->result = DID_IMM_RETRY << 16;
-				return NULL;
-			}
-
-			*frame_count = megasas_build_ldio(instance, scp, cmd);
-
-			if (!(*frame_count)) {
-				megasas_return_cmd(instance, cmd);
-				return NULL;
-			}
-
-			return cmd;
-
-		default:
-			/*
-			 * Fail for LUN > 0
-			 */
-			if (scp->device->lun) {
-				scp->result = DID_BAD_TARGET << 16;
-				return NULL;
-			}
-
-			cmd = megasas_get_cmd(instance);
-
-			if (!cmd) {
-				scp->result = DID_IMM_RETRY << 16;
-				return NULL;
-			}
-
-			*frame_count = megasas_build_dcdb(instance, scp, cmd);
-
-			if (!(*frame_count)) {
-				megasas_return_cmd(instance, cmd);
-				return NULL;
-			}
-
-			return cmd;
-		}
-	} else {
-		cmd = megasas_get_cmd(instance);
-
-		if (!cmd) {
-			scp->result = DID_IMM_RETRY << 16;
-			return NULL;
-		}
-
-		*frame_count = megasas_build_dcdb(instance, scp, cmd);
-
-		if (!(*frame_count)) {
-			megasas_return_cmd(instance, cmd);
-			return NULL;
-		}
-
-		return cmd;
+	if (!MEGASAS_IS_LOGICAL(cmd))
+		return 0;
+	switch (cmd->cmnd[0]) {
+	case READ_10:
+	case WRITE_10:
+	case READ_12:
+	case WRITE_12:
+	case READ_6:
+	case WRITE_6:
+	case READ_16:
+	case WRITE_16:
+		return 1;
+	default:
+		return 0;
 	}
-
-	return NULL;
 }
 
 /**
@@ -684,13 +664,27 @@ megasas_queue_command(struct scsi_cmnd *
 	scmd->scsi_done = done;
 	scmd->result = 0;
 
-	cmd = megasas_build_cmd(instance, scmd, &frame_count);
-
-	if (!cmd) {
-		done(scmd);
-		return 0;
+	if (MEGASAS_IS_LOGICAL(scmd) &&
+	    (scmd->device->id >= MEGASAS_MAX_LD || scmd->device->lun)) {
+		scmd->result = DID_BAD_TARGET << 16;
+		goto out_done;
 	}
 
+	cmd = megasas_get_cmd(instance);
+	if (!cmd)
+		return SCSI_MLQUEUE_HOST_BUSY;
+
+	/*
+	 * Logical drive command
+	 */
+	if (megasas_is_ldio(scmd))
+		frame_count = megasas_build_ldio(instance, scmd, cmd);
+	else
+		frame_count = megasas_build_dcdb(instance, scmd, cmd);
+
+	if (!frame_count)
+		goto out_return_cmd;
+
 	cmd->scmd = scmd;
 	scmd->SCp.ptr = (char *)cmd;
 	scmd->SCp.sent_command = jiffies;
@@ -702,10 +696,15 @@ megasas_queue_command(struct scsi_cmnd *
 	instance->fw_outstanding++;
 	spin_unlock_irqrestore(&instance->instance_lock, flags);
 
-	writel(((cmd->frame_phys_addr >> 3) | (cmd->frame_count - 1)),
-	       &instance->reg_set->inbound_queue_port);
+	instance->instancet->fire_cmd(cmd->frame_phys_addr ,cmd->frame_count-1,instance->reg_set);
 
 	return 0;
+
+ out_return_cmd:
+	megasas_return_cmd(instance, cmd);
+ out_done:
+	done(scmd);
+	return 0;
 }
 
 /**
@@ -1108,7 +1107,6 @@ megasas_complete_cmd(struct megasas_inst
 static int
 megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status)
 {
-	u32 status;
 	u32 producer;
 	u32 consumer;
 	u32 context;
@@ -1116,17 +1114,10 @@ megasas_deplete_reply_queue(struct megas
 
 	/*
 	 * Check if it is our interrupt
+	 * Clear the interrupt 
 	 */
-	status = readl(&instance->reg_set->outbound_intr_status);
-
-	if (!(status & MFI_OB_INTR_STATUS_MASK)) {
+	if(instance->instancet->clear_intr(instance->reg_set))
 		return IRQ_NONE;
-	}
-
-	/*
-	 * Clear the interrupt by writing back the same value
-	 */
-	writel(status, &instance->reg_set->outbound_intr_status);
 
 	producer = *instance->producer;
 	consumer = *instance->consumer;
@@ -1160,7 +1151,7 @@ static irqreturn_t megasas_isr(int irq, 
 
 /**
  * megasas_transition_to_ready -	Move the FW to READY state
- * @reg_set:				MFI register set
+ * @instance:				Adapter soft state
  *
  * During the initialization, FW passes can potentially be in any one of
  * several possible states. If the FW in operational, waiting-for-handshake
@@ -1168,14 +1159,14 @@ static irqreturn_t megasas_isr(int irq, 
  * has to wait for the ready state.
  */
 static int
-megasas_transition_to_ready(struct megasas_register_set __iomem * reg_set)
+megasas_transition_to_ready(struct megasas_instance* instance)
 {
 	int i;
 	u8 max_wait;
 	u32 fw_state;
 	u32 cur_state;
 
-	fw_state = readl(&reg_set->outbound_msg_0) & MFI_STATE_MASK;
+	fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
 
 	while (fw_state != MFI_STATE_READY) {
 
@@ -1193,7 +1184,7 @@ megasas_transition_to_ready(struct megas
 			 * Set the CLR bit in inbound doorbell
 			 */
 			writel(MFI_INIT_CLEAR_HANDSHAKE,
-			       &reg_set->inbound_doorbell);
+				&instance->reg_set->inbound_doorbell);
 
 			max_wait = 2;
 			cur_state = MFI_STATE_WAIT_HANDSHAKE;
@@ -1203,8 +1194,8 @@ megasas_transition_to_ready(struct megas
 			/*
 			 * Bring it to READY state; assuming max wait 2 secs
 			 */
-			megasas_disable_intr(reg_set);
-			writel(MFI_INIT_READY, &reg_set->inbound_doorbell);
+			megasas_disable_intr(instance->reg_set);
+			writel(MFI_INIT_READY, &instance->reg_set->inbound_doorbell);
 
 			max_wait = 10;
 			cur_state = MFI_STATE_OPERATIONAL;
@@ -1253,8 +1244,8 @@ megasas_transition_to_ready(struct megas
 		 * The cur_state should not last for more than max_wait secs
 		 */
 		for (i = 0; i < (max_wait * 1000); i++) {
-			fw_state = MFI_STATE_MASK &
-			    readl(&reg_set->outbound_msg_0);
+			fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) &  
+					MFI_STATE_MASK ;
 
 			if (fw_state == cur_state) {
 				msleep(1);
@@ -1616,18 +1607,20 @@ static int megasas_init_mfi(struct megas
 
 	reg_set = instance->reg_set;
 
+	instance->instancet = &megasas_instance_template_xscale;
+
 	/*
 	 * We expect the FW state to be READY
 	 */
-	if (megasas_transition_to_ready(instance->reg_set))
+	if (megasas_transition_to_ready(instance))
 		goto fail_ready_state;
 
 	/*
 	 * Get various operational parameters from status register
 	 */
-	instance->max_fw_cmds = readl(&reg_set->outbound_msg_0) & 0x00FFFF;
-	instance->max_num_sge = (readl(&reg_set->outbound_msg_0) & 0xFF0000) >>
-	    0x10;
+	instance->max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF;
+	instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >> 
+					0x10;
 	/*
 	 * Create a pool of commands
 	 */
@@ -1936,8 +1929,7 @@ megasas_register_aen(struct megasas_inst
 	/*
 	 * Issue the aen registration frame
 	 */
-	writel(cmd->frame_phys_addr >> 3,
-	       &instance->reg_set->inbound_queue_port);
+	instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
 
 	return 0;
 }
@@ -2126,7 +2118,7 @@ megasas_probe_one(struct pci_dev *pdev, 
 		goto fail_irq;
 	}
 
-	megasas_enable_intr(instance->reg_set);
+	instance->instancet->enable_intr(instance->reg_set);
 
 	/*
 	 * Store instance in PCI softstate
@@ -2681,9 +2673,8 @@ megasas_mgmt_compat_ioctl(struct file *f
 			  unsigned long arg)
 {
 	switch (cmd) {
-	case MEGASAS_IOC_FIRMWARE:{
-			return megasas_mgmt_compat_ioctl_fw(file, arg);
-		}
+	case MEGASAS_IOC_FIRMWARE32:
+		return megasas_mgmt_compat_ioctl_fw(file, arg);
 	case MEGASAS_IOC_GET_AEN:
 		return megasas_mgmt_ioctl_aen(file, arg);
 	}
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index eaec9d5..d6d166c 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -18,10 +18,9 @@
 /**
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION				"00.00.02.00-rc4"
-#define MEGASAS_RELDATE				"Sep 16, 2005"
-#define MEGASAS_EXT_VERSION			"Fri Sep 16 12:37:08 EDT 2005"
-
+#define MEGASAS_VERSION				"00.00.02.02"
+#define MEGASAS_RELDATE				"Jan 23, 2006"
+#define MEGASAS_EXT_VERSION			"Mon Jan 23 14:09:01 PST 2006"
 /*
  * =====================================
  * MegaRAID SAS MFI firmware definitions
@@ -1013,6 +1012,16 @@ struct megasas_evt_detail {
 
 } __attribute__ ((packed));
 
+ struct megasas_instance_template {
+	void (*fire_cmd)(dma_addr_t ,u32 ,struct megasas_register_set __iomem *);
+
+	void (*enable_intr)(struct megasas_register_set __iomem *) ;
+
+	int (*clear_intr)(struct megasas_register_set __iomem *);
+
+	u32 (*read_fw_status_reg)(struct megasas_register_set __iomem *);
+ };
+
 struct megasas_instance {
 
 	u32 *producer;
@@ -1056,6 +1065,8 @@ struct megasas_instance {
 	u32 fw_outstanding;
 	u32 hw_crit_error;
 	spinlock_t instance_lock;
+
+	struct megasas_instance_template *instancet;
 };
 
 #define MEGASAS_IS_LOGICAL(scp)						\
@@ -1125,11 +1136,10 @@ struct compat_megasas_iocpacket {
 	struct compat_iovec sgl[MAX_IOCTL_SGE];
 } __attribute__ ((packed));
 
-#define MEGASAS_IOC_FIRMWARE	_IOWR('M', 1, struct compat_megasas_iocpacket)
-#else
-#define MEGASAS_IOC_FIRMWARE	_IOWR('M', 1, struct megasas_iocpacket)
 #endif
 
+#define MEGASAS_IOC_FIRMWARE	_IOWR('M', 1, struct megasas_iocpacket)
+#define MEGASAS_IOC_FIRMWARE32	_IOWR('M', 1, struct compat_megasas_iocpacket)
 #define MEGASAS_IOC_GET_AEN	_IOW('M', 3, struct megasas_aen)
 
 struct megasas_mgmt_info {
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index 0878f95..e023024 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -17,9 +17,11 @@
 * General Public License for more details.
 *
 ******************************************************************************/
-#define QLA1280_VERSION      "3.25"
+#define QLA1280_VERSION      "3.26"
 /*****************************************************************************
     Revision History:
+    Rev  3.26, January 16, 2006 Jes Sorensen
+	- Ditch all < 2.6 support
     Rev  3.25.1, February 10, 2005 Christoph Hellwig
 	- use pci_map_single to map non-S/G requests
 	- remove qla1280_proc_info
@@ -356,25 +358,18 @@
 #include <asm/types.h>
 #include <asm/system.h>
 
-#if LINUX_VERSION_CODE >= 0x020545
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_tcq.h>
-#else
-#include <linux/blk.h>
-#include "scsi.h"
-#include <scsi/scsi_host.h>
-#include "sd.h"
-#endif
 
 #if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
 #include <asm/sn/io.h>
 #endif
 
-#if LINUX_VERSION_CODE < 0x020407
-#error "Kernels older than 2.4.7 are no longer supported"
+#if LINUX_VERSION_CODE < 0x020600
+#error "Kernels older than 2.6.0 are no longer supported"
 #endif
 
 
@@ -441,52 +436,6 @@
 
 #define NVRAM_DELAY()			udelay(500)	/* 2 microseconds */
 
-#if LINUX_VERSION_CODE < 0x020500
-#define HOST_LOCK			&io_request_lock
-#define irqreturn_t			void
-#define IRQ_RETVAL(foo)
-#define MSG_ORDERED_TAG			1
-
-#define DMA_BIDIRECTIONAL	SCSI_DATA_UNKNOWN
-#define DMA_TO_DEVICE		SCSI_DATA_WRITE
-#define DMA_FROM_DEVICE		SCSI_DATA_READ
-#define DMA_NONE		SCSI_DATA_NONE
-
-#ifndef HAVE_SECTOR_T
-typedef unsigned int sector_t;
-#endif
-
-static inline void
-scsi_adjust_queue_depth(struct scsi_device *device, int tag, int depth)
-{
-	if (tag) {
-		device->tagged_queue = tag;
-		device->current_tag = 0;
-	}
-	device->queue_depth = depth;
-}
-static inline struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *t, size_t s)
-{
-	return scsi_register(t, s);
-}
-static inline void scsi_host_put(struct Scsi_Host *h)
-{
-	scsi_unregister(h);
-}
-#else
-#define HOST_LOCK			ha->host->host_lock
-#endif
-#if LINUX_VERSION_CODE < 0x020600
-#define DEV_SIMPLE_TAGS(device)		device->tagged_queue
-/*
- * Hack around that qla1280_remove_one is called from
- * qla1280_release in 2.4
- */
-#undef __devexit
-#define __devexit
-#else
-#define DEV_SIMPLE_TAGS(device)		device->simple_tags
-#endif
 #if defined(__ia64__) && !defined(ia64_platform_is)
 #define ia64_platform_is(foo)		(!strcmp(x, platform_name))
 #endif
@@ -506,9 +455,6 @@ static void qla1280_remove_one(struct pc
  *  QLogic Driver Support Function Prototypes.
  */
 static void qla1280_done(struct scsi_qla_host *);
-#if LINUX_VERSION_CODE < 0x020545
-static void qla1280_get_target_options(struct scsi_cmnd *, struct scsi_qla_host *);
-#endif
 static int qla1280_get_token(char *);
 static int qla1280_setup(char *s) __init;
 
@@ -610,11 +556,7 @@ __setup("qla1280=", qla1280_setup);
 #define	CMD_SNSLEN(Cmnd)	sizeof(Cmnd->sense_buffer)
 #define	CMD_RESULT(Cmnd)	Cmnd->result
 #define	CMD_HANDLE(Cmnd)	Cmnd->host_scribble
-#if LINUX_VERSION_CODE < 0x020545
-#define CMD_REQUEST(Cmnd)	Cmnd->request.cmd
-#else
 #define CMD_REQUEST(Cmnd)	Cmnd->request->cmd
-#endif
 
 #define CMD_HOST(Cmnd)		Cmnd->device->host
 #define SCSI_BUS_32(Cmnd)	Cmnd->device->channel
@@ -1064,10 +1006,10 @@ qla1280_error_action(struct scsi_cmnd *c
 	add_timer(&timer);
 
 	/* wait for the action to complete (or the timer to expire) */
-	spin_unlock_irq(HOST_LOCK);
+	spin_unlock_irq(ha->host->host_lock);
 	wait_for_completion(&wait);
 	del_timer_sync(&timer);
-	spin_lock_irq(HOST_LOCK);
+	spin_lock_irq(ha->host->host_lock);
 	sp->wait = NULL;
 
 	/* the only action we might get a fail for is abort */
@@ -1173,96 +1115,6 @@ qla1280_biosparam(struct scsi_device *sd
 	return 0;
 }
 
-#if LINUX_VERSION_CODE < 0x020600
-static int
-qla1280_detect(struct scsi_host_template *template)
-{
-	struct pci_device_id *id = &qla1280_pci_tbl[0];
-	struct pci_dev *pdev = NULL;
-	int num_hosts = 0;
-
-	if (sizeof(struct srb) > sizeof(Scsi_Pointer)) {
-		printk(KERN_WARNING
-		       "qla1280: struct srb too big, aborting\n");
-		return 0;
-	}
-
-	if ((DMA_BIDIRECTIONAL != PCI_DMA_BIDIRECTIONAL) ||
-	    (DMA_TO_DEVICE != PCI_DMA_TODEVICE) ||
-	    (DMA_FROM_DEVICE != PCI_DMA_FROMDEVICE) ||
-	    (DMA_NONE != PCI_DMA_NONE)) {
-		printk(KERN_WARNING
-		       "qla1280: dma direction bits don't match\n");
-		return 0;
-	}
-
-#ifdef MODULE
-	/*
-	 * If we are called as a module, the qla1280 pointer may not be null
-	 * and it would point to our bootup string, just like on the lilo
-	 * command line.  IF not NULL, then process this config string with
-	 * qla1280_setup
-	 *
-	 * Boot time Options
-	 * To add options at boot time add a line to your lilo.conf file like:
-	 * append="qla1280=verbose,max_tags:{{255,255,255,255},{255,255,255,255}}"
-	 * which will result in the first four devices on the first two
-	 * controllers being set to a tagged queue depth of 32.
-	 */
-	if (qla1280)
-		qla1280_setup(qla1280);
-#endif
-
-	/* First Initialize QLA12160 on PCI Bus 1 Dev 2 */
-	while ((pdev = pci_find_device(id->vendor, id->device, pdev))) {
-		if (pdev->bus->number == 1 && PCI_SLOT(pdev->devfn) == 2) {
-			if (!qla1280_probe_one(pdev, id))
-				num_hosts++;
-		}
-	}
-
-	pdev = NULL;
-	/* Try and find each different type of adapter we support */
-	for (id = &qla1280_pci_tbl[0]; id->device; id++) {
-		while ((pdev = pci_find_device(id->vendor, id->device, pdev))) {
-			/*
-			 * skip QLA12160 already initialized on
-			 * PCI Bus 1 Dev 2 since we already initialized
-			 * and presented it
-			 */
-			if (id->device == PCI_DEVICE_ID_QLOGIC_ISP12160 &&
-			    pdev->bus->number == 1 &&
-			    PCI_SLOT(pdev->devfn) == 2)
-				continue;
-
-			if (!qla1280_probe_one(pdev, id))
-				num_hosts++;
-		}
-	}
-
-	return num_hosts;
-}
-
-/*
- * This looks a bit ugly as we could just pass down host to
- * qla1280_remove_one, but I want to keep qla1280_release purely a wrapper
- * around pci_driver::remove as used from 2.6 onwards.
- */
-static int
-qla1280_release(struct Scsi_Host *host)
-{
-	struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata;
-
-	qla1280_remove_one(ha->pdev);
-	return 0;
-}
-
-static int
-qla1280_biosparam_old(Disk * disk, kdev_t dev, int geom[])
-{
-	return qla1280_biosparam(disk->device, NULL, disk->capacity, geom);
-}
-#endif
  
 /* disable risc and host interrupts */
 static inline void
@@ -1295,7 +1147,7 @@ qla1280_intr_handler(int irq, void *dev_
 	ENTER_INTR ("qla1280_intr_handler");
 	ha = (struct scsi_qla_host *)dev_id;
 
-	spin_lock(HOST_LOCK);
+	spin_lock(ha->host->host_lock);
 
 	ha->isr_count++;
 	reg = ha->iobase;
@@ -1311,7 +1163,7 @@ qla1280_intr_handler(int irq, void *dev_
 	if (!list_empty(&ha->done_q))
 		qla1280_done(ha);
 
-	spin_unlock(HOST_LOCK);
+	spin_unlock(ha->host->host_lock);
 
 	qla1280_enable_intrs(ha);
 
@@ -1411,11 +1263,9 @@ qla1280_slave_configure(struct scsi_devi
 		scsi_adjust_queue_depth(device, 0, default_depth);
 	}
 
-#if LINUX_VERSION_CODE > 0x020500
 	nv->bus[bus].target[target].parameter.enable_sync = device->sdtr;
 	nv->bus[bus].target[target].parameter.enable_wide = device->wdtr;
 	nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr = device->ppr;
-#endif
 
 	if (driver_setup.no_sync ||
 	    (driver_setup.sync_mask &&
@@ -1432,38 +1282,14 @@ qla1280_slave_configure(struct scsi_devi
 			nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 0;
 	}
 
-	spin_lock_irqsave(HOST_LOCK, flags);
+	spin_lock_irqsave(ha->host->host_lock, flags);
 	if (nv->bus[bus].target[target].parameter.enable_sync)
 		status = qla1280_set_target_parameters(ha, bus, target);
 	qla1280_get_target_parameters(ha, device);
-	spin_unlock_irqrestore(HOST_LOCK, flags);
+	spin_unlock_irqrestore(ha->host->host_lock, flags);
 	return status;
 }
 
-#if LINUX_VERSION_CODE < 0x020545
-/**************************************************************************
- *   qla1280_select_queue_depth
- *
- *   Sets the queue depth for each SCSI device hanging off the input
- *   host adapter.  We use a queue depth of 2 for devices that do not
- *   support tagged queueing.
- **************************************************************************/
-static void
-qla1280_select_queue_depth(struct Scsi_Host *host, struct scsi_device *sdev_q)
-{
-	struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata;
-	struct scsi_device *sdev;
-
-	ENTER("qla1280_select_queue_depth");
-	for (sdev = sdev_q; sdev; sdev = sdev->next)
-		if (sdev->host == host)
-			qla1280_slave_configure(sdev);
-
-	if (sdev_q)
-		qla1280_check_for_dead_scsi_bus(ha, sdev_q->channel);
-	LEAVE("qla1280_select_queue_depth");
-}
-#endif
 
 /*
  * qla1280_done
@@ -1523,10 +1349,6 @@ qla1280_done(struct scsi_qla_host *ha)
 		CMD_HANDLE(sp->cmd) = (unsigned char *)INVALID_HANDLE;
 		ha->actthreads--;
 
-#if LINUX_VERSION_CODE < 0x020500
-		if (cmd->cmnd[0] == INQUIRY)
-			qla1280_get_target_options(cmd, ha);
-#endif
 		(*(cmd)->scsi_done)(cmd);
 
 		if(sp->wait != NULL)
@@ -1655,9 +1477,7 @@ qla1280_initialize_adapter(struct scsi_q
 	struct device_reg __iomem *reg;
 	int status;
 	int bus;
-#if LINUX_VERSION_CODE > 0x020500
 	unsigned long flags;
-#endif
 
 	ENTER("qla1280_initialize_adapter");
 
@@ -1695,15 +1515,12 @@ qla1280_initialize_adapter(struct scsi_q
 			"NVRAM\n");
 	}
 
-#if LINUX_VERSION_CODE >= 0x020500
 	/*
 	 * It's necessary to grab the spin here as qla1280_mailbox_command
 	 * needs to be able to drop the lock unconditionally to wait
 	 * for completion.
-	 * In 2.4 ->detect is called with the io_request_lock held.
 	 */
-	spin_lock_irqsave(HOST_LOCK, flags);
-#endif
+	spin_lock_irqsave(ha->host->host_lock, flags);
 
 	status = qla1280_load_firmware(ha);
 	if (status) {
@@ -1735,9 +1552,8 @@ qla1280_initialize_adapter(struct scsi_q
 
 	ha->flags.online = 1;
  out:
-#if LINUX_VERSION_CODE >= 0x020500
-	spin_unlock_irqrestore(HOST_LOCK, flags);
-#endif
+	spin_unlock_irqrestore(ha->host->host_lock, flags);
+
 	if (status)
 		dprintk(2, "qla1280_initialize_adapter: **** FAILED ****\n");
 
@@ -2650,14 +2466,14 @@ qla1280_mailbox_command(struct scsi_qla_
 	timer.function = qla1280_mailbox_timeout;
 	add_timer(&timer);
 
-	spin_unlock_irq(HOST_LOCK);
+	spin_unlock_irq(ha->host->host_lock);
 	WRT_REG_WORD(&reg->host_cmd, HC_SET_HOST_INT);
 	data = qla1280_debounce_register(&reg->istatus);
 
 	wait_for_completion(&wait);
 	del_timer_sync(&timer);
 
-	spin_lock_irq(HOST_LOCK);
+	spin_lock_irq(ha->host->host_lock);
 
 	ha->mailbox_wait = NULL;
 
@@ -2770,9 +2586,9 @@ qla1280_bus_reset(struct scsi_qla_host *
 			ha->bus_settings[bus].scsi_bus_dead = 1;
 		ha->bus_settings[bus].failed_reset_count++;
 	} else {
-		spin_unlock_irq(HOST_LOCK);
+		spin_unlock_irq(ha->host->host_lock);
 		ssleep(reset_delay);
-		spin_lock_irq(HOST_LOCK);
+		spin_lock_irq(ha->host->host_lock);
 
 		ha->bus_settings[bus].scsi_bus_dead = 0;
 		ha->bus_settings[bus].failed_reset_count = 0;
@@ -3078,7 +2894,7 @@ qla1280_64bit_start_scsi(struct scsi_qla
 		(SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd);
 
 	/* Enable simple tag queuing if device supports it. */
-	if (DEV_SIMPLE_TAGS(cmd->device))
+	if (cmd->device->simple_tags)
 		pkt->control_flags |= cpu_to_le16(BIT_3);
 
 	/* Load SCSI command packet. */
@@ -3377,7 +3193,7 @@ qla1280_32bit_start_scsi(struct scsi_qla
 		(SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd);
 
 	/* Enable simple tag queuing if device supports it. */
-	if (DEV_SIMPLE_TAGS(cmd->device))
+	if (cmd->device->simple_tags)
 		pkt->control_flags |= cpu_to_le16(BIT_3);
 
 	/* Load SCSI command packet. */
@@ -3889,50 +3705,6 @@ qla1280_rst_aen(struct scsi_qla_host *ha
 }
 
 
-#if LINUX_VERSION_CODE < 0x020500
-/*
- *
- */
-static void
-qla1280_get_target_options(struct scsi_cmnd *cmd, struct scsi_qla_host *ha)
-{
-	unsigned char *result;
-	struct nvram *n;
-	int bus, target, lun;
-
-	bus = SCSI_BUS_32(cmd);
-	target = SCSI_TCN_32(cmd);
-	lun = SCSI_LUN_32(cmd);
-
-	/*
-	 * Make sure to not touch anything if someone is using the
-	 * sg interface.
-	 */
-	if (cmd->use_sg || (CMD_RESULT(cmd) >> 16) != DID_OK || lun)
-		return;
-
-	result = cmd->request_buffer;
-	n = &ha->nvram;
-
-	n->bus[bus].target[target].parameter.enable_wide = 0;
-	n->bus[bus].target[target].parameter.enable_sync = 0;
-	n->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 0;
-
-        if (result[7] & 0x60)
-		n->bus[bus].target[target].parameter.enable_wide = 1;
-        if (result[7] & 0x10)
-		n->bus[bus].target[target].parameter.enable_sync = 1;
-	if ((result[2] >= 3) && (result[4] + 5 > 56) &&
-	    (result[56] & 0x4))
-		n->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 1;
-
-	dprintk(2, "get_target_options(): wide %i, sync %i, ppr %i\n",
-		n->bus[bus].target[target].parameter.enable_wide,
-		n->bus[bus].target[target].parameter.enable_sync,
-		n->bus[bus].target[target].ppr_1x160.flags.enable_ppr);
-}
-#endif
-
 /*
  *  qla1280_status_entry
  *      Processes received ISP status entry.
@@ -4271,7 +4043,7 @@ qla1280_get_target_parameters(struct scs
 	} else
 		printk(" Async");
 
-	if (DEV_SIMPLE_TAGS(device))
+	if (device->simple_tags)
 		printk(", Tagged queuing: depth %d", device->queue_depth);
 	printk("\n");
 }
@@ -4485,7 +4257,7 @@ qla1280_get_token(char *str)
 	return ret;
 }
 
-#if LINUX_VERSION_CODE >= 0x020600
+
 static struct scsi_host_template qla1280_driver_template = {
 	.module			= THIS_MODULE,
 	.proc_name		= "qla1280",
@@ -4504,27 +4276,7 @@ static struct scsi_host_template qla1280
 	.cmd_per_lun		= 1,
 	.use_clustering		= ENABLE_CLUSTERING,
 };
-#else
-static struct scsi_host_template qla1280_driver_template = {
-	.proc_name		= "qla1280",
-	.name			= "Qlogic ISP 1280/12160",
-	.detect			= qla1280_detect,
-	.release		= qla1280_release,
-	.info			= qla1280_info,
-	.queuecommand		= qla1280_queuecommand,
-	.eh_abort_handler	= qla1280_eh_abort,
-	.eh_device_reset_handler= qla1280_eh_device_reset,
-	.eh_bus_reset_handler	= qla1280_eh_bus_reset,
-	.eh_host_reset_handler	= qla1280_eh_adapter_reset,
-	.bios_param		= qla1280_biosparam_old,
-	.can_queue		= 0xfffff,
-	.this_id		= -1,
-	.sg_tablesize		= SG_ALL,
-	.cmd_per_lun		= 1,
-	.use_clustering		= ENABLE_CLUSTERING,
-	.use_new_eh_code	= 1,
-};
-#endif
+
 
 static int __devinit
 qla1280_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -4615,10 +4367,6 @@ qla1280_probe_one(struct pci_dev *pdev, 
 	host->max_sectors = 1024;
 	host->unique_id = host->host_no;
 
-#if LINUX_VERSION_CODE < 0x020545
-	host->select_queue_depths = qla1280_select_queue_depth;
-#endif
-
 	error = -ENODEV;
 
 #if MEMORY_MAPPED_IO
@@ -4666,21 +4414,15 @@ qla1280_probe_one(struct pci_dev *pdev, 
 
 	pci_set_drvdata(pdev, host);
 
-#if LINUX_VERSION_CODE >= 0x020600
 	error = scsi_add_host(host, &pdev->dev);
 	if (error)
 		goto error_disable_adapter;
 	scsi_scan_host(host);
-#else
-	scsi_set_pci_device(host, pdev);
-#endif
 
 	return 0;
 
-#if LINUX_VERSION_CODE >= 0x020600
  error_disable_adapter:
 	qla1280_disable_intrs(ha);
-#endif
  error_free_irq:
 	free_irq(pdev->irq, ha);
  error_release_region:
@@ -4712,9 +4454,7 @@ qla1280_remove_one(struct pci_dev *pdev)
 	struct Scsi_Host *host = pci_get_drvdata(pdev);
 	struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata;
 
-#if LINUX_VERSION_CODE >= 0x020600
 	scsi_remove_host(host);
-#endif
 
 	qla1280_disable_intrs(ha);
 
@@ -4738,7 +4478,6 @@ qla1280_remove_one(struct pci_dev *pdev)
 	scsi_host_put(host);
 }
 
-#if LINUX_VERSION_CODE >= 0x020600
 static struct pci_driver qla1280_pci_driver = {
 	.name		= "qla1280",
 	.id_table	= qla1280_pci_tbl,
@@ -4784,10 +4523,6 @@ qla1280_exit(void)
 module_init(qla1280_init);
 module_exit(qla1280_exit);
 
-#else
-# define driver_template qla1280_driver_template
-# include "scsi_module.c"
-#endif
 
 MODULE_AUTHOR("Qlogic & Jes Sorensen");
 MODULE_DESCRIPTION("Qlogic ISP SCSI (qla1x80/qla1x160) driver");
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 79d8a91..bad066e 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -1680,7 +1680,8 @@ typedef struct fc_port {
 	uint8_t mp_byte;		/* multi-path byte (not used) */
     	uint8_t cur_path;		/* current path id */
 
-	struct fc_rport *rport;
+	spinlock_t rport_lock;
+	struct fc_rport *rport, *drport;
 	u32 supported_classes;
 	struct work_struct rport_add_work;
 	struct work_struct rport_del_work;
@@ -2270,6 +2271,7 @@ typedef struct scsi_qla_host {
 #define LOOP_RESET_NEEDED	24
 #define BEACON_BLINK_NEEDED	25
 #define REGISTER_FDMI_NEEDED	26
+#define FCPORT_UPDATE_NEEDED	27
 
 	uint32_t	device_flags;
 #define DFLG_LOCAL_DEVICES		BIT_0
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 32be4c1..35266bd 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -47,9 +47,11 @@ extern int qla2x00_local_device_login(sc
 extern void qla2x00_restart_queues(scsi_qla_host_t *, uint8_t);
 
 extern void qla2x00_rescan_fcports(scsi_qla_host_t *);
+extern void qla2x00_update_fcports(scsi_qla_host_t *);
 
 extern int qla2x00_abort_isp(scsi_qla_host_t *);
 
+extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);
 extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *);
 
 /*
@@ -70,8 +72,8 @@ extern char *qla2x00_get_fw_version_str(
 
 extern void qla2x00_cmd_timeout(srb_t *);
 
-extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int);
-extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *);
+extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int);
+extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int);
 
 extern void qla2x00_blink_led(scsi_qla_host_t *);
 
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index a91fea6..e67bb09 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -32,7 +32,6 @@ static int qla2x00_fw_ready(scsi_qla_hos
 static int qla2x00_configure_hba(scsi_qla_host_t *);
 static int qla2x00_configure_loop(scsi_qla_host_t *);
 static int qla2x00_configure_local_loop(scsi_qla_host_t *);
-static void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);
 static int qla2x00_configure_fabric(scsi_qla_host_t *);
 static int qla2x00_find_all_fabric_devs(scsi_qla_host_t *, struct list_head *);
 static int qla2x00_device_resync(scsi_qla_host_t *);
@@ -1688,10 +1687,16 @@ static void
 qla2x00_rport_del(void *data)
 {
 	fc_port_t *fcport = data;
+	struct fc_rport *rport;
+	unsigned long flags;
+
+	spin_lock_irqsave(&fcport->rport_lock, flags);
+	rport = fcport->drport;
+	fcport->drport = NULL;
+	spin_unlock_irqrestore(&fcport->rport_lock, flags);
+	if (rport)
+		fc_remote_port_delete(rport);
 
-	if (fcport->rport)
-		fc_remote_port_delete(fcport->rport);
-	fcport->rport = NULL;
 }
 
 /**
@@ -1719,6 +1724,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha
 	atomic_set(&fcport->state, FCS_UNCONFIGURED);
 	fcport->flags = FCF_RLC_SUPPORT;
 	fcport->supported_classes = FC_COS_UNSPECIFIED;
+	spin_lock_init(&fcport->rport_lock);
 	INIT_WORK(&fcport->rport_add_work, qla2x00_rport_add, fcport);
 	INIT_WORK(&fcport->rport_del_work, qla2x00_rport_del, fcport);
 
@@ -2008,7 +2014,7 @@ qla2x00_probe_for_all_luns(scsi_qla_host
 {
 	fc_port_t	*fcport;
 
-	qla2x00_mark_all_devices_lost(ha);
+	qla2x00_mark_all_devices_lost(ha, 0);
  	list_for_each_entry(fcport, &ha->fcports, list) {
 		if (fcport->port_type != FCT_TARGET)
 			continue;
@@ -2032,13 +2038,9 @@ qla2x00_probe_for_all_luns(scsi_qla_host
  * Context:
  *	Kernel context.
  */
-static void
+void
 qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport)
 {
-	uint16_t	index;
-	unsigned long flags;
-	srb_t *sp;
-
 	fcport->ha = ha;
 	fcport->login_retry = 0;
 	fcport->port_login_retry_count = ha->port_down_retry_count *
@@ -2047,28 +2049,6 @@ qla2x00_update_fcport(scsi_qla_host_t *h
 	    PORT_RETRY_TIME);
 	fcport->flags &= ~FCF_LOGIN_NEEDED;
 
-	/*
-	 * Check for outstanding cmd on tape Bypass LUN discovery if active
-	 * command on tape.
-	 */
-	if (fcport->flags & FCF_TAPE_PRESENT) {
-		spin_lock_irqsave(&ha->hardware_lock, flags);
-		for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
-			fc_port_t *sfcp;
-
-			if ((sp = ha->outstanding_cmds[index]) != 0) {
-				sfcp = sp->fcport;
-				if (sfcp == fcport) {
-					atomic_set(&fcport->state, FCS_ONLINE);
-					spin_unlock_irqrestore(
-					    &ha->hardware_lock, flags);
-					return;
-				}
-			}
-		}
-		spin_unlock_irqrestore(&ha->hardware_lock, flags);
-	}
-
 	if (fcport->port_type == FCT_INITIATOR ||
 	    fcport->port_type == FCT_BROADCAST)
 		fcport->device_type = TYPE_PROCESSOR;
@@ -2084,24 +2064,29 @@ qla2x00_reg_remote_port(scsi_qla_host_t 
 {
 	struct fc_rport_identifiers rport_ids;
 	struct fc_rport *rport;
+	unsigned long flags;
 
-	if (fcport->rport) {
-		fc_remote_port_delete(fcport->rport);
-		fcport->rport = NULL;
-	}
+	if (fcport->drport)
+		qla2x00_rport_del(fcport);
+	if (fcport->rport)
+		return;
 
 	rport_ids.node_name = wwn_to_u64(fcport->node_name);
 	rport_ids.port_name = wwn_to_u64(fcport->port_name);
 	rport_ids.port_id = fcport->d_id.b.domain << 16 |
 	    fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa;
 	rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
-	fcport->rport = rport = fc_remote_port_add(ha->host, 0, &rport_ids);
+	rport = fc_remote_port_add(ha->host, 0, &rport_ids);
 	if (!rport) {
 		qla_printk(KERN_WARNING, ha,
 		    "Unable to allocate fc remote port!\n");
 		return;
 	}
+	spin_lock_irqsave(&fcport->rport_lock, flags);
+	fcport->rport = rport;
 	*((fc_port_t **)rport->dd_data) = fcport;
+	spin_unlock_irqrestore(&fcport->rport_lock, flags);
+
 	rport->supported_classes = fcport->supported_classes;
 
 	rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
@@ -2217,12 +2202,11 @@ qla2x00_configure_fabric(scsi_qla_host_t
 
 			if (atomic_read(&fcport->state) == FCS_DEVICE_LOST) {
 				qla2x00_mark_device_lost(ha, fcport,
-				    ql2xplogiabsentdevice);
+				    ql2xplogiabsentdevice, 0);
 				if (fcport->loop_id != FC_NO_LOOP_ID &&
 				    (fcport->flags & FCF_TAPE_PRESENT) == 0 &&
 				    fcport->port_type != FCT_INITIATOR &&
 				    fcport->port_type != FCT_BROADCAST) {
-
 					ha->isp_ops.fabric_logout(ha,
 					    fcport->loop_id,
 					    fcport->d_id.b.domain,
@@ -2694,7 +2678,8 @@ qla2x00_device_resync(scsi_qla_host_t *h
 			if (atomic_read(&fcport->state) == FCS_ONLINE) {
 				if (format != 3 ||
 				    fcport->port_type != FCT_INITIATOR) {
-					qla2x00_mark_device_lost(ha, fcport, 0);
+					qla2x00_mark_device_lost(ha, fcport,
+					    0, 0);
 				}
 			}
 			fcport->flags &= ~FCF_FARP_DONE;
@@ -2741,8 +2726,7 @@ qla2x00_fabric_dev_login(scsi_qla_host_t
 			ha->isp_ops.fabric_logout(ha, fcport->loop_id,
 			    fcport->d_id.b.domain, fcport->d_id.b.area,
 			    fcport->d_id.b.al_pa);
-			qla2x00_mark_device_lost(ha, fcport, 1);
-
+			qla2x00_mark_device_lost(ha, fcport, 1, 0);
 		} else {
 			qla2x00_update_fcport(ha, fcport);
 		}
@@ -2855,7 +2839,7 @@ qla2x00_fabric_login(scsi_qla_host_t *ha
 			ha->isp_ops.fabric_logout(ha, fcport->loop_id,
 			    fcport->d_id.b.domain, fcport->d_id.b.area,
 			    fcport->d_id.b.al_pa);
-			qla2x00_mark_device_lost(ha, fcport, 1);
+			qla2x00_mark_device_lost(ha, fcport, 1, 0);
 
 			rval = 1;
 			break;
@@ -2990,6 +2974,17 @@ qla2x00_rescan_fcports(scsi_qla_host_t *
 	qla2x00_probe_for_all_luns(ha);
 }
 
+void
+qla2x00_update_fcports(scsi_qla_host_t *ha)
+{
+	fc_port_t *fcport;
+
+	/* Go with deferred removal of rport references. */
+	list_for_each_entry(fcport, &ha->fcports, list)
+		if (fcport->drport)
+			qla2x00_rport_del(fcport);
+}
+
 /*
 *  qla2x00_abort_isp
 *      Resets ISP and aborts all outstanding commands.
@@ -3019,7 +3014,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
 		atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
 		if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
 			atomic_set(&ha->loop_state, LOOP_DOWN);
-			qla2x00_mark_all_devices_lost(ha);
+			qla2x00_mark_all_devices_lost(ha, 0);
 		} else {
 			if (!atomic_read(&ha->loop_down_timer))
 				atomic_set(&ha->loop_down_timer,
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index f63af08..71a46fc 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -389,7 +389,7 @@ qla2x00_async_event(scsi_qla_host_t *ha,
 		if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
 			atomic_set(&ha->loop_state, LOOP_DOWN);
 			atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
-			qla2x00_mark_all_devices_lost(ha);
+			qla2x00_mark_all_devices_lost(ha, 1);
 		}
 
 		set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags);
@@ -432,7 +432,7 @@ qla2x00_async_event(scsi_qla_host_t *ha,
 			atomic_set(&ha->loop_state, LOOP_DOWN);
 			atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
 			ha->device_flags |= DFLG_NO_CABLE;
-			qla2x00_mark_all_devices_lost(ha);
+			qla2x00_mark_all_devices_lost(ha, 1);
 		}
 
 		ha->flags.management_server_logged_in = 0;
@@ -453,7 +453,7 @@ qla2x00_async_event(scsi_qla_host_t *ha,
 		if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
 			atomic_set(&ha->loop_state, LOOP_DOWN);
 			atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
-			qla2x00_mark_all_devices_lost(ha);
+			qla2x00_mark_all_devices_lost(ha, 1);
 		}
 
 		set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
@@ -482,7 +482,7 @@ qla2x00_async_event(scsi_qla_host_t *ha,
 			if (!atomic_read(&ha->loop_down_timer))
 				atomic_set(&ha->loop_down_timer,
 				    LOOP_DOWN_TIME);
-			qla2x00_mark_all_devices_lost(ha);
+			qla2x00_mark_all_devices_lost(ha, 1);
 		}
 
 		if (!(test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags))) {
@@ -506,7 +506,7 @@ qla2x00_async_event(scsi_qla_host_t *ha,
 			if (!atomic_read(&ha->loop_down_timer))
 				atomic_set(&ha->loop_down_timer,
 				    LOOP_DOWN_TIME);
-			qla2x00_mark_all_devices_lost(ha);
+			qla2x00_mark_all_devices_lost(ha, 1);
 		}
 
 		set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
@@ -580,7 +580,7 @@ qla2x00_async_event(scsi_qla_host_t *ha,
 		 */
 		atomic_set(&ha->loop_state, LOOP_UP);
 
-		qla2x00_mark_all_devices_lost(ha);
+		qla2x00_mark_all_devices_lost(ha, 1);
 
 		ha->flags.rscn_queue_overflow = 1;
 
@@ -1091,7 +1091,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha
 
 		cp->result = DID_BUS_BUSY << 16;
 		if (atomic_read(&fcport->state) == FCS_ONLINE) {
-			qla2x00_mark_device_lost(ha, fcport, 1);
+			qla2x00_mark_device_lost(ha, fcport, 1, 1);
 		}
 		break;
 
@@ -1135,7 +1135,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha
 
 		/* Check to see if logout occurred. */
 		if ((le16_to_cpu(sts->status_flags) & SF_LOGOUT_SENT))
-			qla2x00_mark_device_lost(ha, fcport, 1);
+			qla2x00_mark_device_lost(ha, fcport, 1, 1);
 		break;
 
 	case CS_QUEUE_FULL:
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 4916847..5866a7c 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -756,7 +756,7 @@ qla2xxx_eh_device_reset(struct scsi_cmnd
 		if (ret == SUCCESS) {
 			if (fcport->flags & FC_FABRIC_DEVICE) {
 				ha->isp_ops.fabric_logout(ha, fcport->loop_id);
-				qla2x00_mark_device_lost(ha, fcport);
+				qla2x00_mark_device_lost(ha, fcport, 0, 0);
 			}
 		}
 #endif
@@ -1642,6 +1642,31 @@ qla2x00_free_device(scsi_qla_host_t *ha)
 	pci_disable_device(ha->pdev);
 }
 
+static inline void
+qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport,
+    int defer)
+{
+	unsigned long flags;
+	struct fc_rport *rport;
+
+	if (!fcport->rport)
+		return;
+
+	rport = fcport->rport;
+	if (defer) {
+		spin_lock_irqsave(&fcport->rport_lock, flags);
+		fcport->drport = rport;
+		fcport->rport = NULL;
+		spin_unlock_irqrestore(&fcport->rport_lock, flags);
+		set_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags);
+	} else {
+		spin_lock_irqsave(&fcport->rport_lock, flags);
+		fcport->rport = NULL;
+		spin_unlock_irqrestore(&fcport->rport_lock, flags);
+		fc_remote_port_delete(rport);
+	}
+}
+
 /*
  * qla2x00_mark_device_lost Updates fcport state when device goes offline.
  *
@@ -1652,10 +1677,10 @@ qla2x00_free_device(scsi_qla_host_t *ha)
  * Context:
  */
 void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport,
-    int do_login)
+    int do_login, int defer)
 {
-	if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport)
-		schedule_work(&fcport->rport_del_work);
+	if (atomic_read(&fcport->state) == FCS_ONLINE)
+		qla2x00_schedule_rport_del(ha, fcport, defer);
 
 	/*
 	 * We may need to retry the login, so don't change the state of the
@@ -1702,7 +1727,7 @@ void qla2x00_mark_device_lost(scsi_qla_h
  * Context:
  */
 void
-qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha)
+qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer)
 {
 	fc_port_t *fcport;
 
@@ -1716,10 +1741,13 @@ qla2x00_mark_all_devices_lost(scsi_qla_h
 		 */
 		if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)
 			continue;
-		if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport)
-			schedule_work(&fcport->rport_del_work);
+		if (atomic_read(&fcport->state) == FCS_ONLINE)
+			qla2x00_schedule_rport_del(ha, fcport, defer);
 		atomic_set(&fcport->state, FCS_DEVICE_LOST);
 	}
+
+	if (defer && ha->dpc_wait && !ha->dpc_active)
+		up(ha->dpc_wait);
 }
 
 /*
@@ -2161,6 +2189,9 @@ qla2x00_do_dpc(void *data)
 			    ha->host_no));
 		}
 
+		if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags))
+			qla2x00_update_fcports(ha);
+
 		if (test_and_clear_bit(LOOP_RESET_NEEDED, &ha->dpc_flags)) {
 			DEBUG(printk("scsi(%ld): dpc: sched loop_reset()\n",
 			    ha->host_no));
@@ -2219,13 +2250,8 @@ qla2x00_do_dpc(void *data)
 						DEBUG(printk("scsi(%ld): port login OK: logged in ID 0x%x\n",
 						    ha->host_no, fcport->loop_id));
 
-						fcport->port_login_retry_count =
-						    ha->port_down_retry_count * PORT_RETRY_TIME;
-						atomic_set(&fcport->state, FCS_ONLINE);
-						atomic_set(&fcport->port_down_timer,
-						    ha->port_down_retry_count * PORT_RETRY_TIME);
-
-						fcport->login_retry = 0;
+						qla2x00_update_fcport(ha,
+						    fcport);
 					} else if (status == 1) {
 						set_bit(RELOGIN_NEEDED, &ha->dpc_flags);
 						/* retry the login again */
@@ -2469,6 +2495,7 @@ qla2x00_timer(scsi_qla_host_t *ha)
 	if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) ||
 	    test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) ||
 	    test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags) ||
+	    test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags) ||
 	    start_dpc ||
 	    test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) ||
 	    test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) ||
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index 3d1ea09..b0b0a69 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -66,6 +66,7 @@ enum {
 	board_2037x		= 0,	/* FastTrak S150 TX2plus */
 	board_20319		= 1,	/* FastTrak S150 TX4 */
 	board_20619		= 2,	/* FastTrak TX4000 */
+	board_20771		= 3,	/* FastTrak TX2300 */
 
 	PDC_HAS_PATA		= (1 << 1), /* PDC20375 has PATA */
 
@@ -190,6 +191,16 @@ static const struct ata_port_info pdc_po
 		.udma_mask	= 0x7f, /* udma0-6 ; FIXME */
 		.port_ops	= &pdc_pata_ops,
 	},
+
+	/* board_20771 */
+	{
+		.sht		= &pdc_ata_sht,
+		.host_flags	= PDC_COMMON_FLAGS | ATA_FLAG_SATA,
+		.pio_mask	= 0x1f, /* pio0-4 */
+		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.udma_mask	= 0x7f, /* udma0-6 ; FIXME */
+		.port_ops	= &pdc_sata_ops,
+	},
 };
 
 static const struct pci_device_id pdc_ata_pci_tbl[] = {
@@ -226,6 +237,8 @@ static const struct pci_device_id pdc_at
 	{ PCI_VENDOR_ID_PROMISE, 0x6629, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 	  board_20619 },
 
+	{ PCI_VENDOR_ID_PROMISE, 0x3570, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  board_20771 },
 	{ }	/* terminate list */
 };
 
@@ -706,6 +719,9 @@ static int pdc_ata_init_one (struct pci_
 	case board_2037x:
 		probe_ent->n_ports = 2;
 		break;
+	case board_20771:
+		probe_ent->n_ports = 2;
+		break;
 	case board_20619:
 		probe_ent->n_ports = 4;
 
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
index 6683735..d847256 100644
--- a/drivers/scsi/sata_svw.c
+++ b/drivers/scsi/sata_svw.c
@@ -470,6 +470,7 @@ static const struct pci_device_id k2_sat
 	{ 0x1166, 0x0241, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
 	{ 0x1166, 0x0242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
 	{ 0x1166, 0x024a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
+	{ 0x1166, 0x024b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
 	{ }
 };
 
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index a2333d2..5cc97b7 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -1350,7 +1350,7 @@ static void scsi_eh_lock_door(struct scs
 	cmnd[4] = SCSI_REMOVAL_PREVENT;
 	cmnd[5] = 0;
 
-	scsi_execute_async(sdev, cmnd, DMA_NONE, NULL, 0, 0, 10 * HZ,
+	scsi_execute_async(sdev, cmnd, 6, DMA_NONE, NULL, 0, 0, 10 * HZ,
 			   5, NULL, NULL, GFP_KERNEL);
 }
 
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 3574ba9..4a60285 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -436,6 +436,7 @@ free_bios:
  * scsi_execute_async - insert request
  * @sdev:	scsi device
  * @cmd:	scsi command
+ * @cmd_len:	length of scsi cdb
  * @data_direction: data direction
  * @buffer:	data buffer (this can be a kernel buffer or scatterlist)
  * @bufflen:	len of buffer
@@ -445,7 +446,7 @@ free_bios:
  * @flags:	or into request flags
  **/
 int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd,
-		       int data_direction, void *buffer, unsigned bufflen,
+		       int cmd_len, int data_direction, void *buffer, unsigned bufflen,
 		       int use_sg, int timeout, int retries, void *privdata,
 		       void (*done)(void *, char *, int, int), gfp_t gfp)
 {
@@ -472,7 +473,7 @@ int scsi_execute_async(struct scsi_devic
 	if (err)
 		goto free_req;
 
-	req->cmd_len = COMMAND_SIZE(cmd[0]);
+	req->cmd_len = cmd_len;
 	memcpy(req->cmd, cmd, req->cmd_len);
 	req->sense = sioc->sense;
 	req->sense_len = 0;
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index a3e0b7b..210dab5 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -377,7 +377,7 @@ static void sas_phy_release(struct devic
 /**
  * sas_phy_alloc  --  allocates and initialize a SAS PHY structure
  * @parent:	Parent device
- * @number:	Port number
+ * @number:	Phy index
  *
  * Allocates an SAS PHY structure.  It will be added in the device tree
  * below the device specified by @parent, which has to be either a Scsi_Host
@@ -595,8 +595,8 @@ struct sas_rphy *sas_rphy_alloc(struct s
 	device_initialize(&rphy->dev);
 	rphy->dev.parent = get_device(&parent->dev);
 	rphy->dev.release = sas_rphy_release;
-	sprintf(rphy->dev.bus_id, "rphy-%d:%d",
-		shost->host_no, parent->number);
+	sprintf(rphy->dev.bus_id, "rphy-%d:%d-%d",
+		shost->host_no, parent->port_identifier, parent->number);
 	transport_setup_device(&rphy->dev);
 
 	return rphy;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 78aad95..7d07000 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -741,7 +741,7 @@ sg_common_write(Sg_fd * sfp, Sg_request 
 	hp->duration = jiffies_to_msecs(jiffies);
 /* Now send everything of to mid-level. The next time we hear about this
    packet is when sg_cmd_done() is called (i.e. a callback). */
-	if (scsi_execute_async(sdp->device, cmnd, data_dir, srp->data.buffer,
+	if (scsi_execute_async(sdp->device, cmnd, hp->cmd_len, data_dir, srp->data.buffer,
 				hp->dxfer_len, srp->data.k_use_sg, timeout,
 				SG_DEFAULT_RETRIES, srp, sg_cmd_done,
 				GFP_ATOMIC)) {
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 13b1d3a..7f96f33 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -508,7 +508,7 @@ st_do_scsi(struct st_request * SRpnt, st
 	STp->buffer->cmdstat.have_sense = 0;
 	STp->buffer->syscall_result = 0;
 
-	if (scsi_execute_async(STp->device, cmd, direction,
+	if (scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), direction,
 			&((STp->buffer)->sg[0]), bytes, (STp->buffer)->sg_segs,
 			       timeout, retries, SRpnt, st_sleep_done, GFP_KERNEL)) {
 		/* could not allocate the buffer or request was too large */
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c
index 221999b..7aef751 100644
--- a/drivers/serial/21285.c
+++ b/drivers/serial/21285.c
@@ -366,7 +366,7 @@ static struct uart_port serial21285_port
 	.irq		= NO_IRQ,
 	.fifosize	= 16,
 	.ops		= &serial21285_ops,
-	.flags		= ASYNC_BOOT_AUTOCONF,
+	.flags		= UPF_BOOT_AUTOCONF,
 };
 
 static void serial21285_setup_ports(void)
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index d9ce8c5..179c1f0 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -31,7 +31,6 @@
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/sysrq.h>
-#include <linux/mca.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/tty.h>
@@ -2027,12 +2026,6 @@ static void serial8250_config_port(struc
 	int ret;
 
 	/*
-	 * Don't probe for MCA ports on non-MCA machines.
-	 */
-	if (up->port.flags & UPF_BOOT_ONLYMCA && !MCA_bus)
-		return;
-
-	/*
 	 * Find the region that we can probe for.  This in turn
 	 * tells us whether we can probe for the type of port.
 	 */
@@ -2164,7 +2157,7 @@ serial8250_register_ports(struct uart_dr
 /*
  *	Wait for transmitter & holding register to empty
  */
-static inline void wait_for_xmitr(struct uart_8250_port *up)
+static inline void wait_for_xmitr(struct uart_8250_port *up, int bits)
 {
 	unsigned int status, tmout = 10000;
 
@@ -2178,7 +2171,7 @@ static inline void wait_for_xmitr(struct
 		if (--tmout == 0)
 			break;
 		udelay(1);
-	} while ((status & BOTH_EMPTY) != BOTH_EMPTY);
+	} while ((status & bits) != bits);
 
 	/* Wait up to 1s for flow control if necessary */
 	if (up->port.flags & UPF_CONS_FLOW) {
@@ -2218,7 +2211,7 @@ serial8250_console_write(struct console 
 	 *	Now, do each character
 	 */
 	for (i = 0; i < count; i++, s++) {
-		wait_for_xmitr(up);
+		wait_for_xmitr(up, UART_LSR_THRE);
 
 		/*
 		 *	Send the character out.
@@ -2226,7 +2219,7 @@ serial8250_console_write(struct console 
 		 */
 		serial_out(up, UART_TX, *s);
 		if (*s == 10) {
-			wait_for_xmitr(up);
+			wait_for_xmitr(up, UART_LSR_THRE);
 			serial_out(up, UART_TX, 13);
 		}
 	}
@@ -2235,8 +2228,8 @@ serial8250_console_write(struct console 
 	 *	Finally, wait for transmitter to become empty
 	 *	and restore the IER
 	 */
-	wait_for_xmitr(up);
-	serial_out(up, UART_IER, ier);
+	wait_for_xmitr(up, BOTH_EMPTY);
+	serial_out(up, UART_IER, ier | UART_IER_THRI);
 }
 
 static int serial8250_console_setup(struct console *co, char *options)
@@ -2595,15 +2588,11 @@ static int __init serial8250_init(void)
 	if (ret)
 		goto out;
 
-	ret = platform_driver_register(&serial8250_isa_driver);
-	if (ret)
-		goto unreg_uart_drv;
-
 	serial8250_isa_devs = platform_device_alloc("serial8250",
 						    PLAT8250_DEV_LEGACY);
 	if (!serial8250_isa_devs) {
 		ret = -ENOMEM;
-		goto unreg_plat_drv;
+		goto unreg_uart_drv;
 	}
 
 	ret = platform_device_add(serial8250_isa_devs);
@@ -2612,12 +2601,13 @@ static int __init serial8250_init(void)
 
 	serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);
 
-	goto out;
+	ret = platform_driver_register(&serial8250_isa_driver);
+	if (ret == 0)
+		goto out;
 
+	platform_device_del(serial8250_isa_devs);
  put_dev:
 	platform_device_put(serial8250_isa_devs);
- unreg_plat_drv:
-	platform_driver_unregister(&serial8250_isa_driver);
  unreg_uart_drv:
 	uart_unregister_driver(&serial8250_reg);
  out:
diff --git a/drivers/serial/8250_acpi.c b/drivers/serial/8250_acpi.c
index a802bdc..809f89a 100644
--- a/drivers/serial/8250_acpi.c
+++ b/drivers/serial/8250_acpi.c
@@ -27,7 +27,7 @@ struct serial_private {
 static acpi_status acpi_serial_mmio(struct uart_port *port,
 				    struct acpi_resource_address64 *addr)
 {
-	port->mapbase = addr->min_address_range;
+	port->mapbase = addr->minimum;
 	port->iotype = UPIO_MEM;
 	port->flags |= UPF_IOREMAP;
 	return AE_OK;
@@ -36,8 +36,8 @@ static acpi_status acpi_serial_mmio(stru
 static acpi_status acpi_serial_port(struct uart_port *port,
 				    struct acpi_resource_io *io)
 {
-	if (io->range_length) {
-		port->iobase = io->min_base_address;
+	if (io->address_length) {
+		port->iobase = io->minimum;
 		port->iotype = UPIO_PORT;
 	} else
 		printk(KERN_ERR "%s: zero-length IO port range?\n", __FUNCTION__);
@@ -45,13 +45,13 @@ static acpi_status acpi_serial_port(stru
 }
 
 static acpi_status acpi_serial_ext_irq(struct uart_port *port,
-				       struct acpi_resource_ext_irq *ext_irq)
+				       struct acpi_resource_extended_irq *ext_irq)
 {
 	int rc;
 
-	if (ext_irq->number_of_interrupts > 0) {
+	if (ext_irq->interrupt_count > 0) {
 		rc = acpi_register_gsi(ext_irq->interrupts[0],
-	                   ext_irq->edge_level, ext_irq->active_high_low);
+	                   ext_irq->triggering, ext_irq->polarity);
 		if (rc < 0)
 			return AE_ERROR;
 		port->irq = rc;
@@ -64,9 +64,9 @@ static acpi_status acpi_serial_irq(struc
 {
 	int rc;
 
-	if (irq->number_of_interrupts > 0) {
+	if (irq->interrupt_count > 0) {
 		rc = acpi_register_gsi(irq->interrupts[0],
-	                   irq->edge_level, irq->active_high_low);
+	                   irq->triggering, irq->polarity);
 		if (rc < 0)
 			return AE_ERROR;
 		port->irq = rc;
@@ -83,11 +83,11 @@ static acpi_status acpi_serial_resource(
 	status = acpi_resource_to_address64(res, &addr);
 	if (ACPI_SUCCESS(status))
 		return acpi_serial_mmio(port, &addr);
-	else if (res->id == ACPI_RSTYPE_IO)
+	else if (res->type == ACPI_RESOURCE_TYPE_IO)
 		return acpi_serial_port(port, &res->data.io);
-	else if (res->id == ACPI_RSTYPE_EXT_IRQ)
+	else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ)
 		return acpi_serial_ext_irq(port, &res->data.extended_irq);
-	else if (res->id == ACPI_RSTYPE_IRQ)
+	else if (res->type == ACPI_RESOURCE_TYPE_IRQ)
 		return acpi_serial_irq(port, &res->data.irq);
 	return AE_OK;
 }
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 589fb07..2a91215 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -940,6 +940,7 @@ enum pci_board_num_t {
 	pbn_b2_bt_2_921600,
 	pbn_b2_bt_4_921600,
 
+	pbn_b3_2_115200,
 	pbn_b3_4_115200,
 	pbn_b3_8_115200,
 
@@ -1311,6 +1312,12 @@ static struct pciserial_board pci_boards
 		.uart_offset	= 8,
 	},
 
+	[pbn_b3_2_115200] = {
+		.flags		= FL_BASE3,
+		.num_ports	= 2,
+		.base_baud	= 115200,
+		.uart_offset	= 8,
+	},
 	[pbn_b3_4_115200] = {
 		.flags		= FL_BASE3,
 		.num_ports	= 4,
@@ -2272,6 +2279,9 @@ static struct pci_device_id serial_pci_t
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_nec_nile4 },
 
+	{	PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM2,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b3_2_115200 },
 	{	PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM4,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_b3_4_115200 },
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 5e7199f..0d38f0f 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -23,7 +23,7 @@ config SERIAL_8250
 	  work.)
 
 	  To compile this driver as a module, choose M here: the
-	  module will be called serial.
+	  module will be called 8250.
 	  [WARNING: Do not compile this driver as a module if you are using
 	  non-standard serial ports, since the configuration information will
 	  be lost when the driver is unloaded.  This limitation may be lifted
@@ -301,7 +301,7 @@ config SERIAL_AT91_TTYAT
 	depends on SERIAL_AT91=y
 	help
 	  Say Y here if you wish to have the five internal AT91RM9200 UARTs
-	  appear as /dev/ttyAT0-4 (major 240, minor 0-4) instead of the
+	  appear as /dev/ttyAT0-4 (major 204, minor 154-158) instead of the
 	  normal /dev/ttyS0-4 (major 4, minor 64-68). This is necessary if
 	  you also want other UARTs, such as external 8250/16C550 compatible
 	  UARTs.
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index 3490022..429de27 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -566,7 +566,7 @@ static struct uart_amba_port amba_ports[
 			.uartclk	= 14745600,
 			.fifosize	= 16,
 			.ops		= &amba_pl010_pops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 0,
 		},
 		.dtr_mask	= 1 << 5,
@@ -581,7 +581,7 @@ static struct uart_amba_port amba_ports[
 			.uartclk	= 14745600,
 			.fifosize	= 16,
 			.ops		= &amba_pl010_pops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 1,
 		},
 		.dtr_mask	= 1 << 7,
diff --git a/drivers/serial/at91_serial.c b/drivers/serial/at91_serial.c
index 0e20606..2113feb 100644
--- a/drivers/serial/at91_serial.c
+++ b/drivers/serial/at91_serial.c
@@ -222,8 +222,6 @@ static void at91_rx_chars(struct uart_po
 	while (status & (AT91_US_RXRDY)) {
 		ch = UART_GET_CHAR(port);
 
-		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-			goto ignore_char;
 		port->icount.rx++;
 
 		flg = TTY_NORMAL;
diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c
index 8ef9994..ce7b2e4 100644
--- a/drivers/serial/clps711x.c
+++ b/drivers/serial/clps711x.c
@@ -410,7 +410,7 @@ static struct uart_port clps711x_ports[U
 		.fifosize	= 16,
 		.ops		= &clps711x_pops,
 		.line		= 0,
-		.flags		= ASYNC_BOOT_AUTOCONF,
+		.flags		= UPF_BOOT_AUTOCONF,
 	},
 	{
 		.iobase		= SYSCON2,
@@ -419,7 +419,7 @@ static struct uart_port clps711x_ports[U
 		.fifosize	= 16,
 		.ops		= &clps711x_pops,
 		.line		= 1,
-		.flags		= ASYNC_BOOT_AUTOCONF,
+		.flags		= UPF_BOOT_AUTOCONF,
 	}
 };
 
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 587cc6a..858048e 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -402,10 +402,10 @@ static int imx_startup(struct uart_port 
 			     DRIVER_NAME, sport);
 	if (retval) goto error_out2;
 
-	retval = request_irq(sport->rtsirq, imx_rtsint, 0,
+	retval = request_irq(sport->rtsirq, imx_rtsint,
+			     SA_TRIGGER_FALLING | SA_TRIGGER_RISING,
 			     DRIVER_NAME, sport);
 	if (retval) goto error_out3;
-	set_irq_type(sport->rtsirq, IRQT_BOTHEDGE);
 
 	/*
 	 * Finally, clear and enable interrupts
@@ -674,7 +674,7 @@ static struct imx_port imx_ports[] = {
 		.irq		= UART1_MINT_RX,
 		.uartclk	= 16000000,
 		.fifosize	= 8,
-		.flags		= ASYNC_BOOT_AUTOCONF,
+		.flags		= UPF_BOOT_AUTOCONF,
 		.ops		= &imx_pops,
 		.line		= 0,
 	},
@@ -690,7 +690,7 @@ static struct imx_port imx_ports[] = {
 		.irq		= UART2_MINT_RX,
 		.uartclk	= 16000000,
 		.fifosize	= 8,
-		.flags		= ASYNC_BOOT_AUTOCONF,
+		.flags		= UPF_BOOT_AUTOCONF,
 		.ops		= &imx_pops,
 		.line		= 1,
 	},
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c
index 6f22b42..87e4e2c 100644
--- a/drivers/serial/jsm/jsm_neo.c
+++ b/drivers/serial/jsm/jsm_neo.c
@@ -965,56 +965,47 @@ static void neo_param(struct jsm_channel
 			baud = ch->ch_custom_speed;
 			if (ch->ch_flags & CH_BAUD0)
 				ch->ch_flags &= ~(CH_BAUD0);
-		} else {
-			int iindex = 0;
-			int jindex = 0;
+	} else {
+		int i;
+		unsigned int cflag;
+		static struct {
+			unsigned int rate;
+			unsigned int cflag;
+		} baud_rates[] = {
+			{ 921600, B921600 },
+			{ 460800, B460800 },
+			{ 230400, B230400 },
+			{ 115200, B115200 },
+			{  57600, B57600  },
+			{  38400, B38400  },
+			{  19200, B19200  },
+			{   9600, B9600   },
+			{   4800, B4800   },
+			{   2400, B2400   },
+			{   1200, B1200   },
+			{    600, B600    },
+			{    300, B300    },
+			{    200, B200    },
+			{    150, B150    },
+			{    134, B134    },
+			{    110, B110    },
+			{     75, B75     },
+			{     50, B50     },
+		};
 
-			const u64 bauds[4][16] = {
-				{
-					0,	50,	75,	110,
-					134,	150,	200,	300,
-					600,	1200,	1800,	2400,
-					4800,	9600,	19200,	38400 },
-				{
-					0,	57600,	115200, 230400,
-					460800, 150,	200,	921600,
-					600,	1200,	1800,	2400,
-					4800,	9600,	19200,	38400 },
-				{
-					0,	57600,	76800, 115200,
-					131657, 153600, 230400, 460800,
-					921600, 1200,	1800,	2400,
-					4800,	9600,	19200,	38400 },
-				{
-					0,	57600,	115200, 230400,
-					460800, 150,	200,	921600,
-					600,	1200,	1800,	2400,
-					4800,	9600,	19200,	38400 }
-			};
-
-			baud = C_BAUD(ch->uart_port.info->tty) & 0xff;
-
-			if (ch->ch_c_cflag & CBAUDEX)
-				iindex = 1;
-
-			jindex = baud;
-
-			if ((iindex >= 0) && (iindex < 4) && (jindex >= 0) && (jindex < 16))
-				baud = bauds[iindex][jindex];
-			else {
-				jsm_printk(IOCTL, DEBUG, &ch->ch_bd->pci_dev,
-					"baud indices were out of range (%d)(%d)",
-				iindex, jindex);
-				baud = 0;
+		cflag = C_BAUD(ch->uart_port.info->tty);
+		baud = 9600;
+		for (i = 0; i < ARRAY_SIZE(baud_rates); i++) {
+			if (baud_rates[i].cflag == cflag) {
+				baud = baud_rates[i].rate;
+				break;
 			}
-
-			if (baud == 0)
-				baud = 9600;
-
-			if (ch->ch_flags & CH_BAUD0)
-				ch->ch_flags &= ~(CH_BAUD0);
 		}
 
+		if (ch->ch_flags & CH_BAUD0)
+			ch->ch_flags &= ~(CH_BAUD0);
+	}
+
 	if (ch->ch_c_cflag & PARENB)
 		lcr |= UART_LCR_PARITY;
 
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index eb4883e..0a2dd6c 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -1060,7 +1060,7 @@ static int s3c24xx_serial_init_port(stru
 	dbg("resource %p (%lx..%lx)\n", res, res->start, res->end);
 
 	port->mapbase	= res->start;
-	port->membase	= S3C24XX_VA_UART + (res->start - S3C2410_PA_UART);
+	port->membase	= S3C24XX_VA_UART + (res->start - S3C24XX_PA_UART);
 	port->irq	= platform_get_irq(platdev, 0);
 
 	ourport->clk	= clk_get(&platdev->dev, "uart");
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index 1bd9316..ff7b60b 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -665,21 +665,21 @@ void __init sa1100_register_uart(int idx
 		sa1100_ports[idx].port.membase = (void __iomem *)&Ser1UTCR0;
 		sa1100_ports[idx].port.mapbase = _Ser1UTCR0;
 		sa1100_ports[idx].port.irq     = IRQ_Ser1UART;
-		sa1100_ports[idx].port.flags   = ASYNC_BOOT_AUTOCONF;
+		sa1100_ports[idx].port.flags   = UPF_BOOT_AUTOCONF;
 		break;
 
 	case 2:
 		sa1100_ports[idx].port.membase = (void __iomem *)&Ser2UTCR0;
 		sa1100_ports[idx].port.mapbase = _Ser2UTCR0;
 		sa1100_ports[idx].port.irq     = IRQ_Ser2ICP;
-		sa1100_ports[idx].port.flags   = ASYNC_BOOT_AUTOCONF;
+		sa1100_ports[idx].port.flags   = UPF_BOOT_AUTOCONF;
 		break;
 
 	case 3:
 		sa1100_ports[idx].port.membase = (void __iomem *)&Ser3UTCR0;
 		sa1100_ports[idx].port.mapbase = _Ser3UTCR0;
 		sa1100_ports[idx].port.irq     = IRQ_Ser3UART;
-		sa1100_ports[idx].port.flags   = ASYNC_BOOT_AUTOCONF;
+		sa1100_ports[idx].port.flags   = UPF_BOOT_AUTOCONF;
 		break;
 
 	default:
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 9437704..0717abf 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -332,7 +332,7 @@ uart_get_baud_rate(struct uart_port *por
 		   struct termios *old, unsigned int min, unsigned int max)
 {
 	unsigned int try, baud, altbaud = 38400;
-	unsigned int flags = port->flags & UPF_SPD_MASK;
+	upf_t flags = port->flags & UPF_SPD_MASK;
 
 	if (flags == UPF_SPD_HI)
 		altbaud = 57600;
@@ -615,8 +615,9 @@ static int uart_set_info(struct uart_sta
 	struct serial_struct new_serial;
 	struct uart_port *port = state->port;
 	unsigned long new_port;
-	unsigned int change_irq, change_port, old_flags, closing_wait;
+	unsigned int change_irq, change_port, closing_wait;
 	unsigned int old_custom_divisor, close_delay;
+	upf_t old_flags, new_flags;
 	int retval = 0;
 
 	if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
@@ -655,6 +656,7 @@ static int uart_set_info(struct uart_sta
 		      new_serial.type != port->type;
 
 	old_flags = port->flags;
+	new_flags = new_serial.flags;
 	old_custom_divisor = port->custom_divisor;
 
 	if (!capable(CAP_SYS_ADMIN)) {
@@ -664,10 +666,10 @@ static int uart_set_info(struct uart_sta
 		    (close_delay != state->close_delay) ||
 		    (closing_wait != state->closing_wait) ||
 		    (new_serial.xmit_fifo_size != port->fifosize) ||
-		    (((new_serial.flags ^ old_flags) & ~UPF_USR_MASK) != 0))
+		    (((new_flags ^ old_flags) & ~UPF_USR_MASK) != 0))
 			goto exit;
 		port->flags = ((port->flags & ~UPF_USR_MASK) |
-			       (new_serial.flags & UPF_USR_MASK));
+			       (new_flags & UPF_USR_MASK));
 		port->custom_divisor = new_serial.custom_divisor;
 		goto check_and_exit;
 	}
@@ -764,7 +766,7 @@ static int uart_set_info(struct uart_sta
 	port->irq              = new_serial.irq;
 	port->uartclk          = new_serial.baud_base * 16;
 	port->flags            = (port->flags & ~UPF_CHANGE_MASK) |
-				 (new_serial.flags & UPF_CHANGE_MASK);
+				 (new_flags & UPF_CHANGE_MASK);
 	port->custom_divisor   = new_serial.custom_divisor;
 	state->close_delay     = close_delay;
 	state->closing_wait    = closing_wait;
@@ -1870,7 +1872,7 @@ int uart_suspend_port(struct uart_driver
 	mutex_lock(&state->mutex);
 
 	if (state->info && state->info->flags & UIF_INITIALIZED) {
-		struct uart_ops *ops = port->ops;
+		const struct uart_ops *ops = port->ops;
 
 		spin_lock_irq(&port->lock);
 		ops->stop_tx(port);
@@ -1932,7 +1934,7 @@ int uart_resume_port(struct uart_driver 
 	}
 
 	if (state->info && state->info->flags & UIF_INITIALIZED) {
-		struct uart_ops *ops = port->ops;
+		const struct uart_ops *ops = port->ops;
 		int ret;
 
 		ops->set_mctrl(port, 0);
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c
index d4a1f0e..d0490f6 100644
--- a/drivers/serial/serial_lh7a40x.c
+++ b/drivers/serial/serial_lh7a40x.c
@@ -506,7 +506,7 @@ static struct uart_port_lh7a40x lh7a40x_
 			.uartclk	= 14745600/2,
 			.fifosize	= 16,
 			.ops		= &lh7a40x_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 0,
 		},
 	},
@@ -519,7 +519,7 @@ static struct uart_port_lh7a40x lh7a40x_
 			.uartclk	= 14745600/2,
 			.fifosize	= 16,
 			.ops		= &lh7a40x_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 1,
 		},
 	},
@@ -532,7 +532,7 @@ static struct uart_port_lh7a40x lh7a40x_
 			.uartclk	= 14745600/2,
 			.fifosize	= 16,
 			.ops		= &lh7a40x_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 2,
 		},
 	},
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index a9e0707..80737c1 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -42,6 +42,7 @@
 #include <linux/delay.h>
 #include <linux/console.h>
 #include <linux/bitops.h>
+#include <linux/generic_serial.h>
 
 #ifdef CONFIG_CPU_FREQ
 #include <linux/notifier.h>
@@ -53,7 +54,9 @@
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
-#include <linux/generic_serial.h>
+#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
+#include <asm/clock.h>
+#endif
 
 #ifdef CONFIG_SH_STANDARD_BIOS
 #include <asm/sh_bios.h>
@@ -86,9 +89,11 @@ static void sci_stop_rx(struct uart_port
 static int sci_request_irq(struct sci_port *port);
 static void sci_free_irq(struct sci_port *port);
 
-static struct sci_port sci_ports[SCI_NPORTS];
+static struct sci_port sci_ports[];
 static struct uart_driver sci_uart_driver;
 
+#define SCI_NPORTS sci_uart_driver.nr
+
 #if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
 
 static void handle_error(struct uart_port *port)
@@ -168,7 +173,7 @@ static void put_string(struct sci_port *
 	int usegdb=0;
 
 #ifdef CONFIG_SH_STANDARD_BIOS
-    	/* This call only does a trap the first time it is
+	/* This call only does a trap the first time it is
 	 * called, and so is safe to do here unconditionally
 	 */
 	usegdb |= sh_bios_in_gdb_mode();
@@ -324,47 +329,46 @@ static void sci_init_pins_sci(struct uar
 	/* tx mark output*/
 	H8300_SCI_DR(ch) |= h8300_sci_pins[ch].tx;
 }
-#else
-static void sci_init_pins_sci(struct uart_port *port, unsigned int cflag)
-{
-}
 #endif
 #endif
 
 #if defined(SCIF_ONLY) || defined(SCI_AND_SCIF)
-#if defined(CONFIG_CPU_SH3)
-/* For SH7705, SH7707, SH7709, SH7709A, SH7729, SH7300*/
+#if defined(CONFIG_CPU_SUBTYPE_SH7300)
+/* SH7300 doesn't use RTS/CTS */
+static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
+{
+	sci_out(port, SCFCR, 0);
+}
+#elif defined(CONFIG_CPU_SH3)
+/* For SH7705, SH7707, SH7709, SH7709A, SH7729 */
 static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
 {
 	unsigned int fcr_val = 0;
-#if !defined(CONFIG_CPU_SUBTYPE_SH7300) /* SH7300 doesn't use RTS/CTS */
-	{
-		unsigned short data;
+	unsigned short data;
+
+	/* We need to set SCPCR to enable RTS/CTS */
+	data = ctrl_inw(SCPCR);
+	/* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/
+	ctrl_outw(data & 0x0fcf, SCPCR);
 
-		/* We need to set SCPCR to enable RTS/CTS */
-		data = ctrl_inw(SCPCR);
-		/* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/
-		ctrl_outw(data&0x0fcf, SCPCR);
-	}
 	if (cflag & CRTSCTS)
 		fcr_val |= SCFCR_MCE;
 	else {
-		unsigned short data;
-
 		/* We need to set SCPCR to enable RTS/CTS */
 		data = ctrl_inw(SCPCR);
 		/* Clear out SCP7MD1,0, SCP4MD1,0,
 		   Set SCP6MD1,0 = {01} (output)  */
-		ctrl_outw((data&0x0fcf)|0x1000, SCPCR);
+		ctrl_outw((data & 0x0fcf) | 0x1000, SCPCR);
 
 		data = ctrl_inb(SCPDR);
 		/* Set /RTS2 (bit6) = 0 */
-		ctrl_outb(data&0xbf, SCPDR);
+		ctrl_outb(data & 0xbf, SCPDR);
 	}
-#endif
+
 	sci_out(port, SCFCR, fcr_val);
 }
 
+#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
 static void sci_init_pins_irda(struct uart_port *port, unsigned int cflag)
 {
 	unsigned int fcr_val = 0;
@@ -374,7 +378,7 @@ static void sci_init_pins_irda(struct ua
 
 	sci_out(port, SCFCR, fcr_val);
 }
-
+#endif
 #else
 
 /* For SH7750 */
@@ -385,7 +389,11 @@ static void sci_init_pins_scif(struct ua
 	if (cflag & CRTSCTS) {
 		fcr_val |= SCFCR_MCE;
 	} else {
+#ifdef CONFIG_CPU_SUBTYPE_SH7780
+		ctrl_outw(0x0080, SCSPTR0); /* Set RTS = 1 */
+#else
 		ctrl_outw(0x0080, SCSPTR2); /* Set RTS = 1 */
+#endif
 	}
 	sci_out(port, SCFCR, fcr_val);
 }
@@ -422,7 +430,11 @@ static void sci_transmit_chars(struct ua
 
 #if !defined(SCI_ONLY)
 	if (port->type == PORT_SCIF) {
+#if defined(CONFIG_CPU_SUBTYPE_SH7760) || defined(CONFIG_CPU_SUBTYPE_SH7780)
+		txroom = SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0x7f);
+#else
 		txroom = SCIF_TXROOM_MAX - (sci_in(port, SCFDR)>>8);
+#endif
 	} else {
 		txroom = (sci_in(port, SCxSR) & SCI_TDRE)?1:0;
 	}
@@ -491,7 +503,11 @@ static inline void sci_receive_chars(str
 	while (1) {
 #if !defined(SCI_ONLY)
 		if (port->type == PORT_SCIF) {
+#if defined(CONFIG_CPU_SUBTYPE_SH7760) || defined(CONFIG_CPU_SUBTYPE_SH7780)
+			count = sci_in(port, SCRFDR) & 0x7f;
+#else
 			count = sci_in(port, SCFDR)&SCIF_RFDC_MASK ;
+#endif
 		} else {
 			count = (sci_in(port, SCxSR)&SCxSR_RDxF(port))?1:0;
 		}
@@ -652,7 +668,7 @@ static inline int sci_handle_breaks(stru
 	struct tty_struct *tty = port->info->tty;
 	struct sci_port *s = &sci_ports[port->line];
 
-	if (!s->break_flag && status & SCxSR_BRK(port))
+	if (!s->break_flag && status & SCxSR_BRK(port)) {
 #if defined(CONFIG_CPU_SH3)
 		/* Debounce break */
 		s->break_flag = 1;
@@ -783,6 +799,7 @@ static int sci_notifier(struct notifier_
 	    (phase == CPUFREQ_RESUMECHANGE)){
 		for (i = 0; i < SCI_NPORTS; i++) {
 			struct uart_port *port = &sci_ports[i].port;
+			struct clk *clk;
 
 			/*
 			 * Update the uartclk per-port if frequency has
@@ -795,7 +812,9 @@ static int sci_notifier(struct notifier_
 			 *
 			 * Clean this up later..
 			 */
-			port->uartclk = current_cpu_data.module_clock * 16;
+			clk = clk_get("module_clk");
+			port->uartclk = clk_get_rate(clk) * 16;
+			clk_put(clk);
 		}
 
 		printk("%s: got a postchange notification for cpu %d (old %d, new %d)\n",
@@ -1008,15 +1027,20 @@ static void sci_set_termios(struct uart_
 	sci_out(port, SCSMR, smr_val);
 
 	switch (baud) {
-		case 0:		t = -1;		break;
-		case 2400:	t = BPS_2400;	break;
-		case 4800:	t = BPS_4800;	break;
-		case 9600:	t = BPS_9600;	break;
-		case 19200:	t = BPS_19200;	break;
-		case 38400:	t = BPS_38400;	break;
-		case 57600:	t = BPS_57600;	break;
-		case 115200:	t = BPS_115200;	break;
-		default:	t = SCBRR_VALUE(baud); break;
+		case 0:
+			t = -1;
+			break;
+		default:
+		{
+#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
+			struct clk *clk = clk_get("module_clk");
+			t = SCBRR_VALUE(baud, clk_get_rate(clk));
+			clk_put(clk);
+#else
+			t = SCBRR_VALUE(baud);
+#endif
+		}
+			break;
 	}
 
 	if (t > 0) {
@@ -1030,7 +1054,9 @@ static void sci_set_termios(struct uart_
 		udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */
 	}
 
-	s->init_pins(port, termios->c_cflag);
+	if (likely(s->init_pins))
+		s->init_pins(port, termios->c_cflag);
+
 	sci_out(port, SCSCR, SCSCR_INIT(port));
 
 	if ((termios->c_cflag & CREAD) != 0)
@@ -1107,31 +1133,30 @@ static struct uart_ops sci_uart_ops = {
 	.verify_port	= sci_verify_port,
 };
 
-static struct sci_port sci_ports[SCI_NPORTS] = {
+static struct sci_port sci_ports[] = {
 #if defined(CONFIG_CPU_SUBTYPE_SH7708)
 	{
 		.port	= {
 			.membase	= (void *)0xfffffe80,
 			.mapbase	= 0xfffffe80,
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 25,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 0,
 		},
 		.type		= PORT_SCI,
 		.irqs		= SCI_IRQS,
-		.init_pins	= sci_init_pins_sci,
 	},
 #elif defined(CONFIG_CPU_SUBTYPE_SH7705)
 	{
 		.port	= {
 			.membase	= (void *)SCIF0,
 			.mapbase	= SCIF0,
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 55,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 0,
 		},
 		.type		= PORT_SCIF,
@@ -1142,10 +1167,10 @@ static struct sci_port sci_ports[SCI_NPO
 		.port	= {
 			.membase	= (void *)SCIF2,
 			.mapbase	= SCIF2,
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 59,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 1,
 		},
 		.type		= PORT_SCIF,
@@ -1157,24 +1182,23 @@ static struct sci_port sci_ports[SCI_NPO
 		.port	= {
 			.membase	= (void *)0xfffffe80,
 			.mapbase	= 0xfffffe80,
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 25,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 0,
 		},
 		.type		= PORT_SCI,
 		.irqs		= SCI_IRQS,
-		.init_pins	= sci_init_pins_sci,
 	},
 	{
 		.port	= {
 			.membase	= (void *)0xa4000150,
 			.mapbase	= 0xa4000150,
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 59,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 1,
 		},
 		.type		= PORT_SCIF,
@@ -1185,10 +1209,10 @@ static struct sci_port sci_ports[SCI_NPO
 		.port	= {
 			.membase	= (void *)0xa4000140,
 			.mapbase	= 0xa4000140,
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 55,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 2,
 		},
 		.type		= PORT_IRDA,
@@ -1200,10 +1224,10 @@ static struct sci_port sci_ports[SCI_NPO
 		.port	= {
 			.membase	= (void *)0xA4430000,
 			.mapbase	= 0xA4430000,
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 25,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 0,
 		},
 		.type		= PORT_SCIF,
@@ -1215,25 +1239,25 @@ static struct sci_port sci_ports[SCI_NPO
 		.port	= {
 			.membase	= (void *)0xffe00000,
 			.mapbase	= 0xffe00000,
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 25,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 0,
 		},
 		.type		= PORT_SCIF,
 		.irqs		= SH73180_SCIF_IRQS,
 		.init_pins	= sci_init_pins_scif,
 	},
-#elif defined(CONFIG_SH_RTS7751R2D)
+#elif defined(CONFIG_CPU_SUBTYPE_SH4_202)
 	{
 		.port	= {
 			.membase	= (void *)0xffe80000,
 			.mapbase	= 0xffe80000,
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 43,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 0,
 		},
 		.type		= PORT_SCIF,
@@ -1245,24 +1269,23 @@ static struct sci_port sci_ports[SCI_NPO
 		.port	= {
 			.membase	= (void *)0xffe00000,
 			.mapbase	= 0xffe00000,
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 25,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 0,
 		},
 		.type		= PORT_SCI,
 		.irqs		= SCI_IRQS,
-		.init_pins	= sci_init_pins_sci,
 	},
 	{
 		.port	= {
 			.membase	= (void *)0xffe80000,
 			.mapbase	= 0xffe80000,
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 43,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 1,
 		},
 		.type		= PORT_SCIF,
@@ -1274,10 +1297,10 @@ static struct sci_port sci_ports[SCI_NPO
 		.port	= {
 			.membase	= (void *)0xfe600000,
 			.mapbase	= 0xfe600000,
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 55,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 0,
 		},
 		.type		= PORT_SCIF,
@@ -1288,10 +1311,10 @@ static struct sci_port sci_ports[SCI_NPO
 		.port	= {
 			.membase	= (void *)0xfe610000,
 			.mapbase	= 0xfe610000,
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 75,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 1,
 		},
 		.type		= PORT_SCIF,
@@ -1302,40 +1325,25 @@ static struct sci_port sci_ports[SCI_NPO
 		.port	= {
 			.membase	= (void *)0xfe620000,
 			.mapbase	= 0xfe620000,
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 79,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 2,
 		},
 		.type		= PORT_SCIF,
 		.irqs		= SH7760_SCIF2_IRQS,
 		.init_pins	= sci_init_pins_scif,
 	},
-#elif defined(CONFIG_CPU_SUBTYPE_SH4_202)
-	{
-		.port	= {
-			.membase	= (void *)0xffe80000,
-			.mapbase	= 0xffe80000,
-			.iotype		= SERIAL_IO_MEM,
-			.irq		= 43,
-			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
-			.line		= 0,
-		},
-		.type		= PORT_SCIF,
-		.irqs		= SH4_SCIF_IRQS,
-		.init_pins	= sci_init_pins_scif,
-	},
 #elif defined(CONFIG_CPU_SUBTYPE_ST40STB1)
 	{
 		.port	= {
 			.membase	= (void *)0xffe00000,
 			.mapbase	= 0xffe00000,
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 26,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 0,
 		},
 		.type		= PORT_SCIF,
@@ -1346,10 +1354,10 @@ static struct sci_port sci_ports[SCI_NPO
 		.port	= {
 			.membase	= (void *)0xffe80000,
 			.mapbase	= 0xffe80000,
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 43,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 1,
 		},
 		.type		= PORT_SCIF,
@@ -1359,10 +1367,10 @@ static struct sci_port sci_ports[SCI_NPO
 #elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
 	{
 		.port	= {
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 42,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 0,
 		},
 		.type		= PORT_SCIF,
@@ -1374,10 +1382,10 @@ static struct sci_port sci_ports[SCI_NPO
 		.port	= {
 			.membase	= (void *)0x00ffffb0,
 			.mapbase	= 0x00ffffb0,
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 54,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 0,
 		},
 		.type		= PORT_SCI,
@@ -1388,10 +1396,10 @@ static struct sci_port sci_ports[SCI_NPO
 		.port	= {
 			.membase	= (void *)0x00ffffb8,
 			.mapbase	= 0x00ffffb8,
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 58,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 1,
 		},
 		.type		= PORT_SCI,
@@ -1402,10 +1410,10 @@ static struct sci_port sci_ports[SCI_NPO
 		.port	= {
 			.membase	= (void *)0x00ffffc0,
 			.mapbase	= 0x00ffffc0,
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 62,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 2,
 		},
 		.type		= PORT_SCI,
@@ -1417,10 +1425,10 @@ static struct sci_port sci_ports[SCI_NPO
 		.port	= {
 			.membase	= (void *)0x00ffff78,
 			.mapbase	= 0x00ffff78,
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 90,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 0,
 		},
 		.type		= PORT_SCI,
@@ -1431,10 +1439,10 @@ static struct sci_port sci_ports[SCI_NPO
 		.port	= {
 			.membase	= (void *)0x00ffff80,
 			.mapbase	= 0x00ffff80,
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 94,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 1,
 		},
 		.type		= PORT_SCI,
@@ -1445,16 +1453,88 @@ static struct sci_port sci_ports[SCI_NPO
 		.port	= {
 			.membase	= (void *)0x00ffff88,
 			.mapbase	= 0x00ffff88,
-			.iotype		= SERIAL_IO_MEM,
+			.iotype		= UPIO_MEM,
 			.irq		= 98,
 			.ops		= &sci_uart_ops,
-			.flags		= ASYNC_BOOT_AUTOCONF,
+			.flags		= UPF_BOOT_AUTOCONF,
 			.line		= 2,
 		},
 		.type		= PORT_SCI,
 		.irqs		= H8S_SCI_IRQS2,
 		.init_pins	= sci_init_pins_sci,
 	},
+#elif defined(CONFIG_CPU_SUBTYPE_SH7770)
+	{
+		.port   = {
+			.membase	= (void *)0xff923000,
+			.mapbase	= 0xff923000,
+			.iotype		= SERIAL_IO_MEM,
+			.irq		= 61,
+			.ops		= &sci_uart_ops,
+			.flags		= ASYNC_BOOT_AUTOCONF,
+			.line		= 0,
+		},
+		.type		= PORT_SCIF,
+		.irqs		= SH7770_SCIF0_IRQS,
+		.init_pins	= sci_init_pins_scif,
+	},
+	{
+		.port   = {
+			.membase	= (void *)0xff924000,
+			.mapbase	= 0xff924000,
+			.iotype		= SERIAL_IO_MEM,
+			.irq		= 62,
+			.ops		= &sci_uart_ops,
+			.flags		= ASYNC_BOOT_AUTOCONF,
+			.line		= 1,
+		},
+		.type		= PORT_SCIF,
+		.irqs		= SH7770_SCIF1_IRQS,
+		.init_pins	= sci_init_pins_scif,
+	},
+	{
+		.port   = {
+			.membase	= (void *)0xff925000,
+			.mapbase	= 0xff925000,
+			.iotype		= SERIAL_IO_MEM,
+			.irq		= 63,
+			.ops		= &sci_uart_ops,
+			.flags		= ASYNC_BOOT_AUTOCONF,
+			.line		= 2,
+		},
+		.type		= PORT_SCIF,
+		.irqs		= SH7770_SCIF2_IRQS,
+		.init_pins	= sci_init_pins_scif,
+	},
+#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
+	{
+		.port   = {
+			.membase	= (void *)0xffe00000,
+			.mapbase	= 0xffe00000,
+			.iotype		= SERIAL_IO_MEM,
+			.irq		= 43,
+			.ops		= &sci_uart_ops,
+			.flags		= ASYNC_BOOT_AUTOCONF,
+			.line		= 0,
+		},
+		.type		= PORT_SCIF,
+		.irqs		= SH7780_SCIF0_IRQS,
+		.init_pins	= sci_init_pins_scif,
+	},
+	{
+		.port   = {
+			.membase	= (void *)0xffe10000,
+			.mapbase	= 0xffe10000,
+			.iotype		= SERIAL_IO_MEM,
+			.irq		= 79,
+			.ops		= &sci_uart_ops,
+			.flags		= ASYNC_BOOT_AUTOCONF,
+			.line		= 1,
+		},
+		.type		= PORT_SCIF,
+		.irqs		= SH7780_SCIF1_IRQS,
+		.init_pins	= sci_init_pins_scif,
+	},
 #else
 #error "CPU subtype not defined"
 #endif
@@ -1480,9 +1560,6 @@ static int __init serial_console_setup(s
 	int flow = 'n';
 	int ret;
 
-	if (co->index >= SCI_NPORTS)
-		co->index = 0;
-
 	serial_console_port = &sci_ports[co->index];
 	port = &serial_console_port->port;
 	port->type = serial_console_port->type;
@@ -1496,14 +1573,21 @@ static int __init serial_console_setup(s
 	 * We need to set the initial uartclk here, since otherwise it will
 	 * only ever be setup at sci_init() time.
 	 */
-#if !defined(__H8300H__) && !defined(__H8300S__)
-	port->uartclk = current_cpu_data.module_clock * 16;
-#else
+#if defined(__H8300H__) || defined(__H8300S__)
 	port->uartclk = CONFIG_CPU_CLOCK;
-#endif
+
 #if defined(__H8300S__)
 	h8300_sci_enable(port, sci_enable);
 #endif
+#elif defined(CONFIG_SUPERH64)
+	port->uartclk = current_cpu_info.module_clock * 16;
+#else
+	{
+		struct clk *clk = clk_get("module_clk");
+		port->uartclk = clk_get_rate(clk) * 16;
+		clk_put(clk);
+	}
+#endif
 	if (options)
 		uart_parse_options(options, &baud, &parity, &bits, &flow);
 
@@ -1566,7 +1650,7 @@ int __init kgdb_console_setup(struct con
 	int parity = 'n';
 	int flow = 'n';
 
-	if (co->index >= SCI_NPORTS || co->index != kgdb_portnum)
+	if (co->index != kgdb_portnum)
 		co->index = kgdb_portnum;
 
 	if (options)
@@ -1606,7 +1690,7 @@ console_initcall(kgdb_console_init);
 #elif defined(CONFIG_SERIAL_SH_SCI_CONSOLE)
 #define SCI_CONSOLE	&serial_console
 #else
-#define SCI_CONSOLE 	0
+#define SCI_CONSOLE	0
 #endif
 
 static char banner[] __initdata =
@@ -1621,7 +1705,6 @@ static struct uart_driver sci_uart_drive
 	.dev_name	= "ttySC",
 	.major		= SCI_MAJOR,
 	.minor		= SCI_MINOR_START,
-	.nr		= SCI_NPORTS,
 	.cons		= SCI_CONSOLE,
 };
 
@@ -1631,15 +1714,21 @@ static int __init sci_init(void)
 
 	printk("%s", banner);
 
+	sci_uart_driver.nr = ARRAY_SIZE(sci_ports);
+
 	ret = uart_register_driver(&sci_uart_driver);
 	if (ret == 0) {
 		for (chan = 0; chan < SCI_NPORTS; chan++) {
 			struct sci_port *sciport = &sci_ports[chan];
 
-#if !defined(__H8300H__) && !defined(__H8300S__)
-			sciport->port.uartclk = (current_cpu_data.module_clock * 16);
-#else
+#if defined(__H8300H__) || defined(__H8300S__)
 			sciport->port.uartclk = CONFIG_CPU_CLOCK;
+#elif defined(CONFIG_SUPERH64)
+			sciport->port.uartclk = current_cpu_info.module_clock * 16;
+#else
+			struct clk *clk = clk_get("module_clk");
+			sciport->port.uartclk = clk_get_rate(clk) * 16;
+			clk_put(clk);
 #endif
 			uart_add_one_port(&sci_uart_driver, &sciport->port);
 			sciport->break_timer.data = (unsigned long)sciport;
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index 2892169..1f14bb4 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -46,14 +46,17 @@
 #define H8S_SCI_IRQS1 {92, 93, 94,   0 }
 #define H8S_SCI_IRQS2 {96, 97, 98,   0 }
 #define SH5_SCIF_IRQS {39, 40, 42,   0 }
+#define	SH7770_SCIF0_IRQS {61, 61, 61, 61 }
+#define	SH7770_SCIF1_IRQS {62, 62, 62, 62 }
+#define	SH7770_SCIF2_IRQS {63, 63, 63, 63 }
+#define	SH7780_SCIF0_IRQS {40, 41, 43, 42 }
+#define	SH7780_SCIF1_IRQS {76, 77, 79, 78 }
 
 #if defined(CONFIG_CPU_SUBTYPE_SH7708)
-# define SCI_NPORTS 1
 # define SCSPTR 0xffffff7c /* 8 bit */
 # define SCSCR_INIT(port)          0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
 # define SCI_ONLY
 #elif defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
-# define SCI_NPORTS 3
 # define SCPCR  0xA4000116 /* 16 bit SCI and SCIF */
 # define SCPDR  0xA4000136 /* 8  bit SCI and SCIF */
 # define SCSCR_INIT(port)          0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
@@ -61,9 +64,8 @@
 #elif defined(CONFIG_CPU_SUBTYPE_SH7705)
 # define SCIF0		0xA4400000
 # define SCIF2		0xA4410000
-# define SCSMR_Ir 	0xA44A0000
-# define IRDA_SCIF 	SCIF0
-# define SCI_NPORTS 2
+# define SCSMR_Ir	0xA44A0000
+# define IRDA_SCIF	SCIF0
 # define SCPCR 0xA4000116
 # define SCPDR 0xA4000136
 
@@ -74,14 +76,11 @@
 # define SCSCR_INIT(port) (port->mapbase == SCIF2) ? 0xF3 : 0xF0
 # define SCIF_ONLY
 #elif defined(CONFIG_SH_RTS7751R2D)
-# define SCI_NPORTS 1
-# define SCSPTR1 0xffe0001c /* 8  bit SCI */
 # define SCSPTR2 0xFFE80020 /* 16 bit SCIF */
 # define SCIF_ORER 0x0001   /* overrun error bit */
 # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
 # define SCIF_ONLY
 #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751)
-# define SCI_NPORTS 2
 # define SCSPTR1 0xffe0001c /* 8  bit SCI */
 # define SCSPTR2 0xFFE80020 /* 16 bit SCIF */
 # define SCIF_ORER 0x0001   /* overrun error bit */
@@ -90,34 +89,29 @@
 	0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ )
 # define SCI_AND_SCIF
 #elif defined(CONFIG_CPU_SUBTYPE_SH7760)
-# define SCI_NPORTS 3
-# define SCSPTR0 0xfe600000 /* 16 bit SCIF */
-# define SCSPTR1 0xfe610000 /* 16 bit SCIF */
-# define SCSPTR2 0xfe620000 /* 16 bit SCIF */
+# define SCSPTR0 0xfe600024 /* 16 bit SCIF */
+# define SCSPTR1 0xfe610024 /* 16 bit SCIF */
+# define SCSPTR2 0xfe620024 /* 16 bit SCIF */
 # define SCIF_ORER 0x0001  /* overrun error bit */
 # define SCSCR_INIT(port)          0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
 # define SCIF_ONLY
 #elif defined(CONFIG_CPU_SUBTYPE_SH7300)
-# define SCI_NPORTS 1
 # define SCPCR  0xA4050116        /* 16 bit SCIF */
 # define SCPDR  0xA4050136        /* 16 bit SCIF */
 # define SCSCR_INIT(port)  0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */
 # define SCIF_ONLY
 #elif defined(CONFIG_CPU_SUBTYPE_SH73180)
-# define SCI_NPORTS 1
 # define SCPDR  0xA4050138        /* 16 bit SCIF */
 # define SCSPTR2 SCPDR
 # define SCIF_ORER 0x0001   /* overrun error bit */
 # define SCSCR_INIT(port)  0x0038 /* TIE=0,RIE=0,TE=1,RE=1 */
 # define SCIF_ONLY
 #elif defined(CONFIG_CPU_SUBTYPE_SH4_202)
-# define SCI_NPORTS 1
 # define SCSPTR2 0xffe80020 /* 16 bit SCIF */
 # define SCIF_ORER 0x0001   /* overrun error bit */
 # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
 # define SCIF_ONLY
 #elif defined(CONFIG_CPU_SUBTYPE_ST40STB1)
-# define SCI_NPORTS 2
 # define SCSPTR1 0xffe00020 /* 16 bit SCIF */
 # define SCSPTR2 0xffe80020 /* 16 bit SCIF */
 # define SCIF_ORER 0x0001   /* overrun error bit */
@@ -129,26 +123,32 @@
 # define SCIF_ADDR_SH5     PHYS_PERIPHERAL_BLOCK+SCIF_BASE_ADDR
 # define SCIF_PTR2_OFFS    0x0000020
 # define SCIF_LSR2_OFFS    0x0000024
-# define SCI_NPORTS 1
-# define SCI_INIT { \
-  { {}, PORT_SCIF, 0, \
-     SH5_SCIF_IRQS, sci_init_pins_scif }  \
-}
 # define SCSPTR2           ((port->mapbase)+SCIF_PTR2_OFFS) /* 16 bit SCIF */
 # define SCLSR2            ((port->mapbase)+SCIF_LSR2_OFFS) /* 16 bit SCIF */
 # define SCSCR_INIT(port)  0x38                           /* TIE=0,RIE=0,
 							     TE=1,RE=1,REIE=1 */
 # define SCIF_ONLY
 #elif defined(CONFIG_H83007) || defined(CONFIG_H83068)
-# define SCI_NPORTS 3
 # define SCSCR_INIT(port)          0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
 # define SCI_ONLY
 # define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port)
 #elif defined(CONFIG_H8S2678)
-# define SCI_NPORTS 3
 # define SCSCR_INIT(port)          0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
 # define SCI_ONLY
 # define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7770)
+# define SCSPTR0 0xff923020 /* 16 bit SCIF */
+# define SCSPTR1 0xff924020 /* 16 bit SCIF */
+# define SCSPTR2 0xff925020 /* 16 bit SCIF */
+# define SCIF_ORER 0x0001  /* overrun error bit */
+# define SCSCR_INIT(port)	0x3c /* TIE=0,RIE=0,TE=1,RE=1,REIE=1,cke=2 */
+# define SCIF_ONLY
+#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
+# define SCSPTR0	0xffe00024	/* 16 bit SCIF */
+# define SCSPTR1	0xffe10024	/* 16 bit SCIF */
+# define SCIF_OPER	0x0001		/* Overrun error bit */
+# define SCSCR_INIT(port)	0x3a	/* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
+# define SCIF_ONLY
 #else
 # error CPU subtype not defined
 #endif
@@ -158,7 +158,7 @@
 #define SCI_CTRL_FLAGS_RIE  0x40 /* all */
 #define SCI_CTRL_FLAGS_TE   0x20 /* all */
 #define SCI_CTRL_FLAGS_RE   0x10 /* all */
-#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751)
+#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH7780)
 #define SCI_CTRL_FLAGS_REIE 0x08 /* 7750 SCIF */
 #else
 #define SCI_CTRL_FLAGS_REIE 0
@@ -213,7 +213,7 @@
 # define SCxSR_RDxF_CLEAR(port)		0xbc
 # define SCxSR_ERROR_CLEAR(port)	0xc4
 # define SCxSR_TDxE_CLEAR(port)		0x78
-# define SCxSR_BREAK_CLEAR(port)   	0xc4
+# define SCxSR_BREAK_CLEAR(port)	0xc4
 #elif defined(SCIF_ONLY)
 # define SCxSR_TEND(port)		SCIF_TEND
 # define SCxSR_ERRORS(port)		SCIF_ERRORS
@@ -237,7 +237,7 @@
 # define SCxSR_RDxF_CLEAR(port)		0x00fc
 # define SCxSR_ERROR_CLEAR(port)	0x0073
 # define SCxSR_TDxE_CLEAR(port)		0x00df
-# define SCxSR_BREAK_CLEAR(port)   	0x00e3
+# define SCxSR_BREAK_CLEAR(port)	0x00e3
 #endif
 #else
 # define SCxSR_TEND(port)	 (((port)->type == PORT_SCI) ? SCI_TEND   : SCIF_TEND)
@@ -285,14 +285,14 @@ struct sci_port {
 
 #define SCI_IN(size, offset)					\
   unsigned int addr = port->mapbase + (offset);			\
-  if ((size) == 8) { 						\
+  if ((size) == 8) {						\
     return ctrl_inb(addr);					\
-  } else {					 		\
+  } else {							\
     return ctrl_inw(addr);					\
   }
 #define SCI_OUT(size, offset, value)				\
   unsigned int addr = port->mapbase + (offset);			\
-  if ((size) == 8) { 						\
+  if ((size) == 8) {						\
     ctrl_outb(value, addr);					\
   } else {							\
     ctrl_outw(value, addr);					\
@@ -301,10 +301,10 @@ struct sci_port {
 #define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\
   static inline unsigned int sci_##name##_in(struct uart_port *port)	\
   {									\
-    if (port->type == PORT_SCI) { 					\
+    if (port->type == PORT_SCI) {					\
       SCI_IN(sci_size, sci_offset)					\
     } else {								\
-      SCI_IN(scif_size, scif_offset);		 			\
+      SCI_IN(scif_size, scif_offset);					\
     }									\
   }									\
   static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \
@@ -319,7 +319,7 @@ struct sci_port {
 #define CPU_SCIF_FNS(name, scif_offset, scif_size)				\
   static inline unsigned int sci_##name##_in(struct uart_port *port)	\
   {									\
-    SCI_IN(scif_size, scif_offset);		 			\
+    SCI_IN(scif_size, scif_offset);					\
   }									\
   static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \
   {									\
@@ -329,7 +329,7 @@ struct sci_port {
 #define CPU_SCI_FNS(name, sci_offset, sci_size)				\
   static inline unsigned int sci_##name##_in(struct uart_port* port)	\
   {									\
-    SCI_IN(sci_size, sci_offset);		 			\
+    SCI_IN(sci_size, sci_offset);					\
   }									\
   static inline void sci_##name##_out(struct uart_port* port, unsigned int value) \
   {									\
@@ -385,10 +385,17 @@ SCIx_FNS(SCxTDR, 0x06,  8, 0x0c,  8, 0x0
 SCIx_FNS(SCxSR,  0x08,  8, 0x10,  8, 0x08, 16, 0x10, 16, 0x04,  8)
 SCIx_FNS(SCxRDR, 0x0a,  8, 0x14,  8, 0x0A,  8, 0x14,  8, 0x05,  8)
 SCIF_FNS(SCFCR,                      0x0c,  8, 0x18, 16)
+#if defined(CONFIG_CPU_SUBTYPE_SH7760) || defined(CONFIG_CPU_SUBTYPE_SH7780)
+SCIF_FNS(SCTFDR,		     0x0e, 16, 0x1C, 16)
+SCIF_FNS(SCRFDR,		     0x0e, 16, 0x20, 16)
+SCIF_FNS(SCSPTR,			0,  0, 0x24, 16)
+SCIF_FNS(SCLSR,				0,  0, 0x28, 16)
+#else
 SCIF_FNS(SCFDR,                      0x0e, 16, 0x1C, 16)
 SCIF_FNS(SCSPTR,                        0,  0, 0x20, 16)
 SCIF_FNS(SCLSR,                         0,  0, 0x24, 16)
 #endif
+#endif
 #define sci_in(port, reg) sci_##reg##_in(port)
 #define sci_out(port, reg, value) sci_##reg##_out(port, value)
 
@@ -518,6 +525,24 @@ static inline int sci_rxd_in(struct uart
 	int ch = (port->mapbase - SMR0) >> 3;
 	return (H8300_SCI_DR(ch) & h8300_sci_pins[ch].rx) ? 1 : 0;
 }
+#elif defined(CONFIG_CPU_SUBTYPE_SH7770)
+static inline int sci_rxd_in(struct uart_port *port)
+{
+	if (port->mapbase == 0xff923000)
+		return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
+	if (port->mapbase == 0xff924000)
+		return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
+	if (port->mapbase == 0xff925000)
+		return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
+}
+#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
+static inline int sci_rxd_in(struct uart_port *port)
+{
+	if (port->mapbase == 0xffe00000)
+		return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
+	if (port->mapbase == 0xffe10000)
+		return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
+}
 #endif
 
 /*
@@ -552,22 +577,15 @@ static inline int sci_rxd_in(struct uart
  * -- Mitch Davis - 15 Jul 2000
  */
 
-#define PCLK           (current_cpu_data.module_clock)
-
-#if defined(CONFIG_CPU_SUBTYPE_SH7300)
-#define SCBRR_VALUE(bps) ((PCLK+16*bps)/(16*bps)-1)
+#if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7780)
+#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1)
 #elif defined(CONFIG_CPU_SUBTYPE_SH7705)
-#define SCBRR_VALUE(bps) (((PCLK*2)+16*bps)/(32*bps)-1)
-#elif !defined(__H8300H__) && !defined(__H8300S__)
-#define SCBRR_VALUE(bps) ((PCLK+16*bps)/(32*bps)-1)
-#else
+#define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1)
+#elif defined(__H8300H__) || defined(__H8300S__)
 #define SCBRR_VALUE(bps) (((CONFIG_CPU_CLOCK*1000/32)/bps)-1)
+#elif defined(CONFIG_SUPERH64)
+#define SCBRR_VALUE(bps) ((current_cpu_data.module_clock+16*bps)/(32*bps)-1)
+#else /* Generic SH */
+#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(32*bps)-1)
 #endif
-#define BPS_2400       SCBRR_VALUE(2400)
-#define BPS_4800       SCBRR_VALUE(4800)
-#define BPS_9600       SCBRR_VALUE(9600)
-#define BPS_19200      SCBRR_VALUE(19200)
-#define BPS_38400      SCBRR_VALUE(38400)
-#define BPS_57600      SCBRR_VALUE(57600)
-#define BPS_115200     SCBRR_VALUE(115200)
 
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c
index 5468e5a..43e67d6 100644
--- a/drivers/serial/sn_console.c
+++ b/drivers/serial/sn_console.c
@@ -6,7 +6,7 @@
  * driver for that.
  *
  *
- * Copyright (c) 2004-2005 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2004-2006 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License
@@ -829,8 +829,8 @@ static int __init sn_sal_module_init(voi
 		misc.name = DEVICE_NAME_DYNAMIC;
 		retval = misc_register(&misc);
 		if (retval != 0) {
-			printk
-			    ("Failed to register console device using misc_register.\n");
+			printk(KERN_WARNING "Failed to register console "
+			       "device using misc_register.\n");
 			return -ENODEV;
 		}
 		sal_console_uart.major = MISC_MAJOR;
@@ -942,88 +942,75 @@ sn_sal_console_write(struct console *co,
 {
 	unsigned long flags = 0;
 	struct sn_cons_port *port = &sal_console_port;
-#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
 	static int stole_lock = 0;
-#endif
 
 	BUG_ON(!port->sc_is_asynch);
 
 	/* We can't look at the xmit buffer if we're not registered with serial core
 	 *  yet.  So only do the fancy recovery after registering
 	 */
-	if (port->sc_port.info) {
-
-		/* somebody really wants this output, might be an
-		 * oops, kdb, panic, etc.  make sure they get it. */
-#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
-		if (spin_is_locked(&port->sc_port.lock)) {
-			int lhead = port->sc_port.info->xmit.head;
-			int ltail = port->sc_port.info->xmit.tail;
-			int counter, got_lock = 0;
+	if (!port->sc_port.info) {
+		/* Not yet registered with serial core - simple case */
+		puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count);
+		return;
+	}
 
-			/*
-			 * We attempt to determine if someone has died with the
-			 * lock. We wait ~20 secs after the head and tail ptrs
-			 * stop moving and assume the lock holder is not functional
-			 * and plow ahead. If the lock is freed within the time out
-			 * period we re-get the lock and go ahead normally. We also
-			 * remember if we have plowed ahead so that we don't have
-			 * to wait out the time out period again - the asumption
-			 * is that we will time out again.
-			 */
+	/* somebody really wants this output, might be an
+	 * oops, kdb, panic, etc.  make sure they get it. */
+	if (spin_is_locked(&port->sc_port.lock)) {
+		int lhead = port->sc_port.info->xmit.head;
+		int ltail = port->sc_port.info->xmit.tail;
+		int counter, got_lock = 0;
+
+		/*
+		 * We attempt to determine if someone has died with the
+		 * lock. We wait ~20 secs after the head and tail ptrs
+		 * stop moving and assume the lock holder is not functional
+		 * and plow ahead. If the lock is freed within the time out
+		 * period we re-get the lock and go ahead normally. We also
+		 * remember if we have plowed ahead so that we don't have
+		 * to wait out the time out period again - the asumption
+		 * is that we will time out again.
+		 */
 
-			for (counter = 0; counter < 150; mdelay(125), counter++) {
-				if (!spin_is_locked(&port->sc_port.lock)
-				    || stole_lock) {
-					if (!stole_lock) {
-						spin_lock_irqsave(&port->
-								  sc_port.lock,
-								  flags);
-						got_lock = 1;
-					}
-					break;
-				} else {
-					/* still locked */
-					if ((lhead !=
-					     port->sc_port.info->xmit.head)
-					    || (ltail !=
-						port->sc_port.info->xmit.
-						tail)) {
-						lhead =
-						    port->sc_port.info->xmit.
-						    head;
-						ltail =
-						    port->sc_port.info->xmit.
-						    tail;
-						counter = 0;
-					}
+		for (counter = 0; counter < 150; mdelay(125), counter++) {
+			if (!spin_is_locked(&port->sc_port.lock)
+			    || stole_lock) {
+				if (!stole_lock) {
+					spin_lock_irqsave(&port->sc_port.lock,
+							  flags);
+					got_lock = 1;
 				}
-			}
-			/* flush anything in the serial core xmit buffer, raw */
-			sn_transmit_chars(port, 1);
-			if (got_lock) {
-				spin_unlock_irqrestore(&port->sc_port.lock,
-						       flags);
-				stole_lock = 0;
+				break;
 			} else {
-				/* fell thru */
-				stole_lock = 1;
+				/* still locked */
+				if ((lhead != port->sc_port.info->xmit.head)
+				    || (ltail !=
+					port->sc_port.info->xmit.tail)) {
+					lhead =
+						port->sc_port.info->xmit.head;
+					ltail =
+						port->sc_port.info->xmit.tail;
+					counter = 0;
+				}
 			}
-			puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count);
-		} else {
-			stole_lock = 0;
-#endif
-			spin_lock_irqsave(&port->sc_port.lock, flags);
-			sn_transmit_chars(port, 1);
+		}
+		/* flush anything in the serial core xmit buffer, raw */
+		sn_transmit_chars(port, 1);
+		if (got_lock) {
 			spin_unlock_irqrestore(&port->sc_port.lock, flags);
-
-			puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count);
-#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
+			stole_lock = 0;
+		} else {
+			/* fell thru */
+			stole_lock = 1;
 		}
-#endif
-	}
-	else {
-		/* Not yet registered with serial core - simple case */
+		puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count);
+	} else {
+		stole_lock = 0;
+		spin_lock_irqsave(&port->sc_port.lock, flags);
+		sn_transmit_chars(port, 1);
+		spin_unlock_irqrestore(&port->sc_port.lock, flags);
+
 		puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count);
 	}
 }
diff --git a/drivers/serial/suncore.c b/drivers/serial/suncore.c
index 5fc4a62..fa4ae94 100644
--- a/drivers/serial/suncore.c
+++ b/drivers/serial/suncore.c
@@ -34,6 +34,7 @@ sunserial_console_termios(struct console
 	char *mode_prop = "ttyX-mode";
 	char *cd_prop = "ttyX-ignore-cd";
 	char *dtr_prop = "ttyX-rts-dtr-off";
+	char *ssp_console_modes_prop = "ssp-console-modes";
 	int baud, bits, stop, cflag;
 	char parity;
 	int carrier = 0;
@@ -43,14 +44,39 @@ sunserial_console_termios(struct console
 	if (!serial_console)
 		return;
 
-	if (serial_console == 1) {
+	switch (serial_console) {
+	case PROMDEV_OTTYA:
 		mode_prop[3] = 'a';
 		cd_prop[3] = 'a';
 		dtr_prop[3] = 'a';
-	} else {
+		break;
+
+	case PROMDEV_OTTYB:
 		mode_prop[3] = 'b';
 		cd_prop[3] = 'b';
 		dtr_prop[3] = 'b';
+		break;
+
+	case PROMDEV_ORSC:
+
+		nd = prom_pathtoinode("rsc");
+		if (!nd) {
+			strcpy(mode, "115200,8,n,1,-");
+			goto no_options;
+		}
+
+		if (!prom_node_has_property(nd, ssp_console_modes_prop)) {
+			strcpy(mode, "115200,8,n,1,-");
+			goto no_options;
+		}
+
+		memset(mode, 0, sizeof(mode));
+		prom_getstring(nd, ssp_console_modes_prop, mode, sizeof(mode));
+		goto no_options;
+
+	default:
+		strcpy(mode, "9600,8,n,1,-");
+		goto no_options;
 	}
 
 	topnd = prom_getchild(prom_root_node);
@@ -110,6 +136,10 @@ no_options:
 		case 9600: cflag |= B9600; break;
 		case 19200: cflag |= B19200; break;
 		case 38400: cflag |= B38400; break;
+		case 57600: cflag |= B57600; break;
+		case 115200: cflag |= B115200; break;
+		case 230400: cflag |= B230400; break;
+		case 460800: cflag |= B460800; break;
 		default: baud = 9600; cflag |= B9600; break;
 	}
 
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index 7e773ff..8bcaebc 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -897,9 +897,6 @@ static int sunsab_console_setup(struct c
 
 	sunserial_console_termios(con);
 
-	/* Firmware console speed is limited to 150-->38400 baud so
-	 * this hackish cflag thing is OK.
-	 */
 	switch (con->cflag & CBAUD) {
 	case B150: baud = 150; break;
 	case B300: baud = 300; break;
@@ -910,6 +907,10 @@ static int sunsab_console_setup(struct c
 	default: case B9600: baud = 9600; break;
 	case B19200: baud = 19200; break;
 	case B38400: baud = 38400; break;
+	case B57600: baud = 57600; break;
+	case B115200: baud = 115200; break;
+	case B230400: baud = 230400; break;
+	case B460800: baud = 460800; break;
 	};
 
 	/*
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 9a3665b..bc67442 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -669,7 +669,7 @@ static int sunsu_startup(struct uart_por
 	 * if it is, then bail out, because there's likely no UART
 	 * here.
 	 */
-	if (!(up->port.flags & ASYNC_BUGGY_UART) &&
+	if (!(up->port.flags & UPF_BUGGY_UART) &&
 	    (serial_inp(up, UART_LSR) == 0xff)) {
 		printk("ttyS%d: LSR safety check engaged!\n", up->port.line);
 		return -ENODEV;
@@ -707,7 +707,7 @@ static int sunsu_startup(struct uart_por
 	up->ier = UART_IER_RLSI | UART_IER_RDI;
 	serial_outp(up, UART_IER, up->ier);
 
-	if (up->port.flags & ASYNC_FOURPORT) {
+	if (up->port.flags & UPF_FOURPORT) {
 		unsigned int icp;
 		/*
 		 * Enable interrupts on the AST Fourport board
@@ -740,7 +740,7 @@ static void sunsu_shutdown(struct uart_p
 	serial_outp(up, UART_IER, 0);
 
 	spin_lock_irqsave(&up->port.lock, flags);
-	if (up->port.flags & ASYNC_FOURPORT) {
+	if (up->port.flags & UPF_FOURPORT) {
 		/* reset interrupts on the AST Fourport board */
 		inb((up->port.iobase & 0xfe0) | 0x1f);
 		up->port.mctrl |= TIOCM_OUT1;
@@ -1132,7 +1132,7 @@ ebus_done:
 
 	spin_lock_irqsave(&up->port.lock, flags);
 
-	if (!(up->port.flags & ASYNC_BUGGY_UART)) {
+	if (!(up->port.flags & UPF_BUGGY_UART)) {
 		/*
 		 * Do a simple existence test first; if we fail this, there's
 		 * no point trying anything else.
@@ -1170,7 +1170,7 @@ ebus_done:
 	 * manufacturer would be stupid enough to design a board
 	 * that conflicts with COM 1-4 --- we hope!
 	 */
-	if (!(up->port.flags & ASYNC_SKIP_TEST)) {
+	if (!(up->port.flags & UPF_SKIP_TEST)) {
 		serial_outp(up, UART_MCR, UART_MCR_LOOP | 0x0A);
 		status1 = serial_inp(up, UART_MSR) & 0xF0;
 		serial_outp(up, UART_MCR, save_mcr);
@@ -1371,7 +1371,7 @@ static __inline__ void wait_for_xmitr(st
 	} while ((status & BOTH_EMPTY) != BOTH_EMPTY);
 
 	/* Wait up to 1s for flow control if necessary */
-	if (up->port.flags & ASYNC_CONS_FLOW) {
+	if (up->port.flags & UPF_CONS_FLOW) {
 		tmout = 1000000;
 		while (--tmout &&
 		       ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0))
@@ -1513,7 +1513,7 @@ static int __init sunsu_serial_init(void
 		    up->su_type == SU_PORT_KBD)
 			continue;
 
-		up->port.flags |= ASYNC_BOOT_AUTOCONF;
+		up->port.flags |= UPF_BOOT_AUTOCONF;
 		up->port.type = PORT_UNKNOWN;
 		up->port.uartclk = (SU_BASE_BAUD * 16);
 
diff --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c
index aaa009f..c70ae81 100644
--- a/drivers/sn/ioc3.c
+++ b/drivers/sn/ioc3.c
@@ -843,9 +843,9 @@ MODULE_AUTHOR("Stanislaw Skowronek <skyl
 MODULE_DESCRIPTION("PCI driver for SGI IOC3");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(ioc3_register_submodule);
-EXPORT_SYMBOL(ioc3_unregister_submodule);
-EXPORT_SYMBOL(ioc3_ack);
-EXPORT_SYMBOL(ioc3_gpcr_set);
-EXPORT_SYMBOL(ioc3_disable);
-EXPORT_SYMBOL(ioc3_enable);
+EXPORT_SYMBOL_GPL(ioc3_register_submodule);
+EXPORT_SYMBOL_GPL(ioc3_unregister_submodule);
+EXPORT_SYMBOL_GPL(ioc3_ack);
+EXPORT_SYMBOL_GPL(ioc3_gpcr_set);
+EXPORT_SYMBOL_GPL(ioc3_disable);
+EXPORT_SYMBOL_GPL(ioc3_enable);
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index 3639c3f..36e476d 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_USB_XPAD)		+= input/
 
 obj-$(CONFIG_USB_DABUSB)	+= media/
 obj-$(CONFIG_USB_DSBR)		+= media/
+obj-$(CONFIG_USB_ET61X251)	+= media/
 obj-$(CONFIG_USB_IBMCAM)	+= media/
 obj-$(CONFIG_USB_KONICAWC)	+= media/
 obj-$(CONFIG_USB_OV511)		+= media/
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index af0a41e..04631dc 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -36,6 +36,7 @@
 #include <linux/init.h>
 #include <linux/device.h>	/* FIXME: linux/firmware.h should include it itself */
 #include <linux/firmware.h>
+#include <linux/mutex.h>
 
 #include "usbatm.h"
 
@@ -160,7 +161,7 @@ struct cxacru_data {
 	struct work_struct poll_work;
 
 	/* contol handles */
-	struct semaphore cm_serialize;
+	struct mutex cm_serialize;
 	u8 *rcv_buf;
 	u8 *snd_buf;
 	struct urb *rcv_urb;
@@ -219,7 +220,7 @@ static int cxacru_cm(struct cxacru_data 
 		goto fail;
 	}
 
-	down(&instance->cm_serialize);
+	mutex_lock(&instance->cm_serialize);
 
 	/* submit reading urb before the writing one */
 	init_completion(&instance->rcv_done);
@@ -288,7 +289,7 @@ static int cxacru_cm(struct cxacru_data 
 	ret = offd;
 	dbg("cm %#x", cm);
 fail:
-	up(&instance->cm_serialize);
+	mutex_unlock(&instance->cm_serialize);
 	return ret;
 }
 
@@ -352,7 +353,6 @@ static int cxacru_atm_start(struct usbat
 		struct atm_dev *atm_dev)
 {
 	struct cxacru_data *instance = usbatm_instance->driver_data;
-	struct device *dev = &usbatm_instance->usb_intf->dev;
 	/*
 	struct atm_dev *atm_dev = usbatm_instance->atm_dev;
 	*/
@@ -364,14 +364,14 @@ static int cxacru_atm_start(struct usbat
 	ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_MAC_ADDRESS, NULL, 0,
 			atm_dev->esi, sizeof(atm_dev->esi));
 	if (ret < 0) {
-		dev_err(dev, "cxacru_atm_start: CARD_GET_MAC_ADDRESS returned %d\n", ret);
+		atm_err(usbatm_instance, "cxacru_atm_start: CARD_GET_MAC_ADDRESS returned %d\n", ret);
 		return ret;
 	}
 
 	/* start ADSL */
 	ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0);
 	if (ret < 0) {
-		dev_err(dev, "cxacru_atm_start: CHIP_ADSL_LINE_START returned %d\n", ret);
+		atm_err(usbatm_instance, "cxacru_atm_start: CHIP_ADSL_LINE_START returned %d\n", ret);
 		return ret;
 	}
 
@@ -383,13 +383,13 @@ static int cxacru_atm_start(struct usbat
 static void cxacru_poll_status(struct cxacru_data *instance)
 {
 	u32 buf[CXINF_MAX] = {};
-	struct device *dev = &instance->usbatm->usb_intf->dev;
-	struct atm_dev *atm_dev = instance->usbatm->atm_dev;
+	struct usbatm_data *usbatm = instance->usbatm;
+	struct atm_dev *atm_dev = usbatm->atm_dev;
 	int ret;
 
 	ret = cxacru_cm_get_array(instance, CM_REQUEST_CARD_INFO_GET, buf, CXINF_MAX);
 	if (ret < 0) {
-		dev_warn(dev, "poll status: error %d\n", ret);
+		atm_warn(usbatm, "poll status: error %d\n", ret);
 		goto reschedule;
 	}
 
@@ -400,50 +400,50 @@ static void cxacru_poll_status(struct cx
 	switch (instance->line_status) {
 	case 0:
 		atm_dev->signal = ATM_PHY_SIG_LOST;
-		dev_info(dev, "ADSL line: down\n");
+		atm_info(usbatm, "ADSL line: down\n");
 		break;
 
 	case 1:
 		atm_dev->signal = ATM_PHY_SIG_LOST;
-		dev_info(dev, "ADSL line: attemtping to activate\n");
+		atm_info(usbatm, "ADSL line: attempting to activate\n");
 		break;
 
 	case 2:
 		atm_dev->signal = ATM_PHY_SIG_LOST;
-		dev_info(dev, "ADSL line: training\n");
+		atm_info(usbatm, "ADSL line: training\n");
 		break;
 
 	case 3:
 		atm_dev->signal = ATM_PHY_SIG_LOST;
-		dev_info(dev, "ADSL line: channel analysis\n");
+		atm_info(usbatm, "ADSL line: channel analysis\n");
 		break;
 
 	case 4:
 		atm_dev->signal = ATM_PHY_SIG_LOST;
-		dev_info(dev, "ADSL line: exchange\n");
+		atm_info(usbatm, "ADSL line: exchange\n");
 		break;
 
 	case 5:
 		atm_dev->link_rate = buf[CXINF_DOWNSTREAM_RATE] * 1000 / 424;
 		atm_dev->signal = ATM_PHY_SIG_FOUND;
 
-		dev_info(dev, "ADSL line: up (%d kb/s down | %d kb/s up)\n",
+		atm_info(usbatm, "ADSL line: up (%d kb/s down | %d kb/s up)\n",
 		     buf[CXINF_DOWNSTREAM_RATE], buf[CXINF_UPSTREAM_RATE]);
 		break;
 
 	case 6:
 		atm_dev->signal = ATM_PHY_SIG_LOST;
-		dev_info(dev, "ADSL line: waiting\n");
+		atm_info(usbatm, "ADSL line: waiting\n");
 		break;
 
 	case 7:
 		atm_dev->signal = ATM_PHY_SIG_LOST;
-		dev_info(dev, "ADSL line: initializing\n");
+		atm_info(usbatm, "ADSL line: initializing\n");
 		break;
 
 	default:
 		atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
-		dev_info(dev, "Unknown line state %02x\n", instance->line_status);
+		atm_info(usbatm, "Unknown line state %02x\n", instance->line_status);
 		break;
 	}
 reschedule:
@@ -504,8 +504,8 @@ static void cxacru_upload_firmware(struc
 {
 	int ret;
 	int off;
-	struct usb_device *usb_dev = instance->usbatm->usb_dev;
-	struct device *dev = &instance->usbatm->usb_intf->dev;
+	struct usbatm_data *usbatm = instance->usbatm;
+	struct usb_device *usb_dev = usbatm->usb_dev;
 	u16 signature[] = { usb_dev->descriptor.idVendor, usb_dev->descriptor.idProduct };
 	u32 val;
 
@@ -515,7 +515,7 @@ static void cxacru_upload_firmware(struc
 	val = cpu_to_le32(instance->modem_type->pll_f_clk);
 	ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLFCLK_ADDR, (u8 *) &val, 4);
 	if (ret) {
-		dev_err(dev, "FirmwarePllFClkValue failed: %d\n", ret);
+		usb_err(usbatm, "FirmwarePllFClkValue failed: %d\n", ret);
 		return;
 	}
 
@@ -523,7 +523,7 @@ static void cxacru_upload_firmware(struc
 	val = cpu_to_le32(instance->modem_type->pll_b_clk);
 	ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLBCLK_ADDR, (u8 *) &val, 4);
 	if (ret) {
-		dev_err(dev, "FirmwarePllBClkValue failed: %d\n", ret);
+		usb_err(usbatm, "FirmwarePllBClkValue failed: %d\n", ret);
 		return;
 	}
 
@@ -531,14 +531,14 @@ static void cxacru_upload_firmware(struc
 	val = cpu_to_le32(SDRAM_ENA);
 	ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SDRAMEN_ADDR, (u8 *) &val, 4);
 	if (ret) {
-		dev_err(dev, "Enable SDRAM failed: %d\n", ret);
+		usb_err(usbatm, "Enable SDRAM failed: %d\n", ret);
 		return;
 	}
 
 	/* Firmware */
 	ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, FW_ADDR, fw->data, fw->size);
 	if (ret) {
-		dev_err(dev, "Firmware upload failed: %d\n", ret);
+		usb_err(usbatm, "Firmware upload failed: %d\n", ret);
 		return;
 	}
 
@@ -546,7 +546,7 @@ static void cxacru_upload_firmware(struc
 	if (instance->modem_type->boot_rom_patch) {
 		ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_ADDR, bp->data, bp->size);
 		if (ret) {
-			dev_err(dev, "Boot ROM patching failed: %d\n", ret);
+			usb_err(usbatm, "Boot ROM patching failed: %d\n", ret);
 			return;
 		}
 	}
@@ -554,7 +554,7 @@ static void cxacru_upload_firmware(struc
 	/* Signature */
 	ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SIG_ADDR, (u8 *) signature, 4);
 	if (ret) {
-		dev_err(dev, "Signature storing failed: %d\n", ret);
+		usb_err(usbatm, "Signature storing failed: %d\n", ret);
 		return;
 	}
 
@@ -566,7 +566,7 @@ static void cxacru_upload_firmware(struc
 		ret = cxacru_fw(usb_dev, FW_GOTO_MEM, 0x0, 0x0, FW_ADDR, NULL, 0);
 	}
 	if (ret) {
-		dev_err(dev, "Passing control to firmware failed: %d\n", ret);
+		usb_err(usbatm, "Passing control to firmware failed: %d\n", ret);
 		return;
 	}
 
@@ -580,7 +580,7 @@ static void cxacru_upload_firmware(struc
 
 	ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0);
 	if (ret < 0) {
-		dev_err(dev, "modem failed to initialize: %d\n", ret);
+		usb_err(usbatm, "modem failed to initialize: %d\n", ret);
 		return;
 	}
 
@@ -597,7 +597,7 @@ static void cxacru_upload_firmware(struc
 			ret = cxacru_cm(instance, CM_REQUEST_CARD_DATA_SET,
 					(u8 *) buf, len, NULL, 0);
 			if (ret < 0) {
-				dev_err(dev, "load config data failed: %d\n", ret);
+				usb_err(usbatm, "load config data failed: %d\n", ret);
 				return;
 			}
 		}
@@ -608,18 +608,19 @@ static void cxacru_upload_firmware(struc
 static int cxacru_find_firmware(struct cxacru_data *instance,
 				char* phase, const struct firmware **fw_p)
 {
-	struct device *dev = &instance->usbatm->usb_intf->dev;
+	struct usbatm_data *usbatm = instance->usbatm;
+	struct device *dev = &usbatm->usb_intf->dev;
 	char buf[16];
 
 	sprintf(buf, "cxacru-%s.bin", phase);
 	dbg("cxacru_find_firmware: looking for %s", buf);
 
 	if (request_firmware(fw_p, buf, dev)) {
-		dev_dbg(dev, "no stage %s firmware found\n", phase);
+		usb_dbg(usbatm, "no stage %s firmware found\n", phase);
 		return -ENOENT;
 	}
 
-	dev_info(dev, "found firmware %s\n", buf);
+	usb_info(usbatm, "found firmware %s\n", buf);
 
 	return 0;
 }
@@ -627,20 +628,19 @@ static int cxacru_find_firmware(struct c
 static int cxacru_heavy_init(struct usbatm_data *usbatm_instance,
 			     struct usb_interface *usb_intf)
 {
-	struct device *dev = &usbatm_instance->usb_intf->dev;
 	const struct firmware *fw, *bp, *cf;
 	struct cxacru_data *instance = usbatm_instance->driver_data;
 
 	int ret = cxacru_find_firmware(instance, "fw", &fw);
 	if (ret) {
-		dev_warn(dev, "firmware (cxacru-fw.bin) unavailable (hotplug misconfiguration?)\n");
+		usb_warn(usbatm_instance, "firmware (cxacru-fw.bin) unavailable (system misconfigured?)\n");
 		return ret;
 	}
 
 	if (instance->modem_type->boot_rom_patch) {
 		ret = cxacru_find_firmware(instance, "bp", &bp);
 		if (ret) {
-			dev_warn(dev, "boot ROM patch (cxacru-bp.bin) unavailable (hotplug misconfiguration?)\n");
+			usb_warn(usbatm_instance, "boot ROM patch (cxacru-bp.bin) unavailable (system misconfigured?)\n");
 			release_firmware(fw);
 			return ret;
 		}
@@ -667,22 +667,19 @@ static int cxacru_heavy_init(struct usba
 }
 
 static int cxacru_bind(struct usbatm_data *usbatm_instance,
-		       struct usb_interface *intf, const struct usb_device_id *id,
-		       int *need_heavy_init)
+		       struct usb_interface *intf, const struct usb_device_id *id)
 {
 	struct cxacru_data *instance;
 	struct usb_device *usb_dev = interface_to_usbdev(intf);
 	int ret;
 
 	/* instance init */
-	instance = kmalloc(sizeof(*instance), GFP_KERNEL);
+	instance = kzalloc(sizeof(*instance), GFP_KERNEL);
 	if (!instance) {
 		dbg("cxacru_bind: no memory for instance data");
 		return -ENOMEM;
 	}
 
-	memset(instance, 0, sizeof(*instance));
-
 	instance->usbatm = usbatm_instance;
 	instance->modem_type = (struct cxacru_modem_type *) id->driver_info;
 
@@ -721,13 +718,13 @@ static int cxacru_bind(struct usbatm_dat
 			instance->snd_buf, PAGE_SIZE,
 			cxacru_blocking_completion, &instance->snd_done, 4);
 
-	init_MUTEX(&instance->cm_serialize);
+	mutex_init(&instance->cm_serialize);
 
 	INIT_WORK(&instance->poll_work, (void *)cxacru_poll_status, instance);
 
 	usbatm_instance->driver_data = instance;
 
-	*need_heavy_init = cxacru_card_status(instance);
+	usbatm_instance->flags = (cxacru_card_status(instance) ? 0 : UDSL_SKIP_HEAVY_INIT);
 
 	return 0;
 
@@ -787,12 +784,12 @@ static const struct usb_device_id cxacru
 	{ /* V = Conexant			P = ADSL modem (Hasbani project)	*/
 		USB_DEVICE(0x0572, 0xcb00),	.driver_info = (unsigned long) &cxacru_cb00
 	},
-	{ /* V = Conexant             P = ADSL modem (Well PTI-800 */
-		USB_DEVICE(0x0572, 0xcb02),	.driver_info = (unsigned long) &cxacru_cb00
-	},
 	{ /* V = Conexant			P = ADSL modem				*/
 		USB_DEVICE(0x0572, 0xcb01),	.driver_info = (unsigned long) &cxacru_cb00
 	},
+	{ /* V = Conexant			P = ADSL modem (Well PTI-800) */
+		USB_DEVICE(0x0572, 0xcb02),	.driver_info = (unsigned long) &cxacru_cb00
+	},
 	{ /* V = Conexant			P = ADSL modem				*/
 		USB_DEVICE(0x0572, 0xcb06),	.driver_info = (unsigned long) &cxacru_cb00
 	},
@@ -835,14 +832,13 @@ static const struct usb_device_id cxacru
 MODULE_DEVICE_TABLE(usb, cxacru_usb_ids);
 
 static struct usbatm_driver cxacru_driver = {
-	.owner		= THIS_MODULE,
 	.driver_name	= cxacru_driver_name,
 	.bind		= cxacru_bind,
 	.heavy_init	= cxacru_heavy_init,
 	.unbind		= cxacru_unbind,
 	.atm_start	= cxacru_atm_start,
-	.in		= CXACRU_EP_DATA,
-	.out		= CXACRU_EP_DATA,
+	.bulk_in	= CXACRU_EP_DATA,
+	.bulk_out	= CXACRU_EP_DATA,
 	.rx_padding	= 3,
 	.tx_padding	= 11,
 };
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c
index c1b47d7..7860c8a 100644
--- a/drivers/usb/atm/speedtch.c
+++ b/drivers/usb/atm/speedtch.c
@@ -35,12 +35,14 @@
 #include <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/timer.h>
+#include <linux/types.h>
+#include <linux/usb_ch9.h>
 #include <linux/workqueue.h>
 
 #include "usbatm.h"
 
 #define DRIVER_AUTHOR	"Johan Verrept, Duncan Sands <duncan.sands@free.fr>"
-#define DRIVER_VERSION	"1.9"
+#define DRIVER_VERSION	"1.10"
 #define DRIVER_DESC	"Alcatel SpeedTouch USB driver version " DRIVER_VERSION
 
 static const char speedtch_driver_name[] = "speedtch";
@@ -66,31 +68,42 @@ static const char speedtch_driver_name[]
 
 #define RESUBMIT_DELAY		1000	/* milliseconds */
 
-#define DEFAULT_ALTSETTING	1
+#define DEFAULT_BULK_ALTSETTING	1
+#define DEFAULT_ISOC_ALTSETTING	2
 #define DEFAULT_DL_512_FIRST	0
+#define DEFAULT_ENABLE_ISOC	0
 #define DEFAULT_SW_BUFFERING	0
 
-static int altsetting = DEFAULT_ALTSETTING;
+static unsigned int altsetting = 0; /* zero means: use the default */
 static int dl_512_first = DEFAULT_DL_512_FIRST;
+static int enable_isoc = DEFAULT_ENABLE_ISOC;
 static int sw_buffering = DEFAULT_SW_BUFFERING;
 
-module_param(altsetting, int, S_IRUGO | S_IWUSR);
+module_param(altsetting, uint, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(altsetting,
-		 "Alternative setting for data interface (default: "
-		 __MODULE_STRING(DEFAULT_ALTSETTING) ")");
+		"Alternative setting for data interface (bulk_default: "
+		__MODULE_STRING(DEFAULT_BULK_ALTSETTING) "; isoc_default: "
+		__MODULE_STRING(DEFAULT_ISOC_ALTSETTING) ")");
 
 module_param(dl_512_first, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(dl_512_first,
 		 "Read 512 bytes before sending firmware (default: "
 		 __MODULE_STRING(DEFAULT_DL_512_FIRST) ")");
 
+module_param(enable_isoc, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(enable_isoc,
+		"Use isochronous transfers if available (default: "
+		__MODULE_STRING(DEFAULT_ENABLE_ISOC) ")");
+
 module_param(sw_buffering, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(sw_buffering,
 		 "Enable software buffering (default: "
 		 __MODULE_STRING(DEFAULT_SW_BUFFERING) ")");
 
+#define INTERFACE_DATA		1
 #define ENDPOINT_INT		0x81
-#define ENDPOINT_DATA		0x07
+#define ENDPOINT_BULK_DATA	0x07
+#define ENDPOINT_ISOC_DATA	0x07
 #define ENDPOINT_FIRMWARE	0x05
 
 #define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) )
@@ -98,6 +111,8 @@ MODULE_PARM_DESC(sw_buffering,
 struct speedtch_instance_data {
 	struct usbatm_data *usbatm;
 
+	unsigned int altsetting;
+
 	struct work_struct status_checker;
 
 	unsigned char last_status;
@@ -205,7 +220,7 @@ static int speedtch_upload_firmware(stru
 				   buffer, 0x200, &actual_length, 2000);
 
 		if (ret < 0 && ret != -ETIMEDOUT)
-			usb_dbg(usbatm, "%s: read BLOCK0 from modem failed (%d)!\n", __func__, ret);
+			usb_warn(usbatm, "%s: read BLOCK0 from modem failed (%d)!\n", __func__, ret);
 		else
 			usb_dbg(usbatm, "%s: BLOCK0 downloaded (%d bytes)\n", __func__, ret);
 	}
@@ -219,7 +234,7 @@ static int speedtch_upload_firmware(stru
 				   buffer, thislen, &actual_length, DATA_TIMEOUT);
 
 		if (ret < 0) {
-			usb_dbg(usbatm, "%s: write BLOCK1 to modem failed (%d)!\n", __func__, ret);
+			usb_err(usbatm, "%s: write BLOCK1 to modem failed (%d)!\n", __func__, ret);
 			goto out_free;
 		}
 		usb_dbg(usbatm, "%s: BLOCK1 uploaded (%zu bytes)\n", __func__, fw1->size);
@@ -232,7 +247,7 @@ static int speedtch_upload_firmware(stru
 			   buffer, 0x200, &actual_length, DATA_TIMEOUT);
 
 	if (ret < 0) {
-		usb_dbg(usbatm, "%s: read BLOCK2 from modem failed (%d)!\n", __func__, ret);
+		usb_err(usbatm, "%s: read BLOCK2 from modem failed (%d)!\n", __func__, ret);
 		goto out_free;
 	}
 	usb_dbg(usbatm, "%s: BLOCK2 downloaded (%d bytes)\n", __func__, actual_length);
@@ -246,7 +261,7 @@ static int speedtch_upload_firmware(stru
 				   buffer, thislen, &actual_length, DATA_TIMEOUT);
 
 		if (ret < 0) {
-			usb_dbg(usbatm, "%s: write BLOCK3 to modem failed (%d)!\n", __func__, ret);
+			usb_err(usbatm, "%s: write BLOCK3 to modem failed (%d)!\n", __func__, ret);
 			goto out_free;
 		}
 	}
@@ -259,7 +274,7 @@ static int speedtch_upload_firmware(stru
 			   buffer, 0x200, &actual_length, DATA_TIMEOUT);
 
 	if (ret < 0) {
-		usb_dbg(usbatm, "%s: read BLOCK4 from modem failed (%d)!\n", __func__, ret);
+		usb_err(usbatm, "%s: read BLOCK4 from modem failed (%d)!\n", __func__, ret);
 		goto out_free;
 	}
 
@@ -270,6 +285,11 @@ static int speedtch_upload_firmware(stru
 	   because we're in our own kernel thread anyway. */
 	msleep_interruptible(1000);
 
+	if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->altsetting)) < 0) {
+		usb_err(usbatm, "%s: setting interface to %d failed (%d)!\n", __func__, instance->altsetting, ret);
+		goto out_free;
+	}
+
 	/* Enable software buffering, if requested */
 	if (sw_buffering)
 		speedtch_set_swbuff(instance, 1);
@@ -285,8 +305,8 @@ out:
 	return ret;
 }
 
-static int speedtch_find_firmware(struct usb_interface *intf, int phase,
-				  const struct firmware **fw_p)
+static int speedtch_find_firmware(struct usbatm_data *usbatm, struct usb_interface *intf,
+				  int phase, const struct firmware **fw_p)
 {
 	struct device *dev = &intf->dev;
 	const u16 bcdDevice = le16_to_cpu(interface_to_usbdev(intf)->descriptor.bcdDevice);
@@ -295,24 +315,24 @@ static int speedtch_find_firmware(struct
 	char buf[24];
 
 	sprintf(buf, "speedtch-%d.bin.%x.%02x", phase, major_revision, minor_revision);
-	dev_dbg(dev, "%s: looking for %s\n", __func__, buf);
+	usb_dbg(usbatm, "%s: looking for %s\n", __func__, buf);
 
 	if (request_firmware(fw_p, buf, dev)) {
 		sprintf(buf, "speedtch-%d.bin.%x", phase, major_revision);
-		dev_dbg(dev, "%s: looking for %s\n", __func__, buf);
+		usb_dbg(usbatm, "%s: looking for %s\n", __func__, buf);
 
 		if (request_firmware(fw_p, buf, dev)) {
 			sprintf(buf, "speedtch-%d.bin", phase);
-			dev_dbg(dev, "%s: looking for %s\n", __func__, buf);
+			usb_dbg(usbatm, "%s: looking for %s\n", __func__, buf);
 
 			if (request_firmware(fw_p, buf, dev)) {
-				dev_warn(dev, "no stage %d firmware found!\n", phase);
+				usb_err(usbatm, "%s: no stage %d firmware found!\n", __func__, phase);
 				return -ENOENT;
 			}
 		}
 	}
 
-	dev_info(dev, "found stage %d firmware %s\n", phase, buf);
+	usb_info(usbatm, "found stage %d firmware %s\n", phase, buf);
 
 	return 0;
 }
@@ -323,15 +343,16 @@ static int speedtch_heavy_init(struct us
 	struct speedtch_instance_data *instance = usbatm->driver_data;
 	int ret;
 
-	if ((ret = speedtch_find_firmware(intf, 1, &fw1)) < 0)
-			return ret;
+	if ((ret = speedtch_find_firmware(usbatm, intf, 1, &fw1)) < 0)
+		return ret;
 
-	if ((ret = speedtch_find_firmware(intf, 2, &fw2)) < 0) {
+	if ((ret = speedtch_find_firmware(usbatm, intf, 2, &fw2)) < 0) {
 		release_firmware(fw1);
 		return ret;
 	}
 
-	ret = speedtch_upload_firmware(instance, fw1, fw2);
+	if ((ret = speedtch_upload_firmware(instance, fw1, fw2)) < 0)
+		usb_err(usbatm, "%s: firmware upload failed (%d)!\n", __func__, ret);
 
 	release_firmware(fw2);
 	release_firmware(fw1);
@@ -428,7 +449,9 @@ static void speedtch_check_status(struct
 	int down_speed, up_speed, ret;
 	unsigned char status;
 
+#ifdef VERBOSE_DEBUG
 	atm_dbg(usbatm, "%s entered\n", __func__);
+#endif
 
 	ret = speedtch_read_status(instance);
 	if (ret < 0) {
@@ -441,9 +464,9 @@ static void speedtch_check_status(struct
 
 	status = buf[OFFSET_7];
 
-	atm_dbg(usbatm, "%s: line state %02x\n", __func__, status);
-
 	if ((status != instance->last_status) || !status) {
+		atm_dbg(usbatm, "%s: line state 0x%02x\n", __func__, status);
+
 		switch (status) {
 		case 0:
 			atm_dev->signal = ATM_PHY_SIG_LOST;
@@ -484,7 +507,7 @@ static void speedtch_check_status(struct
 
 		default:
 			atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
-			atm_info(usbatm, "Unknown line state %02x\n", status);
+			atm_info(usbatm, "unknown line state %02x\n", status);
 			break;
 		}
 
@@ -583,11 +606,6 @@ static int speedtch_atm_start(struct usb
 
 	atm_dbg(usbatm, "%s entered\n", __func__);
 
-	if ((ret = usb_set_interface(usb_dev, 1, altsetting)) < 0) {
-		atm_dbg(usbatm, "%s: usb_set_interface returned %d!\n", __func__, ret);
-		return ret;
-	}
-
 	/* Set MAC address, it is stored in the serial number */
 	memset(atm_dev->esi, 0, sizeof(atm_dev->esi));
 	if (usb_string(usb_dev, usb_dev->descriptor.iSerialNumber, mac_str, sizeof(mac_str)) == 12) {
@@ -678,20 +696,27 @@ static void speedtch_release_interfaces(
 
 static int speedtch_bind(struct usbatm_data *usbatm,
 			 struct usb_interface *intf,
-			 const struct usb_device_id *id,
-			 int *need_heavy_init)
+			 const struct usb_device_id *id)
 {
 	struct usb_device *usb_dev = interface_to_usbdev(intf);
-	struct usb_interface *cur_intf;
+	struct usb_interface *cur_intf, *data_intf;
 	struct speedtch_instance_data *instance;
 	int ifnum = intf->altsetting->desc.bInterfaceNumber;
 	int num_interfaces = usb_dev->actconfig->desc.bNumInterfaces;
 	int i, ret;
+	int use_isoc;
 
 	usb_dbg(usbatm, "%s entered\n", __func__);
 
+	/* sanity checks */
+
 	if (usb_dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) {
-		usb_dbg(usbatm, "%s: wrong device class %d\n", __func__, usb_dev->descriptor.bDeviceClass);
+		usb_err(usbatm, "%s: wrong device class %d\n", __func__, usb_dev->descriptor.bDeviceClass);
+		return -ENODEV;
+	}
+
+	if (!(data_intf = usb_ifnum_to_if(usb_dev, INTERFACE_DATA))) {
+		usb_err(usbatm, "%s: data interface not found!\n", __func__);
 		return -ENODEV;
 	}
 
@@ -704,25 +729,71 @@ static int speedtch_bind(struct usbatm_d
 			ret = usb_driver_claim_interface(&speedtch_usb_driver, cur_intf, usbatm);
 
 			if (ret < 0) {
-				usb_dbg(usbatm, "%s: failed to claim interface %d (%d)\n", __func__, i, ret);
+				usb_err(usbatm, "%s: failed to claim interface %2d (%d)!\n", __func__, i, ret);
 				speedtch_release_interfaces(usb_dev, i);
 				return ret;
 			}
 		}
 	}
 
-	instance = kmalloc(sizeof(*instance), GFP_KERNEL);
+	instance = kzalloc(sizeof(*instance), GFP_KERNEL);
 
 	if (!instance) {
-		usb_dbg(usbatm, "%s: no memory for instance data!\n", __func__);
+		usb_err(usbatm, "%s: no memory for instance data!\n", __func__);
 		ret = -ENOMEM;
 		goto fail_release;
 	}
 
-	memset(instance, 0, sizeof(struct speedtch_instance_data));
-
 	instance->usbatm = usbatm;
 
+	/* altsetting and enable_isoc may change at any moment, so take a snapshot */
+	instance->altsetting = altsetting;
+	use_isoc = enable_isoc;
+
+	if (instance->altsetting)
+		if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->altsetting)) < 0) {
+			usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, instance->altsetting, ret);
+			instance->altsetting = 0; /* fall back to default */
+		}
+
+	if (!instance->altsetting && use_isoc)
+		if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_ISOC_ALTSETTING)) < 0) {
+			usb_dbg(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_ISOC_ALTSETTING, ret);
+			use_isoc = 0; /* fall back to bulk */
+		}
+
+	if (use_isoc) {
+		const struct usb_host_interface *desc = data_intf->cur_altsetting;
+		const __u8 target_address = USB_DIR_IN | usbatm->driver->isoc_in;
+		int i;
+
+		use_isoc = 0; /* fall back to bulk if endpoint not found */
+
+		for (i=0; i<desc->desc.bNumEndpoints; i++) {
+			const struct usb_endpoint_descriptor *endpoint_desc = &desc->endpoint[i].desc;
+
+			if ((endpoint_desc->bEndpointAddress == target_address)) {
+				use_isoc = (endpoint_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+					USB_ENDPOINT_XFER_ISOC;
+				break;
+			}
+		}
+
+		if (!use_isoc)
+			usb_info(usbatm, "isochronous transfer not supported - using bulk\n");
+	}
+
+	if (!use_isoc && !instance->altsetting)
+		if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_BULK_ALTSETTING)) < 0) {
+			usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_BULK_ALTSETTING, ret);
+			goto fail_free;
+		}
+
+	if (!instance->altsetting)
+		instance->altsetting = use_isoc ? DEFAULT_ISOC_ALTSETTING : DEFAULT_BULK_ALTSETTING;
+
+	usbatm->flags |= (use_isoc ? UDSL_USE_ISOC : 0);
+
 	INIT_WORK(&instance->status_checker, (void *)speedtch_check_status, instance);
 
 	instance->status_checker.timer.function = speedtch_status_poll;
@@ -749,13 +820,15 @@ static int speedtch_bind(struct usbatm_d
 			      0x12, 0xc0, 0x07, 0x00,
 			      instance->scratch_buffer + OFFSET_7, SIZE_7, 500);
 
-	*need_heavy_init = (ret != SIZE_7);
+	usbatm->flags |= (ret == SIZE_7 ? UDSL_SKIP_HEAVY_INIT : 0);
 
-	usb_dbg(usbatm, "%s: firmware %s loaded\n", __func__, need_heavy_init ? "not" : "already");
+	usb_dbg(usbatm, "%s: firmware %s loaded\n", __func__, usbatm->flags & UDSL_SKIP_HEAVY_INIT ? "already" : "not");
 
-	if (*need_heavy_init)
-		if ((ret = usb_reset_device(usb_dev)) < 0)
+	if (!(usbatm->flags & UDSL_SKIP_HEAVY_INIT))
+		if ((ret = usb_reset_device(usb_dev)) < 0) {
+			usb_err(usbatm, "%s: device reset failed (%d)!\n", __func__, ret);
 			goto fail_free;
+		}
 
         usbatm->driver_data = instance;
 
@@ -787,15 +860,15 @@ static void speedtch_unbind(struct usbat
 ***********/
 
 static struct usbatm_driver speedtch_usbatm_driver = {
-	.owner		= THIS_MODULE,
 	.driver_name	= speedtch_driver_name,
 	.bind		= speedtch_bind,
 	.heavy_init	= speedtch_heavy_init,
 	.unbind		= speedtch_unbind,
 	.atm_start	= speedtch_atm_start,
 	.atm_stop	= speedtch_atm_stop,
-	.in		= ENDPOINT_DATA,
-	.out		= ENDPOINT_DATA
+	.bulk_in	= ENDPOINT_BULK_DATA,
+	.bulk_out	= ENDPOINT_BULK_DATA,
+	.isoc_in	= ENDPOINT_ISOC_DATA
 };
 
 static int speedtch_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index 7d2a679..830d2c9 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -63,11 +63,12 @@
 #include <linux/ctype.h>
 #include <linux/kthread.h>
 #include <linux/version.h>
+#include <linux/mutex.h>
 #include <asm/unaligned.h>
 
 #include "usbatm.h"
 
-#define EAGLEUSBVERSION "ueagle 1.1"
+#define EAGLEUSBVERSION "ueagle 1.2"
 
 
 /*
@@ -358,16 +359,19 @@ struct intr_pkt {
 #define INTR_PKT_SIZE 28
 
 static struct usb_driver uea_driver;
-static DECLARE_MUTEX(uea_semaphore);
+static DEFINE_MUTEX(uea_mutex);
 static const char *chip_name[] = {"ADI930", "Eagle I", "Eagle II", "Eagle III"};
 
 static int modem_index;
 static unsigned int debug;
+static int use_iso[NB_MODEM] = {[0 ... (NB_MODEM - 1)] = 1};
 static int sync_wait[NB_MODEM];
 static char *cmv_file[NB_MODEM];
 
 module_param(debug, uint, 0644);
 MODULE_PARM_DESC(debug, "module debug level (0=off,1=on,2=verbose)");
+module_param_array(use_iso, bool, NULL, 0644);
+MODULE_PARM_DESC(use_iso, "use isochronous usb pipe for incoming traffic");
 module_param_array(sync_wait, bool, NULL, 0644);
 MODULE_PARM_DESC(sync_wait, "wait the synchronisation before starting ATM");
 module_param_array(cmv_file, charp, NULL, 0644);
@@ -628,8 +632,7 @@ static int request_dsp(struct uea_softc 
 			dsp_name = FW_DIR "DSPep.bin";
 	}
 
-	ret = request_firmware(&sc->dsp_firm,
-				dsp_name, &sc->usb_dev->dev);
+	ret = request_firmware(&sc->dsp_firm, dsp_name, &sc->usb_dev->dev);
 	if (ret < 0) {
 		uea_err(INS_TO_USBDEV(sc),
 		       "requesting firmware %s failed with error %d\n",
@@ -744,7 +747,6 @@ static inline int wait_cmv_ack(struct ue
 		return ret;
 
 	return (ret == 0) ? -ETIMEDOUT : 0;
-
 }
 
 #define UCDC_SEND_ENCAPSULATED_COMMAND 0x00
@@ -935,6 +937,7 @@ static int uea_stat(struct uea_softc *sc
 	 * ADI930 don't support it (-EPIPE error).
 	 */
 	if (UEA_CHIP_VERSION(sc) != ADI930
+		    && !use_iso[sc->modem_index]
 		    && sc->stats.phy.dsrate != (data >> 16) * 32) {
 		/* Original timming from ADI(used in windows driver)
 		 * 0x20ffff>>16 * 32 = 32 * 32 = 1Mbits
@@ -1010,7 +1013,7 @@ static int request_cmvs(struct uea_softc
 	int ret, size;
 	u8 *data;
 	char *file;
-	static char cmv_name[256] = FW_DIR;
+	char cmv_name[FIRMWARE_NAME_MAX]; /* 30 bytes stack variable */
 
 	if (cmv_file[sc->modem_index] == NULL) {
 		if (UEA_CHIP_VERSION(sc) == ADI930)
@@ -1184,8 +1187,7 @@ static int load_XILINX_firmware(struct u
 		}
 	}
 
-	/* finish to send the fpga
-	 */
+	/* finish to send the fpga */
 	ret = uea_request(sc, 0xe, 1, 0, NULL);
 	if (ret < 0) {
 		uea_err(INS_TO_USBDEV(sc),
@@ -1193,9 +1195,7 @@ static int load_XILINX_firmware(struct u
 		goto err1;
 	}
 
-	/*
-	 * Tell the modem we finish : de-assert reset
-	 */
+	/* Tell the modem we finish : de-assert reset */
 	value = 0;
 	ret = uea_send_modem_cmd(sc->usb_dev, 0xe, 1, &value);
 	if (ret < 0)
@@ -1209,6 +1209,7 @@ err0:
 	return ret;
 }
 
+/* The modem send us an ack. First with check if it right */
 static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv)
 {
 	uea_enters(INS_TO_USBDEV(sc));
@@ -1268,23 +1269,19 @@ bad1:
  */
 static void uea_intr(struct urb *urb, struct pt_regs *regs)
 {
-	struct uea_softc *sc = (struct uea_softc *)urb->context;
-	struct intr_pkt *intr;
+	struct uea_softc *sc = urb->context;
+	struct intr_pkt *intr = urb->transfer_buffer;
 	uea_enters(INS_TO_USBDEV(sc));
 
-	if (urb->status < 0) {
+	if (unlikely(urb->status < 0)) {
 		uea_err(INS_TO_USBDEV(sc), "uea_intr() failed with %d\n",
 		       urb->status);
 		return;
 	}
 
-	intr = (struct intr_pkt *) urb->transfer_buffer;
-
 	/* device-to-host interrupt */
 	if (intr->bType != 0x08 || sc->booting) {
-		uea_err(INS_TO_USBDEV(sc), "wrong intr\n");
-		// rebooting ?
-		// sc->reset = 1;
+		uea_err(INS_TO_USBDEV(sc), "wrong interrupt\n");
 		goto resubmit;
 	}
 
@@ -1300,7 +1297,7 @@ static void uea_intr(struct urb *urb, st
 		break;
 
 	default:
-		uea_err(INS_TO_USBDEV(sc), "unknown intr %u\n",
+		uea_err(INS_TO_USBDEV(sc), "unknown interrupt %u\n",
 		       le16_to_cpu(intr->wInterrupt));
 	}
 
@@ -1379,7 +1376,7 @@ static void uea_stop(struct uea_softc *s
 	int ret;
 	uea_enters(INS_TO_USBDEV(sc));
 	ret = kthread_stop(sc->kthread);
-	uea_info(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret);
+	uea_dbg(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret);
 
 	/* stop any pending boot process */
 	flush_scheduled_work();
@@ -1418,13 +1415,13 @@ static ssize_t read_status(struct device
 	int ret = -ENODEV;
 	struct uea_softc *sc;
 
-	down(&uea_semaphore);
+	mutex_lock(&uea_mutex);
 	sc = dev_to_uea(dev);
 	if (!sc)
 		goto out;
 	ret = snprintf(buf, 10, "%08x\n", sc->stats.phy.state);
 out:
-	up(&uea_semaphore);
+	mutex_unlock(&uea_mutex);
 	return ret;
 }
 
@@ -1434,14 +1431,14 @@ static ssize_t reboot(struct device *dev
 	int ret = -ENODEV;
 	struct uea_softc *sc;
 
-	down(&uea_semaphore);
+	mutex_lock(&uea_mutex);
 	sc = dev_to_uea(dev);
 	if (!sc)
 		goto out;
 	sc->reset = 1;
 	ret = count;
 out:
-	up(&uea_semaphore);
+	mutex_unlock(&uea_mutex);
 	return ret;
 }
 
@@ -1453,7 +1450,7 @@ static ssize_t read_human_status(struct 
 	int ret = -ENODEV;
 	struct uea_softc *sc;
 
-	down(&uea_semaphore);
+	mutex_lock(&uea_mutex);
 	sc = dev_to_uea(dev);
 	if (!sc)
 		goto out;
@@ -1473,7 +1470,7 @@ static ssize_t read_human_status(struct 
 		break;
 	}
 out:
-	up(&uea_semaphore);
+	mutex_unlock(&uea_mutex);
 	return ret;
 }
 
@@ -1485,7 +1482,7 @@ static ssize_t read_delin(struct device 
 	int ret = -ENODEV;
 	struct uea_softc *sc;
 
-	down(&uea_semaphore);
+	mutex_lock(&uea_mutex);
 	sc = dev_to_uea(dev);
 	if (!sc)
 		goto out;
@@ -1497,7 +1494,7 @@ static ssize_t read_delin(struct device 
 	else
 		ret = sprintf(buf, "GOOD\n");
 out:
-	up(&uea_semaphore);
+	mutex_unlock(&uea_mutex);
 	return ret;
 }
 
@@ -1511,7 +1508,7 @@ static ssize_t read_##name(struct device
 	int ret = -ENODEV; 					\
 	struct uea_softc *sc; 					\
  								\
-	down(&uea_semaphore); 					\
+	mutex_lock(&uea_mutex); 					\
 	sc = dev_to_uea(dev);					\
 	if (!sc) 						\
 		goto out; 					\
@@ -1519,7 +1516,7 @@ static ssize_t read_##name(struct device
 	if (reset)						\
 		sc->stats.phy.name = 0;				\
 out: 								\
-	up(&uea_semaphore); 					\
+	mutex_unlock(&uea_mutex); 					\
 	return ret; 						\
 } 								\
 								\
@@ -1617,7 +1614,7 @@ static void create_fs_entries(struct uea
 }
 
 static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf,
-		   const struct usb_device_id *id, int *heavy)
+		   const struct usb_device_id *id)
 {
 	struct usb_device *usb = interface_to_usbdev(intf);
 	struct uea_softc *sc;
@@ -1629,16 +1626,14 @@ static int uea_bind(struct usbatm_data *
 	if (ifnum != UEA_INTR_IFACE_NO)
 		return -ENODEV;
 
-	*heavy = sync_wait[modem_index];
+	usbatm->flags = (sync_wait[modem_index] ? 0 : UDSL_SKIP_HEAVY_INIT);
 
 	/* interface 1 is for outbound traffic */
 	ret = claim_interface(usb, usbatm, UEA_US_IFACE_NO);
 	if (ret < 0)
 		return ret;
 
-	/* ADI930 has only 2 interfaces and inbound traffic
-	 * is on interface 1
-	 */
+	/* ADI930 has only 2 interfaces and inbound traffic is on interface 1 */
 	if (UEA_CHIP_VERSION(id) != ADI930) {
 		/* interface 2 is for inbound traffic */
 		ret = claim_interface(usb, usbatm, UEA_DS_IFACE_NO);
@@ -1658,6 +1653,25 @@ static int uea_bind(struct usbatm_data *
 	sc->modem_index = (modem_index < NB_MODEM) ? modem_index++ : 0;
 	sc->driver_info = id->driver_info;
 
+	/* ADI930 don't support iso */
+	if (UEA_CHIP_VERSION(id) != ADI930 && use_iso[sc->modem_index]) {
+		int i;
+
+		/* try set fastest alternate for inbound traffic interface */
+		for (i = FASTEST_ISO_INTF; i > 0; i--)
+			if (usb_set_interface(usb, UEA_DS_IFACE_NO, i) == 0)
+				break;
+
+		if (i > 0) {
+			uea_dbg(usb, "set alternate %d for 2 interface\n", i);
+			uea_info(usb, "using iso mode\n");
+			usbatm->flags |= UDSL_USE_ISOC | UDSL_IGNORE_EILSEQ;
+		} else {
+			uea_err(usb, "setting any alternate failed for "
+					"2 interface, using bulk mode\n");
+		}
+	}
+
 	ret = uea_boot(sc);
 	if (ret < 0) {
 		kfree(sc);
@@ -1701,13 +1715,13 @@ static void uea_unbind(struct usbatm_dat
 
 static struct usbatm_driver uea_usbatm_driver = {
 	.driver_name = "ueagle-atm",
-	.owner = THIS_MODULE,
 	.bind = uea_bind,
 	.atm_start = uea_atm_open,
 	.unbind = uea_unbind,
 	.heavy_init = uea_heavy,
-	.in = UEA_BULK_DATA_PIPE,
-	.out = UEA_BULK_DATA_PIPE,
+	.bulk_in = UEA_BULK_DATA_PIPE,
+	.bulk_out = UEA_BULK_DATA_PIPE,
+	.isoc_in = UEA_ISO_DATA_PIPE,
 };
 
 static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -1738,9 +1752,9 @@ static void uea_disconnect(struct usb_in
 	 * Pre-firmware device has one interface
 	 */
 	if (usb->config->desc.bNumInterfaces != 1 && ifnum == 0) {
-		down(&uea_semaphore);
+		mutex_lock(&uea_mutex);
 		usbatm_usb_disconnect(intf);
-		up(&uea_semaphore);
+		mutex_unlock(&uea_mutex);
 		uea_info(usb, "ADSL device removed\n");
 	}
 
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c
index 7af1883..c1211fc 100644
--- a/drivers/usb/atm/usbatm.c
+++ b/drivers/usb/atm/usbatm.c
@@ -72,6 +72,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/netdevice.h>
 #include <linux/proc_fs.h>
 #include <linux/sched.h>
 #include <linux/signal.h>
@@ -91,19 +92,18 @@ static int usbatm_print_packet(const uns
 #endif
 
 #define DRIVER_AUTHOR	"Johan Verrept, Duncan Sands <duncan.sands@free.fr>"
-#define DRIVER_VERSION	"1.9"
+#define DRIVER_VERSION	"1.10"
 #define DRIVER_DESC	"Generic USB ATM/DSL I/O, version " DRIVER_VERSION
 
 static const char usbatm_driver_name[] = "usbatm";
 
 #define UDSL_MAX_RCV_URBS		16
 #define UDSL_MAX_SND_URBS		16
-#define UDSL_MAX_RCV_BUF_SIZE		1024	/* ATM cells */
-#define UDSL_MAX_SND_BUF_SIZE		1024	/* ATM cells */
+#define UDSL_MAX_BUF_SIZE		64 * 1024	/* bytes */
 #define UDSL_DEFAULT_RCV_URBS		4
 #define UDSL_DEFAULT_SND_URBS		4
-#define UDSL_DEFAULT_RCV_BUF_SIZE	64	/* ATM cells */
-#define UDSL_DEFAULT_SND_BUF_SIZE	64	/* ATM cells */
+#define UDSL_DEFAULT_RCV_BUF_SIZE	64 * ATM_CELL_SIZE	/* bytes */
+#define UDSL_DEFAULT_SND_BUF_SIZE	64 * ATM_CELL_SIZE	/* bytes */
 
 #define ATM_CELL_HEADER			(ATM_CELL_SIZE - ATM_CELL_PAYLOAD)
 
@@ -111,8 +111,8 @@ static const char usbatm_driver_name[] =
 
 static unsigned int num_rcv_urbs = UDSL_DEFAULT_RCV_URBS;
 static unsigned int num_snd_urbs = UDSL_DEFAULT_SND_URBS;
-static unsigned int rcv_buf_size = UDSL_DEFAULT_RCV_BUF_SIZE;
-static unsigned int snd_buf_size = UDSL_DEFAULT_SND_BUF_SIZE;
+static unsigned int rcv_buf_bytes = UDSL_DEFAULT_RCV_BUF_SIZE;
+static unsigned int snd_buf_bytes = UDSL_DEFAULT_SND_BUF_SIZE;
 
 module_param(num_rcv_urbs, uint, S_IRUGO);
 MODULE_PARM_DESC(num_rcv_urbs,
@@ -126,15 +126,15 @@ MODULE_PARM_DESC(num_snd_urbs,
 		 __MODULE_STRING(UDSL_MAX_SND_URBS) ", default: "
 		 __MODULE_STRING(UDSL_DEFAULT_SND_URBS) ")");
 
-module_param(rcv_buf_size, uint, S_IRUGO);
-MODULE_PARM_DESC(rcv_buf_size,
-		 "Size of the buffers used for reception in ATM cells (range: 1-"
-		 __MODULE_STRING(UDSL_MAX_RCV_BUF_SIZE) ", default: "
+module_param(rcv_buf_bytes, uint, S_IRUGO);
+MODULE_PARM_DESC(rcv_buf_bytes,
+		 "Size of the buffers used for reception, in bytes (range: 1-"
+		 __MODULE_STRING(UDSL_MAX_BUF_SIZE) ", default: "
 		 __MODULE_STRING(UDSL_DEFAULT_RCV_BUF_SIZE) ")");
 
-module_param(snd_buf_size, uint, S_IRUGO);
-MODULE_PARM_DESC(snd_buf_size,
-		 "Size of the buffers used for transmission in ATM cells (range: 1-"
+module_param(snd_buf_bytes, uint, S_IRUGO);
+MODULE_PARM_DESC(snd_buf_bytes,
+		 "Size of the buffers used for transmission, in bytes (range: 1-"
 		 __MODULE_STRING(UDSL_MAX_SND_BUF_SIZE) ", default: "
 		 __MODULE_STRING(UDSL_DEFAULT_SND_BUF_SIZE) ")");
 
@@ -166,10 +166,10 @@ struct usbatm_control {
 
 /* ATM */
 
-static void usbatm_atm_dev_close(struct atm_dev *dev);
+static void usbatm_atm_dev_close(struct atm_dev *atm_dev);
 static int usbatm_atm_open(struct atm_vcc *vcc);
 static void usbatm_atm_close(struct atm_vcc *vcc);
-static int usbatm_atm_ioctl(struct atm_dev *dev, unsigned int cmd, void __user * arg);
+static int usbatm_atm_ioctl(struct atm_dev *atm_dev, unsigned int cmd, void __user * arg);
 static int usbatm_atm_send(struct atm_vcc *vcc, struct sk_buff *skb);
 static int usbatm_atm_proc_read(struct atm_dev *atm_dev, loff_t * pos, char *page);
 
@@ -199,7 +199,7 @@ static inline void usbatm_pop(struct atm
 	if (vcc->pop)
 		vcc->pop(vcc, skb);
 	else
-		dev_kfree_skb(skb);
+		dev_kfree_skb_any(skb);
 }
 
 
@@ -234,8 +234,9 @@ static int usbatm_submit_urb(struct urb 
 
 	ret = usb_submit_urb(urb, GFP_ATOMIC);
 	if (ret) {
-		atm_dbg(channel->usbatm, "%s: urb 0x%p submission failed (%d)!\n",
-			__func__, urb, ret);
+		if (printk_ratelimit())
+			atm_warn(channel->usbatm, "%s: urb 0x%p submission failed (%d)!\n",
+				__func__, urb, ret);
 
 		/* consider all errors transient and return the buffer back to the queue */
 		urb->status = -EAGAIN;
@@ -269,10 +270,16 @@ static void usbatm_complete(struct urb *
 
 	spin_unlock_irqrestore(&channel->lock, flags);
 
-	if (unlikely(urb->status))
+	if (unlikely(urb->status) &&
+			(!(channel->usbatm->flags & UDSL_IGNORE_EILSEQ) ||
+			 urb->status != -EILSEQ ))
+	{
+		if (printk_ratelimit())
+			atm_warn(channel->usbatm, "%s: urb 0x%p failed (%d)!\n",
+				__func__, urb, urb->status);
 		/* throttle processing in case of an error */
 		mod_timer(&channel->delay, jiffies + msecs_to_jiffies(THROTTLE_MSECS));
-	else
+	} else
 		tasklet_schedule(&channel->tasklet);
 }
 
@@ -284,129 +291,167 @@ static void usbatm_complete(struct urb *
 static inline struct usbatm_vcc_data *usbatm_find_vcc(struct usbatm_data *instance,
 						  short vpi, int vci)
 {
-	struct usbatm_vcc_data *vcc;
+	struct usbatm_vcc_data *vcc_data;
 
-	list_for_each_entry(vcc, &instance->vcc_list, list)
-		if ((vcc->vci == vci) && (vcc->vpi == vpi))
-			return vcc;
+	list_for_each_entry(vcc_data, &instance->vcc_list, list)
+		if ((vcc_data->vci == vci) && (vcc_data->vpi == vpi))
+			return vcc_data;
 	return NULL;
 }
 
-static void usbatm_extract_cells(struct usbatm_data *instance,
-			       unsigned char *source, unsigned int avail_data)
+static void usbatm_extract_one_cell(struct usbatm_data *instance, unsigned char *source)
 {
-	struct usbatm_vcc_data *cached_vcc = NULL;
 	struct atm_vcc *vcc;
 	struct sk_buff *sarb;
-	unsigned int stride = instance->rx_channel.stride;
-	int vci, cached_vci = 0;
-	short vpi, cached_vpi = 0;
-	u8 pti;
+	short vpi = ((source[0] & 0x0f) << 4)  | (source[1] >> 4);
+	int vci = ((source[1] & 0x0f) << 12) | (source[2] << 4) | (source[3] >> 4);
+	u8 pti = ((source[3] & 0xe) >> 1);
 
-	for (; avail_data >= stride; avail_data -= stride, source += stride) {
-		vpi = ((source[0] & 0x0f) << 4)  | (source[1] >> 4);
-		vci = ((source[1] & 0x0f) << 12) | (source[2] << 4) | (source[3] >> 4);
-		pti = ((source[3] & 0xe) >> 1);
+	vdbg("%s: vpi %hd, vci %d, pti %d", __func__, vpi, vci, pti);
 
-		vdbg("%s: vpi %hd, vci %d, pti %d", __func__, vpi, vci, pti);
+	if ((vci != instance->cached_vci) || (vpi != instance->cached_vpi)) {
+		instance->cached_vpi = vpi;
+		instance->cached_vci = vci;
 
-		if ((vci != cached_vci) || (vpi != cached_vpi)) {
-			cached_vpi = vpi;
-			cached_vci = vci;
+		instance->cached_vcc = usbatm_find_vcc(instance, vpi, vci);
 
-			cached_vcc = usbatm_find_vcc(instance, vpi, vci);
+		if (!instance->cached_vcc)
+			atm_rldbg(instance, "%s: unknown vpi/vci (%hd/%d)!\n", __func__, vpi, vci);
+	}
 
-			if (!cached_vcc)
-				atm_dbg(instance, "%s: unknown vpi/vci (%hd/%d)!\n", __func__, vpi, vci);
-		}
+	if (!instance->cached_vcc)
+		return;
 
-		if (!cached_vcc)
-			continue;
+	vcc = instance->cached_vcc->vcc;
 
-		vcc = cached_vcc->vcc;
+	/* OAM F5 end-to-end */
+	if (pti == ATM_PTI_E2EF5) {
+		if (printk_ratelimit())
+			atm_warn(instance, "%s: OAM not supported (vpi %d, vci %d)!\n",
+				__func__, vpi, vci);
+		atomic_inc(&vcc->stats->rx_err);
+		return;
+	}
+
+	sarb = instance->cached_vcc->sarb;
 
-		/* OAM F5 end-to-end */
-		if (pti == ATM_PTI_E2EF5) {
-			atm_warn(instance, "%s: OAM not supported (vpi %d, vci %d)!\n", __func__, vpi, vci);
+	if (sarb->tail + ATM_CELL_PAYLOAD > sarb->end) {
+		atm_rldbg(instance, "%s: buffer overrun (sarb->len %u, vcc: 0x%p)!\n",
+				__func__, sarb->len, vcc);
+		/* discard cells already received */
+		skb_trim(sarb, 0);
+		UDSL_ASSERT(sarb->tail + ATM_CELL_PAYLOAD <= sarb->end);
+	}
+
+	memcpy(sarb->tail, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD);
+	__skb_put(sarb, ATM_CELL_PAYLOAD);
+
+	if (pti & 1) {
+		struct sk_buff *skb;
+		unsigned int length;
+		unsigned int pdu_length;
+
+		length = (source[ATM_CELL_SIZE - 6] << 8) + source[ATM_CELL_SIZE - 5];
+
+		/* guard against overflow */
+		if (length > ATM_MAX_AAL5_PDU) {
+			atm_rldbg(instance, "%s: bogus length %u (vcc: 0x%p)!\n",
+				  __func__, length, vcc);
 			atomic_inc(&vcc->stats->rx_err);
-			continue;
+			goto out;
 		}
 
-		sarb = cached_vcc->sarb;
+		pdu_length = usbatm_pdu_length(length);
 
-		if (sarb->tail + ATM_CELL_PAYLOAD > sarb->end) {
-			atm_dbg(instance, "%s: buffer overrun (sarb->len %u, vcc: 0x%p)!\n",
-					__func__, sarb->len, vcc);
-			/* discard cells already received */
-			skb_trim(sarb, 0);
-			UDSL_ASSERT(sarb->tail + ATM_CELL_PAYLOAD <= sarb->end);
+		if (sarb->len < pdu_length) {
+			atm_rldbg(instance, "%s: bogus pdu_length %u (sarb->len: %u, vcc: 0x%p)!\n",
+				  __func__, pdu_length, sarb->len, vcc);
+			atomic_inc(&vcc->stats->rx_err);
+			goto out;
 		}
 
-		memcpy(sarb->tail, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD);
-		__skb_put(sarb, ATM_CELL_PAYLOAD);
-
-		if (pti & 1) {
-			struct sk_buff *skb;
-			unsigned int length;
-			unsigned int pdu_length;
-
-			length = (source[ATM_CELL_SIZE - 6] << 8) + source[ATM_CELL_SIZE - 5];
-
-			/* guard against overflow */
-			if (length > ATM_MAX_AAL5_PDU) {
-				atm_dbg(instance, "%s: bogus length %u (vcc: 0x%p)!\n",
-						__func__, length, vcc);
-				atomic_inc(&vcc->stats->rx_err);
-				goto out;
-			}
+		if (crc32_be(~0, sarb->tail - pdu_length, pdu_length) != 0xc704dd7b) {
+			atm_rldbg(instance, "%s: packet failed crc check (vcc: 0x%p)!\n",
+				  __func__, vcc);
+			atomic_inc(&vcc->stats->rx_err);
+			goto out;
+		}
 
-			pdu_length = usbatm_pdu_length(length);
+		vdbg("%s: got packet (length: %u, pdu_length: %u, vcc: 0x%p)", __func__, length, pdu_length, vcc);
 
-			if (sarb->len < pdu_length) {
-				atm_dbg(instance, "%s: bogus pdu_length %u (sarb->len: %u, vcc: 0x%p)!\n",
-						__func__, pdu_length, sarb->len, vcc);
-				atomic_inc(&vcc->stats->rx_err);
-				goto out;
-			}
+		if (!(skb = dev_alloc_skb(length))) {
+			if (printk_ratelimit())
+				atm_err(instance, "%s: no memory for skb (length: %u)!\n",
+					__func__, length);
+			atomic_inc(&vcc->stats->rx_drop);
+			goto out;
+		}
 
-			if (crc32_be(~0, sarb->tail - pdu_length, pdu_length) != 0xc704dd7b) {
-				atm_dbg(instance, "%s: packet failed crc check (vcc: 0x%p)!\n",
-						__func__, vcc);
-				atomic_inc(&vcc->stats->rx_err);
-				goto out;
-			}
+		vdbg("%s: allocated new sk_buff (skb: 0x%p, skb->truesize: %u)", __func__, skb, skb->truesize);
 
-			vdbg("%s: got packet (length: %u, pdu_length: %u, vcc: 0x%p)", __func__, length, pdu_length, vcc);
+		if (!atm_charge(vcc, skb->truesize)) {
+			atm_rldbg(instance, "%s: failed atm_charge (skb->truesize: %u)!\n",
+				  __func__, skb->truesize);
+			dev_kfree_skb_any(skb);
+			goto out;	/* atm_charge increments rx_drop */
+		}
 
-			if (!(skb = dev_alloc_skb(length))) {
-				atm_dbg(instance, "%s: no memory for skb (length: %u)!\n", __func__, length);
-				atomic_inc(&vcc->stats->rx_drop);
-				goto out;
-			}
+		memcpy(skb->data, sarb->tail - pdu_length, length);
+		__skb_put(skb, length);
 
-			vdbg("%s: allocated new sk_buff (skb: 0x%p, skb->truesize: %u)", __func__, skb, skb->truesize);
+		vdbg("%s: sending skb 0x%p, skb->len %u, skb->truesize %u",
+		     __func__, skb, skb->len, skb->truesize);
 
-			if (!atm_charge(vcc, skb->truesize)) {
-				atm_dbg(instance, "%s: failed atm_charge (skb->truesize: %u)!\n", __func__, skb->truesize);
-				dev_kfree_skb(skb);
-				goto out;	/* atm_charge increments rx_drop */
-			}
+		PACKETDEBUG(skb->data, skb->len);
 
-			memcpy(skb->data, sarb->tail - pdu_length, length);
-			__skb_put(skb, length);
+		vcc->push(vcc, skb);
 
-			vdbg("%s: sending skb 0x%p, skb->len %u, skb->truesize %u",
-			     __func__, skb, skb->len, skb->truesize);
+		atomic_inc(&vcc->stats->rx);
+	out:
+		skb_trim(sarb, 0);
+	}
+}
 
-			PACKETDEBUG(skb->data, skb->len);
+static void usbatm_extract_cells(struct usbatm_data *instance,
+		unsigned char *source, unsigned int avail_data)
+{
+	unsigned int stride = instance->rx_channel.stride;
+	unsigned int buf_usage = instance->buf_usage;
 
-			vcc->push(vcc, skb);
+	/* extract cells from incoming data, taking into account that
+	 * the length of avail data may not be a multiple of stride */
 
-			atomic_inc(&vcc->stats->rx);
-		out:
-			skb_trim(sarb, 0);
+	if (buf_usage > 0) {
+		/* we have a partially received atm cell */
+		unsigned char *cell_buf = instance->cell_buf;
+		unsigned int space_left = stride - buf_usage;
+
+		UDSL_ASSERT(buf_usage <= stride);
+
+		if (avail_data >= space_left) {
+			/* add new data and process cell */
+			memcpy(cell_buf + buf_usage, source, space_left);
+			source += space_left;
+			avail_data -= space_left;
+			usbatm_extract_one_cell(instance, cell_buf);
+			instance->buf_usage = 0;
+		} else {
+			/* not enough data to fill the cell */
+			memcpy(cell_buf + buf_usage, source, avail_data);
+			instance->buf_usage = buf_usage + avail_data;
+			return;
 		}
 	}
+
+	for (; avail_data >= stride; avail_data -= stride, source += stride)
+		usbatm_extract_one_cell(instance, source);
+
+	if (avail_data > 0) {
+		/* length was not a multiple of stride -
+		 * save remaining data for next call */
+		memcpy(instance->cell_buf, source, avail_data);
+		instance->buf_usage = avail_data;
+	}
 }
 
 
@@ -420,14 +465,14 @@ static unsigned int usbatm_write_cells(s
 {
 	struct usbatm_control *ctrl = UDSL_SKB(skb);
 	struct atm_vcc *vcc = ctrl->atm.vcc;
-	unsigned int num_written;
+	unsigned int bytes_written;
 	unsigned int stride = instance->tx_channel.stride;
 
 	vdbg("%s: skb->len=%d, avail_space=%u", __func__, skb->len, avail_space);
 	UDSL_ASSERT(!(avail_space % stride));
 
-	for (num_written = 0; num_written < avail_space && ctrl->len;
-	     num_written += stride, target += stride) {
+	for (bytes_written = 0; bytes_written < avail_space && ctrl->len;
+	     bytes_written += stride, target += stride) {
 		unsigned int data_len = min_t(unsigned int, skb->len, ATM_CELL_PAYLOAD);
 		unsigned int left = ATM_CELL_PAYLOAD - data_len;
 		u8 *ptr = target;
@@ -470,7 +515,7 @@ static unsigned int usbatm_write_cells(s
 			ctrl->crc = crc32_be(ctrl->crc, ptr, left);
 	}
 
-	return num_written;
+	return bytes_written;
 }
 
 
@@ -487,16 +532,40 @@ static void usbatm_rx_process(unsigned l
 		vdbg("%s: processing urb 0x%p", __func__, urb);
 
 		if (usb_pipeisoc(urb->pipe)) {
+			unsigned char *merge_start = NULL;
+			unsigned int merge_length = 0;
+			const unsigned int packet_size = instance->rx_channel.packet_size;
 			int i;
-			for (i = 0; i < urb->number_of_packets; i++)
-				if (!urb->iso_frame_desc[i].status)
-					usbatm_extract_cells(instance,
-							     (u8 *)urb->transfer_buffer + urb->iso_frame_desc[i].offset,
-							     urb->iso_frame_desc[i].actual_length);
-		}
-		else
+
+			for (i = 0; i < urb->number_of_packets; i++) {
+				if (!urb->iso_frame_desc[i].status) {
+					unsigned int actual_length = urb->iso_frame_desc[i].actual_length;
+
+					UDSL_ASSERT(actual_length <= packet_size);
+
+					if (!merge_length)
+						merge_start = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
+					merge_length += actual_length;
+					if (merge_length && (actual_length < packet_size)) {
+						usbatm_extract_cells(instance, merge_start, merge_length);
+						merge_length = 0;
+					}
+				} else {
+					atm_rldbg(instance, "%s: status %d in frame %d!\n", __func__, urb->status, i);
+					if (merge_length)
+						usbatm_extract_cells(instance, merge_start, merge_length);
+					merge_length = 0;
+					instance->buf_usage = 0;
+				}
+			}
+
+			if (merge_length)
+				usbatm_extract_cells(instance, merge_start, merge_length);
+		} else
 			if (!urb->status)
 				usbatm_extract_cells(instance, urb->transfer_buffer, urb->actual_length);
+			else
+				instance->buf_usage = 0;
 
 		if (usbatm_submit_urb(urb))
 			return;
@@ -514,7 +583,7 @@ static void usbatm_tx_process(unsigned l
 	struct sk_buff *skb = instance->current_skb;
 	struct urb *urb = NULL;
 	const unsigned int buf_size = instance->tx_channel.buf_size;
-	unsigned int num_written = 0;
+	unsigned int bytes_written = 0;
 	u8 *buffer = NULL;
 
 	if (!skb)
@@ -526,16 +595,16 @@ static void usbatm_tx_process(unsigned l
 			if (!urb)
 				break;		/* no more senders */
 			buffer = urb->transfer_buffer;
-			num_written = (urb->status == -EAGAIN) ?
+			bytes_written = (urb->status == -EAGAIN) ?
 				urb->transfer_buffer_length : 0;
 		}
 
-		num_written += usbatm_write_cells(instance, skb,
-						  buffer + num_written,
-						  buf_size - num_written);
+		bytes_written += usbatm_write_cells(instance, skb,
+						  buffer + bytes_written,
+						  buf_size - bytes_written);
 
 		vdbg("%s: wrote %u bytes from skb 0x%p to urb 0x%p",
-		     __func__, num_written, skb, urb);
+		     __func__, bytes_written, skb, urb);
 
 		if (!UDSL_SKB(skb)->len) {
 			struct atm_vcc *vcc = UDSL_SKB(skb)->atm.vcc;
@@ -546,8 +615,8 @@ static void usbatm_tx_process(unsigned l
 			skb = skb_dequeue(&instance->sndqueue);
 		}
 
-		if (num_written == buf_size || (!skb && num_written)) {
-			urb->transfer_buffer_length = num_written;
+		if (bytes_written == buf_size || (!skb && bytes_written)) {
+			urb->transfer_buffer_length = bytes_written;
 
 			if (usbatm_submit_urb(urb))
 				break;
@@ -593,20 +662,24 @@ static int usbatm_atm_send(struct atm_vc
 
 	vdbg("%s called (skb 0x%p, len %u)", __func__, skb, skb->len);
 
-	if (!instance) {
-		dbg("%s: NULL data!", __func__);
+	/* racy disconnection check - fine */
+	if (!instance || instance->disconnected) {
+#ifdef DEBUG
+		if (printk_ratelimit())
+			printk(KERN_DEBUG "%s: %s!\n", __func__, instance ? "disconnected" : "NULL instance");
+#endif
 		err = -ENODEV;
 		goto fail;
 	}
 
 	if (vcc->qos.aal != ATM_AAL5) {
-		atm_dbg(instance, "%s: unsupported ATM type %d!\n", __func__, vcc->qos.aal);
+		atm_rldbg(instance, "%s: unsupported ATM type %d!\n", __func__, vcc->qos.aal);
 		err = -EINVAL;
 		goto fail;
 	}
 
 	if (skb->len > ATM_MAX_AAL5_PDU) {
-		atm_dbg(instance, "%s: packet too long (%d vs %d)!\n",
+		atm_rldbg(instance, "%s: packet too long (%d vs %d)!\n",
 				__func__, skb->len, ATM_MAX_AAL5_PDU);
 		err = -EINVAL;
 		goto fail;
@@ -665,16 +738,16 @@ static void usbatm_put_instance(struct u
 **  ATM  **
 **********/
 
-static void usbatm_atm_dev_close(struct atm_dev *dev)
+static void usbatm_atm_dev_close(struct atm_dev *atm_dev)
 {
-	struct usbatm_data *instance = dev->dev_data;
+	struct usbatm_data *instance = atm_dev->dev_data;
 
 	dbg("%s", __func__);
 
 	if (!instance)
 		return;
 
-	dev->dev_data = NULL;
+	atm_dev->dev_data = NULL; /* catch bugs */
 	usbatm_put_instance(instance);	/* taken in usbatm_atm_init */
 }
 
@@ -706,15 +779,19 @@ static int usbatm_atm_proc_read(struct a
 			       atomic_read(&atm_dev->stats.aal5.rx_err),
 			       atomic_read(&atm_dev->stats.aal5.rx_drop));
 
-	if (!left--)
-		switch (atm_dev->signal) {
-		case ATM_PHY_SIG_FOUND:
-			return sprintf(page, "Line up\n");
-		case ATM_PHY_SIG_LOST:
-			return sprintf(page, "Line down\n");
-		default:
-			return sprintf(page, "Line state unknown\n");
-		}
+	if (!left--) {
+		if (instance->disconnected)
+			return sprintf(page, "Disconnected\n");
+		else
+			switch (atm_dev->signal) {
+			case ATM_PHY_SIG_FOUND:
+				return sprintf(page, "Line up\n");
+			case ATM_PHY_SIG_LOST:
+				return sprintf(page, "Line down\n");
+			default:
+				return sprintf(page, "Line state unknown\n");
+			}
+	}
 
 	return 0;
 }
@@ -735,13 +812,24 @@ static int usbatm_atm_open(struct atm_vc
 	atm_dbg(instance, "%s: vpi %hd, vci %d\n", __func__, vpi, vci);
 
 	/* only support AAL5 */
-	if ((vcc->qos.aal != ATM_AAL5) || (vcc->qos.rxtp.max_sdu < 0)
-	    || (vcc->qos.rxtp.max_sdu > ATM_MAX_AAL5_PDU)) {
-		atm_dbg(instance, "%s: unsupported ATM type %d!\n", __func__, vcc->qos.aal);
+	if ((vcc->qos.aal != ATM_AAL5)) {
+		atm_warn(instance, "%s: unsupported ATM type %d!\n", __func__, vcc->qos.aal);
+		return -EINVAL;
+	}
+
+	/* sanity checks */
+	if ((vcc->qos.rxtp.max_sdu < 0) || (vcc->qos.rxtp.max_sdu > ATM_MAX_AAL5_PDU)) {
+		atm_dbg(instance, "%s: max_sdu %d out of range!\n", __func__, vcc->qos.rxtp.max_sdu);
 		return -EINVAL;
 	}
 
-	down(&instance->serialize);	/* vs self, usbatm_atm_close */
+	mutex_lock(&instance->serialize);	/* vs self, usbatm_atm_close, usbatm_usb_disconnect */
+
+	if (instance->disconnected) {
+		atm_dbg(instance, "%s: disconnected!\n", __func__);
+		ret = -ENODEV;
+		goto fail;
+	}
 
 	if (usbatm_find_vcc(instance, vpi, vci)) {
 		atm_dbg(instance, "%s: %hd/%d already in use!\n", __func__, vpi, vci);
@@ -749,20 +837,19 @@ static int usbatm_atm_open(struct atm_vc
 		goto fail;
 	}
 
-	if (!(new = kmalloc(sizeof(struct usbatm_vcc_data), GFP_KERNEL))) {
-		atm_dbg(instance, "%s: no memory for vcc_data!\n", __func__);
+	if (!(new = kzalloc(sizeof(struct usbatm_vcc_data), GFP_KERNEL))) {
+		atm_err(instance, "%s: no memory for vcc_data!\n", __func__);
 		ret = -ENOMEM;
 		goto fail;
 	}
 
-	memset(new, 0, sizeof(struct usbatm_vcc_data));
 	new->vcc = vcc;
 	new->vpi = vpi;
 	new->vci = vci;
 
 	new->sarb = alloc_skb(usbatm_pdu_length(vcc->qos.rxtp.max_sdu), GFP_KERNEL);
 	if (!new->sarb) {
-		atm_dbg(instance, "%s: no memory for SAR buffer!\n", __func__);
+		atm_err(instance, "%s: no memory for SAR buffer!\n", __func__);
 		ret = -ENOMEM;
 		goto fail;
 	}
@@ -770,6 +857,9 @@ static int usbatm_atm_open(struct atm_vc
 	vcc->dev_data = new;
 
 	tasklet_disable(&instance->rx_channel.tasklet);
+	instance->cached_vcc = new;
+	instance->cached_vpi = vpi;
+	instance->cached_vci = vci;
 	list_add(&new->list, &instance->vcc_list);
 	tasklet_enable(&instance->rx_channel.tasklet);
 
@@ -777,7 +867,7 @@ static int usbatm_atm_open(struct atm_vc
 	set_bit(ATM_VF_PARTIAL, &vcc->flags);
 	set_bit(ATM_VF_READY, &vcc->flags);
 
-	up(&instance->serialize);
+	mutex_unlock(&instance->serialize);
 
 	atm_dbg(instance, "%s: allocated vcc data 0x%p\n", __func__, new);
 
@@ -785,7 +875,7 @@ static int usbatm_atm_open(struct atm_vc
 
 fail:
 	kfree(new);
-	up(&instance->serialize);
+	mutex_unlock(&instance->serialize);
 	return ret;
 }
 
@@ -806,9 +896,14 @@ static void usbatm_atm_close(struct atm_
 
 	usbatm_cancel_send(instance, vcc);
 
-	down(&instance->serialize);	/* vs self, usbatm_atm_open */
+	mutex_lock(&instance->serialize);	/* vs self, usbatm_atm_open, usbatm_usb_disconnect */
 
 	tasklet_disable(&instance->rx_channel.tasklet);
+	if (instance->cached_vcc == vcc_data) {
+		instance->cached_vcc = NULL;
+		instance->cached_vpi = ATM_VPI_UNSPEC;
+		instance->cached_vci = ATM_VCI_UNSPEC;
+	}
 	list_del(&vcc_data->list);
 	tasklet_enable(&instance->rx_channel.tasklet);
 
@@ -824,14 +919,21 @@ static void usbatm_atm_close(struct atm_
 	clear_bit(ATM_VF_PARTIAL, &vcc->flags);
 	clear_bit(ATM_VF_ADDR, &vcc->flags);
 
-	up(&instance->serialize);
+	mutex_unlock(&instance->serialize);
 
 	atm_dbg(instance, "%s successful\n", __func__);
 }
 
-static int usbatm_atm_ioctl(struct atm_dev *dev, unsigned int cmd,
+static int usbatm_atm_ioctl(struct atm_dev *atm_dev, unsigned int cmd,
 			  void __user * arg)
 {
+	struct usbatm_data *instance = atm_dev->dev_data;
+
+	if (!instance || instance->disconnected) {
+		dbg("%s: %s!", __func__, instance ? "disconnected" : "NULL instance");
+		return -ENODEV;
+	}
+
 	switch (cmd) {
 	case ATM_QUERYLOOP:
 		return put_user(ATM_LM_NONE, (int __user *)arg) ? -EFAULT : 0;
@@ -845,10 +947,13 @@ static int usbatm_atm_init(struct usbatm
 	struct atm_dev *atm_dev;
 	int ret, i;
 
-	/* ATM init */
+	/* ATM init.  The ATM initialization scheme suffers from an intrinsic race
+	 * condition: callbacks we register can be executed at once, before we have
+	 * initialized the struct atm_dev.  To protect against this, all callbacks
+	 * abort if atm_dev->dev_data is NULL. */
 	atm_dev = atm_dev_register(instance->driver_name, &usbatm_atm_devops, -1, NULL);
 	if (!atm_dev) {
-		usb_dbg(instance, "%s: failed to register ATM device!\n", __func__);
+		usb_err(instance, "%s: failed to register ATM device!\n", __func__);
 		return -1;
 	}
 
@@ -862,12 +967,13 @@ static int usbatm_atm_init(struct usbatm
 	atm_dev->link_rate = 128 * 1000 / 424;
 
 	if (instance->driver->atm_start && ((ret = instance->driver->atm_start(instance, atm_dev)) < 0)) {
-		atm_dbg(instance, "%s: atm_start failed: %d!\n", __func__, ret);
+		atm_err(instance, "%s: atm_start failed: %d!\n", __func__, ret);
 		goto fail;
 	}
 
-	/* ready for ATM callbacks */
 	usbatm_get_instance(instance);	/* dropped in usbatm_atm_dev_close */
+
+	/* ready for ATM callbacks */
 	mb();
 	atm_dev->dev_data = instance;
 
@@ -903,9 +1009,9 @@ static int usbatm_do_heavy_init(void *ar
 	if (!ret)
 		ret = usbatm_atm_init(instance);
 
-	down(&instance->serialize);
+	mutex_lock(&instance->serialize);
 	instance->thread_pid = -1;
-	up(&instance->serialize);
+	mutex_unlock(&instance->serialize);
 
 	complete_and_exit(&instance->thread_exited, ret);
 }
@@ -915,13 +1021,13 @@ static int usbatm_heavy_init(struct usba
 	int ret = kernel_thread(usbatm_do_heavy_init, instance, CLONE_KERNEL);
 
 	if (ret < 0) {
-		usb_dbg(instance, "%s: failed to create kernel_thread (%d)!\n", __func__, ret);
+		usb_err(instance, "%s: failed to create kernel_thread (%d)!\n", __func__, ret);
 		return ret;
 	}
 
-	down(&instance->serialize);
+	mutex_lock(&instance->serialize);
 	instance->thread_pid = ret;
-	up(&instance->serialize);
+	mutex_unlock(&instance->serialize);
 
 	wait_for_completion(&instance->thread_started);
 
@@ -951,9 +1057,9 @@ int usbatm_usb_probe(struct usb_interfac
 	char *buf;
 	int error = -ENOMEM;
 	int i, length;
-	int need_heavy;
+	unsigned int maxpacket, num_packets;
 
-	dev_dbg(dev, "%s: trying driver %s with vendor=0x%x, product=0x%x, ifnum %d\n",
+	dev_dbg(dev, "%s: trying driver %s with vendor=%04x, product=%04x, ifnum %2d\n",
 			__func__, driver->driver_name,
 			le16_to_cpu(usb_dev->descriptor.idVendor),
 			le16_to_cpu(usb_dev->descriptor.idProduct),
@@ -962,7 +1068,7 @@ int usbatm_usb_probe(struct usb_interfac
 	/* instance init */
 	instance = kzalloc(sizeof(*instance) + sizeof(struct urb *) * (num_rcv_urbs + num_snd_urbs), GFP_KERNEL);
 	if (!instance) {
-		dev_dbg(dev, "%s: no memory for instance data!\n", __func__);
+		dev_err(dev, "%s: no memory for instance data!\n", __func__);
 		return -ENOMEM;
 	}
 
@@ -996,66 +1102,96 @@ int usbatm_usb_probe(struct usb_interfac
 	snprintf(buf, length, ")");
 
  bind:
-	need_heavy = 1;
-	if (driver->bind && (error = driver->bind(instance, intf, id, &need_heavy)) < 0) {
-			dev_dbg(dev, "%s: bind failed: %d!\n", __func__, error);
+	if (driver->bind && (error = driver->bind(instance, intf, id)) < 0) {
+			dev_err(dev, "%s: bind failed: %d!\n", __func__, error);
 			goto fail_free;
 	}
 
 	/* private fields */
 
 	kref_init(&instance->refcount);		/* dropped in usbatm_usb_disconnect */
-	init_MUTEX(&instance->serialize);
+	mutex_init(&instance->serialize);
 
 	instance->thread_pid = -1;
 	init_completion(&instance->thread_started);
 	init_completion(&instance->thread_exited);
 
 	INIT_LIST_HEAD(&instance->vcc_list);
+	skb_queue_head_init(&instance->sndqueue);
 
 	usbatm_init_channel(&instance->rx_channel);
 	usbatm_init_channel(&instance->tx_channel);
 	tasklet_init(&instance->rx_channel.tasklet, usbatm_rx_process, (unsigned long)instance);
 	tasklet_init(&instance->tx_channel.tasklet, usbatm_tx_process, (unsigned long)instance);
-	instance->rx_channel.endpoint = usb_rcvbulkpipe(usb_dev, driver->in);
-	instance->tx_channel.endpoint = usb_sndbulkpipe(usb_dev, driver->out);
 	instance->rx_channel.stride = ATM_CELL_SIZE + driver->rx_padding;
 	instance->tx_channel.stride = ATM_CELL_SIZE + driver->tx_padding;
-	instance->rx_channel.buf_size = rcv_buf_size * instance->rx_channel.stride;
-	instance->tx_channel.buf_size = snd_buf_size * instance->tx_channel.stride;
 	instance->rx_channel.usbatm = instance->tx_channel.usbatm = instance;
 
-	skb_queue_head_init(&instance->sndqueue);
+	if ((instance->flags & UDSL_USE_ISOC) && driver->isoc_in)
+		instance->rx_channel.endpoint = usb_rcvisocpipe(usb_dev, driver->isoc_in);
+	else
+		instance->rx_channel.endpoint = usb_rcvbulkpipe(usb_dev, driver->bulk_in);
+
+	instance->tx_channel.endpoint = usb_sndbulkpipe(usb_dev, driver->bulk_out);
+
+	/* tx buffer size must be a positive multiple of the stride */
+	instance->tx_channel.buf_size = max (instance->tx_channel.stride,
+			snd_buf_bytes - (snd_buf_bytes % instance->tx_channel.stride));
+
+	/* rx buffer size must be a positive multiple of the endpoint maxpacket */
+	maxpacket = usb_maxpacket(usb_dev, instance->rx_channel.endpoint, 0);
+
+	if ((maxpacket < 1) || (maxpacket > UDSL_MAX_BUF_SIZE)) {
+		dev_err(dev, "%s: invalid endpoint %02x!\n", __func__,
+				usb_pipeendpoint(instance->rx_channel.endpoint));
+		error = -EINVAL;
+		goto fail_unbind;
+	}
+
+	num_packets = max (1U, (rcv_buf_bytes + maxpacket / 2) / maxpacket); /* round */
+
+	if (num_packets * maxpacket > UDSL_MAX_BUF_SIZE)
+		num_packets--;
+
+	instance->rx_channel.buf_size = num_packets * maxpacket;
+	instance->rx_channel.packet_size = maxpacket;
+
+#ifdef DEBUG
+	for (i = 0; i < 2; i++) {
+		struct usbatm_channel *channel = i ?
+			&instance->tx_channel : &instance->rx_channel;
+
+		dev_dbg(dev, "%s: using %d byte buffer for %s channel 0x%p\n", __func__, channel->buf_size, i ? "tx" : "rx", channel);
+	}
+#endif
+
+	/* initialize urbs */
 
 	for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++) {
-		struct urb *urb;
 		u8 *buffer;
-		unsigned int iso_packets = 0, iso_size = 0;
 		struct usbatm_channel *channel = i < num_rcv_urbs ?
 			&instance->rx_channel : &instance->tx_channel;
+		struct urb *urb;
+		unsigned int iso_packets = usb_pipeisoc(channel->endpoint) ? channel->buf_size / channel->packet_size : 0;
 
-		if (usb_pipeisoc(channel->endpoint)) {
-			/* don't expect iso out endpoints */
-			iso_size = usb_maxpacket(instance->usb_dev, channel->endpoint, 0);
-			iso_size -= iso_size % channel->stride;	/* alignment */
-			BUG_ON(!iso_size);
-			iso_packets = (channel->buf_size - 1) / iso_size + 1;
-		}
+		UDSL_ASSERT(!usb_pipeisoc(channel->endpoint) || usb_pipein(channel->endpoint));
 
 		urb = usb_alloc_urb(iso_packets, GFP_KERNEL);
 		if (!urb) {
-			dev_dbg(dev, "%s: no memory for urb %d!\n", __func__, i);
+			dev_err(dev, "%s: no memory for urb %d!\n", __func__, i);
+			error = -ENOMEM;
 			goto fail_unbind;
 		}
 
 		instance->urbs[i] = urb;
 
-		buffer = kmalloc(channel->buf_size, GFP_KERNEL);
+		/* zero the tx padding to avoid leaking information */
+		buffer = kzalloc(channel->buf_size, GFP_KERNEL);
 		if (!buffer) {
-			dev_dbg(dev, "%s: no memory for buffer %d!\n", __func__, i);
+			dev_err(dev, "%s: no memory for buffer %d!\n", __func__, i);
+			error = -ENOMEM;
 			goto fail_unbind;
 		}
-		memset(buffer, 0, channel->buf_size);
 
 		usb_fill_bulk_urb(urb, instance->usb_dev, channel->endpoint,
 				  buffer, channel->buf_size, usbatm_complete, channel);
@@ -1065,9 +1201,8 @@ int usbatm_usb_probe(struct usb_interfac
 			urb->transfer_flags = URB_ISO_ASAP;
 			urb->number_of_packets = iso_packets;
 			for (j = 0; j < iso_packets; j++) {
-				urb->iso_frame_desc[j].offset = iso_size * j;
-				urb->iso_frame_desc[j].length = min_t(int, iso_size,
-								      channel->buf_size - urb->iso_frame_desc[j].offset);
+				urb->iso_frame_desc[j].offset = channel->packet_size * j;
+				urb->iso_frame_desc[j].length = channel->packet_size;
 			}
 		}
 
@@ -1079,7 +1214,17 @@ int usbatm_usb_probe(struct usb_interfac
 		     __func__, urb->transfer_buffer, urb->transfer_buffer_length, urb);
 	}
 
-	if (need_heavy && driver->heavy_init) {
+	instance->cached_vpi = ATM_VPI_UNSPEC;
+	instance->cached_vci = ATM_VCI_UNSPEC;
+	instance->cell_buf = kmalloc(instance->rx_channel.stride, GFP_KERNEL);
+
+	if (!instance->cell_buf) {
+		dev_err(dev, "%s: no memory for cell buffer!\n", __func__);
+		error = -ENOMEM;
+		goto fail_unbind;
+	}
+
+	if (!(instance->flags & UDSL_SKIP_HEAVY_INIT) && driver->heavy_init) {
 		error = usbatm_heavy_init(instance);
 	} else {
 		complete(&instance->thread_exited);	/* pretend that heavy_init was run */
@@ -1098,6 +1243,8 @@ int usbatm_usb_probe(struct usb_interfac
 	if (instance->driver->unbind)
 		instance->driver->unbind(instance, intf);
  fail_free:
+	kfree(instance->cell_buf);
+
 	for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++) {
 		if (instance->urbs[i])
 			kfree(instance->urbs[i]->transfer_buffer);
@@ -1114,6 +1261,7 @@ void usbatm_usb_disconnect(struct usb_in
 {
 	struct device *dev = &intf->dev;
 	struct usbatm_data *instance = usb_get_intfdata(intf);
+	struct usbatm_vcc_data *vcc_data;
 	int i;
 
 	dev_dbg(dev, "%s entered\n", __func__);
@@ -1125,13 +1273,19 @@ void usbatm_usb_disconnect(struct usb_in
 
 	usb_set_intfdata(intf, NULL);
 
-	down(&instance->serialize);
+	mutex_lock(&instance->serialize);
+	instance->disconnected = 1;
 	if (instance->thread_pid >= 0)
 		kill_proc(instance->thread_pid, SIGTERM, 1);
-	up(&instance->serialize);
+	mutex_unlock(&instance->serialize);
 
 	wait_for_completion(&instance->thread_exited);
 
+	mutex_lock(&instance->serialize);
+	list_for_each_entry(vcc_data, &instance->vcc_list, list)
+		vcc_release_async(vcc_data->vcc, -EPIPE);
+	mutex_unlock(&instance->serialize);
+
 	tasklet_disable(&instance->rx_channel.tasklet);
 	tasklet_disable(&instance->tx_channel.tasklet);
 
@@ -1141,6 +1295,14 @@ void usbatm_usb_disconnect(struct usb_in
 	del_timer_sync(&instance->rx_channel.delay);
 	del_timer_sync(&instance->tx_channel.delay);
 
+	/* turn usbatm_[rt]x_process into something close to a no-op */
+	/* no need to take the spinlock */
+	INIT_LIST_HEAD(&instance->rx_channel.list);
+	INIT_LIST_HEAD(&instance->tx_channel.list);
+
+	tasklet_enable(&instance->rx_channel.tasklet);
+	tasklet_enable(&instance->tx_channel.tasklet);
+
 	if (instance->atm_dev && instance->driver->atm_stop)
 		instance->driver->atm_stop(instance, instance->atm_dev);
 
@@ -1149,19 +1311,13 @@ void usbatm_usb_disconnect(struct usb_in
 
 	instance->driver_data = NULL;
 
-	/* turn usbatm_[rt]x_process into noop */
-	/* no need to take the spinlock */
-	INIT_LIST_HEAD(&instance->rx_channel.list);
-	INIT_LIST_HEAD(&instance->tx_channel.list);
-
-	tasklet_enable(&instance->rx_channel.tasklet);
-	tasklet_enable(&instance->tx_channel.tasklet);
-
 	for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++) {
 		kfree(instance->urbs[i]->transfer_buffer);
 		usb_free_urb(instance->urbs[i]);
 	}
 
+	kfree(instance->cell_buf);
+
 	/* ATM finalize */
 	if (instance->atm_dev)
 		atm_dev_deregister(instance->atm_dev);
@@ -1186,10 +1342,10 @@ static int __init usbatm_usb_init(void)
 
 	if ((num_rcv_urbs > UDSL_MAX_RCV_URBS)
 	    || (num_snd_urbs > UDSL_MAX_SND_URBS)
-	    || (rcv_buf_size < 1)
-	    || (rcv_buf_size > UDSL_MAX_RCV_BUF_SIZE)
-	    || (snd_buf_size < 1)
-	    || (snd_buf_size > UDSL_MAX_SND_BUF_SIZE))
+	    || (rcv_buf_bytes < 1)
+	    || (rcv_buf_bytes > UDSL_MAX_BUF_SIZE)
+	    || (snd_buf_bytes < 1)
+	    || (snd_buf_bytes > UDSL_MAX_BUF_SIZE))
 		return -EINVAL;
 
 	return 0;
diff --git a/drivers/usb/atm/usbatm.h b/drivers/usb/atm/usbatm.h
index 1adacd6..ff8551e 100644
--- a/drivers/usb/atm/usbatm.h
+++ b/drivers/usb/atm/usbatm.h
@@ -24,21 +24,21 @@
 #ifndef	_USBATM_H_
 #define	_USBATM_H_
 
-#include <linux/config.h>
-
-/*
-#define VERBOSE_DEBUG
-*/
-
 #include <asm/semaphore.h>
 #include <linux/atm.h>
 #include <linux/atmdev.h>
 #include <linux/completion.h>
 #include <linux/device.h>
+#include <linux/kernel.h>
 #include <linux/kref.h>
 #include <linux/list.h>
 #include <linux/stringify.h>
 #include <linux/usb.h>
+#include <linux/mutex.h>
+
+/*
+#define VERBOSE_DEBUG
+*/
 
 #ifdef DEBUG
 #define UDSL_ASSERT(x)	BUG_ON(!(x))
@@ -52,8 +52,13 @@
 	dev_info(&(instance)->usb_intf->dev , format , ## arg)
 #define usb_warn(instance, format, arg...)	\
 	dev_warn(&(instance)->usb_intf->dev , format , ## arg)
+#ifdef DEBUG
 #define usb_dbg(instance, format, arg...)	\
-	dev_dbg(&(instance)->usb_intf->dev , format , ## arg)
+        dev_printk(KERN_DEBUG , &(instance)->usb_intf->dev , format , ## arg)
+#else
+#define usb_dbg(instance, format, arg...)	\
+	do {} while (0)
+#endif
 
 /* FIXME: move to dev_* once ATM is driver model aware */
 #define atm_printk(level, instance, format, arg...)	\
@@ -69,12 +74,24 @@
 #ifdef DEBUG
 #define atm_dbg(instance, format, arg...)	\
 	atm_printk(KERN_DEBUG, instance , format , ## arg)
+#define atm_rldbg(instance, format, arg...)	\
+	if (printk_ratelimit())				\
+		atm_printk(KERN_DEBUG, instance , format , ## arg)
 #else
 #define atm_dbg(instance, format, arg...)	\
 	do {} while (0)
+#define atm_rldbg(instance, format, arg...)	\
+	do {} while (0)
 #endif
 
 
+/* flags, set by mini-driver in bind() */
+
+#define UDSL_SKIP_HEAVY_INIT	(1<<0)
+#define UDSL_USE_ISOC		(1<<1)
+#define UDSL_IGNORE_EILSEQ	(1<<2)
+
+
 /* mini driver */
 
 struct usbatm_data;
@@ -86,16 +103,11 @@ struct usbatm_data;
 */
 
 struct usbatm_driver {
-	struct module *owner;
-
 	const char *driver_name;
 
-	/*
-	*  init device ... can sleep, or cause probe() failure.  Drivers with a heavy_init
-	*  method can avoid having it called by setting need_heavy_init to zero.
-	*/
+	/* init device ... can sleep, or cause probe() failure */
         int (*bind) (struct usbatm_data *, struct usb_interface *,
-		     const struct usb_device_id *id, int *need_heavy_init);
+		     const struct usb_device_id *id);
 
 	/* additional device initialization that is too slow to be done in probe() */
         int (*heavy_init) (struct usbatm_data *, struct usb_interface *);
@@ -109,8 +121,9 @@ struct usbatm_driver {
 	/* cleanup ATM device ... can sleep, but can't fail */
 	void (*atm_stop) (struct usbatm_data *, struct atm_dev *);
 
-        int in;		/* rx endpoint */
-        int out;	/* tx endpoint */
+        int bulk_in;	/* bulk rx endpoint */
+        int isoc_in;	/* isochronous rx endpoint */
+        int bulk_out;	/* bulk tx endpoint */
 
 	unsigned rx_padding;
 	unsigned tx_padding;
@@ -125,6 +138,7 @@ struct usbatm_channel {
 	int endpoint;			/* usb pipe */
 	unsigned int stride;		/* ATM cell size + padding */
 	unsigned int buf_size;		/* urb buffer size */
+	unsigned int packet_size;	/* endpoint maxpacket */
 	spinlock_t lock;
 	struct list_head list;
 	struct tasklet_struct tasklet;
@@ -143,6 +157,7 @@ struct usbatm_data {
 	struct usbatm_driver *driver;
 	void *driver_data;
 	char driver_name[16];
+	unsigned int flags; /* set by mini-driver in bind() */
 
 	/* USB device */
 	struct usb_device *usb_dev;
@@ -157,7 +172,8 @@ struct usbatm_data {
         ********************************/
 
 	struct kref refcount;
-	struct semaphore serialize;
+	struct mutex serialize;
+	int disconnected;
 
 	/* heavy init */
 	int thread_pid;
@@ -171,7 +187,14 @@ struct usbatm_data {
 	struct usbatm_channel tx_channel;
 
 	struct sk_buff_head sndqueue;
-	struct sk_buff *current_skb;			/* being emptied */
+	struct sk_buff *current_skb;	/* being emptied */
+
+	struct usbatm_vcc_data *cached_vcc;
+	int cached_vci;
+	short cached_vpi;
+
+	unsigned char *cell_buf;	/* holds partial rx cell */
+	unsigned int buf_usage;
 
 	struct urb *urbs[0];
 };
diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c
index 5c76e3a..42d6823 100644
--- a/drivers/usb/atm/xusbatm.c
+++ b/drivers/usb/atm/xusbatm.c
@@ -41,6 +41,8 @@ XUSBATM_PARM(rx_endpoint, unsigned char,
 XUSBATM_PARM(tx_endpoint, unsigned char, byte, "tx endpoint number");
 XUSBATM_PARM(rx_padding, unsigned char, byte, "rx padding (default 0)");
 XUSBATM_PARM(tx_padding, unsigned char, byte, "tx padding (default 0)");
+XUSBATM_PARM(rx_altsetting, unsigned char, byte, "rx altsetting (default 0)");
+XUSBATM_PARM(tx_altsetting, unsigned char, byte, "rx altsetting (default 0)");
 
 static const char xusbatm_driver_name[] = "xusbatm";
 
@@ -48,82 +50,118 @@ static struct usbatm_driver xusbatm_driv
 static struct usb_device_id xusbatm_usb_ids[XUSBATM_DRIVERS_MAX + 1];
 static struct usb_driver xusbatm_usb_driver;
 
-static int usb_intf_has_ep(const struct usb_interface *intf, u8 ep)
+static struct usb_interface *xusbatm_find_intf (struct usb_device *usb_dev, int altsetting, u8 ep)
 {
+	struct usb_host_interface *alt;
+	struct usb_interface *intf;
 	int i, j;
 
-	for (i = 0; i < intf->num_altsetting; i++) {
-		struct usb_host_interface *alt = intf->altsetting;
-		for (j = 0; j < alt->desc.bNumEndpoints; j++)
-			if ((alt->endpoint[i].desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) == ep)
-				return 1;
+	for(i = 0; i < usb_dev->actconfig->desc.bNumInterfaces; i++)
+		if ((intf = usb_dev->actconfig->interface[i]) && (alt = usb_altnum_to_altsetting(intf, altsetting)))
+			for (j = 0; j < alt->desc.bNumEndpoints; j++)
+				if (alt->endpoint[j].desc.bEndpointAddress == ep)
+					return intf;
+	return NULL;
+}
+
+static int xusbatm_capture_intf (struct usbatm_data *usbatm, struct usb_device *usb_dev,
+		struct usb_interface *intf, int altsetting, int claim)
+{
+	int ifnum = intf->altsetting->desc.bInterfaceNumber;
+	int ret;
+
+	if (claim && (ret = usb_driver_claim_interface(&xusbatm_usb_driver, intf, usbatm))) {
+		usb_err(usbatm, "%s: failed to claim interface %2d (%d)!\n", __func__, ifnum, ret);
+		return ret;
+	}
+	if ((ret = usb_set_interface(usb_dev, ifnum, altsetting))) {
+		usb_err(usbatm, "%s: altsetting %2d for interface %2d failed (%d)!\n", __func__, altsetting, ifnum, ret);
+		return ret;
 	}
 	return 0;
 }
 
-static int xusbatm_bind(struct usbatm_data *usbatm_instance,
-			struct usb_interface *intf, const struct usb_device_id *id,
-			int *need_heavy_init)
+static void xusbatm_release_intf (struct usb_device *usb_dev, struct usb_interface *intf, int claimed)
+{
+	if (claimed) {
+		usb_set_intfdata(intf, NULL);
+		usb_driver_release_interface(&xusbatm_usb_driver, intf);
+	}
+}
+
+static int xusbatm_bind(struct usbatm_data *usbatm,
+			struct usb_interface *intf, const struct usb_device_id *id)
 {
 	struct usb_device *usb_dev = interface_to_usbdev(intf);
 	int drv_ix = id - xusbatm_usb_ids;
-	int rx_ep_present = usb_intf_has_ep(intf, rx_endpoint[drv_ix]);
-	int tx_ep_present = usb_intf_has_ep(intf, tx_endpoint[drv_ix]);
-	u8 searched_ep = rx_ep_present ? tx_endpoint[drv_ix] : rx_endpoint[drv_ix];
-	int i, ret;
+	int rx_alt = rx_altsetting[drv_ix];
+	int tx_alt = tx_altsetting[drv_ix];
+	struct usb_interface *rx_intf = xusbatm_find_intf(usb_dev, rx_alt, rx_endpoint[drv_ix]);
+	struct usb_interface *tx_intf = xusbatm_find_intf(usb_dev, tx_alt, tx_endpoint[drv_ix]);
+	int ret;
 
-	usb_dbg(usbatm_instance, "%s: binding driver %d: vendor %#x product %#x"
-		" rx: ep %#x padd %d tx: ep %#x padd %d\n",
+	usb_dbg(usbatm, "%s: binding driver %d: vendor %04x product %04x"
+		" rx: ep %02x padd %d alt %2d tx: ep %02x padd %d alt %2d\n",
 		__func__, drv_ix, vendor[drv_ix], product[drv_ix],
-		rx_endpoint[drv_ix], rx_padding[drv_ix],
-		tx_endpoint[drv_ix], tx_padding[drv_ix]);
+		rx_endpoint[drv_ix], rx_padding[drv_ix], rx_alt,
+		tx_endpoint[drv_ix], tx_padding[drv_ix], tx_alt);
 
-	if (!rx_ep_present && !tx_ep_present) {
-		usb_dbg(usbatm_instance, "%s: intf #%d has neither rx (%#x) nor tx (%#x) endpoint\n",
-			__func__, intf->altsetting->desc.bInterfaceNumber,
-			rx_endpoint[drv_ix], tx_endpoint[drv_ix]);
+	if (!rx_intf || !tx_intf) {
+		if (!rx_intf)
+			usb_dbg(usbatm, "%s: no interface contains endpoint %02x in altsetting %2d\n",
+				__func__, rx_endpoint[drv_ix], rx_alt);
+		if (!tx_intf)
+			usb_dbg(usbatm, "%s: no interface contains endpoint %02x in altsetting %2d\n",
+				__func__, tx_endpoint[drv_ix], tx_alt);
 		return -ENODEV;
 	}
 
-	if (rx_ep_present && tx_ep_present)
-		return 0;
+	if ((rx_intf != intf) && (tx_intf != intf))
+		return -ENODEV;
 
-	for(i = 0; i < usb_dev->actconfig->desc.bNumInterfaces; i++) {
-		struct usb_interface *cur_if = usb_dev->actconfig->interface[i];
+	if ((rx_intf == tx_intf) && (rx_alt != tx_alt)) {
+		usb_err(usbatm, "%s: altsettings clash on interface %2d (%2d vs %2d)!\n", __func__,
+				rx_intf->altsetting->desc.bInterfaceNumber, rx_alt, tx_alt);
+		return -EINVAL;
+	}
 
-		if (cur_if != intf && usb_intf_has_ep(cur_if, searched_ep)) {
-			ret = usb_driver_claim_interface(&xusbatm_usb_driver,
-							 cur_if, usbatm_instance);
-			if (!ret)
-				usb_err(usbatm_instance, "%s: failed to claim interface #%d (%d)\n",
-					__func__, cur_if->altsetting->desc.bInterfaceNumber, ret);
-			return ret;
-		}
+	usb_dbg(usbatm, "%s: rx If#=%2d; tx If#=%2d\n", __func__,
+			rx_intf->altsetting->desc.bInterfaceNumber,
+			tx_intf->altsetting->desc.bInterfaceNumber);
+
+	if ((ret = xusbatm_capture_intf(usbatm, usb_dev, rx_intf, rx_alt, rx_intf != intf)))
+		return ret;
+
+	if ((tx_intf != rx_intf) && (ret = xusbatm_capture_intf(usbatm, usb_dev, tx_intf, tx_alt, tx_intf != intf))) {
+		xusbatm_release_intf(usb_dev, rx_intf, rx_intf != intf);
+		return ret;
 	}
 
-	usb_err(usbatm_instance, "%s: no interface has endpoint %#x\n",
-		__func__, searched_ep);
-	return -ENODEV;
+	return 0;
 }
 
-static void xusbatm_unbind(struct usbatm_data *usbatm_instance,
+static void xusbatm_unbind(struct usbatm_data *usbatm,
 			   struct usb_interface *intf)
 {
 	struct usb_device *usb_dev = interface_to_usbdev(intf);
 	int i;
-	usb_dbg(usbatm_instance, "%s entered\n", __func__);
+
+	usb_dbg(usbatm, "%s entered\n", __func__);
 
 	for(i = 0; i < usb_dev->actconfig->desc.bNumInterfaces; i++) {
-		struct usb_interface *cur_if = usb_dev->actconfig->interface[i];
-		usb_set_intfdata(cur_if, NULL);
-		usb_driver_release_interface(&xusbatm_usb_driver, cur_if);
+		struct usb_interface *cur_intf = usb_dev->actconfig->interface[i];
+
+		if (cur_intf && (usb_get_intfdata(cur_intf) == usbatm)) {
+			usb_set_intfdata(cur_intf, NULL);
+			usb_driver_release_interface(&xusbatm_usb_driver, cur_intf);
+		}
 	}
 }
 
-static int xusbatm_atm_start(struct usbatm_data *usbatm_instance,
+static int xusbatm_atm_start(struct usbatm_data *usbatm,
 			     struct atm_dev *atm_dev)
 {
-	atm_dbg(usbatm_instance, "%s entered\n", __func__);
+	atm_dbg(usbatm, "%s entered\n", __func__);
 
 	/* use random MAC as we've no way to get it from the device */
 	random_ether_addr(atm_dev->esi);
@@ -161,18 +199,19 @@ static int __init xusbatm_init(void)
 	}
 
 	for (i = 0; i < num_vendor; i++) {
+		rx_endpoint[i] |= USB_DIR_IN;
+		tx_endpoint[i] &= USB_ENDPOINT_NUMBER_MASK;
+
 		xusbatm_usb_ids[i].match_flags	= USB_DEVICE_ID_MATCH_DEVICE;
 		xusbatm_usb_ids[i].idVendor	= vendor[i];
 		xusbatm_usb_ids[i].idProduct	= product[i];
 
-
-		xusbatm_drivers[i].owner	= THIS_MODULE;
 		xusbatm_drivers[i].driver_name	= xusbatm_driver_name;
 		xusbatm_drivers[i].bind		= xusbatm_bind;
 		xusbatm_drivers[i].unbind	= xusbatm_unbind;
 		xusbatm_drivers[i].atm_start	= xusbatm_atm_start;
-		xusbatm_drivers[i].in		= rx_endpoint[i];
-		xusbatm_drivers[i].out		= tx_endpoint[i];
+		xusbatm_drivers[i].bulk_in	= rx_endpoint[i];
+		xusbatm_drivers[i].bulk_out	= tx_endpoint[i];
 		xusbatm_drivers[i].rx_padding	= rx_padding[i];
 		xusbatm_drivers[i].tx_padding	= tx_padding[i];
 	}
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index b9fd39f..97bdeb1 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1014,8 +1014,13 @@ static void acm_disconnect(struct usb_in
 	}
 
 	down(&open_sem);
+	if (!usb_get_intfdata(intf)) {
+		up(&open_sem);
+		return;
+	}
 	acm->dev = NULL;
-	usb_set_intfdata (intf, NULL);
+	usb_set_intfdata(acm->control, NULL);
+	usb_set_intfdata(acm->data, NULL);
 
 	tasklet_disable(&acm->urb_task);
 
@@ -1036,7 +1041,7 @@ static void acm_disconnect(struct usb_in
 	for (i = 0; i < ACM_NRB; i++)
 		usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma);
 
-	usb_driver_release_interface(&acm_driver, acm->data);
+	usb_driver_release_interface(&acm_driver, intf == acm->control ? acm->data : intf);
 
 	if (!acm->used) {
 		acm_tty_unregister(acm);
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index dba4cc0..d34848a 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -7,6 +7,7 @@
  * Copyright (c) 2000 Vojtech Pavlik	<vojtech@suse.cz>
  # Copyright (c) 2001 Pete Zaitcev	<zaitcev@redhat.com>
  # Copyright (c) 2001 David Paschal	<paschal@rcsis.com>
+ * Copyright (c) 2006 Oliver Neukum	<oliver@neukum.name>
  *
  * USB Printer Device Class driver for USB printers and printer cables
  *
@@ -273,13 +274,16 @@ static void usblp_bulk_read(struct urb *
 {
 	struct usblp *usblp = urb->context;
 
-	if (!usblp || !usblp->dev || !usblp->used || !usblp->present)
+	if (unlikely(!usblp || !usblp->dev || !usblp->used))
 		return;
 
+	if (unlikely(!usblp->present))
+		goto unplug;
 	if (unlikely(urb->status))
 		warn("usblp%d: nonzero read/write bulk status received: %d",
 			usblp->minor, urb->status);
 	usblp->rcomplete = 1;
+unplug:
 	wake_up_interruptible(&usblp->wait);
 }
 
@@ -287,13 +291,15 @@ static void usblp_bulk_write(struct urb 
 {
 	struct usblp *usblp = urb->context;
 
-	if (!usblp || !usblp->dev || !usblp->used || !usblp->present)
+	if (unlikely(!usblp || !usblp->dev || !usblp->used))
 		return;
-
+	if (unlikely(!usblp->present))
+		goto unplug;
 	if (unlikely(urb->status))
 		warn("usblp%d: nonzero read/write bulk status received: %d",
 			usblp->minor, urb->status);
 	usblp->wcomplete = 1;
+unplug:
 	wake_up_interruptible(&usblp->wait);
 }
 
@@ -627,9 +633,8 @@ done:
 
 static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
 {
-	DECLARE_WAITQUEUE(wait, current);
 	struct usblp *usblp = file->private_data;
-	int timeout, err = 0, transfer_length = 0;
+	int timeout, rv, err = 0, transfer_length = 0;
 	size_t writecount = 0;
 
 	while (writecount < count) {
@@ -641,24 +646,11 @@ static ssize_t usblp_write(struct file *
 			}
 
 			timeout = USBLP_WRITE_TIMEOUT;
-			add_wait_queue(&usblp->wait, &wait);
-			while ( 1==1 ) {
 
-				if (signal_pending(current)) {
-					remove_wait_queue(&usblp->wait, &wait);
-					return writecount ? writecount : -EINTR;
-				}
-				set_current_state(TASK_INTERRUPTIBLE);
-				if (timeout && !usblp->wcomplete) {
-					timeout = schedule_timeout(timeout);
-				} else {
-					set_current_state(TASK_RUNNING);
-					break;
-				}
-			}
-			remove_wait_queue(&usblp->wait, &wait);
+			rv = wait_event_interruptible_timeout(usblp->wait, usblp->wcomplete || !usblp->present , timeout);
+			if (rv < 0)
+				return writecount ? writecount : -EINTR;
 		}
-
 		down (&usblp->sem);
 		if (!usblp->present) {
 			up (&usblp->sem);
@@ -724,7 +716,7 @@ static ssize_t usblp_write(struct file *
 static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
 {
 	struct usblp *usblp = file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
+	int rv;
 
 	if (!usblp->bidir)
 		return -EINVAL;
@@ -742,26 +734,13 @@ static ssize_t usblp_read(struct file *f
 			count = -EAGAIN;
 			goto done;
 		}
-
-		add_wait_queue(&usblp->wait, &wait);
-		while (1==1) {
-			if (signal_pending(current)) {
-				count = -EINTR;
-				remove_wait_queue(&usblp->wait, &wait);
-				goto done;
-			}
-			up (&usblp->sem);
-			set_current_state(TASK_INTERRUPTIBLE);
-			if (!usblp->rcomplete) {
-				schedule();
-			} else {
-				set_current_state(TASK_RUNNING);
-				down(&usblp->sem);
-				break;
-			}
-			down (&usblp->sem);
+		up(&usblp->sem);
+		rv = wait_event_interruptible(usblp->wait, usblp->rcomplete || !usblp->present);
+		down(&usblp->sem);
+		if (rv < 0) {
+			count = -EINTR;
+			goto done;
 		}
-		remove_wait_queue(&usblp->wait, &wait);
 	}
 
 	if (!usblp->present) {
@@ -874,11 +853,10 @@ static int usblp_probe(struct usb_interf
 
 	/* Malloc and start initializing usblp structure so we can use it
 	 * directly. */
-	if (!(usblp = kmalloc(sizeof(struct usblp), GFP_KERNEL))) {
+	if (!(usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL))) {
 		err("out of memory for usblp");
 		goto abort;
 	}
-	memset(usblp, 0, sizeof(struct usblp));
 	usblp->dev = dev;
 	init_MUTEX (&usblp->sem);
 	init_waitqueue_head(&usblp->wait);
@@ -1214,10 +1192,9 @@ static int __init usblp_init(void)
 {
 	int retval;
 	retval = usb_register(&usblp_driver);
-	if (retval)
-		goto out;
-	info(DRIVER_VERSION ": " DRIVER_DESC);
-out:
+	if (!retval)
+		info(DRIVER_VERSION ": " DRIVER_DESC);
+
 	return retval;
 }
 
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 319de03..7135e54 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -13,6 +13,7 @@
 #include <linux/ctype.h>
 #include <linux/device.h>
 #include <asm/byteorder.h>
+#include <asm/scatterlist.h>
 
 #include "hcd.h"	/* for usbcore internals */
 #include "usb.h"
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 0817967..dad4d8f 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -468,6 +468,7 @@ int usb_unlink_urb(struct urb *urb)
  */
 void usb_kill_urb(struct urb *urb)
 {
+	might_sleep();
 	if (!(urb && urb->dev && urb->dev->bus && urb->dev->bus->op))
 		return;
 	spin_lock_irq(&urb->lock);
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 9a4edc5..0aab7d2 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -135,6 +135,7 @@ struct dev_data {
 					setup_out_ready : 1,
 					setup_out_error : 1,
 					setup_abort : 1;
+	unsigned			setup_wLength;
 
 	/* the rest is basically write-once */
 	struct usb_config_descriptor	*config, *hs_config;
@@ -942,6 +943,7 @@ static int setup_req (struct usb_ep *ep,
 	}
 	req->complete = ep0_complete;
 	req->length = len;
+	req->zero = 0;
 	return 0;
 }
 
@@ -1161,10 +1163,13 @@ ep0_write (struct file *fd, const char _
 				spin_unlock_irq (&dev->lock);
 				if (copy_from_user (dev->req->buf, buf, len))
 					retval = -EFAULT;
-				else
+				else {
+					if (len < dev->setup_wLength)
+						dev->req->zero = 1;
 					retval = usb_ep_queue (
 						dev->gadget->ep0, dev->req,
 						GFP_KERNEL);
+				}
 				if (retval < 0) {
 					spin_lock_irq (&dev->lock);
 					clean_req (dev->gadget->ep0, dev->req);
@@ -1483,6 +1488,7 @@ unrecognized:
 delegate:
 			dev->setup_in = (ctrl->bRequestType & USB_DIR_IN)
 						? 1 : 0;
+			dev->setup_wLength = w_length;
 			dev->setup_out_ready = 0;
 			dev->setup_out_error = 0;
 			value = 0;
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index c32e1f7..67b13ab 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -47,6 +47,7 @@
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/dma-mapping.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index 2fc110d..ae7a1c0 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -165,8 +165,8 @@ static unsigned buflen = 4096;
 static unsigned qlen = 32;
 static unsigned pattern = 0;
 
-module_param (buflen, uint, S_IRUGO|S_IWUSR);
-module_param (qlen, uint, S_IRUGO|S_IWUSR);
+module_param (buflen, uint, S_IRUGO);
+module_param (qlen, uint, S_IRUGO);
 module_param (pattern, uint, S_IRUGO|S_IWUSR);
 
 /*
@@ -1127,8 +1127,10 @@ zero_unbind (struct usb_gadget *gadget)
 	DBG (dev, "unbind\n");
 
 	/* we've already been disconnected ... no i/o is active */
-	if (dev->req)
+	if (dev->req) {
+		dev->req->length = USB_BUFSIZ;
 		free_ep_req (gadget->ep0, dev->req);
+	}
 	del_timer_sync (&dev->resume);
 	kfree (dev);
 	set_gadget_data (gadget, NULL);
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 08ca0f8..3a6687d 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -24,46 +24,11 @@
 
 /*-------------------------------------------------------------------------*/
 
-/* EHCI 0.96 (and later) section 5.1 says how to kick BIOS/SMM/...
- * off the controller (maybe it can boot from highspeed USB disks).
- */
-static int bios_handoff(struct ehci_hcd *ehci, int where, u32 cap)
-{
-	struct pci_dev *pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller);
-
-	/* always say Linux will own the hardware */
-	pci_write_config_byte(pdev, where + 3, 1);
-
-	/* maybe wait a while for BIOS to respond */
-	if (cap & (1 << 16)) {
-		int msec = 5000;
-
-		do {
-			msleep(10);
-			msec -= 10;
-			pci_read_config_dword(pdev, where, &cap);
-		} while ((cap & (1 << 16)) && msec);
-		if (cap & (1 << 16)) {
-			ehci_err(ehci, "BIOS handoff failed (%d, %08x)\n",
-				where, cap);
-			// some BIOS versions seem buggy...
-			// return 1;
-			ehci_warn(ehci, "continuing after BIOS bug...\n");
-			/* disable all SMIs, and clear "BIOS owns" flag */
-			pci_write_config_dword(pdev, where + 4, 0);
-			pci_write_config_byte(pdev, where + 2, 0);
-		} else
-			ehci_dbg(ehci, "BIOS handoff succeeded\n");
-	}
-	return 0;
-}
-
 /* called after powerup, by probe or system-pm "wakeup" */
 static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev)
 {
 	u32			temp;
 	int			retval;
-	unsigned		count = 256/4;
 
 	/* optional debug port, normally in the first BAR */
 	temp = pci_find_capability(pdev, 0x0a);
@@ -84,32 +49,9 @@ static int ehci_pci_reinit(struct ehci_h
 		}
 	}
 
-	temp = HCC_EXT_CAPS(readl(&ehci->caps->hcc_params));
-
-	/* EHCI 0.96 and later may have "extended capabilities" */
-	while (temp && count--) {
-		u32		cap;
-
-		pci_read_config_dword(pdev, temp, &cap);
-		ehci_dbg(ehci, "capability %04x at %02x\n", cap, temp);
-		switch (cap & 0xff) {
-		case 1:			/* BIOS/SMM/... handoff */
-			if (bios_handoff(ehci, temp, cap) != 0)
-				return -EOPNOTSUPP;
-			break;
-		case 0:			/* illegal reserved capability */
-			ehci_dbg(ehci, "illegal capability!\n");
-			cap = 0;
-			/* FALLTHROUGH */
-		default:		/* unknown */
-			break;
-		}
-		temp = (cap >> 8) & 0xff;
-	}
-	if (!count) {
-		ehci_err(ehci, "bogus capabilities ... PCI problems!\n");
-		return -EIO;
-	}
+	/* we expect static quirk code to handle the "extended capabilities"
+	 * (currently just BIOS handoff) allowed starting with EHCI 0.96
+	 */
 
 	/* PCI Memory-Write-Invalidate cycle support is optional (uncommon) */
 	retval = pci_set_mwi(pdev);
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 57e7737..ebcca97 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -1063,6 +1063,7 @@ sitd_slot_ok (
 
 		/* for IN, check CSPLIT */
 		if (stream->c_usecs) {
+			uf = uframe & 7;
 			max_used = 100 - stream->c_usecs;
 			do {
 				tmp = 1 << uf;
@@ -1843,8 +1844,7 @@ done:
 #else
 
 static inline int
-sitd_submit (struct ehci_hcd *ehci, struct urb *urb,
-	unsigned mem_flags)
+sitd_submit (struct ehci_hcd *ehci, struct urb *urb, gfp_t mem_flags)
 {
 	ehci_dbg (ehci, "split iso support is disabled\n");
 	return -ENOSYS;
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index 584b8dc..972ce04 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -1420,20 +1420,22 @@ static int isp116x_bus_suspend(struct us
 	int ret = 0;
 
 	spin_lock_irqsave(&isp116x->lock, flags);
-
 	val = isp116x_read_reg32(isp116x, HCCONTROL);
+
 	switch (val & HCCONTROL_HCFS) {
 	case HCCONTROL_USB_OPER:
+		spin_unlock_irqrestore(&isp116x->lock, flags);
 		val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE);
 		val |= HCCONTROL_USB_SUSPEND;
 		if (device_may_wakeup(&hcd->self.root_hub->dev))
 			val |= HCCONTROL_RWE;
 		/* Wait for usb transfers to finish */
-		mdelay(2);
+		msleep(2);
+		spin_lock_irqsave(&isp116x->lock, flags);
 		isp116x_write_reg32(isp116x, HCCONTROL, val);
+		spin_unlock_irqrestore(&isp116x->lock, flags);
 		/* Wait for devices to suspend */
-		mdelay(5);
-	case HCCONTROL_USB_SUSPEND:
+		msleep(5);
 		break;
 	case HCCONTROL_USB_RESUME:
 		isp116x_write_reg32(isp116x, HCCONTROL,
@@ -1441,12 +1443,11 @@ static int isp116x_bus_suspend(struct us
 				    HCCONTROL_USB_RESET);
 	case HCCONTROL_USB_RESET:
 		ret = -EBUSY;
+	default:		/* HCCONTROL_USB_SUSPEND */
+		spin_unlock_irqrestore(&isp116x->lock, flags);
 		break;
-	default:
-		ret = -EINVAL;
 	}
 
-	spin_unlock_irqrestore(&isp116x->lock, flags);
 	return ret;
 }
 
@@ -1715,9 +1716,9 @@ static struct platform_driver isp116x_dr
 	.remove = isp116x_remove,
 	.suspend = isp116x_suspend,
 	.resume = isp116x_resume,
-	.driver	= {
-		.name = (char *)hcd_name,
-	},
+	.driver = {
+		   .name = (char *)hcd_name,
+		   },
 };
 
 /*-----------------------------------------------------------------*/
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c
index 77cd6ac..db280ca 100644
--- a/drivers/usb/host/ohci-au1xxx.c
+++ b/drivers/usb/host/ohci-au1xxx.c
@@ -67,7 +67,7 @@ static void au1xxx_stop_hc(struct platfo
 	       ": stopping Au1xxx OHCI USB Controller\n");
 
 	/* Disable clock */
-	au_writel(readl((void *)USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG);
+	au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG);
 }
 
 
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 3ef2c0c..e9e5bc1 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -190,7 +190,7 @@ static void __devinit quirk_usb_handoff_
 			msleep(10);
 		}
 		if (wait_time <= 0)
-			printk(KERN_WARNING "%s %s: early BIOS handoff "
+			printk(KERN_WARNING "%s %s: BIOS handoff "
 					"failed (BIOS bug ?)\n",
 					pdev->dev.bus_id, "OHCI");
 
@@ -212,8 +212,9 @@ static void __devinit quirk_usb_disable_
 {
 	int wait_time, delta;
 	void __iomem *base, *op_reg_base;
-	u32 hcc_params, val, temp;
-	u8 cap_length;
+	u32	hcc_params, val;
+	u8	offset, cap_length;
+	int	count = 256/4;
 
 	if (!mmio_resource_enabled(pdev, 0))
 		return;
@@ -224,51 +225,80 @@ static void __devinit quirk_usb_disable_
 
 	cap_length = readb(base);
 	op_reg_base = base + cap_length;
+
+	/* EHCI 0.96 and later may have "extended capabilities"
+	 * spec section 5.1 explains the bios handoff, e.g. for
+	 * booting from USB disk or using a usb keyboard
+	 */
 	hcc_params = readl(base + EHCI_HCC_PARAMS);
-	hcc_params = (hcc_params >> 8) & 0xff;
-	if (hcc_params) {
-		pci_read_config_dword(pdev,
-					hcc_params + EHCI_USBLEGSUP,
-					&val);
-		if (((val & 0xff) == 1) && (val & EHCI_USBLEGSUP_BIOS)) {
-			/*
-			 * Ok, BIOS is in smm mode, try to hand off...
-			 */
-			pci_read_config_dword(pdev,
-						hcc_params + EHCI_USBLEGCTLSTS,
-						&temp);
-			pci_write_config_dword(pdev,
-						hcc_params + EHCI_USBLEGCTLSTS,
-						temp | EHCI_USBLEGCTLSTS_SOOE);
-			val |= EHCI_USBLEGSUP_OS;
-			pci_write_config_dword(pdev,
-						hcc_params + EHCI_USBLEGSUP,
-						val);
+	offset = (hcc_params >> 8) & 0xff;
+	while (offset && count--) {
+		u32		cap;
+		int		msec;
+
+		pci_read_config_dword(pdev, offset, &cap);
+		switch (cap & 0xff) {
+		case 1:			/* BIOS/SMM/... handoff support */
+			if ((cap & EHCI_USBLEGSUP_BIOS)) {
+				pr_debug("%s %s: BIOS handoff\n",
+						pdev->dev.bus_id, "EHCI");
 
-			wait_time = 500;
-			do {
-				msleep(10);
-				wait_time -= 10;
+				/* BIOS workaround (?): be sure the
+				 * pre-Linux code receives the SMI
+				 */
 				pci_read_config_dword(pdev,
-						hcc_params + EHCI_USBLEGSUP,
+						offset + EHCI_USBLEGCTLSTS,
 						&val);
-			} while (wait_time && (val & EHCI_USBLEGSUP_BIOS));
-			if (!wait_time) {
-				/*
-				 * well, possibly buggy BIOS...
+				pci_write_config_dword(pdev,
+						offset + EHCI_USBLEGCTLSTS,
+						val | EHCI_USBLEGCTLSTS_SOOE);
+			}
+
+			/* always say Linux will own the hardware
+			 * by setting EHCI_USBLEGSUP_OS.
+			 */
+			pci_write_config_byte(pdev, offset + 3, 1);
+
+			/* if boot firmware now owns EHCI, spin till
+			 * it hands it over.
+			 */
+			msec = 5000;
+			while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) {
+				msleep(10);
+				msec -= 10;
+				pci_read_config_dword(pdev, offset, &cap);
+			}
+
+			if (cap & EHCI_USBLEGSUP_BIOS) {
+				/* well, possibly buggy BIOS... try to shut
+				 * it down, and hope nothing goes too wrong
 				 */
-				printk(KERN_WARNING "%s %s: early BIOS handoff "
+				printk(KERN_WARNING "%s %s: BIOS handoff "
 						"failed (BIOS bug ?)\n",
 					pdev->dev.bus_id, "EHCI");
-				pci_write_config_dword(pdev,
-						hcc_params + EHCI_USBLEGSUP,
-						EHCI_USBLEGSUP_OS);
-				pci_write_config_dword(pdev,
-						hcc_params + EHCI_USBLEGCTLSTS,
-						0);
+				pci_write_config_byte(pdev, offset + 2, 0);
 			}
+
+			/* just in case, always disable EHCI SMIs */
+			pci_write_config_dword(pdev,
+					offset + EHCI_USBLEGCTLSTS,
+					0);
+			break;
+		case 0:			/* illegal reserved capability */
+			cap = 0;
+			/* FALLTHROUGH */
+		default:
+			printk(KERN_WARNING "%s %s: unrecognized "
+					"capability %02x\n",
+					pdev->dev.bus_id, "EHCI",
+					cap & 0xff);
+			break;
 		}
+		offset = (cap >> 8) & 0xff;
 	}
+	if (!count)
+		printk(KERN_DEBUG "%s %s: capability loop?\n",
+				pdev->dev.bus_id, "EHCI");
 
 	/*
 	 * halt EHCI & disable its interrupts in any case
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index b607600..7823980 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -672,9 +672,9 @@ static int uhci_submit_control(struct uh
 	/* Low-speed transfers get a different queue, and won't hog the bus.
 	 * Also, some devices enumerate better without FSBR; the easiest way
 	 * to do that is to put URBs on the low-speed queue while the device
-	 * is in the DEFAULT state. */
+	 * isn't in the CONFIGURED state. */
 	if (urb->dev->speed == USB_SPEED_LOW ||
-			urb->dev->state == USB_STATE_DEFAULT)
+			urb->dev->state != USB_STATE_CONFIGURED)
 		skelqh = uhci->skel_ls_control_qh;
 	else {
 		skelqh = uhci->skel_fs_control_qh;
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index a91e72c..6f7a684 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -1307,7 +1307,7 @@ void hid_init_reports(struct hid_device 
 	}
 
 	if (err)
-		warn("timeout initializing reports\n");
+		warn("timeout initializing reports");
 }
 
 #define USB_VENDOR_ID_WACOM		0x056a
@@ -1453,6 +1453,9 @@ void hid_init_reports(struct hid_device 
 #define USB_VENDOR_ID_CHERRY		0x046a
 #define USB_DEVICE_ID_CHERRY_CYMOTION	0x0023
 
+#define USB_VENDOR_ID_HP		0x03f0
+#define USB_DEVICE_ID_HP_USBHUB_KB	0x020c
+
 /*
  * Alphabetically sorted blacklist by quirk type.
  */
@@ -1566,6 +1569,7 @@ static const struct hid_blacklist {
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_KEYBOARD, HID_QUIRK_NOGET},
 	{ USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_USBHUB_KB, HID_QUIRK_NOGET},
+	{ USB_VENDOR_ID_HP, USB_DEVICE_ID_HP_USBHUB_KB, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET },
 
 	{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_POWERMOUSE, HID_QUIRK_2WHEEL_POWERMOUSE },
@@ -1828,9 +1832,6 @@ static struct hid_device *usb_hid_config
 	hid->urbctrl->transfer_dma = hid->ctrlbuf_dma;
 	hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
 
-	/* May be needed for some devices */
-	usb_clear_halt(hid->dev, hid->urbin->pipe);
-
 	return hid;
 
 fail:
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
index 4dff847..925f5ab 100644
--- a/drivers/usb/input/hiddev.c
+++ b/drivers/usb/input/hiddev.c
@@ -35,7 +35,6 @@
 #include <linux/usb.h>
 #include "hid.h"
 #include <linux/hiddev.h>
-#include <linux/devfs_fs_kernel.h>
 
 #ifdef CONFIG_USB_DYNAMIC_MINORS
 #define HIDDEV_MINOR_BASE	0
@@ -632,7 +631,7 @@ static int hiddev_ioctl(struct inode *in
 
 			else if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
 				 (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
-				  uref->usage_index + uref_multi->num_values >= field->report_count))
+				  uref->usage_index + uref_multi->num_values > field->report_count))
 				goto inval;
 			}
 
@@ -832,12 +831,10 @@ static /* const */ struct usb_driver hid
 
 int __init hiddev_init(void)
 {
-	devfs_mk_dir("usb/hid");
 	return usb_register(&hiddev_driver);
 }
 
 void hiddev_exit(void)
 {
 	usb_deregister(&hiddev_driver);
-	devfs_remove("usb/hid");
 }
diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c
index 3b3c7b4..697c5e5 100644
--- a/drivers/usb/input/touchkitusb.c
+++ b/drivers/usb/input/touchkitusb.c
@@ -337,6 +337,9 @@ static int touchkit_probe(struct usb_int
 			 touchkit->data, TOUCHKIT_REPORT_DATA_SIZE,
 			 touchkit_irq, touchkit, endpoint->bInterval);
 
+	touchkit->irq->transfer_dma = touchkit->data_dma;
+	touchkit->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
 	input_register_device(touchkit->input);
 
 	usb_set_intfdata(intf, touchkit);
diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c
index 1bfc105..37d2f0b 100644
--- a/drivers/usb/input/yealink.c
+++ b/drivers/usb/input/yealink.c
@@ -59,7 +59,7 @@
 #include "map_to_7segment.h"
 #include "yealink.h"
 
-#define DRIVER_VERSION "yld-20050816"
+#define DRIVER_VERSION "yld-20051230"
 #define DRIVER_AUTHOR "Henk Vergonet"
 #define DRIVER_DESC "Yealink phone driver"
 
@@ -786,16 +786,25 @@ static struct attribute_group yld_attr_g
  * Linux interface and usb initialisation
  ******************************************************************************/
 
-static const struct yld_device {
-	u16 idVendor;
-	u16 idProduct;
+struct driver_info {
 	char *name;
-} yld_device[] = {
-	{ 0x6993, 0xb001, "Yealink usb-p1k" },
 };
 
-static struct usb_device_id usb_table [] = {
-	{ USB_INTERFACE_INFO(USB_CLASS_HID, 0, 0) },
+static const struct driver_info info_P1K = {
+	.name	= "Yealink usb-p1k",
+};
+
+static const struct usb_device_id usb_table [] = {
+	{
+		.match_flags		= USB_DEVICE_ID_MATCH_DEVICE |
+						USB_DEVICE_ID_MATCH_INT_INFO,
+		.idVendor		= 0x6993,
+		.idProduct		= 0xb001,
+		.bInterfaceClass	= USB_CLASS_HID,
+		.bInterfaceSubClass	= 0,
+		.bInterfaceProtocol	= 0,
+		.driver_info		= (kernel_ulong_t)&info_P1K
+	},
 	{ }
 };
 
@@ -842,33 +851,16 @@ static void usb_disconnect(struct usb_in
 	usb_cleanup(yld, 0);
 }
 
-static int usb_match(struct usb_device *udev)
-{
-	int i;
-	u16 idVendor = le16_to_cpu(udev->descriptor.idVendor);
-	u16 idProduct = le16_to_cpu(udev->descriptor.idProduct);
-
-	for (i = 0; i < ARRAY_SIZE(yld_device); i++) {
-		if ((idVendor == yld_device[i].idVendor) &&
-		    (idProduct == yld_device[i].idProduct))
-			return i;
-	}
-	return -ENODEV;
-}
-
 static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
 	struct usb_device *udev = interface_to_usbdev (intf);
+	struct driver_info *nfo = (struct driver_info *)id->driver_info;
 	struct usb_host_interface *interface;
 	struct usb_endpoint_descriptor *endpoint;
 	struct yealink_dev *yld;
 	struct input_dev *input_dev;
 	int ret, pipe, i;
 
-	i = usb_match(udev);
-	if (i < 0)
-		return -ENODEV;
-
 	interface = intf->cur_altsetting;
 	endpoint = &interface->endpoint[0].desc;
 	if (!(endpoint->bEndpointAddress & USB_DIR_IN))
@@ -915,7 +907,7 @@ static int usb_probe(struct usb_interfac
 	pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
 	ret = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
 	if (ret != USB_PKT_LEN)
-		err("invalid payload size %d, expected %d", ret, USB_PKT_LEN);
+		err("invalid payload size %d, expected %zd", ret, USB_PKT_LEN);
 
 	/* initialise irq urb */
 	usb_fill_int_urb(yld->urb_irq, udev, pipe, yld->irq_data,
@@ -948,7 +940,7 @@ static int usb_probe(struct usb_interfac
 	strlcat(yld->phys,  "/input0", sizeof(yld->phys));
 
 	/* register settings for the input device */
-	input_dev->name = yld_device[i].name;
+	input_dev->name = nfo->name;
 	input_dev->phys = yld->phys;
 	usb_to_input_id(udev, &input_dev->id);
 	input_dev->cdev.dev = &intf->dev;
diff --git a/drivers/usb/media/Kconfig b/drivers/usb/media/Kconfig
index 21232ee..0d3d2cc 100644
--- a/drivers/usb/media/Kconfig
+++ b/drivers/usb/media/Kconfig
@@ -53,6 +53,21 @@ config USB_DSBR
 	  To compile this driver as a module, choose M here: the
 	  module will be called dsbr100.
 
+config USB_ET61X251
+	tristate "USB ET61X[12]51 PC Camera Controller support"
+	depends on USB && VIDEO_DEV
+	---help---
+	  Say Y here if you want support for cameras based on Etoms ET61X151
+	  or ET61X251 PC Camera Controllers.
+
+	  See <file:Documentation/usb/et61x251.txt> for more informations.
+
+	  This driver uses the Video For Linux API. You must say Y or M to
+	  "Video For Linux" to use this driver.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called et61x251.
+
 config USB_IBMCAM
 	tristate "USB IBM (Xirlink) C-it Camera support"
 	depends on USB && VIDEO_DEV
@@ -209,5 +224,3 @@ config USB_PWC
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called pwc.
-
-
diff --git a/drivers/usb/media/Makefile b/drivers/usb/media/Makefile
index d83adff..3957aa1 100644
--- a/drivers/usb/media/Makefile
+++ b/drivers/usb/media/Makefile
@@ -3,9 +3,11 @@
 #
 
 sn9c102-objs	:= sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o sn9c102_ov7630.o sn9c102_pas106b.o sn9c102_pas202bcb.o sn9c102_tas5110c1b.o sn9c102_tas5130d1b.o
+et61x251-objs	:= et61x251_core.o et61x251_tas5130d1b.o
 
 obj-$(CONFIG_USB_DABUSB)	+= dabusb.o
 obj-$(CONFIG_USB_DSBR)		+= dsbr100.o
+obj-$(CONFIG_USB_ET61X251)	+= et61x251.o
 obj-$(CONFIG_USB_IBMCAM)	+= ibmcam.o usbvideo.o ultracam.o
 obj-$(CONFIG_USB_KONICAWC)	+= konicawc.o usbvideo.o
 obj-$(CONFIG_USB_OV511)		+= ov511.o
diff --git a/drivers/usb/media/et61x251.h b/drivers/usb/media/et61x251.h
new file mode 100644
index 0000000..652238f
--- /dev/null
+++ b/drivers/usb/media/et61x251.h
@@ -0,0 +1,220 @@
+/***************************************************************************
+ * V4L2 driver for ET61X[12]51 PC Camera Controllers                       *
+ *                                                                         *
+ * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it>       *
+ *                                                                         *
+ * This program is free software; you can redistribute it and/or modify    *
+ * it under the terms of the GNU General Public License as published by    *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.               *
+ ***************************************************************************/
+
+#ifndef _ET61X251_H_
+#define _ET61X251_H_
+
+#include <linux/version.h>
+#include <linux/usb.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/time.h>
+#include <linux/wait.h>
+#include <linux/types.h>
+#include <linux/param.h>
+#include <linux/rwsem.h>
+#include <asm/semaphore.h>
+
+#include "et61x251_sensor.h"
+
+/*****************************************************************************/
+
+#define ET61X251_DEBUG
+#define ET61X251_DEBUG_LEVEL         2
+#define ET61X251_MAX_DEVICES         64
+#define ET61X251_PRESERVE_IMGSCALE   0
+#define ET61X251_FORCE_MUNMAP        0
+#define ET61X251_MAX_FRAMES          32
+#define ET61X251_COMPRESSION_QUALITY 0
+#define ET61X251_URBS                2
+#define ET61X251_ISO_PACKETS         7
+#define ET61X251_ALTERNATE_SETTING   13
+#define ET61X251_URB_TIMEOUT         msecs_to_jiffies(2 * ET61X251_ISO_PACKETS)
+#define ET61X251_CTRL_TIMEOUT        100
+
+/*****************************************************************************/
+
+static const struct usb_device_id et61x251_id_table[] = {
+	{ USB_DEVICE(0x102c, 0x6151), },
+	{ USB_DEVICE(0x102c, 0x6251), },
+	{ USB_DEVICE(0x102c, 0x6253), },
+	{ USB_DEVICE(0x102c, 0x6254), },
+	{ USB_DEVICE(0x102c, 0x6255), },
+	{ USB_DEVICE(0x102c, 0x6256), },
+	{ USB_DEVICE(0x102c, 0x6257), },
+	{ USB_DEVICE(0x102c, 0x6258), },
+	{ USB_DEVICE(0x102c, 0x6259), },
+	{ USB_DEVICE(0x102c, 0x625a), },
+	{ USB_DEVICE(0x102c, 0x625b), },
+	{ USB_DEVICE(0x102c, 0x625c), },
+	{ USB_DEVICE(0x102c, 0x625d), },
+	{ USB_DEVICE(0x102c, 0x625e), },
+	{ USB_DEVICE(0x102c, 0x625f), },
+	{ USB_DEVICE(0x102c, 0x6260), },
+	{ USB_DEVICE(0x102c, 0x6261), },
+	{ USB_DEVICE(0x102c, 0x6262), },
+	{ USB_DEVICE(0x102c, 0x6263), },
+	{ USB_DEVICE(0x102c, 0x6264), },
+	{ USB_DEVICE(0x102c, 0x6265), },
+	{ USB_DEVICE(0x102c, 0x6266), },
+	{ USB_DEVICE(0x102c, 0x6267), },
+	{ USB_DEVICE(0x102c, 0x6268), },
+	{ USB_DEVICE(0x102c, 0x6269), },
+	{ }
+};
+
+ET61X251_SENSOR_TABLE
+
+/*****************************************************************************/
+
+enum et61x251_frame_state {
+	F_UNUSED,
+	F_QUEUED,
+	F_GRABBING,
+	F_DONE,
+	F_ERROR,
+};
+
+struct et61x251_frame_t {
+	void* bufmem;
+	struct v4l2_buffer buf;
+	enum et61x251_frame_state state;
+	struct list_head frame;
+	unsigned long vma_use_count;
+};
+
+enum et61x251_dev_state {
+	DEV_INITIALIZED = 0x01,
+	DEV_DISCONNECTED = 0x02,
+	DEV_MISCONFIGURED = 0x04,
+};
+
+enum et61x251_io_method {
+	IO_NONE,
+	IO_READ,
+	IO_MMAP,
+};
+
+enum et61x251_stream_state {
+	STREAM_OFF,
+	STREAM_INTERRUPT,
+	STREAM_ON,
+};
+
+struct et61x251_sysfs_attr {
+	u8 reg, i2c_reg;
+};
+
+struct et61x251_module_param {
+	u8 force_munmap;
+};
+
+static DECLARE_MUTEX(et61x251_sysfs_lock);
+static DECLARE_RWSEM(et61x251_disconnect);
+
+struct et61x251_device {
+	struct video_device* v4ldev;
+
+	struct et61x251_sensor* sensor;
+
+	struct usb_device* usbdev;
+	struct urb* urb[ET61X251_URBS];
+	void* transfer_buffer[ET61X251_URBS];
+	u8* control_buffer;
+
+	struct et61x251_frame_t *frame_current, frame[ET61X251_MAX_FRAMES];
+	struct list_head inqueue, outqueue;
+	u32 frame_count, nbuffers, nreadbuffers;
+
+	enum et61x251_io_method io;
+	enum et61x251_stream_state stream;
+
+	struct v4l2_jpegcompression compression;
+
+	struct et61x251_sysfs_attr sysfs;
+	struct et61x251_module_param module_param;
+
+	enum et61x251_dev_state state;
+	u8 users;
+
+	struct semaphore dev_sem, fileop_sem;
+	spinlock_t queue_lock;
+	wait_queue_head_t open, wait_frame, wait_stream;
+};
+
+/*****************************************************************************/
+
+void
+et61x251_attach_sensor(struct et61x251_device* cam,
+                       struct et61x251_sensor* sensor)
+{
+	cam->sensor = sensor;
+	cam->sensor->usbdev = cam->usbdev;
+}
+
+/*****************************************************************************/
+
+#undef DBG
+#undef KDBG
+#ifdef ET61X251_DEBUG
+#	define DBG(level, fmt, args...)                                       \
+do {                                                                          \
+	if (debug >= (level)) {                                               \
+		if ((level) == 1)                                             \
+			dev_err(&cam->usbdev->dev, fmt "\n", ## args);        \
+		else if ((level) == 2)                                        \
+			dev_info(&cam->usbdev->dev, fmt "\n", ## args);       \
+		else if ((level) >= 3)                                        \
+			dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n",      \
+			         __FUNCTION__, __LINE__ , ## args);           \
+	}                                                                     \
+} while (0)
+#	define KDBG(level, fmt, args...)                                      \
+do {                                                                          \
+	if (debug >= (level)) {                                               \
+		if ((level) == 1 || (level) == 2)                             \
+			pr_info("et61x251: " fmt "\n", ## args);              \
+		else if ((level) == 3)                                        \
+			pr_debug("et61x251: [%s:%d] " fmt "\n", __FUNCTION__, \
+			         __LINE__ , ## args);                         \
+	}                                                                     \
+} while (0)
+#	define V4LDBG(level, name, cmd)                                       \
+do {                                                                          \
+	if (debug >= (level))                                                 \
+		v4l_print_ioctl(name, cmd);                                   \
+} while (0)
+#else
+#	define DBG(level, fmt, args...) do {;} while(0)
+#	define KDBG(level, fmt, args...) do {;} while(0)
+#	define V4LDBG(level, name, cmd) do {;} while(0)
+#endif
+
+#undef PDBG
+#define PDBG(fmt, args...)                                                    \
+dev_info(&cam->dev, "[%s:%d] " fmt "\n", __FUNCTION__, __LINE__ , ## args)
+
+#undef PDBGG
+#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */
+
+#endif /* _ET61X251_H_ */
diff --git a/drivers/usb/media/et61x251_core.c b/drivers/usb/media/et61x251_core.c
new file mode 100644
index 0000000..2c0171a
--- /dev/null
+++ b/drivers/usb/media/et61x251_core.c
@@ -0,0 +1,2605 @@
+/***************************************************************************
+ * V4L2 driver for ET61X[12]51 PC Camera Controllers                       *
+ *                                                                         *
+ * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it>       *
+ *                                                                         *
+ * This program is free software; you can redistribute it and/or modify    *
+ * it under the terms of the GNU General Public License as published by    *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.               *
+ ***************************************************************************/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/moduleparam.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/delay.h>
+#include <linux/stddef.h>
+#include <linux/compiler.h>
+#include <linux/ioctl.h>
+#include <linux/poll.h>
+#include <linux/stat.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/page-flags.h>
+#include <linux/byteorder/generic.h>
+#include <asm/page.h>
+#include <asm/uaccess.h>
+
+#include "et61x251.h"
+
+/*****************************************************************************/
+
+#define ET61X251_MODULE_NAME    "V4L2 driver for ET61X[12]51 "                \
+                                "PC Camera Controllers"
+#define ET61X251_MODULE_AUTHOR  "(C) 2006 Luca Risolia"
+#define ET61X251_AUTHOR_EMAIL   "<luca.risolia@studio.unibo.it>"
+#define ET61X251_MODULE_LICENSE "GPL"
+#define ET61X251_MODULE_VERSION "1:1.01"
+#define ET61X251_MODULE_VERSION_CODE  KERNEL_VERSION(1, 0, 1)
+
+/*****************************************************************************/
+
+MODULE_DEVICE_TABLE(usb, et61x251_id_table);
+
+MODULE_AUTHOR(ET61X251_MODULE_AUTHOR " " ET61X251_AUTHOR_EMAIL);
+MODULE_DESCRIPTION(ET61X251_MODULE_NAME);
+MODULE_VERSION(ET61X251_MODULE_VERSION);
+MODULE_LICENSE(ET61X251_MODULE_LICENSE);
+
+static short video_nr[] = {[0 ... ET61X251_MAX_DEVICES-1] = -1};
+module_param_array(video_nr, short, NULL, 0444);
+MODULE_PARM_DESC(video_nr,
+                 "\n<-1|n[,...]> Specify V4L2 minor mode number."
+                 "\n -1 = use next available (default)"
+                 "\n  n = use minor number n (integer >= 0)"
+                 "\nYou can specify up to "
+                 __MODULE_STRING(ET61X251_MAX_DEVICES) " cameras this way."
+                 "\nFor example:"
+                 "\nvideo_nr=-1,2,-1 would assign minor number 2 to"
+                 "\nthe second registered camera and use auto for the first"
+                 "\none and for every other camera."
+                 "\n");
+
+static short force_munmap[] = {[0 ... ET61X251_MAX_DEVICES-1] =
+                               ET61X251_FORCE_MUNMAP};
+module_param_array(force_munmap, bool, NULL, 0444);
+MODULE_PARM_DESC(force_munmap,
+                 "\n<0|1[,...]> Force the application to unmap previously"
+                 "\nmapped buffer memory before calling any VIDIOC_S_CROP or"
+                 "\nVIDIOC_S_FMT ioctl's. Not all the applications support"
+                 "\nthis feature. This parameter is specific for each"
+                 "\ndetected camera."
+                 "\n 0 = do not force memory unmapping"
+                 "\n 1 = force memory unmapping (save memory)"
+                 "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"."
+                 "\n");
+
+#ifdef ET61X251_DEBUG
+static unsigned short debug = ET61X251_DEBUG_LEVEL;
+module_param(debug, ushort, 0644);
+MODULE_PARM_DESC(debug,
+                 "\n<n> Debugging information level, from 0 to 3:"
+                 "\n0 = none (use carefully)"
+                 "\n1 = critical errors"
+                 "\n2 = significant informations"
+                 "\n3 = more verbose messages"
+                 "\nLevel 3 is useful for testing only, when only "
+                 "one device is used."
+                 "\nDefault value is "__MODULE_STRING(ET61X251_DEBUG_LEVEL)"."
+                 "\n");
+#endif
+
+/*****************************************************************************/
+
+static u32
+et61x251_request_buffers(struct et61x251_device* cam, u32 count,
+                         enum et61x251_io_method io)
+{
+	struct v4l2_pix_format* p = &(cam->sensor->pix_format);
+	struct v4l2_rect* r = &(cam->sensor->cropcap.bounds);
+	const size_t imagesize = cam->module_param.force_munmap ||
+	                         io == IO_READ ?
+	                         (p->width * p->height * p->priv) / 8 :
+	                         (r->width * r->height * p->priv) / 8;
+	void* buff = NULL;
+	u32 i;
+
+	if (count > ET61X251_MAX_FRAMES)
+		count = ET61X251_MAX_FRAMES;
+
+	cam->nbuffers = count;
+	while (cam->nbuffers > 0) {
+		if ((buff = vmalloc_32(cam->nbuffers * PAGE_ALIGN(imagesize))))
+			break;
+		cam->nbuffers--;
+	}
+
+	for (i = 0; i < cam->nbuffers; i++) {
+		cam->frame[i].bufmem = buff + i*PAGE_ALIGN(imagesize);
+		cam->frame[i].buf.index = i;
+		cam->frame[i].buf.m.offset = i*PAGE_ALIGN(imagesize);
+		cam->frame[i].buf.length = imagesize;
+		cam->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		cam->frame[i].buf.sequence = 0;
+		cam->frame[i].buf.field = V4L2_FIELD_NONE;
+		cam->frame[i].buf.memory = V4L2_MEMORY_MMAP;
+		cam->frame[i].buf.flags = 0;
+	}
+
+	return cam->nbuffers;
+}
+
+
+static void et61x251_release_buffers(struct et61x251_device* cam)
+{
+	if (cam->nbuffers) {
+		vfree(cam->frame[0].bufmem);
+		cam->nbuffers = 0;
+	}
+	cam->frame_current = NULL;
+}
+
+
+static void et61x251_empty_framequeues(struct et61x251_device* cam)
+{
+	u32 i;
+
+	INIT_LIST_HEAD(&cam->inqueue);
+	INIT_LIST_HEAD(&cam->outqueue);
+
+	for (i = 0; i < ET61X251_MAX_FRAMES; i++) {
+		cam->frame[i].state = F_UNUSED;
+		cam->frame[i].buf.bytesused = 0;
+	}
+}
+
+
+static void et61x251_requeue_outqueue(struct et61x251_device* cam)
+{
+	struct et61x251_frame_t *i;
+
+	list_for_each_entry(i, &cam->outqueue, frame) {
+		i->state = F_QUEUED;
+		list_add(&i->frame, &cam->inqueue);
+	}
+
+	INIT_LIST_HEAD(&cam->outqueue);
+}
+
+
+static void et61x251_queue_unusedframes(struct et61x251_device* cam)
+{
+	unsigned long lock_flags;
+	u32 i;
+
+	for (i = 0; i < cam->nbuffers; i++)
+		if (cam->frame[i].state == F_UNUSED) {
+			cam->frame[i].state = F_QUEUED;
+			spin_lock_irqsave(&cam->queue_lock, lock_flags);
+			list_add_tail(&cam->frame[i].frame, &cam->inqueue);
+			spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
+		}
+}
+
+/*****************************************************************************/
+
+int et61x251_write_reg(struct et61x251_device* cam, u8 value, u16 index)
+{
+	struct usb_device* udev = cam->usbdev;
+	u8* buff = cam->control_buffer;
+	int res;
+
+	*buff = value;
+
+	res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
+	                      0, index, buff, 1, ET61X251_CTRL_TIMEOUT);
+	if (res < 0) {
+		DBG(3, "Failed to write a register (value 0x%02X, index "
+		       "0x%02X, error %d)", value, index, res);
+		return -1;
+	}
+
+	return 0;
+}
+
+
+int et61x251_read_reg(struct et61x251_device* cam, u16 index)
+{
+	struct usb_device* udev = cam->usbdev;
+	u8* buff = cam->control_buffer;
+	int res;
+
+	res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
+	                      0, index, buff, 1, ET61X251_CTRL_TIMEOUT);
+	if (res < 0)
+		DBG(3, "Failed to read a register (index 0x%02X, error %d)",
+		    index, res);
+
+	return (res >= 0) ? (int)(*buff) : -1;
+}
+
+
+static int
+et61x251_i2c_wait(struct et61x251_device* cam, struct et61x251_sensor* sensor)
+{
+	int i, r;
+
+	for (i = 1; i <= 8; i++) {
+		if (sensor->interface == ET61X251_I2C_3WIRES) {
+			r = et61x251_read_reg(cam, 0x8e);
+			if (!(r & 0x02) && (r >= 0))
+				return 0;
+		} else {
+			r = et61x251_read_reg(cam, 0x8b);
+			if (!(r & 0x01) && (r >= 0))
+				return 0;
+		}
+		if (r < 0)
+			return -EIO;
+		udelay(8*8); /* minimum for sensors at 400kHz */
+	}
+
+	return -EBUSY;
+}
+
+
+int
+et61x251_i2c_try_read(struct et61x251_device* cam,
+                      struct et61x251_sensor* sensor, u8 address)
+{
+	struct usb_device* udev = cam->usbdev;
+	u8* data = cam->control_buffer;
+	int err = 0, res;
+
+	data[0] = address;
+	data[1] = cam->sensor->i2c_slave_id;
+	data[2] = cam->sensor->rsta | 0x10;
+	data[3] = !(et61x251_read_reg(cam, 0x8b) & 0x02);
+	res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
+	                      0, 0x88, data, 4, ET61X251_CTRL_TIMEOUT);
+	if (res < 0)
+		err += res;
+
+	err += et61x251_i2c_wait(cam, sensor);
+
+	res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
+	                      0, 0x80, data, 8, ET61X251_CTRL_TIMEOUT);
+	if (res < 0)
+		err += res;
+
+	if (err)
+		DBG(3, "I2C read failed for %s image sensor", sensor->name);
+
+	PDBGG("I2C read: address 0x%02X, value: 0x%02X", address, data[0]);
+
+	return err ? -1 : (int)data[0];
+}
+
+
+int
+et61x251_i2c_try_write(struct et61x251_device* cam,
+                       struct et61x251_sensor* sensor, u8 address, u8 value)
+{
+	struct usb_device* udev = cam->usbdev;
+	u8* data = cam->control_buffer;
+	int err = 0, res;
+
+	data[0] = address;
+	data[1] = cam->sensor->i2c_slave_id;
+	data[2] = cam->sensor->rsta | 0x12;
+	res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
+	                      0, 0x88, data, 3, ET61X251_CTRL_TIMEOUT);
+	if (res < 0)
+		err += res;
+
+	data[0] = value;
+	res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
+	                      0, 0x80, data, 1, ET61X251_CTRL_TIMEOUT);
+	if (res < 0)
+		err += res;
+
+	err += et61x251_i2c_wait(cam, sensor);
+
+	if (err)
+		DBG(3, "I2C write failed for %s image sensor", sensor->name);
+
+	PDBGG("I2C write: address 0x%02X, value: 0x%02X", address, value);
+
+	return err ? -1 : 0;
+}
+
+
+int
+et61x251_i2c_raw_write(struct et61x251_device* cam, u8 n, u8 data1, u8 data2,
+                       u8 data3, u8 data4, u8 data5, u8 data6, u8 data7,
+                       u8 data8, u8 address)
+{
+	struct usb_device* udev = cam->usbdev;
+	u8* data = cam->control_buffer;
+	int err = 0, res;
+
+	if (!cam->sensor)
+		return -1;
+
+	data[0] = data2;
+	data[1] = data3;
+	data[2] = data4;
+	data[3] = data5;
+	data[4] = data6;
+	data[5] = data7;
+	data[6] = data8;
+	res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
+	                      0, 0x81, data, n-1, ET61X251_CTRL_TIMEOUT);
+	if (res < 0)
+		err += res;
+
+	data[0] = address;
+	data[1] = cam->sensor->i2c_slave_id;
+	data[2] = cam->sensor->rsta | 0x02 | (n << 4);
+	res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
+	                      0, 0x88, data, 3, ET61X251_CTRL_TIMEOUT);
+	if (res < 0)
+		err += res;
+
+	/* Start writing through the serial interface */
+	data[0] = data1;
+	res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
+	                      0, 0x80, data, 1, ET61X251_CTRL_TIMEOUT);
+	if (res < 0)
+		err += res;
+
+	err += et61x251_i2c_wait(cam, cam->sensor);
+
+	if (err)
+		DBG(3, "I2C raw write failed for %s image sensor",
+		    cam->sensor->name);
+
+	PDBGG("I2C raw write: %u bytes, address = 0x%02X, data1 = 0x%02X, "
+	      "data2 = 0x%02X, data3 = 0x%02X, data4 = 0x%02X, data5 = 0x%02X,"
+	      " data6 = 0x%02X, data7 = 0x%02X, data8 = 0x%02X", n, address,
+	      data1, data2, data3, data4, data5, data6, data7, data8);
+
+	return err ? -1 : 0;
+
+}
+
+
+int et61x251_i2c_read(struct et61x251_device* cam, u8 address)
+{
+	if (!cam->sensor)
+		return -1;
+
+	return et61x251_i2c_try_read(cam, cam->sensor, address);
+}
+
+
+int et61x251_i2c_write(struct et61x251_device* cam, u8 address, u8 value)
+{
+	if (!cam->sensor)
+		return -1;
+
+	return et61x251_i2c_try_write(cam, cam->sensor, address, value);
+}
+
+/*****************************************************************************/
+
+static void et61x251_urb_complete(struct urb *urb, struct pt_regs* regs)
+{
+	struct et61x251_device* cam = urb->context;
+	struct et61x251_frame_t** f;
+	size_t imagesize;
+	u8 i;
+	int err = 0;
+
+	if (urb->status == -ENOENT)
+		return;
+
+	f = &cam->frame_current;
+
+	if (cam->stream == STREAM_INTERRUPT) {
+		cam->stream = STREAM_OFF;
+		if ((*f))
+			(*f)->state = F_QUEUED;
+		DBG(3, "Stream interrupted");
+		wake_up_interruptible(&cam->wait_stream);
+	}
+
+	if (cam->state & DEV_DISCONNECTED)
+		return;
+
+	if (cam->state & DEV_MISCONFIGURED) {
+		wake_up_interruptible(&cam->wait_frame);
+		return;
+	}
+
+	if (cam->stream == STREAM_OFF || list_empty(&cam->inqueue))
+		goto resubmit_urb;
+
+	if (!(*f))
+		(*f) = list_entry(cam->inqueue.next, struct et61x251_frame_t,
+		                  frame);
+
+	imagesize = (cam->sensor->pix_format.width *
+	             cam->sensor->pix_format.height *
+	             cam->sensor->pix_format.priv) / 8;
+
+	for (i = 0; i < urb->number_of_packets; i++) {
+		unsigned int len, status;
+		void *pos;
+		u8* b1, * b2, sof;
+		const u8 VOID_BYTES = 6;
+		size_t imglen;
+
+		len = urb->iso_frame_desc[i].actual_length;
+		status = urb->iso_frame_desc[i].status;
+		pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
+
+		if (status) {
+			DBG(3, "Error in isochronous frame");
+			(*f)->state = F_ERROR;
+			continue;
+		}
+
+		b1 = pos++;
+		b2 = pos++;
+		sof = ((*b1 & 0x3f) == 63);
+		imglen = ((*b1 & 0xc0) << 2) | *b2;
+
+		PDBGG("Isochrnous frame: length %u, #%u i, image length %zu",
+		      len, i, imglen);
+
+		if ((*f)->state == F_QUEUED || (*f)->state == F_ERROR)
+start_of_frame:
+			if (sof) {
+				(*f)->state = F_GRABBING;
+				(*f)->buf.bytesused = 0;
+				do_gettimeofday(&(*f)->buf.timestamp);
+				pos += 22;
+				DBG(3, "SOF detected: new video frame");
+			}
+
+		if ((*f)->state == F_GRABBING) {
+			if (sof && (*f)->buf.bytesused) {
+				if (cam->sensor->pix_format.pixelformat ==
+				                         V4L2_PIX_FMT_ET61X251)
+					goto end_of_frame;
+				else {
+					DBG(3, "Not expected SOF detected "
+					       "after %lu bytes",
+					   (unsigned long)(*f)->buf.bytesused);
+					(*f)->state = F_ERROR;
+					continue;
+				}
+			}
+
+			if ((*f)->buf.bytesused + imglen > imagesize) {
+				DBG(3, "Video frame size exceeded");
+				(*f)->state = F_ERROR;
+				continue;
+			}
+
+			pos += VOID_BYTES;
+
+			memcpy((*f)->bufmem+(*f)->buf.bytesused, pos, imglen);
+			(*f)->buf.bytesused += imglen;
+
+			if ((*f)->buf.bytesused == imagesize) {
+				u32 b;
+end_of_frame:
+				b = (*f)->buf.bytesused;
+				(*f)->state = F_DONE;
+				(*f)->buf.sequence= ++cam->frame_count;
+				spin_lock(&cam->queue_lock);
+				list_move_tail(&(*f)->frame, &cam->outqueue);
+				if (!list_empty(&cam->inqueue))
+					(*f) = list_entry(cam->inqueue.next,
+					               struct et61x251_frame_t,
+					                  frame);
+				else
+					(*f) = NULL;
+				spin_unlock(&cam->queue_lock);
+				DBG(3, "Video frame captured: : %lu bytes",
+				       (unsigned long)(b));
+
+				if (!(*f))
+					goto resubmit_urb;
+
+				if (sof &&
+				    cam->sensor->pix_format.pixelformat ==
+				                         V4L2_PIX_FMT_ET61X251)
+					goto start_of_frame;
+			}
+		}
+	}
+
+resubmit_urb:
+	urb->dev = cam->usbdev;
+	err = usb_submit_urb(urb, GFP_ATOMIC);
+	if (err < 0 && err != -EPERM) {
+		cam->state |= DEV_MISCONFIGURED;
+		DBG(1, "usb_submit_urb() failed");
+	}
+
+	wake_up_interruptible(&cam->wait_frame);
+}
+
+
+static int et61x251_start_transfer(struct et61x251_device* cam)
+{
+	struct usb_device *udev = cam->usbdev;
+	struct urb* urb;
+	const unsigned int wMaxPacketSize[] = {0, 256, 384, 512, 640, 768, 832,
+	                                       864, 896, 920, 956, 980, 1000,
+	                                       1022};
+	const unsigned int psz = wMaxPacketSize[ET61X251_ALTERNATE_SETTING];
+	s8 i, j;
+	int err = 0;
+
+	for (i = 0; i < ET61X251_URBS; i++) {
+		cam->transfer_buffer[i] = kzalloc(ET61X251_ISO_PACKETS * psz,
+		                                  GFP_KERNEL);
+		if (!cam->transfer_buffer[i]) {
+			err = -ENOMEM;
+			DBG(1, "Not enough memory");
+			goto free_buffers;
+		}
+	}
+
+	for (i = 0; i < ET61X251_URBS; i++) {
+		urb = usb_alloc_urb(ET61X251_ISO_PACKETS, GFP_KERNEL);
+		cam->urb[i] = urb;
+		if (!urb) {
+			err = -ENOMEM;
+			DBG(1, "usb_alloc_urb() failed");
+			goto free_urbs;
+		}
+		urb->dev = udev;
+		urb->context = cam;
+		urb->pipe = usb_rcvisocpipe(udev, 1);
+		urb->transfer_flags = URB_ISO_ASAP;
+		urb->number_of_packets = ET61X251_ISO_PACKETS;
+		urb->complete = et61x251_urb_complete;
+		urb->transfer_buffer = cam->transfer_buffer[i];
+		urb->transfer_buffer_length = psz * ET61X251_ISO_PACKETS;
+		urb->interval = 1;
+		for (j = 0; j < ET61X251_ISO_PACKETS; j++) {
+			urb->iso_frame_desc[j].offset = psz * j;
+			urb->iso_frame_desc[j].length = psz;
+		}
+	}
+
+	err = et61x251_write_reg(cam, 0x01, 0x03);
+	err = et61x251_write_reg(cam, 0x00, 0x03);
+	err = et61x251_write_reg(cam, 0x08, 0x03);
+	if (err) {
+		err = -EIO;
+		DBG(1, "I/O hardware error");
+		goto free_urbs;
+	}
+
+	err = usb_set_interface(udev, 0, ET61X251_ALTERNATE_SETTING);
+	if (err) {
+		DBG(1, "usb_set_interface() failed");
+		goto free_urbs;
+	}
+
+	cam->frame_current = NULL;
+
+	for (i = 0; i < ET61X251_URBS; i++) {
+		err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
+		if (err) {
+			for (j = i-1; j >= 0; j--)
+				usb_kill_urb(cam->urb[j]);
+			DBG(1, "usb_submit_urb() failed, error %d", err);
+			goto free_urbs;
+		}
+	}
+
+	return 0;
+
+free_urbs:
+	for (i = 0; (i < ET61X251_URBS) &&  cam->urb[i]; i++)
+		usb_free_urb(cam->urb[i]);
+
+free_buffers:
+	for (i = 0; (i < ET61X251_URBS) && cam->transfer_buffer[i]; i++)
+		kfree(cam->transfer_buffer[i]);
+
+	return err;
+}
+
+
+static int et61x251_stop_transfer(struct et61x251_device* cam)
+{
+	struct usb_device *udev = cam->usbdev;
+	s8 i;
+	int err = 0;
+
+	if (cam->state & DEV_DISCONNECTED)
+		return 0;
+
+	for (i = ET61X251_URBS-1; i >= 0; i--) {
+		usb_kill_urb(cam->urb[i]);
+		usb_free_urb(cam->urb[i]);
+		kfree(cam->transfer_buffer[i]);
+	}
+
+	err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */
+	if (err)
+		DBG(3, "usb_set_interface() failed");
+
+	return err;
+}
+
+
+static int et61x251_stream_interrupt(struct et61x251_device* cam)
+{
+	int err = 0;
+
+	cam->stream = STREAM_INTERRUPT;
+	err = wait_event_timeout(cam->wait_stream,
+	                         (cam->stream == STREAM_OFF) ||
+	                         (cam->state & DEV_DISCONNECTED),
+	                         ET61X251_URB_TIMEOUT);
+	if (cam->state & DEV_DISCONNECTED)
+		return -ENODEV;
+	else if (err) {
+		cam->state |= DEV_MISCONFIGURED;
+		DBG(1, "URB timeout reached. The camera is misconfigured. To "
+		       "use it, close and open /dev/video%d again.",
+		    cam->v4ldev->minor);
+		return err;
+	}
+
+	return 0;
+}
+
+/*****************************************************************************/
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static u8 et61x251_strtou8(const char* buff, size_t len, ssize_t* count)
+{
+	char str[5];
+	char* endp;
+	unsigned long val;
+
+	if (len < 4) {
+		strncpy(str, buff, len);
+		str[len+1] = '\0';
+	} else {
+		strncpy(str, buff, 4);
+		str[4] = '\0';
+	}
+
+	val = simple_strtoul(str, &endp, 0);
+
+	*count = 0;
+	if (val <= 0xff)
+		*count = (ssize_t)(endp - str);
+	if ((*count) && (len == *count+1) && (buff[*count] == '\n'))
+		*count += 1;
+
+	return (u8)val;
+}
+
+/*
+   NOTE 1: being inside one of the following methods implies that the v4l
+           device exists for sure (see kobjects and reference counters)
+   NOTE 2: buffers are PAGE_SIZE long
+*/
+
+static ssize_t et61x251_show_reg(struct class_device* cd, char* buf)
+{
+	struct et61x251_device* cam;
+	ssize_t count;
+
+	if (down_interruptible(&et61x251_sysfs_lock))
+		return -ERESTARTSYS;
+
+	cam = video_get_drvdata(to_video_device(cd));
+	if (!cam) {
+		up(&et61x251_sysfs_lock);
+		return -ENODEV;
+	}
+
+	count = sprintf(buf, "%u\n", cam->sysfs.reg);
+
+	up(&et61x251_sysfs_lock);
+
+	return count;
+}
+
+
+static ssize_t
+et61x251_store_reg(struct class_device* cd, const char* buf, size_t len)
+{
+	struct et61x251_device* cam;
+	u8 index;
+	ssize_t count;
+
+	if (down_interruptible(&et61x251_sysfs_lock))
+		return -ERESTARTSYS;
+
+	cam = video_get_drvdata(to_video_device(cd));
+	if (!cam) {
+		up(&et61x251_sysfs_lock);
+		return -ENODEV;
+	}
+
+	index = et61x251_strtou8(buf, len, &count);
+	if (index > 0x8e || !count) {
+		up(&et61x251_sysfs_lock);
+		return -EINVAL;
+	}
+
+	cam->sysfs.reg = index;
+
+	DBG(2, "Moved ET61X[12]51 register index to 0x%02X", cam->sysfs.reg);
+	DBG(3, "Written bytes: %zd", count);
+
+	up(&et61x251_sysfs_lock);
+
+	return count;
+}
+
+
+static ssize_t et61x251_show_val(struct class_device* cd, char* buf)
+{
+	struct et61x251_device* cam;
+	ssize_t count;
+	int val;
+
+	if (down_interruptible(&et61x251_sysfs_lock))
+		return -ERESTARTSYS;
+
+	cam = video_get_drvdata(to_video_device(cd));
+	if (!cam) {
+		up(&et61x251_sysfs_lock);
+		return -ENODEV;
+	}
+
+	if ((val = et61x251_read_reg(cam, cam->sysfs.reg)) < 0) {
+		up(&et61x251_sysfs_lock);
+		return -EIO;
+	}
+
+	count = sprintf(buf, "%d\n", val);
+
+	DBG(3, "Read bytes: %zd", count);
+
+	up(&et61x251_sysfs_lock);
+
+	return count;
+}
+
+
+static ssize_t
+et61x251_store_val(struct class_device* cd, const char* buf, size_t len)
+{
+	struct et61x251_device* cam;
+	u8 value;
+	ssize_t count;
+	int err;
+
+	if (down_interruptible(&et61x251_sysfs_lock))
+		return -ERESTARTSYS;
+
+	cam = video_get_drvdata(to_video_device(cd));
+	if (!cam) {
+		up(&et61x251_sysfs_lock);
+		return -ENODEV;
+	}
+
+	value = et61x251_strtou8(buf, len, &count);
+	if (!count) {
+		up(&et61x251_sysfs_lock);
+		return -EINVAL;
+	}
+
+	err = et61x251_write_reg(cam, value, cam->sysfs.reg);
+	if (err) {
+		up(&et61x251_sysfs_lock);
+		return -EIO;
+	}
+
+	DBG(2, "Written ET61X[12]51 reg. 0x%02X, val. 0x%02X",
+	    cam->sysfs.reg, value);
+	DBG(3, "Written bytes: %zd", count);
+
+	up(&et61x251_sysfs_lock);
+
+	return count;
+}
+
+
+static ssize_t et61x251_show_i2c_reg(struct class_device* cd, char* buf)
+{
+	struct et61x251_device* cam;
+	ssize_t count;
+
+	if (down_interruptible(&et61x251_sysfs_lock))
+		return -ERESTARTSYS;
+
+	cam = video_get_drvdata(to_video_device(cd));
+	if (!cam) {
+		up(&et61x251_sysfs_lock);
+		return -ENODEV;
+	}
+
+	count = sprintf(buf, "%u\n", cam->sysfs.i2c_reg);
+
+	DBG(3, "Read bytes: %zd", count);
+
+	up(&et61x251_sysfs_lock);
+
+	return count;
+}
+
+
+static ssize_t
+et61x251_store_i2c_reg(struct class_device* cd, const char* buf, size_t len)
+{
+	struct et61x251_device* cam;
+	u8 index;
+	ssize_t count;
+
+	if (down_interruptible(&et61x251_sysfs_lock))
+		return -ERESTARTSYS;
+
+	cam = video_get_drvdata(to_video_device(cd));
+	if (!cam) {
+		up(&et61x251_sysfs_lock);
+		return -ENODEV;
+	}
+
+	index = et61x251_strtou8(buf, len, &count);
+	if (!count) {
+		up(&et61x251_sysfs_lock);
+		return -EINVAL;
+	}
+
+	cam->sysfs.i2c_reg = index;
+
+	DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg);
+	DBG(3, "Written bytes: %zd", count);
+
+	up(&et61x251_sysfs_lock);
+
+	return count;
+}
+
+
+static ssize_t et61x251_show_i2c_val(struct class_device* cd, char* buf)
+{
+	struct et61x251_device* cam;
+	ssize_t count;
+	int val;
+
+	if (down_interruptible(&et61x251_sysfs_lock))
+		return -ERESTARTSYS;
+
+	cam = video_get_drvdata(to_video_device(cd));
+	if (!cam) {
+		up(&et61x251_sysfs_lock);
+		return -ENODEV;
+	}
+
+	if (!(cam->sensor->sysfs_ops & ET61X251_I2C_READ)) {
+		up(&et61x251_sysfs_lock);
+		return -ENOSYS;
+	}
+
+	if ((val = et61x251_i2c_read(cam, cam->sysfs.i2c_reg)) < 0) {
+		up(&et61x251_sysfs_lock);
+		return -EIO;
+	}
+
+	count = sprintf(buf, "%d\n", val);
+
+	DBG(3, "Read bytes: %zd", count);
+
+	up(&et61x251_sysfs_lock);
+
+	return count;
+}
+
+
+static ssize_t
+et61x251_store_i2c_val(struct class_device* cd, const char* buf, size_t len)
+{
+	struct et61x251_device* cam;
+	u8 value;
+	ssize_t count;
+	int err;
+
+	if (down_interruptible(&et61x251_sysfs_lock))
+		return -ERESTARTSYS;
+
+	cam = video_get_drvdata(to_video_device(cd));
+	if (!cam) {
+		up(&et61x251_sysfs_lock);
+		return -ENODEV;
+	}
+
+	if (!(cam->sensor->sysfs_ops & ET61X251_I2C_READ)) {
+		up(&et61x251_sysfs_lock);
+		return -ENOSYS;
+	}
+
+	value = et61x251_strtou8(buf, len, &count);
+	if (!count) {
+		up(&et61x251_sysfs_lock);
+		return -EINVAL;
+	}
+
+	err = et61x251_i2c_write(cam, cam->sysfs.i2c_reg, value);
+	if (err) {
+		up(&et61x251_sysfs_lock);
+		return -EIO;
+	}
+
+	DBG(2, "Written sensor reg. 0x%02X, val. 0x%02X",
+	    cam->sysfs.i2c_reg, value);
+	DBG(3, "Written bytes: %zd", count);
+
+	up(&et61x251_sysfs_lock);
+
+	return count;
+}
+
+
+static CLASS_DEVICE_ATTR(reg, S_IRUGO | S_IWUSR,
+                         et61x251_show_reg, et61x251_store_reg);
+static CLASS_DEVICE_ATTR(val, S_IRUGO | S_IWUSR,
+                         et61x251_show_val, et61x251_store_val);
+static CLASS_DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR,
+                         et61x251_show_i2c_reg, et61x251_store_i2c_reg);
+static CLASS_DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
+                         et61x251_show_i2c_val, et61x251_store_i2c_val);
+
+
+static void et61x251_create_sysfs(struct et61x251_device* cam)
+{
+	struct video_device *v4ldev = cam->v4ldev;
+
+	video_device_create_file(v4ldev, &class_device_attr_reg);
+	video_device_create_file(v4ldev, &class_device_attr_val);
+	if (cam->sensor && cam->sensor->sysfs_ops) {
+		video_device_create_file(v4ldev, &class_device_attr_i2c_reg);
+		video_device_create_file(v4ldev, &class_device_attr_i2c_val);
+	}
+}
+#endif /* CONFIG_VIDEO_ADV_DEBUG */
+
+/*****************************************************************************/
+
+static int
+et61x251_set_pix_format(struct et61x251_device* cam,
+                        struct v4l2_pix_format* pix)
+{
+	int r, err = 0;
+
+	if ((r = et61x251_read_reg(cam, 0x12)) < 0)
+		err += r;
+	if (pix->pixelformat == V4L2_PIX_FMT_ET61X251)
+		err += et61x251_write_reg(cam, r & 0xfd, 0x12);
+	else
+		err += et61x251_write_reg(cam, r | 0x02, 0x12);
+
+	return err ? -EIO : 0;
+}
+
+
+static int
+et61x251_set_compression(struct et61x251_device* cam,
+                         struct v4l2_jpegcompression* compression)
+{
+	int r, err = 0;
+
+	if ((r = et61x251_read_reg(cam, 0x12)) < 0)
+		err += r;
+	if (compression->quality == 0)
+		err += et61x251_write_reg(cam, r & 0xfb, 0x12);
+	else
+		err += et61x251_write_reg(cam, r | 0x04, 0x12);
+
+	return err ? -EIO : 0;
+}
+
+
+static int et61x251_set_scale(struct et61x251_device* cam, u8 scale)
+{
+	int r = 0, err = 0;
+
+	r = et61x251_read_reg(cam, 0x12);
+	if (r < 0)
+		err += r;
+
+	if (scale == 1)
+		err += et61x251_write_reg(cam, r & ~0x01, 0x12);
+	else if (scale == 2)
+		err += et61x251_write_reg(cam, r | 0x01, 0x12);
+
+	if (err)
+		return -EIO;
+
+	PDBGG("Scaling factor: %u", scale);
+
+	return 0;
+}
+
+
+static int
+et61x251_set_crop(struct et61x251_device* cam, struct v4l2_rect* rect)
+{
+	struct et61x251_sensor* s = cam->sensor;
+	u16 fmw_sx = (u16)(rect->left - s->cropcap.bounds.left +
+	                   s->active_pixel.left),
+	    fmw_sy = (u16)(rect->top - s->cropcap.bounds.top +
+	                   s->active_pixel.top),
+	    fmw_length = (u16)(rect->width),
+	    fmw_height = (u16)(rect->height);
+	int err = 0;
+
+	err += et61x251_write_reg(cam, fmw_sx & 0xff, 0x69);
+	err += et61x251_write_reg(cam, fmw_sy & 0xff, 0x6a);
+	err += et61x251_write_reg(cam, fmw_length & 0xff, 0x6b);
+	err += et61x251_write_reg(cam, fmw_height & 0xff, 0x6c);
+	err += et61x251_write_reg(cam, (fmw_sx >> 8) | ((fmw_sy & 0x300) >> 6)
+	                               | ((fmw_length & 0x300) >> 4)
+	                               | ((fmw_height & 0x300) >> 2), 0x6d);
+	if (err)
+		return -EIO;
+
+	PDBGG("fmw_sx, fmw_sy, fmw_length, fmw_height: %u %u %u %u",
+	      fmw_sx, fmw_sy, fmw_length, fmw_height);
+
+	return 0;
+}
+
+
+static int et61x251_init(struct et61x251_device* cam)
+{
+	struct et61x251_sensor* s = cam->sensor;
+	struct v4l2_control ctrl;
+	struct v4l2_queryctrl *qctrl;
+	struct v4l2_rect* rect;
+	u8 i = 0;
+	int err = 0;
+
+	if (!(cam->state & DEV_INITIALIZED)) {
+		init_waitqueue_head(&cam->open);
+		qctrl = s->qctrl;
+		rect = &(s->cropcap.defrect);
+		cam->compression.quality = ET61X251_COMPRESSION_QUALITY;
+	} else { /* use current values */
+		qctrl = s->_qctrl;
+		rect = &(s->_rect);
+	}
+
+	err += et61x251_set_scale(cam, rect->width / s->pix_format.width);
+	err += et61x251_set_crop(cam, rect);
+	if (err)
+		return err;
+
+	if (s->init) {
+		err = s->init(cam);
+		if (err) {
+			DBG(3, "Sensor initialization failed");
+			return err;
+		}
+	}
+
+	err += et61x251_set_compression(cam, &cam->compression);
+	err += et61x251_set_pix_format(cam, &s->pix_format);
+	if (s->set_pix_format)
+		err += s->set_pix_format(cam, &s->pix_format);
+	if (err)
+		return err;
+
+	if (s->pix_format.pixelformat == V4L2_PIX_FMT_ET61X251)
+		DBG(3, "Compressed video format is active, quality %d",
+		    cam->compression.quality);
+	else
+		DBG(3, "Uncompressed video format is active");
+
+	if (s->set_crop)
+		if ((err = s->set_crop(cam, rect))) {
+			DBG(3, "set_crop() failed");
+			return err;
+		}
+
+	if (s->set_ctrl) {
+		for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
+			if (s->qctrl[i].id != 0 &&
+			    !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) {
+				ctrl.id = s->qctrl[i].id;
+				ctrl.value = qctrl[i].default_value;
+				err = s->set_ctrl(cam, &ctrl);
+				if (err) {
+					DBG(3, "Set %s control failed",
+					    s->qctrl[i].name);
+					return err;
+				}
+				DBG(3, "Image sensor supports '%s' control",
+				    s->qctrl[i].name);
+			}
+	}
+
+	if (!(cam->state & DEV_INITIALIZED)) {
+		init_MUTEX(&cam->fileop_sem);
+		spin_lock_init(&cam->queue_lock);
+		init_waitqueue_head(&cam->wait_frame);
+		init_waitqueue_head(&cam->wait_stream);
+		cam->nreadbuffers = 2;
+		memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl));
+		memcpy(&(s->_rect), &(s->cropcap.defrect),
+		       sizeof(struct v4l2_rect));
+		cam->state |= DEV_INITIALIZED;
+	}
+
+	DBG(2, "Initialization succeeded");
+	return 0;
+}
+
+
+static void et61x251_release_resources(struct et61x251_device* cam)
+{
+	down(&et61x251_sysfs_lock);
+
+	DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor);
+	video_set_drvdata(cam->v4ldev, NULL);
+	video_unregister_device(cam->v4ldev);
+
+	up(&et61x251_sysfs_lock);
+
+	kfree(cam->control_buffer);
+}
+
+/*****************************************************************************/
+
+static int et61x251_open(struct inode* inode, struct file* filp)
+{
+	struct et61x251_device* cam;
+	int err = 0;
+
+	/*
+	   This is the only safe way to prevent race conditions with
+	   disconnect
+	*/
+	if (!down_read_trylock(&et61x251_disconnect))
+		return -ERESTARTSYS;
+
+	cam = video_get_drvdata(video_devdata(filp));
+
+	if (down_interruptible(&cam->dev_sem)) {
+		up_read(&et61x251_disconnect);
+		return -ERESTARTSYS;
+	}
+
+	if (cam->users) {
+		DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor);
+		if ((filp->f_flags & O_NONBLOCK) ||
+		    (filp->f_flags & O_NDELAY)) {
+			err = -EWOULDBLOCK;
+			goto out;
+		}
+		up(&cam->dev_sem);
+		err = wait_event_interruptible_exclusive(cam->open,
+		                                  cam->state & DEV_DISCONNECTED
+		                                         || !cam->users);
+		if (err) {
+			up_read(&et61x251_disconnect);
+			return err;
+		}
+		if (cam->state & DEV_DISCONNECTED) {
+			up_read(&et61x251_disconnect);
+			return -ENODEV;
+		}
+		down(&cam->dev_sem);
+	}
+
+
+	if (cam->state & DEV_MISCONFIGURED) {
+		err = et61x251_init(cam);
+		if (err) {
+			DBG(1, "Initialization failed again. "
+			       "I will retry on next open().");
+			goto out;
+		}
+		cam->state &= ~DEV_MISCONFIGURED;
+	}
+
+	if ((err = et61x251_start_transfer(cam)))
+		goto out;
+
+	filp->private_data = cam;
+	cam->users++;
+	cam->io = IO_NONE;
+	cam->stream = STREAM_OFF;
+	cam->nbuffers = 0;
+	cam->frame_count = 0;
+	et61x251_empty_framequeues(cam);
+
+	DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor);
+
+out:
+	up(&cam->dev_sem);
+	up_read(&et61x251_disconnect);
+	return err;
+}
+
+
+static int et61x251_release(struct inode* inode, struct file* filp)
+{
+	struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
+
+	down(&cam->dev_sem); /* prevent disconnect() to be called */
+
+	et61x251_stop_transfer(cam);
+
+	et61x251_release_buffers(cam);
+
+	if (cam->state & DEV_DISCONNECTED) {
+		et61x251_release_resources(cam);
+		up(&cam->dev_sem);
+		kfree(cam);
+		return 0;
+	}
+
+	cam->users--;
+	wake_up_interruptible_nr(&cam->open, 1);
+
+	DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor);
+
+	up(&cam->dev_sem);
+
+	return 0;
+}
+
+
+static ssize_t
+et61x251_read(struct file* filp, char __user * buf,
+              size_t count, loff_t* f_pos)
+{
+	struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
+	struct et61x251_frame_t* f, * i;
+	unsigned long lock_flags;
+	int err = 0;
+
+	if (down_interruptible(&cam->fileop_sem))
+		return -ERESTARTSYS;
+
+	if (cam->state & DEV_DISCONNECTED) {
+		DBG(1, "Device not present");
+		up(&cam->fileop_sem);
+		return -ENODEV;
+	}
+
+	if (cam->state & DEV_MISCONFIGURED) {
+		DBG(1, "The camera is misconfigured. Close and open it "
+		       "again.");
+		up(&cam->fileop_sem);
+		return -EIO;
+	}
+
+	if (cam->io == IO_MMAP) {
+		DBG(3, "Close and open the device again to choose the read "
+		       "method");
+		up(&cam->fileop_sem);
+		return -EINVAL;
+	}
+
+	if (cam->io == IO_NONE) {
+		if (!et61x251_request_buffers(cam, cam->nreadbuffers,
+		                              IO_READ)) {
+			DBG(1, "read() failed, not enough memory");
+			up(&cam->fileop_sem);
+			return -ENOMEM;
+		}
+		cam->io = IO_READ;
+		cam->stream = STREAM_ON;
+	}
+
+	if (list_empty(&cam->inqueue)) {
+		if (!list_empty(&cam->outqueue))
+			et61x251_empty_framequeues(cam);
+		et61x251_queue_unusedframes(cam);
+	}
+
+	if (!count) {
+		up(&cam->fileop_sem);
+		return 0;
+	}
+
+	if (list_empty(&cam->outqueue)) {
+		if (filp->f_flags & O_NONBLOCK) {
+			up(&cam->fileop_sem);
+			return -EAGAIN;
+		}
+		err = wait_event_interruptible
+		      ( cam->wait_frame,
+		        (!list_empty(&cam->outqueue)) ||
+		        (cam->state & DEV_DISCONNECTED) ||
+			(cam->state & DEV_MISCONFIGURED) );
+		if (err) {
+			up(&cam->fileop_sem);
+			return err;
+		}
+		if (cam->state & DEV_DISCONNECTED) {
+			up(&cam->fileop_sem);
+			return -ENODEV;
+		}
+		if (cam->state & DEV_MISCONFIGURED) {
+			up(&cam->fileop_sem);
+			return -EIO;
+		}
+	}
+
+	f = list_entry(cam->outqueue.prev, struct et61x251_frame_t, frame);
+
+	if (count > f->buf.bytesused)
+		count = f->buf.bytesused;
+
+	if (copy_to_user(buf, f->bufmem, count)) {
+		err = -EFAULT;
+		goto exit;
+	}
+	*f_pos += count;
+
+exit:
+	spin_lock_irqsave(&cam->queue_lock, lock_flags);
+	list_for_each_entry(i, &cam->outqueue, frame)
+		i->state = F_UNUSED;
+	INIT_LIST_HEAD(&cam->outqueue);
+	spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
+
+	et61x251_queue_unusedframes(cam);
+
+	PDBGG("Frame #%lu, bytes read: %zu",
+	      (unsigned long)f->buf.index, count);
+
+	up(&cam->fileop_sem);
+
+	return err ? err : count;
+}
+
+
+static unsigned int et61x251_poll(struct file *filp, poll_table *wait)
+{
+	struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
+	struct et61x251_frame_t* f;
+	unsigned long lock_flags;
+	unsigned int mask = 0;
+
+	if (down_interruptible(&cam->fileop_sem))
+		return POLLERR;
+
+	if (cam->state & DEV_DISCONNECTED) {
+		DBG(1, "Device not present");
+		goto error;
+	}
+
+	if (cam->state & DEV_MISCONFIGURED) {
+		DBG(1, "The camera is misconfigured. Close and open it "
+		       "again.");
+		goto error;
+	}
+
+	if (cam->io == IO_NONE) {
+		if (!et61x251_request_buffers(cam, cam->nreadbuffers,
+		                              IO_READ)) {
+			DBG(1, "poll() failed, not enough memory");
+			goto error;
+		}
+		cam->io = IO_READ;
+		cam->stream = STREAM_ON;
+	}
+
+	if (cam->io == IO_READ) {
+		spin_lock_irqsave(&cam->queue_lock, lock_flags);
+		list_for_each_entry(f, &cam->outqueue, frame)
+			f->state = F_UNUSED;
+		INIT_LIST_HEAD(&cam->outqueue);
+		spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
+		et61x251_queue_unusedframes(cam);
+	}
+
+	poll_wait(filp, &cam->wait_frame, wait);
+
+	if (!list_empty(&cam->outqueue))
+		mask |= POLLIN | POLLRDNORM;
+
+	up(&cam->fileop_sem);
+
+	return mask;
+
+error:
+	up(&cam->fileop_sem);
+	return POLLERR;
+}
+
+
+static void et61x251_vm_open(struct vm_area_struct* vma)
+{
+	struct et61x251_frame_t* f = vma->vm_private_data;
+	f->vma_use_count++;
+}
+
+
+static void et61x251_vm_close(struct vm_area_struct* vma)
+{
+	/* NOTE: buffers are not freed here */
+	struct et61x251_frame_t* f = vma->vm_private_data;
+	f->vma_use_count--;
+}
+
+
+static struct vm_operations_struct et61x251_vm_ops = {
+	.open = et61x251_vm_open,
+	.close = et61x251_vm_close,
+};
+
+
+static int et61x251_mmap(struct file* filp, struct vm_area_struct *vma)
+{
+	struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
+	unsigned long size = vma->vm_end - vma->vm_start,
+	              start = vma->vm_start;
+	void *pos;
+	u32 i;
+
+	if (down_interruptible(&cam->fileop_sem))
+		return -ERESTARTSYS;
+
+	if (cam->state & DEV_DISCONNECTED) {
+		DBG(1, "Device not present");
+		up(&cam->fileop_sem);
+		return -ENODEV;
+	}
+
+	if (cam->state & DEV_MISCONFIGURED) {
+		DBG(1, "The camera is misconfigured. Close and open it "
+		       "again.");
+		up(&cam->fileop_sem);
+		return -EIO;
+	}
+
+	if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) ||
+	    size != PAGE_ALIGN(cam->frame[0].buf.length)) {
+		up(&cam->fileop_sem);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < cam->nbuffers; i++) {
+		if ((cam->frame[i].buf.m.offset>>PAGE_SHIFT) == vma->vm_pgoff)
+			break;
+	}
+	if (i == cam->nbuffers) {
+		up(&cam->fileop_sem);
+		return -EINVAL;
+	}
+
+	vma->vm_flags |= VM_IO;
+	vma->vm_flags |= VM_RESERVED;
+
+	pos = cam->frame[i].bufmem;
+	while (size > 0) { /* size is page-aligned */
+		if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
+			up(&cam->fileop_sem);
+			return -EAGAIN;
+		}
+		start += PAGE_SIZE;
+		pos += PAGE_SIZE;
+		size -= PAGE_SIZE;
+	}
+
+	vma->vm_ops = &et61x251_vm_ops;
+	vma->vm_private_data = &cam->frame[i];
+
+	et61x251_vm_open(vma);
+
+	up(&cam->fileop_sem);
+
+	return 0;
+}
+
+/*****************************************************************************/
+
+static int
+et61x251_vidioc_querycap(struct et61x251_device* cam, void __user * arg)
+{
+	struct v4l2_capability cap = {
+		.driver = "et61x251",
+		.version = ET61X251_MODULE_VERSION_CODE,
+		.capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
+		                V4L2_CAP_STREAMING,
+	};
+
+	strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
+	if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
+		strlcpy(cap.bus_info, cam->usbdev->dev.bus_id,
+		        sizeof(cap.bus_info));
+
+	if (copy_to_user(arg, &cap, sizeof(cap)))
+		return -EFAULT;
+
+	return 0;
+}
+
+
+static int
+et61x251_vidioc_enuminput(struct et61x251_device* cam, void __user * arg)
+{
+	struct v4l2_input i;
+
+	if (copy_from_user(&i, arg, sizeof(i)))
+		return -EFAULT;
+
+	if (i.index)
+		return -EINVAL;
+
+	memset(&i, 0, sizeof(i));
+	strcpy(i.name, "Camera");
+
+	if (copy_to_user(arg, &i, sizeof(i)))
+		return -EFAULT;
+
+	return 0;
+}
+
+
+static int
+et61x251_vidioc_gs_input(struct et61x251_device* cam, void __user * arg)
+{
+	int index;
+
+	if (copy_from_user(&index, arg, sizeof(index)))
+		return -EFAULT;
+
+	if (index != 0)
+		return -EINVAL;
+
+	return 0;
+}
+
+
+static int
+et61x251_vidioc_query_ctrl(struct et61x251_device* cam, void __user * arg)
+{
+	struct et61x251_sensor* s = cam->sensor;
+	struct v4l2_queryctrl qc;
+	u8 i;
+
+	if (copy_from_user(&qc, arg, sizeof(qc)))
+		return -EFAULT;
+
+	for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
+		if (qc.id && qc.id == s->qctrl[i].id) {
+			memcpy(&qc, &(s->qctrl[i]), sizeof(qc));
+			if (copy_to_user(arg, &qc, sizeof(qc)))
+				return -EFAULT;
+			return 0;
+		}
+
+	return -EINVAL;
+}
+
+
+static int
+et61x251_vidioc_g_ctrl(struct et61x251_device* cam, void __user * arg)
+{
+	struct et61x251_sensor* s = cam->sensor;
+	struct v4l2_control ctrl;
+	int err = 0;
+	u8 i;
+
+	if (!s->get_ctrl && !s->set_ctrl)
+		return -EINVAL;
+
+	if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
+		return -EFAULT;
+
+	if (!s->get_ctrl) {
+		for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
+			if (ctrl.id == s->qctrl[i].id) {
+				ctrl.value = s->_qctrl[i].default_value;
+				goto exit;
+			}
+		return -EINVAL;
+	} else
+		err = s->get_ctrl(cam, &ctrl);
+
+exit:
+	if (copy_to_user(arg, &ctrl, sizeof(ctrl)))
+		return -EFAULT;
+
+	return err;
+}
+
+
+static int
+et61x251_vidioc_s_ctrl(struct et61x251_device* cam, void __user * arg)
+{
+	struct et61x251_sensor* s = cam->sensor;
+	struct v4l2_control ctrl;
+	u8 i;
+	int err = 0;
+
+	if (!s->set_ctrl)
+		return -EINVAL;
+
+	if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
+		return -EFAULT;
+
+	for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
+		if (ctrl.id == s->qctrl[i].id) {
+			if (ctrl.value < s->qctrl[i].minimum ||
+			    ctrl.value > s->qctrl[i].maximum)
+				return -ERANGE;
+			ctrl.value -= ctrl.value % s->qctrl[i].step;
+			break;
+		}
+
+	if ((err = s->set_ctrl(cam, &ctrl)))
+		return err;
+
+	s->_qctrl[i].default_value = ctrl.value;
+
+	return 0;
+}
+
+
+static int
+et61x251_vidioc_cropcap(struct et61x251_device* cam, void __user * arg)
+{
+	struct v4l2_cropcap* cc = &(cam->sensor->cropcap);
+
+	cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	cc->pixelaspect.numerator = 1;
+	cc->pixelaspect.denominator = 1;
+
+	if (copy_to_user(arg, cc, sizeof(*cc)))
+		return -EFAULT;
+
+	return 0;
+}
+
+
+static int
+et61x251_vidioc_g_crop(struct et61x251_device* cam, void __user * arg)
+{
+	struct et61x251_sensor* s = cam->sensor;
+	struct v4l2_crop crop = {
+		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+	};
+
+	memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect));
+
+	if (copy_to_user(arg, &crop, sizeof(crop)))
+		return -EFAULT;
+
+	return 0;
+}
+
+
+static int
+et61x251_vidioc_s_crop(struct et61x251_device* cam, void __user * arg)
+{
+	struct et61x251_sensor* s = cam->sensor;
+	struct v4l2_crop crop;
+	struct v4l2_rect* rect;
+	struct v4l2_rect* bounds = &(s->cropcap.bounds);
+	struct v4l2_pix_format* pix_format = &(s->pix_format);
+	u8 scale;
+	const enum et61x251_stream_state stream = cam->stream;
+	const u32 nbuffers = cam->nbuffers;
+	u32 i;
+	int err = 0;
+
+	if (copy_from_user(&crop, arg, sizeof(crop)))
+		return -EFAULT;
+
+	rect = &(crop.c);
+
+	if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	if (cam->module_param.force_munmap)
+		for (i = 0; i < cam->nbuffers; i++)
+			if (cam->frame[i].vma_use_count) {
+				DBG(3, "VIDIOC_S_CROP failed. "
+				       "Unmap the buffers first.");
+				return -EINVAL;
+			}
+
+	/* Preserve R,G or B origin */
+	rect->left = (s->_rect.left & 1L) ? rect->left | 1L : rect->left & ~1L;
+	rect->top = (s->_rect.top & 1L) ? rect->top | 1L : rect->top & ~1L;
+
+	if (rect->width < 4)
+		rect->width = 4;
+	if (rect->height < 4)
+		rect->height = 4;
+	if (rect->width > bounds->width)
+		rect->width = bounds->width;
+	if (rect->height > bounds->height)
+		rect->height = bounds->height;
+	if (rect->left < bounds->left)
+		rect->left = bounds->left;
+	if (rect->top < bounds->top)
+		rect->top = bounds->top;
+	if (rect->left + rect->width > bounds->left + bounds->width)
+		rect->left = bounds->left+bounds->width - rect->width;
+	if (rect->top + rect->height > bounds->top + bounds->height)
+		rect->top = bounds->top+bounds->height - rect->height;
+
+	rect->width &= ~3L;
+	rect->height &= ~3L;
+
+	if (ET61X251_PRESERVE_IMGSCALE) {
+		/* Calculate the actual scaling factor */
+		u32 a, b;
+		a = rect->width * rect->height;
+		b = pix_format->width * pix_format->height;
+		scale = b ? (u8)((a / b) < 4 ? 1 : 2) : 1;
+	} else
+		scale = 1;
+
+	if (cam->stream == STREAM_ON)
+		if ((err = et61x251_stream_interrupt(cam)))
+			return err;
+
+	if (copy_to_user(arg, &crop, sizeof(crop))) {
+		cam->stream = stream;
+		return -EFAULT;
+	}
+
+	if (cam->module_param.force_munmap || cam->io == IO_READ)
+		et61x251_release_buffers(cam);
+
+	err = et61x251_set_crop(cam, rect);
+	if (s->set_crop)
+		err += s->set_crop(cam, rect);
+	err += et61x251_set_scale(cam, scale);
+
+	if (err) { /* atomic, no rollback in ioctl() */
+		cam->state |= DEV_MISCONFIGURED;
+		DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
+		       "use the camera, close and open /dev/video%d again.",
+		    cam->v4ldev->minor);
+		return -EIO;
+	}
+
+	s->pix_format.width = rect->width/scale;
+	s->pix_format.height = rect->height/scale;
+	memcpy(&(s->_rect), rect, sizeof(*rect));
+
+	if ((cam->module_param.force_munmap  || cam->io == IO_READ) &&
+	    nbuffers != et61x251_request_buffers(cam, nbuffers, cam->io)) {
+		cam->state |= DEV_MISCONFIGURED;
+		DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
+		       "use the camera, close and open /dev/video%d again.",
+		    cam->v4ldev->minor);
+		return -ENOMEM;
+	}
+
+	if (cam->io == IO_READ)
+		et61x251_empty_framequeues(cam);
+	else if (cam->module_param.force_munmap)
+		et61x251_requeue_outqueue(cam);
+
+	cam->stream = stream;
+
+	return 0;
+}
+
+
+static int
+et61x251_vidioc_enum_fmt(struct et61x251_device* cam, void __user * arg)
+{
+	struct v4l2_fmtdesc fmtd;
+
+	if (copy_from_user(&fmtd, arg, sizeof(fmtd)))
+		return -EFAULT;
+
+	if (fmtd.index == 0) {
+		strcpy(fmtd.description, "bayer rgb");
+		fmtd.pixelformat = V4L2_PIX_FMT_SBGGR8;
+	} else if (fmtd.index == 1) {
+		strcpy(fmtd.description, "compressed");
+		fmtd.pixelformat = V4L2_PIX_FMT_ET61X251;
+		fmtd.flags = V4L2_FMT_FLAG_COMPRESSED;
+	} else
+		return -EINVAL;
+
+	fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	memset(&fmtd.reserved, 0, sizeof(fmtd.reserved));
+
+	if (copy_to_user(arg, &fmtd, sizeof(fmtd)))
+		return -EFAULT;
+
+	return 0;
+}
+
+
+static int
+et61x251_vidioc_g_fmt(struct et61x251_device* cam, void __user * arg)
+{
+	struct v4l2_format format;
+	struct v4l2_pix_format* pfmt = &(cam->sensor->pix_format);
+
+	if (copy_from_user(&format, arg, sizeof(format)))
+		return -EFAULT;
+
+	if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_ET61X251)
+	                     ? 0 : (pfmt->width * pfmt->priv) / 8;
+	pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
+	pfmt->field = V4L2_FIELD_NONE;
+	memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
+
+	if (copy_to_user(arg, &format, sizeof(format)))
+		return -EFAULT;
+
+	return 0;
+}
+
+
+static int
+et61x251_vidioc_try_s_fmt(struct et61x251_device* cam, unsigned int cmd,
+                          void __user * arg)
+{
+	struct et61x251_sensor* s = cam->sensor;
+	struct v4l2_format format;
+	struct v4l2_pix_format* pix;
+	struct v4l2_pix_format* pfmt = &(s->pix_format);
+	struct v4l2_rect* bounds = &(s->cropcap.bounds);
+	struct v4l2_rect rect;
+	u8 scale;
+	const enum et61x251_stream_state stream = cam->stream;
+	const u32 nbuffers = cam->nbuffers;
+	u32 i;
+	int err = 0;
+
+	if (copy_from_user(&format, arg, sizeof(format)))
+		return -EFAULT;
+
+	pix = &(format.fmt.pix);
+
+	if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	memcpy(&rect, &(s->_rect), sizeof(rect));
+
+	{ /* calculate the actual scaling factor */
+		u32 a, b;
+		a = rect.width * rect.height;
+		b = pix->width * pix->height;
+		scale = b ? (u8)((a / b) < 4 ? 1 : 2) : 1;
+	}
+
+	rect.width = scale * pix->width;
+	rect.height = scale * pix->height;
+
+	if (rect.width < 4)
+		rect.width = 4;
+	if (rect.height < 4)
+		rect.height = 4;
+	if (rect.width > bounds->left + bounds->width - rect.left)
+		rect.width = bounds->left + bounds->width - rect.left;
+	if (rect.height > bounds->top + bounds->height - rect.top)
+		rect.height = bounds->top + bounds->height - rect.top;
+
+	rect.width &= ~3L;
+	rect.height &= ~3L;
+
+	{ /* adjust the scaling factor */
+		u32 a, b;
+		a = rect.width * rect.height;
+		b = pix->width * pix->height;
+		scale = b ? (u8)((a / b) < 4 ? 1 : 2) : 1;
+	}
+
+	pix->width = rect.width / scale;
+	pix->height = rect.height / scale;
+
+	if (pix->pixelformat != V4L2_PIX_FMT_ET61X251 &&
+	    pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
+		pix->pixelformat = pfmt->pixelformat;
+	pix->priv = pfmt->priv; /* bpp */
+	pix->colorspace = pfmt->colorspace;
+	pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_ET61X251)
+	                    ? 0 : (pix->width * pix->priv) / 8;
+	pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
+	pix->field = V4L2_FIELD_NONE;
+
+	if (cmd == VIDIOC_TRY_FMT) {
+		if (copy_to_user(arg, &format, sizeof(format)))
+			return -EFAULT;
+		return 0;
+	}
+
+	if (cam->module_param.force_munmap)
+		for (i = 0; i < cam->nbuffers; i++)
+			if (cam->frame[i].vma_use_count) {
+				DBG(3, "VIDIOC_S_FMT failed. "
+				       "Unmap the buffers first.");
+				return -EINVAL;
+			}
+
+	if (cam->stream == STREAM_ON)
+		if ((err = et61x251_stream_interrupt(cam)))
+			return err;
+
+	if (copy_to_user(arg, &format, sizeof(format))) {
+		cam->stream = stream;
+		return -EFAULT;
+	}
+
+	if (cam->module_param.force_munmap || cam->io == IO_READ)
+		et61x251_release_buffers(cam);
+
+	err += et61x251_set_pix_format(cam, pix);
+	err += et61x251_set_crop(cam, &rect);
+	if (s->set_pix_format)
+		err += s->set_pix_format(cam, pix);
+	if (s->set_crop)
+		err += s->set_crop(cam, &rect);
+	err += et61x251_set_scale(cam, scale);
+
+	if (err) { /* atomic, no rollback in ioctl() */
+		cam->state |= DEV_MISCONFIGURED;
+		DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
+		       "use the camera, close and open /dev/video%d again.",
+		    cam->v4ldev->minor);
+		return -EIO;
+	}
+
+	memcpy(pfmt, pix, sizeof(*pix));
+	memcpy(&(s->_rect), &rect, sizeof(rect));
+
+	if ((cam->module_param.force_munmap  || cam->io == IO_READ) &&
+	    nbuffers != et61x251_request_buffers(cam, nbuffers, cam->io)) {
+		cam->state |= DEV_MISCONFIGURED;
+		DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
+		       "use the camera, close and open /dev/video%d again.",
+		    cam->v4ldev->minor);
+		return -ENOMEM;
+	}
+
+	if (cam->io == IO_READ)
+		et61x251_empty_framequeues(cam);
+	else if (cam->module_param.force_munmap)
+		et61x251_requeue_outqueue(cam);
+
+	cam->stream = stream;
+
+	return 0;
+}
+
+
+static int
+et61x251_vidioc_g_jpegcomp(struct et61x251_device* cam, void __user * arg)
+{
+	if (copy_to_user(arg, &cam->compression,
+	                 sizeof(cam->compression)))
+		return -EFAULT;
+
+	return 0;
+}
+
+
+static int
+et61x251_vidioc_s_jpegcomp(struct et61x251_device* cam, void __user * arg)
+{
+	struct v4l2_jpegcompression jc;
+	const enum et61x251_stream_state stream = cam->stream;
+	int err = 0;
+
+	if (copy_from_user(&jc, arg, sizeof(jc)))
+		return -EFAULT;
+
+	if (jc.quality != 0 && jc.quality != 1)
+		return -EINVAL;
+
+	if (cam->stream == STREAM_ON)
+		if ((err = et61x251_stream_interrupt(cam)))
+			return err;
+
+	err += et61x251_set_compression(cam, &jc);
+	if (err) { /* atomic, no rollback in ioctl() */
+		cam->state |= DEV_MISCONFIGURED;
+		DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
+		       "problems. To use the camera, close and open "
+		       "/dev/video%d again.", cam->v4ldev->minor);
+		return -EIO;
+	}
+
+	cam->compression.quality = jc.quality;
+
+	cam->stream = stream;
+
+	return 0;
+}
+
+
+static int
+et61x251_vidioc_reqbufs(struct et61x251_device* cam, void __user * arg)
+{
+	struct v4l2_requestbuffers rb;
+	u32 i;
+	int err;
+
+	if (copy_from_user(&rb, arg, sizeof(rb)))
+		return -EFAULT;
+
+	if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+	    rb.memory != V4L2_MEMORY_MMAP)
+		return -EINVAL;
+
+	if (cam->io == IO_READ) {
+		DBG(3, "Close and open the device again to choose the mmap "
+		       "I/O method");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < cam->nbuffers; i++)
+		if (cam->frame[i].vma_use_count) {
+			DBG(3, "VIDIOC_REQBUFS failed. "
+			       "Previous buffers are still mapped.");
+			return -EINVAL;
+		}
+
+	if (cam->stream == STREAM_ON)
+		if ((err = et61x251_stream_interrupt(cam)))
+			return err;
+
+	et61x251_empty_framequeues(cam);
+
+	et61x251_release_buffers(cam);
+	if (rb.count)
+		rb.count = et61x251_request_buffers(cam, rb.count, IO_MMAP);
+
+	if (copy_to_user(arg, &rb, sizeof(rb))) {
+		et61x251_release_buffers(cam);
+		cam->io = IO_NONE;
+		return -EFAULT;
+	}
+
+	cam->io = rb.count ? IO_MMAP : IO_NONE;
+
+	return 0;
+}
+
+
+static int
+et61x251_vidioc_querybuf(struct et61x251_device* cam, void __user * arg)
+{
+	struct v4l2_buffer b;
+
+	if (copy_from_user(&b, arg, sizeof(b)))
+		return -EFAULT;
+
+	if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+	    b.index >= cam->nbuffers || cam->io != IO_MMAP)
+		return -EINVAL;
+
+	memcpy(&b, &cam->frame[b.index].buf, sizeof(b));
+
+	if (cam->frame[b.index].vma_use_count)
+		b.flags |= V4L2_BUF_FLAG_MAPPED;
+
+	if (cam->frame[b.index].state == F_DONE)
+		b.flags |= V4L2_BUF_FLAG_DONE;
+	else if (cam->frame[b.index].state != F_UNUSED)
+		b.flags |= V4L2_BUF_FLAG_QUEUED;
+
+	if (copy_to_user(arg, &b, sizeof(b)))
+		return -EFAULT;
+
+	return 0;
+}
+
+
+static int
+et61x251_vidioc_qbuf(struct et61x251_device* cam, void __user * arg)
+{
+	struct v4l2_buffer b;
+	unsigned long lock_flags;
+
+	if (copy_from_user(&b, arg, sizeof(b)))
+		return -EFAULT;
+
+	if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+	    b.index >= cam->nbuffers || cam->io != IO_MMAP)
+		return -EINVAL;
+
+	if (cam->frame[b.index].state != F_UNUSED)
+		return -EINVAL;
+
+	cam->frame[b.index].state = F_QUEUED;
+
+	spin_lock_irqsave(&cam->queue_lock, lock_flags);
+	list_add_tail(&cam->frame[b.index].frame, &cam->inqueue);
+	spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
+
+	PDBGG("Frame #%lu queued", (unsigned long)b.index);
+
+	return 0;
+}
+
+
+static int
+et61x251_vidioc_dqbuf(struct et61x251_device* cam, struct file* filp,
+                      void __user * arg)
+{
+	struct v4l2_buffer b;
+	struct et61x251_frame_t *f;
+	unsigned long lock_flags;
+	int err = 0;
+
+	if (copy_from_user(&b, arg, sizeof(b)))
+		return -EFAULT;
+
+	if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io!= IO_MMAP)
+		return -EINVAL;
+
+	if (list_empty(&cam->outqueue)) {
+		if (cam->stream == STREAM_OFF)
+			return -EINVAL;
+		if (filp->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+		err = wait_event_interruptible
+		      ( cam->wait_frame,
+		        (!list_empty(&cam->outqueue)) ||
+		        (cam->state & DEV_DISCONNECTED) ||
+		        (cam->state & DEV_MISCONFIGURED) );
+		if (err)
+			return err;
+		if (cam->state & DEV_DISCONNECTED)
+			return -ENODEV;
+		if (cam->state & DEV_MISCONFIGURED)
+			return -EIO;
+	}
+
+	spin_lock_irqsave(&cam->queue_lock, lock_flags);
+	f = list_entry(cam->outqueue.next, struct et61x251_frame_t, frame);
+	list_del(cam->outqueue.next);
+	spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
+
+	f->state = F_UNUSED;
+
+	memcpy(&b, &f->buf, sizeof(b));
+	if (f->vma_use_count)
+		b.flags |= V4L2_BUF_FLAG_MAPPED;
+
+	if (copy_to_user(arg, &b, sizeof(b)))
+		return -EFAULT;
+
+	PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index);
+
+	return 0;
+}
+
+
+static int
+et61x251_vidioc_streamon(struct et61x251_device* cam, void __user * arg)
+{
+	int type;
+
+	if (copy_from_user(&type, arg, sizeof(type)))
+		return -EFAULT;
+
+	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
+		return -EINVAL;
+
+	if (list_empty(&cam->inqueue))
+		return -EINVAL;
+
+	cam->stream = STREAM_ON;
+
+	DBG(3, "Stream on");
+
+	return 0;
+}
+
+
+static int
+et61x251_vidioc_streamoff(struct et61x251_device* cam, void __user * arg)
+{
+	int type, err;
+
+	if (copy_from_user(&type, arg, sizeof(type)))
+		return -EFAULT;
+
+	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
+		return -EINVAL;
+
+	if (cam->stream == STREAM_ON)
+		if ((err = et61x251_stream_interrupt(cam)))
+			return err;
+
+	et61x251_empty_framequeues(cam);
+
+	DBG(3, "Stream off");
+
+	return 0;
+}
+
+
+static int
+et61x251_vidioc_g_parm(struct et61x251_device* cam, void __user * arg)
+{
+	struct v4l2_streamparm sp;
+
+	if (copy_from_user(&sp, arg, sizeof(sp)))
+		return -EFAULT;
+
+	if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	sp.parm.capture.extendedmode = 0;
+	sp.parm.capture.readbuffers = cam->nreadbuffers;
+
+	if (copy_to_user(arg, &sp, sizeof(sp)))
+		return -EFAULT;
+
+	return 0;
+}
+
+
+static int
+et61x251_vidioc_s_parm(struct et61x251_device* cam, void __user * arg)
+{
+	struct v4l2_streamparm sp;
+
+	if (copy_from_user(&sp, arg, sizeof(sp)))
+		return -EFAULT;
+
+	if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	sp.parm.capture.extendedmode = 0;
+
+	if (sp.parm.capture.readbuffers == 0)
+		sp.parm.capture.readbuffers = cam->nreadbuffers;
+
+	if (sp.parm.capture.readbuffers > ET61X251_MAX_FRAMES)
+		sp.parm.capture.readbuffers = ET61X251_MAX_FRAMES;
+
+	if (copy_to_user(arg, &sp, sizeof(sp)))
+		return -EFAULT;
+
+	cam->nreadbuffers = sp.parm.capture.readbuffers;
+
+	return 0;
+}
+
+
+static int et61x251_ioctl_v4l2(struct inode* inode, struct file* filp,
+                               unsigned int cmd, void __user * arg)
+{
+	struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
+
+	switch (cmd) {
+
+	case VIDIOC_QUERYCAP:
+		return et61x251_vidioc_querycap(cam, arg);
+
+	case VIDIOC_ENUMINPUT:
+		return et61x251_vidioc_enuminput(cam, arg);
+
+	case VIDIOC_G_INPUT:
+	case VIDIOC_S_INPUT:
+		return et61x251_vidioc_gs_input(cam, arg);
+
+	case VIDIOC_QUERYCTRL:
+		return et61x251_vidioc_query_ctrl(cam, arg);
+
+	case VIDIOC_G_CTRL:
+		return et61x251_vidioc_g_ctrl(cam, arg);
+
+	case VIDIOC_S_CTRL_OLD:
+	case VIDIOC_S_CTRL:
+		return et61x251_vidioc_s_ctrl(cam, arg);
+
+	case VIDIOC_CROPCAP_OLD:
+	case VIDIOC_CROPCAP:
+		return et61x251_vidioc_cropcap(cam, arg);
+
+	case VIDIOC_G_CROP:
+		return et61x251_vidioc_g_crop(cam, arg);
+
+	case VIDIOC_S_CROP:
+		return et61x251_vidioc_s_crop(cam, arg);
+
+	case VIDIOC_ENUM_FMT:
+		return et61x251_vidioc_enum_fmt(cam, arg);
+
+	case VIDIOC_G_FMT:
+		return et61x251_vidioc_g_fmt(cam, arg);
+
+	case VIDIOC_TRY_FMT:
+	case VIDIOC_S_FMT:
+		return et61x251_vidioc_try_s_fmt(cam, cmd, arg);
+
+	case VIDIOC_G_JPEGCOMP:
+		return et61x251_vidioc_g_jpegcomp(cam, arg);
+
+	case VIDIOC_S_JPEGCOMP:
+		return et61x251_vidioc_s_jpegcomp(cam, arg);
+
+	case VIDIOC_REQBUFS:
+		return et61x251_vidioc_reqbufs(cam, arg);
+
+	case VIDIOC_QUERYBUF:
+		return et61x251_vidioc_querybuf(cam, arg);
+
+	case VIDIOC_QBUF:
+		return et61x251_vidioc_qbuf(cam, arg);
+
+	case VIDIOC_DQBUF:
+		return et61x251_vidioc_dqbuf(cam, filp, arg);
+
+	case VIDIOC_STREAMON:
+		return et61x251_vidioc_streamon(cam, arg);
+
+	case VIDIOC_STREAMOFF:
+		return et61x251_vidioc_streamoff(cam, arg);
+
+	case VIDIOC_G_PARM:
+		return et61x251_vidioc_g_parm(cam, arg);
+
+	case VIDIOC_S_PARM_OLD:
+	case VIDIOC_S_PARM:
+		return et61x251_vidioc_s_parm(cam, arg);
+
+	case VIDIOC_G_STD:
+	case VIDIOC_S_STD:
+	case VIDIOC_QUERYSTD:
+	case VIDIOC_ENUMSTD:
+	case VIDIOC_QUERYMENU:
+		return -EINVAL;
+
+	default:
+		return -EINVAL;
+
+	}
+}
+
+
+static int et61x251_ioctl(struct inode* inode, struct file* filp,
+                         unsigned int cmd, unsigned long arg)
+{
+	struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
+	int err = 0;
+
+	if (down_interruptible(&cam->fileop_sem))
+		return -ERESTARTSYS;
+
+	if (cam->state & DEV_DISCONNECTED) {
+		DBG(1, "Device not present");
+		up(&cam->fileop_sem);
+		return -ENODEV;
+	}
+
+	if (cam->state & DEV_MISCONFIGURED) {
+		DBG(1, "The camera is misconfigured. Close and open it "
+		       "again.");
+		up(&cam->fileop_sem);
+		return -EIO;
+	}
+
+	V4LDBG(3, "et61x251", cmd);
+
+	err = et61x251_ioctl_v4l2(inode, filp, cmd, (void __user *)arg);
+
+	up(&cam->fileop_sem);
+
+	return err;
+}
+
+
+static struct file_operations et61x251_fops = {
+	.owner = THIS_MODULE,
+	.open =    et61x251_open,
+	.release = et61x251_release,
+	.ioctl =   et61x251_ioctl,
+	.read =    et61x251_read,
+	.poll =    et61x251_poll,
+	.mmap =    et61x251_mmap,
+	.llseek =  no_llseek,
+};
+
+/*****************************************************************************/
+
+/* It exists a single interface only. We do not need to validate anything. */
+static int
+et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
+{
+	struct usb_device *udev = interface_to_usbdev(intf);
+	struct et61x251_device* cam;
+	static unsigned int dev_nr = 0;
+	unsigned int i;
+	int err = 0;
+
+	if (!(cam = kzalloc(sizeof(struct et61x251_device), GFP_KERNEL)))
+		return -ENOMEM;
+
+	cam->usbdev = udev;
+
+	if (!(cam->control_buffer = kzalloc(8, GFP_KERNEL))) {
+		DBG(1, "kmalloc() failed");
+		err = -ENOMEM;
+		goto fail;
+	}
+
+	if (!(cam->v4ldev = video_device_alloc())) {
+		DBG(1, "video_device_alloc() failed");
+		err = -ENOMEM;
+		goto fail;
+	}
+
+	init_MUTEX(&cam->dev_sem);
+
+	DBG(2, "ET61X[12]51 PC Camera Controller detected "
+	       "(vid/pid 0x%04X/0x%04X)",id->idVendor, id->idProduct);
+
+	for  (i = 0; et61x251_sensor_table[i]; i++) {
+		err = et61x251_sensor_table[i](cam);
+		if (!err)
+			break;
+	}
+
+	if (!err && cam->sensor)
+		DBG(2, "%s image sensor detected", cam->sensor->name);
+	else {
+		DBG(1, "No supported image sensor detected");
+		err = -ENODEV;
+		goto fail;
+	}
+
+	if (et61x251_init(cam)) {
+		DBG(1, "Initialization failed. I will retry on open().");
+		cam->state |= DEV_MISCONFIGURED;
+	}
+
+	strcpy(cam->v4ldev->name, "ET61X[12]51 PC Camera");
+	cam->v4ldev->owner = THIS_MODULE;
+	cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
+	cam->v4ldev->hardware = 0;
+	cam->v4ldev->fops = &et61x251_fops;
+	cam->v4ldev->minor = video_nr[dev_nr];
+	cam->v4ldev->release = video_device_release;
+	video_set_drvdata(cam->v4ldev, cam);
+
+	down(&cam->dev_sem);
+
+	err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
+	                            video_nr[dev_nr]);
+	if (err) {
+		DBG(1, "V4L2 device registration failed");
+		if (err == -ENFILE && video_nr[dev_nr] == -1)
+			DBG(1, "Free /dev/videoX node not found");
+		video_nr[dev_nr] = -1;
+		dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0;
+		up(&cam->dev_sem);
+		goto fail;
+	}
+
+	DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor);
+
+	cam->module_param.force_munmap = force_munmap[dev_nr];
+
+	dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0;
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	et61x251_create_sysfs(cam);
+	DBG(2, "Optional device control through 'sysfs' interface ready");
+#endif
+
+	usb_set_intfdata(intf, cam);
+
+	up(&cam->dev_sem);
+
+	return 0;
+
+fail:
+	if (cam) {
+		kfree(cam->control_buffer);
+		if (cam->v4ldev)
+			video_device_release(cam->v4ldev);
+		kfree(cam);
+	}
+	return err;
+}
+
+
+static void et61x251_usb_disconnect(struct usb_interface* intf)
+{
+	struct et61x251_device* cam = usb_get_intfdata(intf);
+
+	if (!cam)
+		return;
+
+	down_write(&et61x251_disconnect);
+
+	down(&cam->dev_sem);
+
+	DBG(2, "Disconnecting %s...", cam->v4ldev->name);
+
+	wake_up_interruptible_all(&cam->open);
+
+	if (cam->users) {
+		DBG(2, "Device /dev/video%d is open! Deregistration and "
+		       "memory deallocation are deferred on close.",
+		    cam->v4ldev->minor);
+		cam->state |= DEV_MISCONFIGURED;
+		et61x251_stop_transfer(cam);
+		cam->state |= DEV_DISCONNECTED;
+		wake_up_interruptible(&cam->wait_frame);
+		wake_up_interruptible(&cam->wait_stream);
+	} else {
+		cam->state |= DEV_DISCONNECTED;
+		et61x251_release_resources(cam);
+	}
+
+	up(&cam->dev_sem);
+
+	if (!cam->users)
+		kfree(cam);
+
+	up_write(&et61x251_disconnect);
+}
+
+
+static struct usb_driver et61x251_usb_driver = {
+	.name =       "et61x251",
+	.id_table =   et61x251_id_table,
+	.probe =      et61x251_usb_probe,
+	.disconnect = et61x251_usb_disconnect,
+};
+
+/*****************************************************************************/
+
+static int __init et61x251_module_init(void)
+{
+	int err = 0;
+
+	KDBG(2, ET61X251_MODULE_NAME " v" ET61X251_MODULE_VERSION);
+	KDBG(3, ET61X251_MODULE_AUTHOR);
+
+	if ((err = usb_register(&et61x251_usb_driver)))
+		KDBG(1, "usb_register() failed");
+
+	return err;
+}
+
+
+static void __exit et61x251_module_exit(void)
+{
+	usb_deregister(&et61x251_usb_driver);
+}
+
+
+module_init(et61x251_module_init);
+module_exit(et61x251_module_exit);
diff --git a/drivers/usb/media/et61x251_sensor.h b/drivers/usb/media/et61x251_sensor.h
new file mode 100644
index 0000000..b9df910
--- /dev/null
+++ b/drivers/usb/media/et61x251_sensor.h
@@ -0,0 +1,115 @@
+/***************************************************************************
+ * API for image sensors connected to ET61X[12]51 PC Camera Controllers    *
+ *                                                                         *
+ * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it>       *
+ *                                                                         *
+ * This program is free software; you can redistribute it and/or modify    *
+ * it under the terms of the GNU General Public License as published by    *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.               *
+ ***************************************************************************/
+
+#ifndef _ET61X251_SENSOR_H_
+#define _ET61X251_SENSOR_H_
+
+#include <linux/usb.h>
+#include <linux/videodev.h>
+#include <linux/device.h>
+#include <linux/stddef.h>
+#include <linux/errno.h>
+#include <asm/types.h>
+
+struct et61x251_device;
+struct et61x251_sensor;
+
+/*****************************************************************************/
+
+extern int et61x251_probe_tas5130d1b(struct et61x251_device* cam);
+
+#define ET61X251_SENSOR_TABLE                                                 \
+/* Weak detections must go at the end of the list */                          \
+static int (*et61x251_sensor_table[])(struct et61x251_device*) = {            \
+	&et61x251_probe_tas5130d1b,                                           \
+	NULL,                                                                 \
+};
+
+extern void
+et61x251_attach_sensor(struct et61x251_device* cam,
+                       struct et61x251_sensor* sensor);
+
+/*****************************************************************************/
+
+extern int et61x251_write_reg(struct et61x251_device*, u8 value, u16 index);
+extern int et61x251_read_reg(struct et61x251_device*, u16 index);
+extern int et61x251_i2c_write(struct et61x251_device*, u8 address, u8 value);
+extern int et61x251_i2c_read(struct et61x251_device*, u8 address);
+extern int et61x251_i2c_try_write(struct et61x251_device*,
+                                  struct et61x251_sensor*, u8 address,
+                                  u8 value);
+extern int et61x251_i2c_try_read(struct et61x251_device*,
+                                 struct et61x251_sensor*, u8 address);
+extern int et61x251_i2c_raw_write(struct et61x251_device*, u8 n, u8 data1,
+                                  u8 data2, u8 data3, u8 data4, u8 data5,
+                                  u8 data6, u8 data7, u8 data8, u8 address);
+
+/*****************************************************************************/
+
+enum et61x251_i2c_sysfs_ops {
+	ET61X251_I2C_READ = 0x01,
+	ET61X251_I2C_WRITE = 0x02,
+};
+
+enum et61x251_i2c_interface {
+	ET61X251_I2C_2WIRES,
+	ET61X251_I2C_3WIRES,
+};
+
+/* Repeat start condition when RSTA is high */
+enum et61x251_i2c_rsta {
+	ET61X251_I2C_RSTA_STOP = 0x00, /* stop then start */
+	ET61X251_I2C_RSTA_REPEAT = 0x01, /* repeat start */
+};
+
+#define ET61X251_MAX_CTRLS V4L2_CID_LASTP1-V4L2_CID_BASE+10
+
+struct et61x251_sensor {
+	char name[32];
+
+	enum et61x251_i2c_sysfs_ops sysfs_ops;
+
+	enum et61x251_i2c_interface interface;
+	u8 i2c_slave_id;
+	enum et61x251_i2c_rsta rsta;
+	struct v4l2_rect active_pixel; /* left and top define FVSX and FVSY */
+
+	struct v4l2_queryctrl qctrl[ET61X251_MAX_CTRLS];
+	struct v4l2_cropcap cropcap;
+	struct v4l2_pix_format pix_format;
+
+	int (*init)(struct et61x251_device* cam);
+	int (*get_ctrl)(struct et61x251_device* cam,
+	                struct v4l2_control* ctrl);
+	int (*set_ctrl)(struct et61x251_device* cam,
+	                const struct v4l2_control* ctrl);
+	int (*set_crop)(struct et61x251_device* cam,
+	                const struct v4l2_rect* rect);
+	int (*set_pix_format)(struct et61x251_device* cam,
+	                      const struct v4l2_pix_format* pix);
+
+	const struct usb_device* usbdev;
+
+	/* Private */
+	struct v4l2_queryctrl _qctrl[ET61X251_MAX_CTRLS];
+	struct v4l2_rect _rect;
+};
+
+#endif /* _ET61X251_SENSOR_H_ */
diff --git a/drivers/usb/media/et61x251_tas5130d1b.c b/drivers/usb/media/et61x251_tas5130d1b.c
new file mode 100644
index 0000000..65f1ae9
--- /dev/null
+++ b/drivers/usb/media/et61x251_tas5130d1b.c
@@ -0,0 +1,137 @@
+/***************************************************************************
+ * Plug-in for TAS5130D1B image sensor connected to the ET61X[12]51        *
+ * PC Camera Controllers                                                   *
+ *                                                                         *
+ * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it>       *
+ *                                                                         *
+ * This program is free software; you can redistribute it and/or modify    *
+ * it under the terms of the GNU General Public License as published by    *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.               *
+ ***************************************************************************/
+
+#include "et61x251_sensor.h"
+
+
+static int tas5130d1b_init(struct et61x251_device* cam)
+{
+	int err = 0;
+
+	err += et61x251_write_reg(cam, 0x14, 0x01);
+	err += et61x251_write_reg(cam, 0x1b, 0x02);
+	err += et61x251_write_reg(cam, 0x02, 0x12);
+	err += et61x251_write_reg(cam, 0x0e, 0x60);
+	err += et61x251_write_reg(cam, 0x80, 0x61);
+	err += et61x251_write_reg(cam, 0xf0, 0x62);
+	err += et61x251_write_reg(cam, 0x03, 0x63);
+	err += et61x251_write_reg(cam, 0x14, 0x64);
+	err += et61x251_write_reg(cam, 0xf4, 0x65);
+	err += et61x251_write_reg(cam, 0x01, 0x66);
+	err += et61x251_write_reg(cam, 0x05, 0x67);
+	err += et61x251_write_reg(cam, 0x8f, 0x68);
+	err += et61x251_write_reg(cam, 0x0f, 0x8d);
+	err += et61x251_write_reg(cam, 0x08, 0x8e);
+
+	return err;
+}
+
+
+static int tas5130d1b_set_ctrl(struct et61x251_device* cam,
+                               const struct v4l2_control* ctrl)
+{
+	int err = 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_GAIN:
+		err += et61x251_i2c_raw_write(cam, 2, 0x20,
+		                              0xf6-ctrl->value, 0, 0, 0,
+		                              0, 0, 0, 0);
+		break;
+	case V4L2_CID_EXPOSURE:
+		err += et61x251_i2c_raw_write(cam, 2, 0x40,
+		                              0x47-ctrl->value, 0, 0, 0,
+		                              0, 0, 0, 0);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return err ? -EIO : 0;
+}
+
+
+static struct et61x251_sensor tas5130d1b = {
+	.name = "TAS5130D1B",
+	.interface = ET61X251_I2C_3WIRES,
+	.rsta = ET61X251_I2C_RSTA_STOP,
+	.active_pixel = {
+		.left = 106,
+		.top = 13,
+	},
+	.init = &tas5130d1b_init,
+	.qctrl = {
+		{
+			.id = V4L2_CID_GAIN,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "global gain",
+			.minimum = 0x00,
+			.maximum = 0xf6,
+			.step = 0x02,
+			.default_value = 0x0d,
+			.flags = 0,
+		},
+		{
+			.id = V4L2_CID_EXPOSURE,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "exposure",
+			.minimum = 0x00,
+			.maximum = 0x47,
+			.step = 0x01,
+			.default_value = 0x23,
+			.flags = 0,
+		},
+	},
+	.set_ctrl = &tas5130d1b_set_ctrl,
+	.cropcap = {
+		.bounds = {
+			.left = 0,
+			.top = 0,
+			.width = 640,
+			.height = 480,
+		},
+		.defrect = {
+			.left = 0,
+			.top = 0,
+			.width = 640,
+			.height = 480,
+		},
+	},
+	.pix_format = {
+		.width = 640,
+		.height = 480,
+		.pixelformat = V4L2_PIX_FMT_SBGGR8,
+		.priv = 8,
+	},
+};
+
+
+int et61x251_probe_tas5130d1b(struct et61x251_device* cam)
+{
+	/* This sensor has no identifiers, so let's attach it anyway */
+	et61x251_attach_sensor(cam, &tas5130d1b);
+
+	/* Sensor detection is based on USB pid/vid */
+	if (le16_to_cpu(tas5130d1b.usbdev->descriptor.idProduct) != 0x6251)
+		return -ENODEV;
+
+	return 0;
+}
diff --git a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c
index 8af665b..51e9cc0 100644
--- a/drivers/usb/media/ov511.c
+++ b/drivers/usb/media/ov511.c
@@ -204,22 +204,10 @@ MODULE_LICENSE("GPL");
 
 static struct usb_driver ov511_driver;
 
-static struct ov51x_decomp_ops *ov511_decomp_ops;
-static struct ov51x_decomp_ops *ov511_mmx_decomp_ops;
-static struct ov51x_decomp_ops *ov518_decomp_ops;
-static struct ov51x_decomp_ops *ov518_mmx_decomp_ops;
-
 /* Number of times to retry a failed I2C transaction. Increase this if you
  * are getting "Failed to read sensor ID..." */
 static const int i2c_detect_tries = 5;
 
-/* MMX support is present in kernel and CPU. Checked upon decomp module load. */
-#if defined(__i386__) || defined(__x86_64__)
-#define ov51x_mmx_available (cpu_has_mmx)
-#else
-#define ov51x_mmx_available (0)
-#endif
-
 static struct usb_device_id device_table [] = {
 	{ USB_DEVICE(VEND_OMNIVISION, PROD_OV511) },
 	{ USB_DEVICE(VEND_OMNIVISION, PROD_OV511PLUS) },
@@ -3012,93 +3000,18 @@ yuv420raw_to_yuv420p(struct ov511_frame 
  *
  **********************************************************************/
 
-/* Chooses a decompression module, locks it, and sets ov->decomp_ops
- * accordingly. Returns -ENXIO if decompressor is not available, otherwise
- * returns 0 if no other error.
- */
 static int
 request_decompressor(struct usb_ov511 *ov)
 {
-	if (!ov)
-		return -ENODEV;
-
-	if (ov->decomp_ops) {
-		err("ERROR: Decompressor already requested!");
-		return -EINVAL;
-	}
-
-	lock_kernel();
-
-	/* Try to get MMX, and fall back on no-MMX if necessary */
-	if (ov->bclass == BCL_OV511) {
-		if (ov511_mmx_decomp_ops) {
-			PDEBUG(3, "Using OV511 MMX decompressor");
-			ov->decomp_ops = ov511_mmx_decomp_ops;
-		} else if (ov511_decomp_ops) {
-			PDEBUG(3, "Using OV511 decompressor");
-			ov->decomp_ops = ov511_decomp_ops;
-		} else {
-			err("No decompressor available");
-		}
-	} else if (ov->bclass == BCL_OV518) {
-		if (ov518_mmx_decomp_ops) {
-			PDEBUG(3, "Using OV518 MMX decompressor");
-			ov->decomp_ops = ov518_mmx_decomp_ops;
-		} else if (ov518_decomp_ops) {
-			PDEBUG(3, "Using OV518 decompressor");
-			ov->decomp_ops = ov518_decomp_ops;
-		} else {
-			err("No decompressor available");
-		}
+	if (ov->bclass == BCL_OV511 || ov->bclass == BCL_OV518) {
+		err("No decompressor available");
 	} else {
 		err("Unknown bridge");
 	}
 
-	if (!ov->decomp_ops)
-		goto nosys;
-
-	if (!ov->decomp_ops->owner) {
-		ov->decomp_ops = NULL;
-		goto nosys;
-	}
-	
-	if (!try_module_get(ov->decomp_ops->owner))
-		goto nosys;
-
-	unlock_kernel();
-	return 0;
-
- nosys:
-	unlock_kernel();
 	return -ENOSYS;
 }
 
-/* Unlocks decompression module and nulls ov->decomp_ops. Safe to call even
- * if ov->decomp_ops is NULL.
- */
-static void
-release_decompressor(struct usb_ov511 *ov)
-{
-	int released = 0;	/* Did we actually do anything? */
-
-	if (!ov)
-		return;
-
-	lock_kernel();
-
-	if (ov->decomp_ops) {
-		module_put(ov->decomp_ops->owner);
-		released = 1;
-	}
-
-	ov->decomp_ops = NULL;
-
-	unlock_kernel();
-
-	if (released)
-		PDEBUG(3, "Decompressor released");
-}
-
 static void
 decompress(struct usb_ov511 *ov, struct ov511_frame *frame,
 	   unsigned char *pIn0, unsigned char *pOut0)
@@ -3107,31 +3020,6 @@ decompress(struct usb_ov511 *ov, struct 
 		if (request_decompressor(ov))
 			return;
 
-	PDEBUG(4, "Decompressing %d bytes", frame->bytes_recvd);
-
-	if (frame->format == VIDEO_PALETTE_GREY
-	    && ov->decomp_ops->decomp_400) {
-		int ret = ov->decomp_ops->decomp_400(
-			pIn0,
-			pOut0,
-			frame->compbuf,
-			frame->rawwidth,
-			frame->rawheight,
-			frame->bytes_recvd);
-		PDEBUG(4, "DEBUG: decomp_400 returned %d", ret);
-	} else if (frame->format != VIDEO_PALETTE_GREY
-		   && ov->decomp_ops->decomp_420) {
-		int ret = ov->decomp_ops->decomp_420(
-			pIn0,
-			pOut0,
-			frame->compbuf,
-			frame->rawwidth,
-			frame->rawheight,
-			frame->bytes_recvd);
-		PDEBUG(4, "DEBUG: decomp_420 returned %d", ret);
-	} else {
-		err("Decompressor does not support this format");
-	}
 }
 
 /**********************************************************************
@@ -4087,8 +3975,6 @@ ov51x_v4l1_close(struct inode *inode, st
 	ov->user--;
 	ov51x_stop_isoc(ov);
 
-	release_decompressor(ov);
-
 	if (ov->led_policy == LED_AUTO)
 		ov51x_led_control(ov, 0);
 
@@ -6021,82 +5907,6 @@ static struct usb_driver ov511_driver = 
  *
  ***************************************************************************/
 
-/* Returns 0 for success */
-int
-ov511_register_decomp_module(int ver, struct ov51x_decomp_ops *ops, int ov518,
-			     int mmx)
-{
-	if (ver != DECOMP_INTERFACE_VER) {
-		err("Decompression module has incompatible");
-		err("interface version %d", ver);
-		err("Interface version %d is required", DECOMP_INTERFACE_VER);
-		return -EINVAL;
-	}
-
-	if (!ops)
-		return -EFAULT;
-
-	if (mmx && !ov51x_mmx_available) {
-		err("MMX not available on this system or kernel");
-		return -EINVAL;
-	}
-
-	lock_kernel();
-
-	if (ov518) {
-		if (mmx) {
-			if (ov518_mmx_decomp_ops)
-				goto err_in_use;
-			else
-				ov518_mmx_decomp_ops = ops;
-		} else {
-			if (ov518_decomp_ops)
-				goto err_in_use;
-			else
-				ov518_decomp_ops = ops;
-		}
-	} else {
-		if (mmx) {
-			if (ov511_mmx_decomp_ops)
-				goto err_in_use;
-			else
-				ov511_mmx_decomp_ops = ops;
-		} else {
-			if (ov511_decomp_ops)
-				goto err_in_use;
-			else
-				ov511_decomp_ops = ops;
-		}
-	}
-
-	unlock_kernel();
-	return 0;
-
-err_in_use:
-	unlock_kernel();
-	return -EBUSY;
-}
-
-void
-ov511_deregister_decomp_module(int ov518, int mmx)
-{
-	lock_kernel();
-
-	if (ov518) {
-		if (mmx)
-			ov518_mmx_decomp_ops = NULL;
-		else
-			ov518_decomp_ops = NULL;
-	} else {
-		if (mmx)
-			ov511_mmx_decomp_ops = NULL;
-		else
-			ov511_decomp_ops = NULL;
-	}
-
-	unlock_kernel();
-}
-
 static int __init
 usb_ov511_init(void)
 {
@@ -6123,5 +5933,3 @@ usb_ov511_exit(void)
 module_init(usb_ov511_init);
 module_exit(usb_ov511_exit);
 
-EXPORT_SYMBOL(ov511_register_decomp_module);
-EXPORT_SYMBOL(ov511_deregister_decomp_module);
diff --git a/drivers/usb/media/pwc/pwc-ctrl.c b/drivers/usb/media/pwc/pwc-ctrl.c
index 359c4b2..3ebb6e9 100644
--- a/drivers/usb/media/pwc/pwc-ctrl.c
+++ b/drivers/usb/media/pwc/pwc-ctrl.c
@@ -1152,45 +1152,6 @@ int pwc_get_cmos_sensor(struct pwc_devic
  /* End of Add-Ons                                    */
  /* ************************************************* */
 
-/* Linux 2.5.something and 2.6 pass direct pointers to arguments of
-   ioctl() calls. With 2.4, you have to do tedious copy_from_user()
-   and copy_to_user() calls. With these macros we circumvent this,
-   and let me maintain only one source file. The functionality is
-   exactly the same otherwise.
- */   
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
-
-/* define local variable for arg */
-#define ARG_DEF(ARG_type, ARG_name)\
-	ARG_type *ARG_name = arg;
-/* copy arg to local variable */	
-#define ARG_IN(ARG_name) /* nothing */
-/* argument itself (referenced) */
-#define ARGR(ARG_name) (*ARG_name)
-/* argument address */
-#define ARGA(ARG_name) ARG_name
-/* copy local variable to arg */
-#define ARG_OUT(ARG_name) /* nothing */
-
-#else
-
-#define ARG_DEF(ARG_type, ARG_name)\
-	ARG_type ARG_name;
-#define ARG_IN(ARG_name)\
-	if (copy_from_user(&ARG_name, arg, sizeof(ARG_name))) {\
-		ret = -EFAULT;\
-		break;\
-	}
-#define ARGR(ARG_name) ARG_name
-#define ARGA(ARG_name) &ARG_name
-#define ARG_OUT(ARG_name)\
-	if (copy_to_user(arg, &ARG_name, sizeof(ARG_name))) {\
-		ret = -EFAULT;\
-		break;\
-	}
-
-#endif
 
 int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
 {
@@ -1220,243 +1181,206 @@ int pwc_ioctl(struct pwc_device *pdev, u
 	
 	case VIDIOCPWCSCQUAL:
 	{	
-		ARG_DEF(int, qual)
+		int *qual = arg;
 
-		ARG_IN(qual)
-		if (ARGR(qual) < 0 || ARGR(qual) > 3)
+		if (*qual < 0 || *qual > 3)
 			ret = -EINVAL;
 		else
-			ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot);
+			ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, *qual, pdev->vsnapshot);
 		if (ret >= 0)
-			pdev->vcompression = ARGR(qual);
+			pdev->vcompression = *qual;
 		break;
 	}
 	
 	case VIDIOCPWCGCQUAL:
 	{
-		ARG_DEF(int, qual)
-		
-		ARGR(qual) = pdev->vcompression;
-		ARG_OUT(qual)
+		int *qual = arg;
+		*qual = pdev->vcompression;
 		break;
 	}
 	
 	case VIDIOCPWCPROBE:
 	{
-		ARG_DEF(struct pwc_probe, probe)
-		
-		strcpy(ARGR(probe).name, pdev->vdev->name);
-		ARGR(probe).type = pdev->type;
-		ARG_OUT(probe)
+		struct pwc_probe *probe = arg;
+		strcpy(probe->name, pdev->vdev->name);
+		probe->type = pdev->type;
 		break;
 	}
 
 	case VIDIOCPWCGSERIAL:
 	{
-		ARG_DEF(struct pwc_serial, serial)
-		
-		strcpy(ARGR(serial).serial, pdev->serial);
-		ARG_OUT(serial)
+		struct pwc_serial *serial = arg;
+		strcpy(serial->serial, pdev->serial);
 		break;
 	}
 
 	case VIDIOCPWCSAGC:
 	{
-		ARG_DEF(int, agc)
-
-		ARG_IN(agc)
-		if (pwc_set_agc(pdev, ARGR(agc) < 0 ? 1 : 0, ARGR(agc)))
+		int *agc = arg;
+		if (pwc_set_agc(pdev, *agc < 0 ? 1 : 0, *agc))
 			ret = -EINVAL;
 		break;
 	}
 	
 	case VIDIOCPWCGAGC:
 	{
-		ARG_DEF(int, agc)
+		int *agc = arg;
 		
-		if (pwc_get_agc(pdev, ARGA(agc)))
+		if (pwc_get_agc(pdev, agc))
 			ret = -EINVAL;
-		ARG_OUT(agc)
 		break;
 	}
 	
 	case VIDIOCPWCSSHUTTER:
 	{
-		ARG_DEF(int, shutter_speed)
-
-		ARG_IN(shutter_speed)
-		ret = pwc_set_shutter_speed(pdev, ARGR(shutter_speed) < 0 ? 1 : 0, ARGR(shutter_speed));
+		int *shutter_speed = arg;
+		ret = pwc_set_shutter_speed(pdev, *shutter_speed < 0 ? 1 : 0, *shutter_speed);
 		break;
 	}
 	
         case VIDIOCPWCSAWB:
 	{
-		ARG_DEF(struct pwc_whitebalance, wb)
+		struct pwc_whitebalance *wb = arg;
 		
-		ARG_IN(wb)
-		ret = pwc_set_awb(pdev, ARGR(wb).mode);
-		if (ret >= 0 && ARGR(wb).mode == PWC_WB_MANUAL) {
-			pwc_set_red_gain(pdev, ARGR(wb).manual_red);
-			pwc_set_blue_gain(pdev, ARGR(wb).manual_blue);
+		ret = pwc_set_awb(pdev, wb->mode);
+		if (ret >= 0 && wb->mode == PWC_WB_MANUAL) {
+			pwc_set_red_gain(pdev, wb->manual_red);
+			pwc_set_blue_gain(pdev, wb->manual_blue);
 		}
 		break;
 	}
 
 	case VIDIOCPWCGAWB:
 	{
-		ARG_DEF(struct pwc_whitebalance, wb)
+		struct pwc_whitebalance *wb = arg;
 
-		memset(ARGA(wb), 0, sizeof(struct pwc_whitebalance));
-		ARGR(wb).mode = pwc_get_awb(pdev);
-		if (ARGR(wb).mode < 0)
+		memset(wb, 0, sizeof(struct pwc_whitebalance));
+		wb->mode = pwc_get_awb(pdev);
+		if (wb->mode < 0)
 			ret = -EINVAL;
 		else {
-			if (ARGR(wb).mode == PWC_WB_MANUAL) {
-				ret = pwc_get_red_gain(pdev, &ARGR(wb).manual_red);
+			if (wb->mode == PWC_WB_MANUAL) {
+				ret = pwc_get_red_gain(pdev, &wb->manual_red);
 				if (ret < 0)
 					break;
-				ret = pwc_get_blue_gain(pdev, &ARGR(wb).manual_blue);
+				ret = pwc_get_blue_gain(pdev, &wb->manual_blue);
 				if (ret < 0)
 					break;
 			}
-			if (ARGR(wb).mode == PWC_WB_AUTO) {
-				ret = pwc_read_red_gain(pdev, &ARGR(wb).read_red);
+			if (wb->mode == PWC_WB_AUTO) {
+				ret = pwc_read_red_gain(pdev, &wb->read_red);
 				if (ret < 0)
 					break;
- 				ret =pwc_read_blue_gain(pdev, &ARGR(wb).read_blue);
+ 				ret = pwc_read_blue_gain(pdev, &wb->read_blue);
  				if (ret < 0)
  					break;
 			}
 		}
-		ARG_OUT(wb)
 		break;
 	}
 	
 	case VIDIOCPWCSAWBSPEED:
 	{
-		ARG_DEF(struct pwc_wb_speed, wbs)
+		struct pwc_wb_speed *wbs = arg;
 		
-		if (ARGR(wbs).control_speed > 0) {
-			ret = pwc_set_wb_speed(pdev, ARGR(wbs).control_speed);
+		if (wbs->control_speed > 0) {
+			ret = pwc_set_wb_speed(pdev, wbs->control_speed);
 		}
-		if (ARGR(wbs).control_delay > 0) {
-			ret = pwc_set_wb_delay(pdev, ARGR(wbs).control_delay);
+		if (wbs->control_delay > 0) {
+			ret = pwc_set_wb_delay(pdev, wbs->control_delay);
 		}
 		break;
 	}
 	
 	case VIDIOCPWCGAWBSPEED:
 	{
-		ARG_DEF(struct pwc_wb_speed, wbs)
+		struct pwc_wb_speed *wbs = arg;
 		
-		ret = pwc_get_wb_speed(pdev, &ARGR(wbs).control_speed);
+		ret = pwc_get_wb_speed(pdev, &wbs->control_speed);
 		if (ret < 0)
 			break;
-		ret = pwc_get_wb_delay(pdev, &ARGR(wbs).control_delay);
+		ret = pwc_get_wb_delay(pdev, &wbs->control_delay);
 		if (ret < 0)
 			break;
-		ARG_OUT(wbs)
 		break;
 	}
 
         case VIDIOCPWCSLED:
 	{
-		ARG_DEF(struct pwc_leds, leds)
-
-		ARG_IN(leds)
-		ret = pwc_set_leds(pdev, ARGR(leds).led_on, ARGR(leds).led_off);
+		struct pwc_leds *leds = arg;
+		ret = pwc_set_leds(pdev, leds->led_on, leds->led_off);
 	    	break;
 	}
 
 
 	case VIDIOCPWCGLED:
 	{
-		ARG_DEF(struct pwc_leds, leds)
-		
-		ret = pwc_get_leds(pdev, &ARGR(leds).led_on, &ARGR(leds).led_off);
-		ARG_OUT(leds)
+		struct pwc_leds *leds = arg;
+		ret = pwc_get_leds(pdev, &leds->led_on, &leds->led_off);
 		break;
 	}
 
 	case VIDIOCPWCSCONTOUR:
 	{
-		ARG_DEF(int, contour)
-
-		ARG_IN(contour)
-		ret = pwc_set_contour(pdev, ARGR(contour));
+		int *contour = arg;
+		ret = pwc_set_contour(pdev, *contour);
 		break;
 	}
 			
 	case VIDIOCPWCGCONTOUR:
 	{
-		ARG_DEF(int, contour)
-		
-		ret = pwc_get_contour(pdev, ARGA(contour));
-		ARG_OUT(contour)
+		int *contour = arg;
+		ret = pwc_get_contour(pdev, contour);
 		break;
 	}
 	
 	case VIDIOCPWCSBACKLIGHT:
 	{
-		ARG_DEF(int, backlight)
-		
-		ARG_IN(backlight)
-		ret = pwc_set_backlight(pdev, ARGR(backlight));
+		int *backlight = arg;
+		ret = pwc_set_backlight(pdev, *backlight);
 		break;
 	}
 
 	case VIDIOCPWCGBACKLIGHT:
 	{
-		ARG_DEF(int, backlight)
-		
-		ret = pwc_get_backlight(pdev, ARGA(backlight));
-		ARG_OUT(backlight)
+		int *backlight = arg;
+		ret = pwc_get_backlight(pdev, backlight);
 		break;
 	}
 	
 	case VIDIOCPWCSFLICKER:
 	{
-		ARG_DEF(int, flicker)
-		
-		ARG_IN(flicker)
-		ret = pwc_set_flicker(pdev, ARGR(flicker));
+		int *flicker = arg;
+		ret = pwc_set_flicker(pdev, *flicker);
 		break;
 	}
 
 	case VIDIOCPWCGFLICKER:
 	{
-		ARG_DEF(int, flicker)
-		
-		ret = pwc_get_flicker(pdev, ARGA(flicker));
-		ARG_OUT(flicker)
+		int *flicker = arg;
+		ret = pwc_get_flicker(pdev, flicker);
 		break;
 	}
 	
 	case VIDIOCPWCSDYNNOISE:
 	{
-		ARG_DEF(int, dynnoise)
-		
-		ARG_IN(dynnoise)
-		ret = pwc_set_dynamic_noise(pdev, ARGR(dynnoise));
+		int *dynnoise = arg;
+		ret = pwc_set_dynamic_noise(pdev, *dynnoise);
 		break;
 	}
 	
 	case VIDIOCPWCGDYNNOISE:
 	{
-		ARG_DEF(int, dynnoise)
-
-		ret = pwc_get_dynamic_noise(pdev, ARGA(dynnoise));
-		ARG_OUT(dynnoise);
+		int *dynnoise = arg;
+		ret = pwc_get_dynamic_noise(pdev, dynnoise);
 		break;
 	}
 
 	case VIDIOCPWCGREALSIZE:
 	{
-		ARG_DEF(struct pwc_imagesize, size)
-		
-		ARGR(size).width = pdev->image.x;
-		ARGR(size).height = pdev->image.y;
-		ARG_OUT(size)
+		struct pwc_imagesize *size = arg;
+		size->width = pdev->image.x;
+		size->height = pdev->image.y;
 		break;
  	}
  	
@@ -1464,10 +1388,9 @@ int pwc_ioctl(struct pwc_device *pdev, u
  	{
  		if (pdev->features & FEATURE_MOTOR_PANTILT)
  		{
-	 		ARG_DEF(int, flags)
+	 		int *flags = arg;
 
- 			ARG_IN(flags)
-			ret = pwc_mpt_reset(pdev, ARGR(flags));
+			ret = pwc_mpt_reset(pdev, *flags);
  			if (ret >= 0)
  			{
  				pdev->pan_angle = 0;
@@ -1485,10 +1408,8 @@ int pwc_ioctl(struct pwc_device *pdev, u
  	{
  		if (pdev->features & FEATURE_MOTOR_PANTILT)
  		{
- 			ARG_DEF(struct pwc_mpt_range, range)
- 			
- 			ARGR(range) = pdev->angle_range;
- 			ARG_OUT(range)
+ 			struct pwc_mpt_range *range = arg;
+ 			*range = pdev->angle_range;
  		}
  		else
  		{	
@@ -1503,21 +1424,19 @@ int pwc_ioctl(struct pwc_device *pdev, u
  		
  		if (pdev->features & FEATURE_MOTOR_PANTILT)
  		{
-	 		ARG_DEF(struct pwc_mpt_angles, angles)
-
-	 		ARG_IN(angles)
+	 		struct pwc_mpt_angles *angles = arg;
 			/* The camera can only set relative angles, so
 			   do some calculations when getting an absolute angle .
 			 */
-			if (ARGR(angles).absolute)
+			if (angles->absolute)
 			{
- 				new_pan  = ARGR(angles).pan; 
- 				new_tilt = ARGR(angles).tilt;
+ 				new_pan  = angles->pan;
+ 				new_tilt = angles->tilt;
  			}
  			else
  			{
- 				new_pan  = pdev->pan_angle  + ARGR(angles).pan;
- 				new_tilt = pdev->tilt_angle + ARGR(angles).tilt;
+ 				new_pan  = pdev->pan_angle  + angles->pan;
+ 				new_tilt = pdev->tilt_angle + angles->tilt;
 			}
 			/* check absolute ranges */
 			if (new_pan  < pdev->angle_range.pan_min  ||
@@ -1560,12 +1479,11 @@ int pwc_ioctl(struct pwc_device *pdev, u
  		
  		if (pdev->features & FEATURE_MOTOR_PANTILT)
  		{
-	 		ARG_DEF(struct pwc_mpt_angles, angles)
+	 		struct pwc_mpt_angles *angles = arg;
 
- 			ARGR(angles).absolute = 1;
- 			ARGR(angles).pan  = pdev->pan_angle;
- 			ARGR(angles).tilt = pdev->tilt_angle;
- 			ARG_OUT(angles)
+ 			angles->absolute = 1;
+ 			angles->pan  = pdev->pan_angle;
+ 			angles->tilt = pdev->tilt_angle;
  		}
  		else
  		{
@@ -1578,10 +1496,8 @@ int pwc_ioctl(struct pwc_device *pdev, u
  	{
  		if (pdev->features & FEATURE_MOTOR_PANTILT)
  		{
- 			ARG_DEF(struct pwc_mpt_status, status)
- 			
- 			ret = pwc_mpt_get_status(pdev, ARGA(status));
- 			ARG_OUT(status)
+ 			struct pwc_mpt_status *status = arg;
+ 			ret = pwc_mpt_get_status(pdev, status);
  		}
  		else
  		{
@@ -1592,24 +1508,22 @@ int pwc_ioctl(struct pwc_device *pdev, u
 
 	case VIDIOCPWCGVIDCMD:
 	{
-		ARG_DEF(struct pwc_video_command, cmd);
+		struct pwc_video_command *cmd = arg;
 		
-                ARGR(cmd).type = pdev->type;
-		ARGR(cmd).release = pdev->release;
-		ARGR(cmd).command_len = pdev->cmd_len;
-		memcpy(&ARGR(cmd).command_buf, pdev->cmd_buf, pdev->cmd_len);
-		ARGR(cmd).bandlength = pdev->vbandlength;
-		ARGR(cmd).frame_size = pdev->frame_size;
-		ARG_OUT(cmd)
+                cmd->type = pdev->type;
+		cmd->release = pdev->release;
+		cmd->command_len = pdev->cmd_len;
+		memcpy(&cmd->command_buf, pdev->cmd_buf, pdev->cmd_len);
+		cmd->bandlength = pdev->vbandlength;
+		cmd->frame_size = pdev->frame_size;
 		break;
 	}
        /*
 	case VIDIOCPWCGVIDTABLE:
 	{
-		ARG_DEF(struct pwc_table_init_buffer, table);
-		ARGR(table).len = pdev->cmd_len;
-		memcpy(&ARGR(table).buffer, pdev->decompress_data, pdev->decompressor->table_size);
-		ARG_OUT(table)
+		struct pwc_table_init_buffer *table = arg;
+		table->len = pdev->cmd_len;
+		memcpy(&table->buffer, pdev->decompress_data, pdev->decompressor->table_size);
 		break;
 	}
 	*/
diff --git a/drivers/usb/media/sn9c102.h b/drivers/usb/media/sn9c102.h
index e5cea0e..17d60c1 100644
--- a/drivers/usb/media/sn9c102.h
+++ b/drivers/usb/media/sn9c102.h
@@ -1,7 +1,7 @@
 /***************************************************************************
  * V4L2 driver for SN9C10x PC Camera Controllers                           *
  *                                                                         *
- * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it>  *
+ * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it>  *
  *                                                                         *
  * This program is free software; you can redistribute it and/or modify    *
  * it under the terms of the GNU General Public License as published by    *
@@ -23,7 +23,8 @@
 
 #include <linux/version.h>
 #include <linux/usb.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
 #include <linux/device.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
@@ -52,13 +53,6 @@
 
 /*****************************************************************************/
 
-#define SN9C102_MODULE_NAME     "V4L2 driver for SN9C10x PC Camera Controllers"
-#define SN9C102_MODULE_AUTHOR   "(C) 2004-2005 Luca Risolia"
-#define SN9C102_AUTHOR_EMAIL    "<luca.risolia@studio.unibo.it>"
-#define SN9C102_MODULE_LICENSE  "GPL"
-#define SN9C102_MODULE_VERSION  "1:1.24a"
-#define SN9C102_MODULE_VERSION_CODE  KERNEL_VERSION(1, 0, 24)
-
 enum sn9c102_bridge {
 	BRIDGE_SN9C101 = 0x01,
 	BRIDGE_SN9C102 = 0x02,
@@ -102,12 +96,13 @@ enum sn9c102_stream_state {
 	STREAM_ON,
 };
 
+typedef char sn9c103_sof_header_t[18];
 typedef char sn9c102_sof_header_t[12];
 typedef char sn9c102_eof_header_t[4];
 
 struct sn9c102_sysfs_attr {
 	u8 reg, i2c_reg;
-	sn9c102_sof_header_t frame_header;
+	sn9c103_sof_header_t frame_header;
 };
 
 struct sn9c102_module_param {
@@ -118,8 +113,6 @@ static DECLARE_MUTEX(sn9c102_sysfs_lock)
 static DECLARE_RWSEM(sn9c102_disconnect);
 
 struct sn9c102_device {
-	struct device dev;
-
 	struct video_device* v4ldev;
 
 	enum sn9c102_bridge bridge;
@@ -140,8 +133,8 @@ struct sn9c102_device {
 	struct v4l2_jpegcompression compression;
 
 	struct sn9c102_sysfs_attr sysfs;
-	sn9c102_sof_header_t sof_header;
-	u16 reg[32];
+	sn9c103_sof_header_t sof_header;
+	u16 reg[63];
 
 	struct sn9c102_module_param module_param;
 
@@ -160,7 +153,6 @@ sn9c102_attach_sensor(struct sn9c102_dev
                       struct sn9c102_sensor* sensor)
 {
 	cam->sensor = sensor;
-	cam->sensor->dev = &cam->dev;
 	cam->sensor->usbdev = cam->usbdev;
 }
 
@@ -170,19 +162,24 @@ sn9c102_attach_sensor(struct sn9c102_dev
 #undef KDBG
 #ifdef SN9C102_DEBUG
 #	define DBG(level, fmt, args...)                                       \
-{                                                                             \
+do {                                                                          \
 	if (debug >= (level)) {                                               \
 		if ((level) == 1)                                             \
-			dev_err(&cam->dev, fmt "\n", ## args);                \
+			dev_err(&cam->usbdev->dev, fmt "\n", ## args);        \
 		else if ((level) == 2)                                        \
-			dev_info(&cam->dev, fmt "\n", ## args);               \
+			dev_info(&cam->usbdev->dev, fmt "\n", ## args);       \
 		else if ((level) >= 3)                                        \
-			dev_info(&cam->dev, "[%s:%d] " fmt "\n",              \
+			dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n",      \
 			         __FUNCTION__, __LINE__ , ## args);           \
 	}                                                                     \
-}
+} while (0)
+#	define V4LDBG(level, name, cmd)                                       \
+do {                                                                          \
+	if (debug >= (level))                                                 \
+		v4l_print_ioctl(name, cmd);                                   \
+} while (0)
 #	define KDBG(level, fmt, args...)                                      \
-{                                                                             \
+do {                                                                          \
 	if (debug >= (level)) {                                               \
 		if ((level) == 1 || (level) == 2)                             \
 			pr_info("sn9c102: " fmt "\n", ## args);               \
@@ -190,17 +187,18 @@ sn9c102_attach_sensor(struct sn9c102_dev
 			pr_debug("sn9c102: [%s:%d] " fmt "\n", __FUNCTION__,  \
 			         __LINE__ , ## args);                         \
 	}                                                                     \
-}
+} while (0)
 #else
-#	define KDBG(level, fmt, args...) do {;} while(0);
-#	define DBG(level, fmt, args...) do {;} while(0);
+#	define DBG(level, fmt, args...) do {;} while(0)
+#	define V4LDBG(level, name, cmd) do {;} while(0)
+#	define KDBG(level, fmt, args...) do {;} while(0)
 #endif
 
 #undef PDBG
 #define PDBG(fmt, args...)                                                    \
-dev_info(&cam->dev, "[%s:%d] " fmt "\n", __FUNCTION__, __LINE__ , ## args);
+dev_info(&cam->dev, "[%s:%d] " fmt "\n", __FUNCTION__, __LINE__ , ## args)
 
 #undef PDBGG
-#define PDBGG(fmt, args...) do {;} while(0); /* placeholder */
+#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */
 
 #endif /* _SN9C102_H_ */
diff --git a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c
index 8d1a1c3..c81397e 100644
--- a/drivers/usb/media/sn9c102_core.c
+++ b/drivers/usb/media/sn9c102_core.c
@@ -1,7 +1,7 @@
 /***************************************************************************
  * V4L2 driver for SN9C10x PC Camera Controllers                           *
  *                                                                         *
- * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it>  *
+ * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it>  *
  *                                                                         *
  * This program is free software; you can redistribute it and/or modify    *
  * it under the terms of the GNU General Public License as published by    *
@@ -45,6 +45,15 @@
 
 /*****************************************************************************/
 
+#define SN9C102_MODULE_NAME     "V4L2 driver for SN9C10x PC Camera Controllers"
+#define SN9C102_MODULE_AUTHOR   "(C) 2004-2006 Luca Risolia"
+#define SN9C102_AUTHOR_EMAIL    "<luca.risolia@studio.unibo.it>"
+#define SN9C102_MODULE_LICENSE  "GPL"
+#define SN9C102_MODULE_VERSION  "1:1.26"
+#define SN9C102_MODULE_VERSION_CODE  KERNEL_VERSION(1, 0, 26)
+
+/*****************************************************************************/
+
 MODULE_DEVICE_TABLE(usb, sn9c102_id_table);
 
 MODULE_AUTHOR(SN9C102_MODULE_AUTHOR " " SN9C102_AUTHOR_EMAIL);
@@ -70,10 +79,10 @@ static short force_munmap[] = {[0 ... SN
                                SN9C102_FORCE_MUNMAP};
 module_param_array(force_munmap, bool, NULL, 0444);
 MODULE_PARM_DESC(force_munmap,
-                 "\n<0|1[,...]> Force the application to unmap previously "
-                 "\nmapped buffer memory before calling any VIDIOC_S_CROP or "
-                 "\nVIDIOC_S_FMT ioctl's. Not all the applications support "
-                 "\nthis feature. This parameter is specific for each "
+                 "\n<0|1[,...]> Force the application to unmap previously"
+                 "\nmapped buffer memory before calling any VIDIOC_S_CROP or"
+                 "\nVIDIOC_S_FMT ioctl's. Not all the applications support"
+                 "\nthis feature. This parameter is specific for each"
                  "\ndetected camera."
                  "\n 0 = do not force memory unmapping"
                  "\n 1 = force memory unmapping (save memory)"
@@ -102,6 +111,9 @@ static sn9c102_sof_header_t sn9c102_sof_
 	{0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96, 0x01},
 };
 
+static sn9c103_sof_header_t sn9c103_sof_header[] = {
+	{0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96, 0x20},
+};
 
 static sn9c102_eof_header_t sn9c102_eof_header[] = {
 	{0x00, 0x00, 0x00, 0x00},
@@ -112,50 +124,6 @@ static sn9c102_eof_header_t sn9c102_eof_
 
 /*****************************************************************************/
 
-static void* rvmalloc(size_t size)
-{
-	void* mem;
-	unsigned long adr;
-
-	size = PAGE_ALIGN(size);
-
-	mem = vmalloc_32((unsigned long)size);
-	if (!mem)
-		return NULL;
-
-	memset(mem, 0, size);
-
-	adr = (unsigned long)mem;
-	while (size > 0) {
-		SetPageReserved(vmalloc_to_page((void *)adr));
-		adr += PAGE_SIZE;
-		size -= PAGE_SIZE;
-	}
-
-	return mem;
-}
-
-
-static void rvfree(void* mem, size_t size)
-{
-	unsigned long adr;
-
-	if (!mem)
-		return;
-
-	size = PAGE_ALIGN(size);
-
-	adr = (unsigned long)mem;
-	while (size > 0) {
-		ClearPageReserved(vmalloc_to_page((void *)adr));
-		adr += PAGE_SIZE;
-		size -= PAGE_SIZE;
-	}
-
-	vfree(mem);
-}
-
-
 static u32 
 sn9c102_request_buffers(struct sn9c102_device* cam, u32 count, 
                         enum sn9c102_io_method io)
@@ -174,7 +142,7 @@ sn9c102_request_buffers(struct sn9c102_d
 
 	cam->nbuffers = count;
 	while (cam->nbuffers > 0) {
-		if ((buff = rvmalloc(cam->nbuffers * PAGE_ALIGN(imagesize))))
+		if ((buff = vmalloc_32(cam->nbuffers * PAGE_ALIGN(imagesize))))
 			break;
 		cam->nbuffers--;
 	}
@@ -198,10 +166,10 @@ sn9c102_request_buffers(struct sn9c102_d
 static void sn9c102_release_buffers(struct sn9c102_device* cam)
 {
 	if (cam->nbuffers) {
-		rvfree(cam->frame[0].bufmem,
-		       cam->nbuffers * PAGE_ALIGN(cam->frame[0].buf.length));
+		vfree(cam->frame[0].bufmem);
 		cam->nbuffers = 0;
 	}
+	cam->frame_current = NULL;
 }
 
 
@@ -219,6 +187,19 @@ static void sn9c102_empty_framequeues(st
 }
 
 
+static void sn9c102_requeue_outqueue(struct sn9c102_device* cam)
+{
+	struct sn9c102_frame_t *i;
+
+	list_for_each_entry(i, &cam->outqueue, frame) {
+		i->state = F_QUEUED;
+		list_add(&i->frame, &cam->inqueue);
+	}
+
+	INIT_LIST_HEAD(&cam->outqueue);
+}
+
+
 static void sn9c102_queue_unusedframes(struct sn9c102_device* cam)
 {
 	unsigned long lock_flags;
@@ -235,19 +216,46 @@ static void sn9c102_queue_unusedframes(s
 
 /*****************************************************************************/
 
+int sn9c102_write_regs(struct sn9c102_device* cam, u8* buff, u16 index)
+{
+	struct usb_device* udev = cam->usbdev;
+	int i, res;
+
+	if (index + sizeof(buff) >= ARRAY_SIZE(cam->reg))
+		return -1;
+
+	res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
+	                      index, 0, buff, sizeof(buff),
+	                      SN9C102_CTRL_TIMEOUT*sizeof(buff));
+	if (res < 0) {
+		DBG(3, "Failed to write registers (index 0x%02X, error %d)",
+		    index, res);
+		return -1;
+	}
+
+	for (i = 0; i < sizeof(buff); i++)
+		cam->reg[index+i] = buff[i];
+
+	return 0;
+}
+
+
 int sn9c102_write_reg(struct sn9c102_device* cam, u8 value, u16 index)
 {
 	struct usb_device* udev = cam->usbdev;
 	u8* buff = cam->control_buffer;
 	int res;
 
+	if (index >= ARRAY_SIZE(cam->reg))
+		return -1;
+
 	*buff = value;
 
 	res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
 	                      index, 0, buff, 1, SN9C102_CTRL_TIMEOUT);
 	if (res < 0) {
 		DBG(3, "Failed to write a register (value 0x%02X, index "
-		       "0x%02X, error %d)", value, index, res)
+		       "0x%02X, error %d)", value, index, res);
 		return -1;
 	}
 
@@ -268,7 +276,7 @@ static int sn9c102_read_reg(struct sn9c1
 	                      index, 0, buff, 1, SN9C102_CTRL_TIMEOUT);
 	if (res < 0)
 		DBG(3, "Failed to read a register (index 0x%02X, error %d)",
-		    index, res)
+		    index, res);
 
 	return (res >= 0) ? (int)(*buff) : -1;
 }
@@ -276,8 +284,8 @@ static int sn9c102_read_reg(struct sn9c1
 
 int sn9c102_pread_reg(struct sn9c102_device* cam, u16 index)
 {
-	if (index > 0x1f)
-		return -EINVAL;
+	if (index >= ARRAY_SIZE(cam->reg))
+		return -1;
 
 	return cam->reg[index];
 }
@@ -367,10 +375,10 @@ sn9c102_i2c_try_raw_read(struct sn9c102_
 	err += sn9c102_i2c_detect_read_error(cam, sensor);
 
 	PDBGG("I2C read: address 0x%02X, first read byte: 0x%02X", data1,
-	      data[4])
+	      data[4]);
 
 	if (err) {
-		DBG(3, "I2C read failed for %s image sensor", sensor->name)
+		DBG(3, "I2C read failed for %s image sensor", sensor->name);
 		return -1;
 	}
 
@@ -410,11 +418,11 @@ sn9c102_i2c_try_raw_write(struct sn9c102
 	err += sn9c102_i2c_detect_write_error(cam, sensor);
 
 	if (err)
-		DBG(3, "I2C write failed for %s image sensor", sensor->name)
+		DBG(3, "I2C write failed for %s image sensor", sensor->name);
 
 	PDBGG("I2C raw write: %u bytes, data0 = 0x%02X, data1 = 0x%02X, "
 	      "data2 = 0x%02X, data3 = 0x%02X, data4 = 0x%02X, data5 = 0x%02X",
-	      n, data0, data1, data2, data3, data4, data5)
+	      n, data0, data1, data2, data3, data4, data5);
 
 	return err ? -1 : 0;
 }
@@ -461,13 +469,27 @@ int sn9c102_i2c_write(struct sn9c102_dev
 static void*
 sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len)
 {
-	size_t soflen = sizeof(sn9c102_sof_header_t), i;
-	u8 j, n = sizeof(sn9c102_sof_header) / soflen;
+	size_t soflen = 0, i;
+	u8 j, n = 0;
+
+	switch (cam->bridge) {
+	case BRIDGE_SN9C101:
+	case BRIDGE_SN9C102:
+		soflen = sizeof(sn9c102_sof_header_t);
+		n = sizeof(sn9c102_sof_header) / soflen;
+		break;
+	case BRIDGE_SN9C103:
+		soflen = sizeof(sn9c103_sof_header_t);
+		n = sizeof(sn9c103_sof_header) / soflen;
+	}
 
-	for (i = 0; (len >= soflen) && (i <= len - soflen); i++)
+ 	for (i = 0; (len >= soflen) && (i <= len - soflen); i++)
 		for (j = 0; j < n; j++)
-			/* It's enough to compare 7 bytes */
-			if (!memcmp(mem + i, sn9c102_sof_header[j], 7)) {
+			/* The invariable part of the header is 6 bytes long */
+			if ((cam->bridge != BRIDGE_SN9C103 &&
+			    !memcmp(mem + i, sn9c102_sof_header[j], 6)) ||
+			    (cam->bridge == BRIDGE_SN9C103 &&
+			    !memcmp(mem + i, sn9c103_sof_header[j], 6))) {
 				memcpy(cam->sof_header, mem + i, soflen);
 				/* Skip the header */
 				return mem + i + soflen;
@@ -499,8 +521,7 @@ static void sn9c102_urb_complete(struct 
 {
 	struct sn9c102_device* cam = urb->context;
 	struct sn9c102_frame_t** f;
-	size_t imagesize;
-	unsigned long lock_flags;
+	size_t imagesize, soflen;
 	u8 i;
 	int err = 0;
 
@@ -513,7 +534,7 @@ static void sn9c102_urb_complete(struct 
 		cam->stream = STREAM_OFF;
 		if ((*f))
 			(*f)->state = F_QUEUED;
-		DBG(3, "Stream interrupted")
+		DBG(3, "Stream interrupted");
 		wake_up_interruptible(&cam->wait_stream);
 	}
 
@@ -536,6 +557,10 @@ static void sn9c102_urb_complete(struct 
 	             cam->sensor->pix_format.height *
 	             cam->sensor->pix_format.priv) / 8;
 
+	soflen = (cam->bridge) == BRIDGE_SN9C103 ?
+	                          sizeof(sn9c103_sof_header_t) :
+	                          sizeof(sn9c102_sof_header_t);
+
 	for (i = 0; i < urb->number_of_packets; i++) {
 		unsigned int img, len, status;
 		void *pos, *sof, *eof;
@@ -545,19 +570,12 @@ static void sn9c102_urb_complete(struct 
 		pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
 
 		if (status) {
-			DBG(3, "Error in isochronous frame")
+			DBG(3, "Error in isochronous frame");
 			(*f)->state = F_ERROR;
 			continue;
 		}
 
-		PDBGG("Isochrnous frame: length %u, #%u i", len, i)
-
-		/*
-		   NOTE: It is probably correct to assume that SOF and EOF
-		         headers do not occur between two consecutive packets,
-		         but who knows..Whatever is the truth, this assumption
-		         doesn't introduce bugs.
-		*/
+		PDBGG("Isochrnous frame: length %u, #%u i", len, i);
 
 redo:
 		sof = sn9c102_find_sof_header(cam, pos, len);
@@ -575,10 +593,10 @@ end_of_frame:
 					        imagesize;
 					img = imagesize - (*f)->buf.bytesused;
 					DBG(3, "Expected EOF not found: "
-					       "video frame cut")
+					       "video frame cut");
 					if (eof)
 						DBG(3, "Exceeded limit: +%u "
-						       "bytes", (unsigned)(b))
+						       "bytes", (unsigned)(b));
 				}
 
 				memcpy((*f)->bufmem + (*f)->buf.bytesused, pos,
@@ -595,8 +613,7 @@ end_of_frame:
 					u32 b = (*f)->buf.bytesused;
 					(*f)->state = F_DONE;
 					(*f)->buf.sequence= ++cam->frame_count;
-					spin_lock_irqsave(&cam->queue_lock,
-					                  lock_flags);
+					spin_lock(&cam->queue_lock);
 					list_move_tail(&(*f)->frame,
 					               &cam->outqueue);
 					if (!list_empty(&cam->inqueue))
@@ -606,13 +623,11 @@ end_of_frame:
 						        frame );
 					else
 						(*f) = NULL;
-					spin_unlock_irqrestore(&cam->queue_lock
-					                       , lock_flags);
+					spin_unlock(&cam->queue_lock);
 					memcpy(cam->sysfs.frame_header,
-					       cam->sof_header,
-					       sizeof(sn9c102_sof_header_t));
-					DBG(3, "Video frame captured: "
-					       "%lu bytes", (unsigned long)(b))
+					       cam->sof_header, soflen);
+					DBG(3, "Video frame captured: %lu "
+					       "bytes", (unsigned long)(b));
 
 					if (!(*f))
 						goto resubmit_urb;
@@ -621,18 +636,19 @@ end_of_frame:
 					(*f)->state = F_ERROR;
 					DBG(3, "Not expected EOF after %lu "
 					       "bytes of image data", 
-					  (unsigned long)((*f)->buf.bytesused))
+					    (unsigned long)
+					    ((*f)->buf.bytesused));
 				}
 
 				if (sof) /* (1) */
 					goto start_of_frame;
 
 			} else if (eof) {
-				DBG(3, "EOF without SOF")
+				DBG(3, "EOF without SOF");
 				continue;
 
 			} else {
-				PDBGG("Ignoring pointless isochronous frame")
+				PDBGG("Ignoring pointless isochronous frame");
 				continue;
 			}
 
@@ -642,7 +658,7 @@ start_of_frame:
 			(*f)->buf.bytesused = 0;
 			len -= (sof - pos);
 			pos = sof;
-			DBG(3, "SOF detected: new video frame")
+			DBG(3, "SOF detected: new video frame");
 			if (len)
 				goto redo;
 
@@ -653,12 +669,13 @@ start_of_frame:
 			else {
 				if (cam->sensor->pix_format.pixelformat ==
 				    V4L2_PIX_FMT_SN9C10X) {
-					eof = sof-sizeof(sn9c102_sof_header_t);
+					eof = sof - soflen;
 					goto end_of_frame;
 				} else {
 					DBG(3, "SOF before expected EOF after "
 					       "%lu bytes of image data", 
-					  (unsigned long)((*f)->buf.bytesused))
+					    (unsigned long)
+					    ((*f)->buf.bytesused));
 					goto start_of_frame;
 				}
 			}
@@ -670,7 +687,7 @@ resubmit_urb:
 	err = usb_submit_urb(urb, GFP_ATOMIC);
 	if (err < 0 && err != -EPERM) {
 		cam->state |= DEV_MISCONFIGURED;
-		DBG(1, "usb_submit_urb() failed")
+		DBG(1, "usb_submit_urb() failed");
 	}
 
 	wake_up_interruptible(&cam->wait_frame);
@@ -681,18 +698,22 @@ static int sn9c102_start_transfer(struct
 {
 	struct usb_device *udev = cam->usbdev;
 	struct urb* urb;
-	const unsigned int wMaxPacketSize[] = {0, 128, 256, 384, 512,
-	                                       680, 800, 900, 1023};
-	const unsigned int psz = wMaxPacketSize[SN9C102_ALTERNATE_SETTING];
+	const unsigned int sn9c102_wMaxPacketSize[] = {0, 128, 256, 384, 512,
+	                                               680, 800, 900, 1023};
+	const unsigned int sn9c103_wMaxPacketSize[] = {0, 128, 256, 384, 512,
+	                                               680, 800, 900, 1003};
+	const unsigned int psz = (cam->bridge == BRIDGE_SN9C103) ?
+	                    sn9c103_wMaxPacketSize[SN9C102_ALTERNATE_SETTING] :
+	                    sn9c102_wMaxPacketSize[SN9C102_ALTERNATE_SETTING];
 	s8 i, j;
 	int err = 0;
 
 	for (i = 0; i < SN9C102_URBS; i++) {
-		cam->transfer_buffer[i] = kmalloc(SN9C102_ISO_PACKETS * psz,
+		cam->transfer_buffer[i] = kzalloc(SN9C102_ISO_PACKETS * psz,
 		                                  GFP_KERNEL);
 		if (!cam->transfer_buffer[i]) {
 			err = -ENOMEM;
-			DBG(1, "Not enough memory")
+			DBG(1, "Not enough memory");
 			goto free_buffers;
 		}
 	}
@@ -702,7 +723,7 @@ static int sn9c102_start_transfer(struct
 		cam->urb[i] = urb;
 		if (!urb) {
 			err = -ENOMEM;
-			DBG(1, "usb_alloc_urb() failed")
+			DBG(1, "usb_alloc_urb() failed");
 			goto free_urbs;
 		}
 		urb->dev = udev;
@@ -725,14 +746,14 @@ static int sn9c102_start_transfer(struct
 		err = sn9c102_write_reg(cam, cam->reg[0x01] | 0x04, 0x01);
 		if (err) {
 			err = -EIO;
-			DBG(1, "I/O hardware error")
+			DBG(1, "I/O hardware error");
 			goto free_urbs;
 		}
 	}
 
 	err = usb_set_interface(udev, 0, SN9C102_ALTERNATE_SETTING);
 	if (err) {
-		DBG(1, "usb_set_interface() failed")
+		DBG(1, "usb_set_interface() failed");
 		goto free_urbs;
 	}
 
@@ -743,7 +764,7 @@ static int sn9c102_start_transfer(struct
 		if (err) {
 			for (j = i-1; j >= 0; j--)
 				usb_kill_urb(cam->urb[j]);
-			DBG(1, "usb_submit_urb() failed, error %d", err)
+			DBG(1, "usb_submit_urb() failed, error %d", err);
 			goto free_urbs;
 		}
 	}
@@ -779,7 +800,7 @@ static int sn9c102_stop_transfer(struct 
 
 	err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */
 	if (err)
-		DBG(3, "usb_set_interface() failed")
+		DBG(3, "usb_set_interface() failed");
 
 	return err;
 }
@@ -799,7 +820,7 @@ static int sn9c102_stream_interrupt(stru
 	else if (err) {
 		cam->state |= DEV_MISCONFIGURED;
 		DBG(1, "The camera is misconfigured. To use it, close and "
-		       "open /dev/video%d again.", cam->v4ldev->minor)
+		       "open /dev/video%d again.", cam->v4ldev->minor);
 		return err;
 	}
 
@@ -808,6 +829,7 @@ static int sn9c102_stream_interrupt(stru
 
 /*****************************************************************************/
 
+#ifdef CONFIG_VIDEO_ADV_DEBUG
 static u8 sn9c102_strtou8(const char* buff, size_t len, ssize_t* count)
 {
 	char str[5];
@@ -885,8 +907,8 @@ sn9c102_store_reg(struct class_device* c
 
 	cam->sysfs.reg = index;
 
-	DBG(2, "Moved SN9C10X register index to 0x%02X", cam->sysfs.reg)
-	DBG(3, "Written bytes: %zd", count)
+	DBG(2, "Moved SN9C10X register index to 0x%02X", cam->sysfs.reg);
+	DBG(3, "Written bytes: %zd", count);
 
 	up(&sn9c102_sysfs_lock);
 
@@ -916,7 +938,7 @@ static ssize_t sn9c102_show_val(struct c
 
 	count = sprintf(buf, "%d\n", val);
 
-	DBG(3, "Read bytes: %zd", count)
+	DBG(3, "Read bytes: %zd", count);
 
 	up(&sn9c102_sysfs_lock);
 
@@ -954,8 +976,8 @@ sn9c102_store_val(struct class_device* c
 	}
 
 	DBG(2, "Written SN9C10X reg. 0x%02X, val. 0x%02X",
-	    cam->sysfs.reg, value)
-	DBG(3, "Written bytes: %zd", count)
+	    cam->sysfs.reg, value);
+	DBG(3, "Written bytes: %zd", count);
 
 	up(&sn9c102_sysfs_lock);
 
@@ -979,7 +1001,7 @@ static ssize_t sn9c102_show_i2c_reg(stru
 
 	count = sprintf(buf, "%u\n", cam->sysfs.i2c_reg);
 
-	DBG(3, "Read bytes: %zd", count)
+	DBG(3, "Read bytes: %zd", count);
 
 	up(&sn9c102_sysfs_lock);
 
@@ -1011,8 +1033,8 @@ sn9c102_store_i2c_reg(struct class_devic
 
 	cam->sysfs.i2c_reg = index;
 
-	DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg)
-	DBG(3, "Written bytes: %zd", count)
+	DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg);
+	DBG(3, "Written bytes: %zd", count);
 
 	up(&sn9c102_sysfs_lock);
 
@@ -1047,7 +1069,7 @@ static ssize_t sn9c102_show_i2c_val(stru
 
 	count = sprintf(buf, "%d\n", val);
 
-	DBG(3, "Read bytes: %zd", count)
+	DBG(3, "Read bytes: %zd", count);
 
 	up(&sn9c102_sysfs_lock);
 
@@ -1090,8 +1112,8 @@ sn9c102_store_i2c_val(struct class_devic
 	}
 
 	DBG(2, "Written sensor reg. 0x%02X, val. 0x%02X",
-	    cam->sysfs.i2c_reg, value)
-	DBG(3, "Written bytes: %zd", count)
+	    cam->sysfs.i2c_reg, value);
+	DBG(3, "Written bytes: %zd", count);
 
 	up(&sn9c102_sysfs_lock);
 
@@ -1193,7 +1215,7 @@ static ssize_t sn9c102_show_frame_header
 	count = sizeof(cam->sysfs.frame_header);
 	memcpy(buf, cam->sysfs.frame_header, count);
 
-	DBG(3, "Frame header, read bytes: %zd", count)
+	DBG(3, "Frame header, read bytes: %zd", count);
 
 	return count;
 } 
@@ -1227,11 +1249,12 @@ static void sn9c102_create_sysfs(struct 
 		video_device_create_file(v4ldev, &class_device_attr_blue);
 		video_device_create_file(v4ldev, &class_device_attr_red);
 	}
-	if (cam->sensor->sysfs_ops) {
+	if (cam->sensor && cam->sensor->sysfs_ops) {
 		video_device_create_file(v4ldev, &class_device_attr_i2c_reg);
 		video_device_create_file(v4ldev, &class_device_attr_i2c_val);
 	}
 }
+#endif /* CONFIG_VIDEO_ADV_DEBUG */
 
 /*****************************************************************************/
 
@@ -1281,7 +1304,7 @@ static int sn9c102_set_scale(struct sn9c
 	if (err)
 		return -EIO;
 
-	PDBGG("Scaling factor: %u", scale)
+	PDBGG("Scaling factor: %u", scale);
 
 	return 0;
 }
@@ -1304,7 +1327,7 @@ static int sn9c102_set_crop(struct sn9c1
 		return -EIO;
 
 	PDBGG("h_start, v_start, h_size, v_size, ho_size, vo_size "
-	      "%u %u %u %u", h_start, v_start, h_size, v_size)
+	      "%u %u %u %u", h_start, v_start, h_size, v_size);
 
 	return 0;
 }
@@ -1336,7 +1359,7 @@ static int sn9c102_init(struct sn9c102_d
 	if (s->init) {
 		err = s->init(cam);
 		if (err) {
-			DBG(3, "Sensor initialization failed")
+			DBG(3, "Sensor initialization failed");
 			return err;
 		}
 	}
@@ -1353,13 +1376,13 @@ static int sn9c102_init(struct sn9c102_d
 
 	if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X)
 		DBG(3, "Compressed video format is active, quality %d",
-		    cam->compression.quality)
+		    cam->compression.quality);
 	else
-		DBG(3, "Uncompressed video format is active")
+		DBG(3, "Uncompressed video format is active");
 
 	if (s->set_crop)
 		if ((err = s->set_crop(cam, rect))) {
-			DBG(3, "set_crop() failed")
+			DBG(3, "set_crop() failed");
 			return err;
 		}
 
@@ -1372,11 +1395,11 @@ static int sn9c102_init(struct sn9c102_d
 				err = s->set_ctrl(cam, &ctrl);
 				if (err) {
 					DBG(3, "Set %s control failed",
-					    s->qctrl[i].name)
+					    s->qctrl[i].name);
 					return err;
 				}
 				DBG(3, "Image sensor supports '%s' control",
-				    s->qctrl[i].name)
+				    s->qctrl[i].name);
 			}
 	}
 
@@ -1392,7 +1415,7 @@ static int sn9c102_init(struct sn9c102_d
 		cam->state |= DEV_INITIALIZED;
 	}
 
-	DBG(2, "Initialization succeeded")
+	DBG(2, "Initialization succeeded");
 	return 0;
 }
 
@@ -1401,7 +1424,7 @@ static void sn9c102_release_resources(st
 {
 	down(&sn9c102_sysfs_lock);
 
-	DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor)
+	DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor);
 	video_set_drvdata(cam->v4ldev, NULL);
 	video_unregister_device(cam->v4ldev);
 
@@ -1432,7 +1455,7 @@ static int sn9c102_open(struct inode* in
 	}
 
 	if (cam->users) {
-		DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor)
+		DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor);
 		if ((filp->f_flags & O_NONBLOCK) ||
 		    (filp->f_flags & O_NDELAY)) {
 			err = -EWOULDBLOCK;
@@ -1458,7 +1481,7 @@ static int sn9c102_open(struct inode* in
 		err = sn9c102_init(cam);
 		if (err) {
 			DBG(1, "Initialization failed again. "
-			       "I will retry on next open().")
+			       "I will retry on next open().");
 			goto out;
 		}
 		cam->state &= ~DEV_MISCONFIGURED;
@@ -1475,7 +1498,7 @@ static int sn9c102_open(struct inode* in
 	cam->frame_count = 0;
 	sn9c102_empty_framequeues(cam);
 
-	DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor)
+	DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor);
 
 out:
 	up(&cam->dev_sem);
@@ -1504,7 +1527,7 @@ static int sn9c102_release(struct inode*
 	cam->users--;
 	wake_up_interruptible_nr(&cam->open, 1);
 
-	DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor)
+	DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor);
 
 	up(&cam->dev_sem);
 
@@ -1524,32 +1547,38 @@ sn9c102_read(struct file* filp, char __u
 		return -ERESTARTSYS;
 
 	if (cam->state & DEV_DISCONNECTED) {
-		DBG(1, "Device not present")
+		DBG(1, "Device not present");
 		up(&cam->fileop_sem);
 		return -ENODEV;
 	}
 
 	if (cam->state & DEV_MISCONFIGURED) {
-		DBG(1, "The camera is misconfigured. Close and open it again.")
+		DBG(1, "The camera is misconfigured. Close and open it "
+		       "again.");
 		up(&cam->fileop_sem);
 		return -EIO;
 	}
 
 	if (cam->io == IO_MMAP) {
 		DBG(3, "Close and open the device again to choose "
-		       "the read method")
+		       "the read method");
 		up(&cam->fileop_sem);
 		return -EINVAL;
 	}
 
 	if (cam->io == IO_NONE) {
 		if (!sn9c102_request_buffers(cam,cam->nreadbuffers, IO_READ)) {
-			DBG(1, "read() failed, not enough memory")
+			DBG(1, "read() failed, not enough memory");
 			up(&cam->fileop_sem);
 			return -ENOMEM;
 		}
 		cam->io = IO_READ;
 		cam->stream = STREAM_ON;
+	}
+
+	if (list_empty(&cam->inqueue)) {
+		if (!list_empty(&cam->outqueue))
+			sn9c102_empty_framequeues(cam);
 		sn9c102_queue_unusedframes(cam);
 	}
 
@@ -1584,6 +1613,16 @@ sn9c102_read(struct file* filp, char __u
 
 	f = list_entry(cam->outqueue.prev, struct sn9c102_frame_t, frame);
 
+	if (count > f->buf.bytesused)
+		count = f->buf.bytesused;
+
+	if (copy_to_user(buf, f->bufmem, count)) {
+		err = -EFAULT;
+		goto exit;
+	}
+	*f_pos += count;
+
+exit:
 	spin_lock_irqsave(&cam->queue_lock, lock_flags);
 	list_for_each_entry(i, &cam->outqueue, frame)
 		i->state = F_UNUSED;
@@ -1592,16 +1631,8 @@ sn9c102_read(struct file* filp, char __u
 
 	sn9c102_queue_unusedframes(cam);
 
-	if (count > f->buf.bytesused)
-		count = f->buf.bytesused;
-
-	if (copy_to_user(buf, f->bufmem, count)) {
-		up(&cam->fileop_sem);
-		return -EFAULT;
-	}
-	*f_pos += count;
-
-	PDBGG("Frame #%lu, bytes read: %zu", (unsigned long)f->buf.index,count)
+	PDBGG("Frame #%lu, bytes read: %zu",
+	      (unsigned long)f->buf.index, count);
 
 	up(&cam->fileop_sem);
 
@@ -1612,33 +1643,42 @@ sn9c102_read(struct file* filp, char __u
 static unsigned int sn9c102_poll(struct file *filp, poll_table *wait)
 {
 	struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
+	struct sn9c102_frame_t* f;
+	unsigned long lock_flags;
 	unsigned int mask = 0;
 
 	if (down_interruptible(&cam->fileop_sem))
 		return POLLERR;
 
 	if (cam->state & DEV_DISCONNECTED) {
-		DBG(1, "Device not present")
+		DBG(1, "Device not present");
 		goto error;
 	}
 
 	if (cam->state & DEV_MISCONFIGURED) {
-		DBG(1, "The camera is misconfigured. Close and open it again.")
+		DBG(1, "The camera is misconfigured. Close and open it "
+		       "again.");
 		goto error;
 	}
 
 	if (cam->io == IO_NONE) {
 		if (!sn9c102_request_buffers(cam, cam->nreadbuffers,
 		                             IO_READ)) {
-			DBG(1, "poll() failed, not enough memory")
+			DBG(1, "poll() failed, not enough memory");
 			goto error;
 		}
 		cam->io = IO_READ;
 		cam->stream = STREAM_ON;
 	}
 
-	if (cam->io == IO_READ)
+	if (cam->io == IO_READ) {
+		spin_lock_irqsave(&cam->queue_lock, lock_flags);
+		list_for_each_entry(f, &cam->outqueue, frame)
+			f->state = F_UNUSED;
+		INIT_LIST_HEAD(&cam->outqueue);
+		spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
 		sn9c102_queue_unusedframes(cam);
+	}
 
 	poll_wait(filp, &cam->wait_frame, wait);
 
@@ -1680,22 +1720,22 @@ static int sn9c102_mmap(struct file* fil
 {
 	struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
 	unsigned long size = vma->vm_end - vma->vm_start,
-	              start = vma->vm_start,
-	              pos,
-	              page;
+	              start = vma->vm_start;
+	void *pos;
 	u32 i;
 
 	if (down_interruptible(&cam->fileop_sem))
 		return -ERESTARTSYS;
 
 	if (cam->state & DEV_DISCONNECTED) {
-		DBG(1, "Device not present")
+		DBG(1, "Device not present");
 		up(&cam->fileop_sem);
 		return -ENODEV;
 	}
 
 	if (cam->state & DEV_MISCONFIGURED) {
-		DBG(1, "The camera is misconfigured. Close and open it again.")
+		DBG(1, "The camera is misconfigured. Close and open it "
+		       "again.");
 		up(&cam->fileop_sem);
 		return -EIO;
 	}
@@ -1715,15 +1755,12 @@ static int sn9c102_mmap(struct file* fil
 		return -EINVAL;
 	}
 
-	/* VM_IO is eventually going to replace PageReserved altogether */
 	vma->vm_flags |= VM_IO;
-	vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
+	vma->vm_flags |= VM_RESERVED;
 
-	pos = (unsigned long)cam->frame[i].bufmem;
+	pos = cam->frame[i].bufmem;
 	while (size > 0) { /* size is page-aligned */
-		page = vmalloc_to_pfn((void *)pos);
-		if (remap_pfn_range(vma, start, page, PAGE_SIZE,
-		                    vma->vm_page_prot)) {
+		if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
 			up(&cam->fileop_sem);
 			return -EAGAIN;
 		}
@@ -1742,738 +1779,861 @@ static int sn9c102_mmap(struct file* fil
 	return 0;
 }
 
+/*****************************************************************************/
 
-static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp,
-                              unsigned int cmd, void __user * arg)
+static int
+sn9c102_vidioc_querycap(struct sn9c102_device* cam, void __user * arg)
 {
-	struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
-
-	switch (cmd) {
-
-	case VIDIOC_QUERYCAP:
-	{
-		struct v4l2_capability cap = {
-			.driver = "sn9c102",
-			.version = SN9C102_MODULE_VERSION_CODE,
-			.capabilities = V4L2_CAP_VIDEO_CAPTURE | 
-			                V4L2_CAP_READWRITE |
-			                V4L2_CAP_STREAMING,
-		};
-
-		strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
-		if (usb_make_path(cam->usbdev, cap.bus_info,
-		    sizeof(cap.bus_info)) < 0)
-			strlcpy(cap.bus_info, cam->dev.bus_id,
-			        sizeof(cap.bus_info));
+	struct v4l2_capability cap = {
+		.driver = "sn9c102",
+		.version = SN9C102_MODULE_VERSION_CODE,
+		.capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
+		                V4L2_CAP_STREAMING,
+	};
+
+	strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
+	if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
+		strlcpy(cap.bus_info, cam->usbdev->dev.bus_id,
+		        sizeof(cap.bus_info));
 
-		if (copy_to_user(arg, &cap, sizeof(cap)))
-			return -EFAULT;
-
-		return 0;
-	}
-
-	case VIDIOC_ENUMINPUT:
-	{
-		struct v4l2_input i;
-
-		if (copy_from_user(&i, arg, sizeof(i)))
-			return -EFAULT;
+	if (copy_to_user(arg, &cap, sizeof(cap)))
+		return -EFAULT;
 
-		if (i.index)
-			return -EINVAL;
+	return 0;
+}
 
-		memset(&i, 0, sizeof(i));
-		strcpy(i.name, "USB");
 
-		if (copy_to_user(arg, &i, sizeof(i)))
-			return -EFAULT;
+static int
+sn9c102_vidioc_enuminput(struct sn9c102_device* cam, void __user * arg)
+{
+	struct v4l2_input i;
 
-		return 0;
-	}
+	if (copy_from_user(&i, arg, sizeof(i)))
+		return -EFAULT;
 
-	case VIDIOC_G_INPUT:
-	case VIDIOC_S_INPUT:
-	{
-		int index;
+	if (i.index)
+		return -EINVAL;
 
-		if (copy_from_user(&index, arg, sizeof(index)))
-			return -EFAULT;
+	memset(&i, 0, sizeof(i));
+	strcpy(i.name, "Camera");
 
-		if (index != 0)
-			return -EINVAL;
+	if (copy_to_user(arg, &i, sizeof(i)))
+		return -EFAULT;
 
-		return 0;
-	}
+	return 0;
+}
 
-	case VIDIOC_QUERYCTRL:
-	{
-		struct sn9c102_sensor* s = cam->sensor;
-		struct v4l2_queryctrl qc;
-		u8 i;
 
-		if (copy_from_user(&qc, arg, sizeof(qc)))
-			return -EFAULT;
+static int
+sn9c102_vidioc_gs_input(struct sn9c102_device* cam, void __user * arg)
+{
+	int index;
 
-		for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
-			if (qc.id && qc.id == s->qctrl[i].id) {
-				memcpy(&qc, &(s->qctrl[i]), sizeof(qc));
-				if (copy_to_user(arg, &qc, sizeof(qc)))
-					return -EFAULT;
-				return 0;
-			}
+	if (copy_from_user(&index, arg, sizeof(index)))
+		return -EFAULT;
 
+	if (index != 0)
 		return -EINVAL;
-	}
 
-	case VIDIOC_G_CTRL:
-	{
-		struct sn9c102_sensor* s = cam->sensor;
-		struct v4l2_control ctrl;
-		int err = 0;
+	return 0;
+}
 
-		if (!s->get_ctrl)
-			return -EINVAL;
 
-		if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
-			return -EFAULT;
+static int
+sn9c102_vidioc_query_ctrl(struct sn9c102_device* cam, void __user * arg)
+{
+	struct sn9c102_sensor* s = cam->sensor;
+	struct v4l2_queryctrl qc;
+	u8 i;
 
-		err = s->get_ctrl(cam, &ctrl);
+	if (copy_from_user(&qc, arg, sizeof(qc)))
+		return -EFAULT;
 
-		if (copy_to_user(arg, &ctrl, sizeof(ctrl)))
-			return -EFAULT;
+	for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
+		if (qc.id && qc.id == s->qctrl[i].id) {
+			memcpy(&qc, &(s->qctrl[i]), sizeof(qc));
+			if (copy_to_user(arg, &qc, sizeof(qc)))
+				return -EFAULT;
+			return 0;
+		}
 
-		return err;
-	}
+	return -EINVAL;
+}
 
-	case VIDIOC_S_CTRL_OLD:
-	case VIDIOC_S_CTRL:
-	{
-		struct sn9c102_sensor* s = cam->sensor;
-		struct v4l2_control ctrl;
-		u8 i;
-		int err = 0;
 
-		if (!s->set_ctrl)
-			return -EINVAL;
+static int
+sn9c102_vidioc_g_ctrl(struct sn9c102_device* cam, void __user * arg)
+{
+	struct sn9c102_sensor* s = cam->sensor;
+	struct v4l2_control ctrl;
+	int err = 0;
+	u8 i;
 
-		if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
-			return -EFAULT;
+	if (!s->get_ctrl && !s->set_ctrl)
+		return -EINVAL;
+
+	if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
+		return -EFAULT;
 
+	if (!s->get_ctrl) {
 		for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
-			if (ctrl.id == s->qctrl[i].id) {
-				if (ctrl.value < s->qctrl[i].minimum ||
-				    ctrl.value > s->qctrl[i].maximum)
-					return -ERANGE;
-				ctrl.value -= ctrl.value % s->qctrl[i].step;
-				break;
+			if (ctrl.id && ctrl.id == s->qctrl[i].id) {
+				ctrl.value = s->_qctrl[i].default_value;
+				goto exit;
 			}
+		return -EINVAL;
+	} else
+		err = s->get_ctrl(cam, &ctrl);
 
-		if ((err = s->set_ctrl(cam, &ctrl)))
-			return err;
+exit:
+	if (copy_to_user(arg, &ctrl, sizeof(ctrl)))
+		return -EFAULT;
 
-		s->_qctrl[i].default_value = ctrl.value;
+	return err;
+}
 
-		PDBGG("VIDIOC_S_CTRL: id %lu, value %lu",
-		      (unsigned long)ctrl.id, (unsigned long)ctrl.value)
 
-		return 0;
-	}
+static int
+sn9c102_vidioc_s_ctrl(struct sn9c102_device* cam, void __user * arg)
+{
+	struct sn9c102_sensor* s = cam->sensor;
+	struct v4l2_control ctrl;
+	u8 i;
+	int err = 0;
 
-	case VIDIOC_CROPCAP:
-	{
-		struct v4l2_cropcap* cc = &(cam->sensor->cropcap);
+	if (!s->set_ctrl)
+		return -EINVAL;
 
-		cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		cc->pixelaspect.numerator = 1;
-		cc->pixelaspect.denominator = 1;
+	if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
+		return -EFAULT;
 
-		if (copy_to_user(arg, cc, sizeof(*cc)))
-			return -EFAULT;
+	for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
+		if (ctrl.id == s->qctrl[i].id) {
+			if (ctrl.value < s->qctrl[i].minimum ||
+			    ctrl.value > s->qctrl[i].maximum)
+				return -ERANGE;
+			ctrl.value -= ctrl.value % s->qctrl[i].step;
+			break;
+		}
 
-		return 0;
-	}
+	if ((err = s->set_ctrl(cam, &ctrl)))
+		return err;
 
-	case VIDIOC_G_CROP:
-	{
-		struct sn9c102_sensor* s = cam->sensor;
-		struct v4l2_crop crop = {
-			.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
-		};
+	s->_qctrl[i].default_value = ctrl.value;
 
-		memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect));
+	PDBGG("VIDIOC_S_CTRL: id %lu, value %lu",
+	      (unsigned long)ctrl.id, (unsigned long)ctrl.value);
 
-		if (copy_to_user(arg, &crop, sizeof(crop)))
-			return -EFAULT;
+	return 0;
+}
 
-		return 0;
-	}
 
-	case VIDIOC_S_CROP:
-	{
-		struct sn9c102_sensor* s = cam->sensor;
-		struct v4l2_crop crop;
-		struct v4l2_rect* rect;
-		struct v4l2_rect* bounds = &(s->cropcap.bounds);
-		struct v4l2_pix_format* pix_format = &(s->pix_format);
-		u8 scale;
-		const enum sn9c102_stream_state stream = cam->stream;
-		const u32 nbuffers = cam->nbuffers;
-		u32 i;
-		int err = 0;
+static int
+sn9c102_vidioc_cropcap(struct sn9c102_device* cam, void __user * arg)
+{
+	struct v4l2_cropcap* cc = &(cam->sensor->cropcap);
 
-		if (copy_from_user(&crop, arg, sizeof(crop)))
-			return -EFAULT;
+	cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	cc->pixelaspect.numerator = 1;
+	cc->pixelaspect.denominator = 1;
 
-		rect = &(crop.c);
+	if (copy_to_user(arg, cc, sizeof(*cc)))
+		return -EFAULT;
 
-		if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-			return -EINVAL;
+	return 0;
+}
 
-		if (cam->module_param.force_munmap)
-			for (i = 0; i < cam->nbuffers; i++)
-				if (cam->frame[i].vma_use_count) {
-					DBG(3, "VIDIOC_S_CROP failed. "
-					       "Unmap the buffers first.")
-					return -EINVAL;
-				}
 
-		/* Preserve R,G or B origin */
-		rect->left = (s->_rect.left & 1L) ?
-		             rect->left | 1L : rect->left & ~1L;
-		rect->top = (s->_rect.top & 1L) ?
-		            rect->top | 1L : rect->top & ~1L;
-
-		if (rect->width < 16)
-			rect->width = 16;
-		if (rect->height < 16)
-			rect->height = 16;
-		if (rect->width > bounds->width)
-			rect->width = bounds->width;
-		if (rect->height > bounds->height)
-			rect->height = bounds->height;
-		if (rect->left < bounds->left)
-			rect->left = bounds->left;
-		if (rect->top < bounds->top)
-			rect->top = bounds->top;
-		if (rect->left + rect->width > bounds->left + bounds->width)
-			rect->left = bounds->left+bounds->width - rect->width;
-		if (rect->top + rect->height > bounds->top + bounds->height)
-			rect->top = bounds->top+bounds->height - rect->height;
-
-		rect->width &= ~15L;
-		rect->height &= ~15L;
-
-		if (SN9C102_PRESERVE_IMGSCALE) {
-			/* Calculate the actual scaling factor */
-			u32 a, b;
-			a = rect->width * rect->height;
-			b = pix_format->width * pix_format->height;
-			scale = b ? (u8)((a / b) < 4 ? 1 :
-		                        ((a / b) < 16 ? 2 : 4)) : 1;
-		} else
-			scale = 1;
-
-		if (cam->stream == STREAM_ON)
-			if ((err = sn9c102_stream_interrupt(cam)))
-				return err;
+static int
+sn9c102_vidioc_g_crop(struct sn9c102_device* cam, void __user * arg)
+{
+	struct sn9c102_sensor* s = cam->sensor;
+	struct v4l2_crop crop = {
+		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+	};
 
-		if (copy_to_user(arg, &crop, sizeof(crop))) {
-			cam->stream = stream;
-			return -EFAULT;
-		}
+	memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect));
 
-		if (cam->module_param.force_munmap || cam->io == IO_READ)
-			sn9c102_release_buffers(cam);
+	if (copy_to_user(arg, &crop, sizeof(crop)))
+		return -EFAULT;
 
-		err = sn9c102_set_crop(cam, rect);
-		if (s->set_crop)
-			err += s->set_crop(cam, rect);
-		err += sn9c102_set_scale(cam, scale);
-
-		if (err) { /* atomic, no rollback in ioctl() */
-			cam->state |= DEV_MISCONFIGURED;
-			DBG(1, "VIDIOC_S_CROP failed because of hardware "
-			       "problems. To use the camera, close and open "
-			       "/dev/video%d again.", cam->v4ldev->minor)
-			return -EIO;
-		}
+	return 0;
+}
 
-		s->pix_format.width = rect->width/scale;
-		s->pix_format.height = rect->height/scale;
-		memcpy(&(s->_rect), rect, sizeof(*rect));
-
-		if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
-		    nbuffers != sn9c102_request_buffers(cam, nbuffers,
-		                                        cam->io)) {
-			cam->state |= DEV_MISCONFIGURED;
-			DBG(1, "VIDIOC_S_CROP failed because of not enough "
-			       "memory. To use the camera, close and open "
-			       "/dev/video%d again.", cam->v4ldev->minor)
-			return -ENOMEM;
-		}
 
-		cam->stream = stream;
+static int
+sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg)
+{
+	struct sn9c102_sensor* s = cam->sensor;
+	struct v4l2_crop crop;
+	struct v4l2_rect* rect;
+	struct v4l2_rect* bounds = &(s->cropcap.bounds);
+	struct v4l2_pix_format* pix_format = &(s->pix_format);
+	u8 scale;
+	const enum sn9c102_stream_state stream = cam->stream;
+	const u32 nbuffers = cam->nbuffers;
+	u32 i;
+	int err = 0;
 
-		return 0;
-	}
+	if (copy_from_user(&crop, arg, sizeof(crop)))
+		return -EFAULT;
 
-	case VIDIOC_ENUM_FMT:
-	{
-		struct v4l2_fmtdesc fmtd;
+	rect = &(crop.c);
 
-		if (copy_from_user(&fmtd, arg, sizeof(fmtd)))
-			return -EFAULT;
+	if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
 
-		if (fmtd.index == 0) {
-			strcpy(fmtd.description, "bayer rgb");
-			fmtd.pixelformat = V4L2_PIX_FMT_SBGGR8;
-		} else if (fmtd.index == 1) {
-			strcpy(fmtd.description, "compressed");
-			fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X;
-			fmtd.flags = V4L2_FMT_FLAG_COMPRESSED;
-		} else
-			return -EINVAL;
+	if (cam->module_param.force_munmap)
+		for (i = 0; i < cam->nbuffers; i++)
+			if (cam->frame[i].vma_use_count) {
+				DBG(3, "VIDIOC_S_CROP failed. "
+				       "Unmap the buffers first.");
+				return -EINVAL;
+			}
 
-		fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		memset(&fmtd.reserved, 0, sizeof(fmtd.reserved));
+	/* Preserve R,G or B origin */
+	rect->left = (s->_rect.left & 1L) ? rect->left | 1L : rect->left & ~1L;
+	rect->top = (s->_rect.top & 1L) ? rect->top | 1L : rect->top & ~1L;
+
+	if (rect->width < 16)
+		rect->width = 16;
+	if (rect->height < 16)
+		rect->height = 16;
+	if (rect->width > bounds->width)
+		rect->width = bounds->width;
+	if (rect->height > bounds->height)
+		rect->height = bounds->height;
+	if (rect->left < bounds->left)
+		rect->left = bounds->left;
+	if (rect->top < bounds->top)
+		rect->top = bounds->top;
+	if (rect->left + rect->width > bounds->left + bounds->width)
+		rect->left = bounds->left+bounds->width - rect->width;
+	if (rect->top + rect->height > bounds->top + bounds->height)
+		rect->top = bounds->top+bounds->height - rect->height;
+
+	rect->width &= ~15L;
+	rect->height &= ~15L;
+
+	if (SN9C102_PRESERVE_IMGSCALE) {
+		/* Calculate the actual scaling factor */
+		u32 a, b;
+		a = rect->width * rect->height;
+		b = pix_format->width * pix_format->height;
+		scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
+	} else
+		scale = 1;
 
-		if (copy_to_user(arg, &fmtd, sizeof(fmtd)))
-			return -EFAULT;
+	if (cam->stream == STREAM_ON)
+		if ((err = sn9c102_stream_interrupt(cam)))
+			return err;
 
-		return 0;
+	if (copy_to_user(arg, &crop, sizeof(crop))) {
+		cam->stream = stream;
+		return -EFAULT;
 	}
 
-	case VIDIOC_G_FMT:
-	{
-		struct v4l2_format format;
-		struct v4l2_pix_format* pfmt = &(cam->sensor->pix_format);
-
-		if (copy_from_user(&format, arg, sizeof(format)))
-			return -EFAULT;
+	if (cam->module_param.force_munmap || cam->io == IO_READ)
+		sn9c102_release_buffers(cam);
 
-		if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-			return -EINVAL;
+	err = sn9c102_set_crop(cam, rect);
+	if (s->set_crop)
+		err += s->set_crop(cam, rect);
+	err += sn9c102_set_scale(cam, scale);
 
-		pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_SN9C10X)
-		                     ? 0 : (pfmt->width * pfmt->priv) / 8;
-		pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
-		pfmt->field = V4L2_FIELD_NONE;
-		memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
+	if (err) { /* atomic, no rollback in ioctl() */
+		cam->state |= DEV_MISCONFIGURED;
+		DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
+		       "use the camera, close and open /dev/video%d again.",
+		    cam->v4ldev->minor);
+		return -EIO;
+	}
 
-		if (copy_to_user(arg, &format, sizeof(format)))
-			return -EFAULT;
+	s->pix_format.width = rect->width/scale;
+	s->pix_format.height = rect->height/scale;
+	memcpy(&(s->_rect), rect, sizeof(*rect));
 
-		return 0;
+	if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
+	    nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {
+		cam->state |= DEV_MISCONFIGURED;
+		DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
+		       "use the camera, close and open /dev/video%d again.",
+		    cam->v4ldev->minor);
+		return -ENOMEM;
 	}
 
-	case VIDIOC_TRY_FMT:
-	case VIDIOC_S_FMT:
-	{
-		struct sn9c102_sensor* s = cam->sensor;
-		struct v4l2_format format;
-		struct v4l2_pix_format* pix;
-		struct v4l2_pix_format* pfmt = &(s->pix_format);
-		struct v4l2_rect* bounds = &(s->cropcap.bounds);
-		struct v4l2_rect rect;
-		u8 scale;
-		const enum sn9c102_stream_state stream = cam->stream;
-		const u32 nbuffers = cam->nbuffers;
-		u32 i;
-		int err = 0;
-
-		if (copy_from_user(&format, arg, sizeof(format)))
-			return -EFAULT;
+	if (cam->io == IO_READ)
+		sn9c102_empty_framequeues(cam);
+	else if (cam->module_param.force_munmap)
+		sn9c102_requeue_outqueue(cam);
 
-		pix = &(format.fmt.pix);
+	cam->stream = stream;
 
-		if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-			return -EINVAL;
-
-		memcpy(&rect, &(s->_rect), sizeof(rect));
+	return 0;
+}
 
-		{ /* calculate the actual scaling factor */
-			u32 a, b;
-			a = rect.width * rect.height;
-			b = pix->width * pix->height;
-			scale = b ? (u8)((a / b) < 4 ? 1 :
-		                        ((a / b) < 16 ? 2 : 4)) : 1;
-		}
-
-		rect.width = scale * pix->width;
-		rect.height = scale * pix->height;
-
-		if (rect.width < 16)
-			rect.width = 16;
-		if (rect.height < 16)
-			rect.height = 16;
-		if (rect.width > bounds->left + bounds->width - rect.left)
-			rect.width = bounds->left + bounds->width - rect.left;
-		if (rect.height > bounds->top + bounds->height - rect.top)
-			rect.height = bounds->top + bounds->height - rect.top;
-
-		rect.width &= ~15L;
-		rect.height &= ~15L;
-
-		{ /* adjust the scaling factor */
-			u32 a, b;
-			a = rect.width * rect.height;
-			b = pix->width * pix->height;
-			scale = b ? (u8)((a / b) < 4 ? 1 :
-		                        ((a / b) < 16 ? 2 : 4)) : 1;
-		}
-
-		pix->width = rect.width / scale;
-		pix->height = rect.height / scale;
-
-		if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X &&
-		    pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
-			pix->pixelformat = pfmt->pixelformat;
-		pix->priv = pfmt->priv; /* bpp */
-		pix->colorspace = pfmt->colorspace;
-		pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
-		                    ? 0 : (pix->width * pix->priv) / 8;
-		pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
-		pix->field = V4L2_FIELD_NONE;
 
-		if (cmd == VIDIOC_TRY_FMT) {
-			if (copy_to_user(arg, &format, sizeof(format)))
-				return -EFAULT;
-			return 0;
-		}
+static int
+sn9c102_vidioc_enum_fmt(struct sn9c102_device* cam, void __user * arg)
+{
+	struct v4l2_fmtdesc fmtd;
 
-		if (cam->module_param.force_munmap)
-			for (i = 0; i < cam->nbuffers; i++)
-				if (cam->frame[i].vma_use_count) {
-					DBG(3, "VIDIOC_S_FMT failed. "
-					       "Unmap the buffers first.")
-					return -EINVAL;
-				}
+	if (copy_from_user(&fmtd, arg, sizeof(fmtd)))
+		return -EFAULT;
 
-		if (cam->stream == STREAM_ON)
-			if ((err = sn9c102_stream_interrupt(cam)))
-				return err;
+	if (fmtd.index == 0) {
+		strcpy(fmtd.description, "bayer rgb");
+		fmtd.pixelformat = V4L2_PIX_FMT_SBGGR8;
+	} else if (fmtd.index == 1) {
+		strcpy(fmtd.description, "compressed");
+		fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X;
+		fmtd.flags = V4L2_FMT_FLAG_COMPRESSED;
+	} else
+		return -EINVAL;
 
-		if (copy_to_user(arg, &format, sizeof(format))) {
-			cam->stream = stream;
-			return -EFAULT;
-		}
+	fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	memset(&fmtd.reserved, 0, sizeof(fmtd.reserved));
 
-		if (cam->module_param.force_munmap  || cam->io == IO_READ)
-			sn9c102_release_buffers(cam);
+	if (copy_to_user(arg, &fmtd, sizeof(fmtd)))
+		return -EFAULT;
 
-		err += sn9c102_set_pix_format(cam, pix);
-		err += sn9c102_set_crop(cam, &rect);
-		if (s->set_pix_format)
-			err += s->set_pix_format(cam, pix);
-		if (s->set_crop)
-			err += s->set_crop(cam, &rect);
-		err += sn9c102_set_scale(cam, scale);
-
-		if (err) { /* atomic, no rollback in ioctl() */
-			cam->state |= DEV_MISCONFIGURED;
-			DBG(1, "VIDIOC_S_FMT failed because of hardware "
-			       "problems. To use the camera, close and open "
-			       "/dev/video%d again.", cam->v4ldev->minor)
-			return -EIO;
-		}
+	return 0;
+}
 
-		memcpy(pfmt, pix, sizeof(*pix));
-		memcpy(&(s->_rect), &rect, sizeof(rect));
 
-		if ((cam->module_param.force_munmap  || cam->io == IO_READ) &&
-		    nbuffers != sn9c102_request_buffers(cam, nbuffers,
-		                                        cam->io)) {
-			cam->state |= DEV_MISCONFIGURED;
-			DBG(1, "VIDIOC_S_FMT failed because of not enough "
-			       "memory. To use the camera, close and open "
-			       "/dev/video%d again.", cam->v4ldev->minor)
-			return -ENOMEM;
-		}
+static int
+sn9c102_vidioc_g_fmt(struct sn9c102_device* cam, void __user * arg)
+{
+	struct v4l2_format format;
+	struct v4l2_pix_format* pfmt = &(cam->sensor->pix_format);
 
-		cam->stream = stream;
+	if (copy_from_user(&format, arg, sizeof(format)))
+		return -EFAULT;
 
-		return 0;
-	}
+	if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
 
-	case VIDIOC_G_JPEGCOMP:
-	{
-		if (copy_to_user(arg, &cam->compression,
-		                 sizeof(cam->compression)))
-			return -EFAULT;
+	pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_SN9C10X)
+	                     ? 0 : (pfmt->width * pfmt->priv) / 8;
+	pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
+	pfmt->field = V4L2_FIELD_NONE;
+	memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
 
-		return 0;
-	}
+	if (copy_to_user(arg, &format, sizeof(format)))
+		return -EFAULT;
 
-	case VIDIOC_S_JPEGCOMP:
-	{
-		struct v4l2_jpegcompression jc;
-		const enum sn9c102_stream_state stream = cam->stream;
-		int err = 0;
+	return 0;
+}
 
-		if (copy_from_user(&jc, arg, sizeof(jc)))
-			return -EFAULT;
 
-		if (jc.quality != 0 && jc.quality != 1)
-			return -EINVAL;
+static int
+sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd,
+                         void __user * arg)
+{
+	struct sn9c102_sensor* s = cam->sensor;
+	struct v4l2_format format;
+	struct v4l2_pix_format* pix;
+	struct v4l2_pix_format* pfmt = &(s->pix_format);
+	struct v4l2_rect* bounds = &(s->cropcap.bounds);
+	struct v4l2_rect rect;
+	u8 scale;
+	const enum sn9c102_stream_state stream = cam->stream;
+	const u32 nbuffers = cam->nbuffers;
+	u32 i;
+	int err = 0;
 
-		if (cam->stream == STREAM_ON)
-			if ((err = sn9c102_stream_interrupt(cam)))
-				return err;
-
-		err += sn9c102_set_compression(cam, &jc);
-		if (err) { /* atomic, no rollback in ioctl() */
-			cam->state |= DEV_MISCONFIGURED;
-			DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
-			       "problems. To use the camera, close and open "
-			       "/dev/video%d again.", cam->v4ldev->minor)
-			return -EIO;
-		}
+	if (copy_from_user(&format, arg, sizeof(format)))
+		return -EFAULT;
 
-		cam->compression.quality = jc.quality;
+	pix = &(format.fmt.pix);
 
-		cam->stream = stream;
+	if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
 
-		return 0;
-	}
+	memcpy(&rect, &(s->_rect), sizeof(rect));
 
-	case VIDIOC_REQBUFS:
-	{
-		struct v4l2_requestbuffers rb;
-		u32 i;
-		int err;
+	{ /* calculate the actual scaling factor */
+		u32 a, b;
+		a = rect.width * rect.height;
+		b = pix->width * pix->height;
+		scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
+	}
+
+	rect.width = scale * pix->width;
+	rect.height = scale * pix->height;
+
+	if (rect.width < 16)
+		rect.width = 16;
+	if (rect.height < 16)
+		rect.height = 16;
+	if (rect.width > bounds->left + bounds->width - rect.left)
+		rect.width = bounds->left + bounds->width - rect.left;
+	if (rect.height > bounds->top + bounds->height - rect.top)
+		rect.height = bounds->top + bounds->height - rect.top;
+
+	rect.width &= ~15L;
+	rect.height &= ~15L;
+
+	{ /* adjust the scaling factor */
+		u32 a, b;
+		a = rect.width * rect.height;
+		b = pix->width * pix->height;
+		scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
+	}
+
+	pix->width = rect.width / scale;
+	pix->height = rect.height / scale;
+
+	if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X &&
+	    pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
+		pix->pixelformat = pfmt->pixelformat;
+	pix->priv = pfmt->priv; /* bpp */
+	pix->colorspace = pfmt->colorspace;
+	pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
+	                    ? 0 : (pix->width * pix->priv) / 8;
+	pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
+	pix->field = V4L2_FIELD_NONE;
 
-		if (copy_from_user(&rb, arg, sizeof(rb)))
+	if (cmd == VIDIOC_TRY_FMT) {
+		if (copy_to_user(arg, &format, sizeof(format)))
 			return -EFAULT;
+		return 0;
+	}
 
-		if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
-		    rb.memory != V4L2_MEMORY_MMAP)
-			return -EINVAL;
-
-		if (cam->io == IO_READ) {
-			DBG(3, "Close and open the device again to choose "
-			       "the mmap I/O method")
-			return -EINVAL;
-		}
-
+	if (cam->module_param.force_munmap)
 		for (i = 0; i < cam->nbuffers; i++)
 			if (cam->frame[i].vma_use_count) {
-				DBG(3, "VIDIOC_REQBUFS failed. "
-				       "Previous buffers are still mapped.")
+				DBG(3, "VIDIOC_S_FMT failed. Unmap the "
+				       "buffers first.");
 				return -EINVAL;
 			}
 
-		if (cam->stream == STREAM_ON)
-			if ((err = sn9c102_stream_interrupt(cam)))
-				return err;
+	if (cam->stream == STREAM_ON)
+		if ((err = sn9c102_stream_interrupt(cam)))
+			return err;
 
-		sn9c102_empty_framequeues(cam);
+	if (copy_to_user(arg, &format, sizeof(format))) {
+		cam->stream = stream;
+		return -EFAULT;
+	}
 
+	if (cam->module_param.force_munmap  || cam->io == IO_READ)
 		sn9c102_release_buffers(cam);
-		if (rb.count)
-			rb.count = sn9c102_request_buffers(cam, rb.count,
-			                                   IO_MMAP);
-
-		if (copy_to_user(arg, &rb, sizeof(rb))) {
-			sn9c102_release_buffers(cam);
-			cam->io = IO_NONE;
-			return -EFAULT;
-		}
 
-		cam->io = rb.count ? IO_MMAP : IO_NONE;
+	err += sn9c102_set_pix_format(cam, pix);
+	err += sn9c102_set_crop(cam, &rect);
+	if (s->set_pix_format)
+		err += s->set_pix_format(cam, pix);
+	if (s->set_crop)
+		err += s->set_crop(cam, &rect);
+	err += sn9c102_set_scale(cam, scale);
 
-		return 0;
+	if (err) { /* atomic, no rollback in ioctl() */
+		cam->state |= DEV_MISCONFIGURED;
+		DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
+		       "use the camera, close and open /dev/video%d again.",
+		    cam->v4ldev->minor);
+		return -EIO;
 	}
 
-	case VIDIOC_QUERYBUF:
-	{
-		struct v4l2_buffer b;
+	memcpy(pfmt, pix, sizeof(*pix));
+	memcpy(&(s->_rect), &rect, sizeof(rect));
 
-		if (copy_from_user(&b, arg, sizeof(b)))
-			return -EFAULT;
+	if ((cam->module_param.force_munmap  || cam->io == IO_READ) &&
+	    nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {
+		cam->state |= DEV_MISCONFIGURED;
+		DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
+		       "use the camera, close and open /dev/video%d again.",
+		    cam->v4ldev->minor);
+		return -ENOMEM;
+	}
 
-		if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
-		    b.index >= cam->nbuffers || cam->io != IO_MMAP)
-			return -EINVAL;
+	if (cam->io == IO_READ)
+		sn9c102_empty_framequeues(cam);
+	else if (cam->module_param.force_munmap)
+		sn9c102_requeue_outqueue(cam);
 
-		memcpy(&b, &cam->frame[b.index].buf, sizeof(b));
+	cam->stream = stream;
 
-		if (cam->frame[b.index].vma_use_count)
-			b.flags |= V4L2_BUF_FLAG_MAPPED;
+	return 0;
+}
 
-		if (cam->frame[b.index].state == F_DONE)
-			b.flags |= V4L2_BUF_FLAG_DONE;
-		else if (cam->frame[b.index].state != F_UNUSED)
-			b.flags |= V4L2_BUF_FLAG_QUEUED;
 
-		if (copy_to_user(arg, &b, sizeof(b)))
-			return -EFAULT;
+static int
+sn9c102_vidioc_g_jpegcomp(struct sn9c102_device* cam, void __user * arg)
+{
+	if (copy_to_user(arg, &cam->compression,
+	                 sizeof(cam->compression)))
+		return -EFAULT;
 
-		return 0;
+	return 0;
+}
+
+
+static int
+sn9c102_vidioc_s_jpegcomp(struct sn9c102_device* cam, void __user * arg)
+{
+	struct v4l2_jpegcompression jc;
+	const enum sn9c102_stream_state stream = cam->stream;
+	int err = 0;
+
+	if (copy_from_user(&jc, arg, sizeof(jc)))
+		return -EFAULT;
+
+	if (jc.quality != 0 && jc.quality != 1)
+		return -EINVAL;
+
+	if (cam->stream == STREAM_ON)
+		if ((err = sn9c102_stream_interrupt(cam)))
+			return err;
+
+	err += sn9c102_set_compression(cam, &jc);
+	if (err) { /* atomic, no rollback in ioctl() */
+		cam->state |= DEV_MISCONFIGURED;
+		DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
+		       "problems. To use the camera, close and open "
+		       "/dev/video%d again.", cam->v4ldev->minor);
+		return -EIO;
 	}
 
-	case VIDIOC_QBUF:
-	{
-		struct v4l2_buffer b;
-		unsigned long lock_flags;
+	cam->compression.quality = jc.quality;
 
-		if (copy_from_user(&b, arg, sizeof(b)))
-			return -EFAULT;
+	cam->stream = stream;
 
-		if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
-		    b.index >= cam->nbuffers || cam->io != IO_MMAP)
-			return -EINVAL;
+	return 0;
+}
+
+
+static int
+sn9c102_vidioc_reqbufs(struct sn9c102_device* cam, void __user * arg)
+{
+	struct v4l2_requestbuffers rb;
+	u32 i;
+	int err;
+
+	if (copy_from_user(&rb, arg, sizeof(rb)))
+		return -EFAULT;
+
+	if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+	    rb.memory != V4L2_MEMORY_MMAP)
+		return -EINVAL;
 
-		if (cam->frame[b.index].state != F_UNUSED)
+	if (cam->io == IO_READ) {
+		DBG(3, "Close and open the device again to choose the mmap "
+		       "I/O method");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < cam->nbuffers; i++)
+		if (cam->frame[i].vma_use_count) {
+			DBG(3, "VIDIOC_REQBUFS failed. Previous buffers are "
+			       "still mapped.");
 			return -EINVAL;
+		}
 
-		cam->frame[b.index].state = F_QUEUED;
+	if (cam->stream == STREAM_ON)
+		if ((err = sn9c102_stream_interrupt(cam)))
+			return err;
 
-		spin_lock_irqsave(&cam->queue_lock, lock_flags);
-		list_add_tail(&cam->frame[b.index].frame, &cam->inqueue);
-		spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
+	sn9c102_empty_framequeues(cam);
 
-		PDBGG("Frame #%lu queued", (unsigned long)b.index)
+	sn9c102_release_buffers(cam);
+	if (rb.count)
+		rb.count = sn9c102_request_buffers(cam, rb.count, IO_MMAP);
 
-		return 0;
+	if (copy_to_user(arg, &rb, sizeof(rb))) {
+		sn9c102_release_buffers(cam);
+		cam->io = IO_NONE;
+		return -EFAULT;
 	}
 
-	case VIDIOC_DQBUF:
-	{
-		struct v4l2_buffer b;
-		struct sn9c102_frame_t *f;
-		unsigned long lock_flags;
-		int err = 0;
+	cam->io = rb.count ? IO_MMAP : IO_NONE;
 
-		if (copy_from_user(&b, arg, sizeof(b)))
-			return -EFAULT;
+	return 0;
+}
 
-		if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io!= IO_MMAP)
-			return -EINVAL;
 
-		if (list_empty(&cam->outqueue)) {
-			if (cam->stream == STREAM_OFF)
-				return -EINVAL;
-			if (filp->f_flags & O_NONBLOCK)
-				return -EAGAIN;
-			err = wait_event_interruptible
-			      ( cam->wait_frame, 
-			        (!list_empty(&cam->outqueue)) ||
-			        (cam->state & DEV_DISCONNECTED) ||
-			        (cam->state & DEV_MISCONFIGURED) );
-			if (err)
-				return err;
-			if (cam->state & DEV_DISCONNECTED)
-				return -ENODEV;
-			if (cam->state & DEV_MISCONFIGURED)
-				return -EIO;
-		}
+static int
+sn9c102_vidioc_querybuf(struct sn9c102_device* cam, void __user * arg)
+{
+	struct v4l2_buffer b;
 
-		spin_lock_irqsave(&cam->queue_lock, lock_flags);
-		f = list_entry(cam->outqueue.next, struct sn9c102_frame_t,
-		               frame);
-		list_del(cam->outqueue.next);
-		spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
+	if (copy_from_user(&b, arg, sizeof(b)))
+		return -EFAULT;
 
-		f->state = F_UNUSED;
+	if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+	    b.index >= cam->nbuffers || cam->io != IO_MMAP)
+		return -EINVAL;
 
-		memcpy(&b, &f->buf, sizeof(b));
-		if (f->vma_use_count)
-			b.flags |= V4L2_BUF_FLAG_MAPPED;
+	memcpy(&b, &cam->frame[b.index].buf, sizeof(b));
 
-		if (copy_to_user(arg, &b, sizeof(b)))
-			return -EFAULT;
+	if (cam->frame[b.index].vma_use_count)
+		b.flags |= V4L2_BUF_FLAG_MAPPED;
 
-		PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index)
+	if (cam->frame[b.index].state == F_DONE)
+		b.flags |= V4L2_BUF_FLAG_DONE;
+	else if (cam->frame[b.index].state != F_UNUSED)
+		b.flags |= V4L2_BUF_FLAG_QUEUED;
 
-		return 0;
-	}
+	if (copy_to_user(arg, &b, sizeof(b)))
+		return -EFAULT;
 
-	case VIDIOC_STREAMON:
-	{
-		int type;
+	return 0;
+}
 
-		if (copy_from_user(&type, arg, sizeof(type)))
-			return -EFAULT;
 
-		if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
-			return -EINVAL;
+static int
+sn9c102_vidioc_qbuf(struct sn9c102_device* cam, void __user * arg)
+{
+	struct v4l2_buffer b;
+	unsigned long lock_flags;
 
-		if (list_empty(&cam->inqueue))
-			return -EINVAL;
+	if (copy_from_user(&b, arg, sizeof(b)))
+		return -EFAULT;
 
-		cam->stream = STREAM_ON;
+	if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+	    b.index >= cam->nbuffers || cam->io != IO_MMAP)
+		return -EINVAL;
 
-		DBG(3, "Stream on")
+	if (cam->frame[b.index].state != F_UNUSED)
+		return -EINVAL;
 
-		return 0;
-	}
+	cam->frame[b.index].state = F_QUEUED;
 
-	case VIDIOC_STREAMOFF:
-	{
-		int type, err;
+	spin_lock_irqsave(&cam->queue_lock, lock_flags);
+	list_add_tail(&cam->frame[b.index].frame, &cam->inqueue);
+	spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
 
-		if (copy_from_user(&type, arg, sizeof(type)))
-			return -EFAULT;
+	PDBGG("Frame #%lu queued", (unsigned long)b.index);
 
-		if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
-			return -EINVAL;
+	return 0;
+}
 
-		if (cam->stream == STREAM_ON)
-			if ((err = sn9c102_stream_interrupt(cam)))
-				return err;
 
-		sn9c102_empty_framequeues(cam);
+static int
+sn9c102_vidioc_dqbuf(struct sn9c102_device* cam, struct file* filp,
+                     void __user * arg)
+{
+	struct v4l2_buffer b;
+	struct sn9c102_frame_t *f;
+	unsigned long lock_flags;
+	int err = 0;
 
-		DBG(3, "Stream off")
+	if (copy_from_user(&b, arg, sizeof(b)))
+		return -EFAULT;
 
-		return 0;
+	if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
+		return -EINVAL;
+
+	if (list_empty(&cam->outqueue)) {
+		if (cam->stream == STREAM_OFF)
+			return -EINVAL;
+		if (filp->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+		err = wait_event_interruptible
+		      ( cam->wait_frame,
+		        (!list_empty(&cam->outqueue)) ||
+		        (cam->state & DEV_DISCONNECTED) ||
+		        (cam->state & DEV_MISCONFIGURED) );
+		if (err)
+			return err;
+		if (cam->state & DEV_DISCONNECTED)
+			return -ENODEV;
+		if (cam->state & DEV_MISCONFIGURED)
+			return -EIO;
 	}
 
-	case VIDIOC_G_PARM:
-	{
-		struct v4l2_streamparm sp;
+	spin_lock_irqsave(&cam->queue_lock, lock_flags);
+	f = list_entry(cam->outqueue.next, struct sn9c102_frame_t, frame);
+	list_del(cam->outqueue.next);
+	spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
 
-		if (copy_from_user(&sp, arg, sizeof(sp)))
-			return -EFAULT;
+	f->state = F_UNUSED;
 
-		if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-			return -EINVAL;
+	memcpy(&b, &f->buf, sizeof(b));
+	if (f->vma_use_count)
+		b.flags |= V4L2_BUF_FLAG_MAPPED;
+
+	if (copy_to_user(arg, &b, sizeof(b)))
+		return -EFAULT;
+
+	PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index);
+
+	return 0;
+}
+
+
+static int
+sn9c102_vidioc_streamon(struct sn9c102_device* cam, void __user * arg)
+{
+	int type;
+
+	if (copy_from_user(&type, arg, sizeof(type)))
+		return -EFAULT;
+
+	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
+		return -EINVAL;
+
+	if (list_empty(&cam->inqueue))
+		return -EINVAL;
+
+	cam->stream = STREAM_ON;
+
+	DBG(3, "Stream on");
+
+	return 0;
+}
+
+
+static int
+sn9c102_vidioc_streamoff(struct sn9c102_device* cam, void __user * arg)
+{
+	int type, err;
+
+	if (copy_from_user(&type, arg, sizeof(type)))
+		return -EFAULT;
+
+	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
+		return -EINVAL;
+
+	if (cam->stream == STREAM_ON)
+		if ((err = sn9c102_stream_interrupt(cam)))
+			return err;
+
+	sn9c102_empty_framequeues(cam);
+
+	DBG(3, "Stream off");
+
+	return 0;
+}
+
+
+static int
+sn9c102_vidioc_g_parm(struct sn9c102_device* cam, void __user * arg)
+{
+	struct v4l2_streamparm sp;
+
+	if (copy_from_user(&sp, arg, sizeof(sp)))
+		return -EFAULT;
+
+	if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	sp.parm.capture.extendedmode = 0;
+	sp.parm.capture.readbuffers = cam->nreadbuffers;
+
+	if (copy_to_user(arg, &sp, sizeof(sp)))
+		return -EFAULT;
+
+	return 0;
+}
+
+
+static int
+sn9c102_vidioc_s_parm(struct sn9c102_device* cam, void __user * arg)
+{
+	struct v4l2_streamparm sp;
+
+	if (copy_from_user(&sp, arg, sizeof(sp)))
+		return -EFAULT;
+
+	if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
 
-		sp.parm.capture.extendedmode = 0;
+	sp.parm.capture.extendedmode = 0;
+
+	if (sp.parm.capture.readbuffers == 0)
 		sp.parm.capture.readbuffers = cam->nreadbuffers;
 
-		if (copy_to_user(arg, &sp, sizeof(sp)))
-			return -EFAULT;
+	if (sp.parm.capture.readbuffers > SN9C102_MAX_FRAMES)
+		sp.parm.capture.readbuffers = SN9C102_MAX_FRAMES;
 
-		return 0;
-	}
+	if (copy_to_user(arg, &sp, sizeof(sp)))
+		return -EFAULT;
 
-	case VIDIOC_S_PARM_OLD:
-	case VIDIOC_S_PARM:
-	{
-		struct v4l2_streamparm sp;
+	cam->nreadbuffers = sp.parm.capture.readbuffers;
 
-		if (copy_from_user(&sp, arg, sizeof(sp)))
-			return -EFAULT;
+	return 0;
+}
 
-		if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-			return -EINVAL;
 
-		sp.parm.capture.extendedmode = 0;
+static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp,
+                              unsigned int cmd, void __user * arg)
+{
+	struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
+
+	switch (cmd) {
 
-		if (sp.parm.capture.readbuffers == 0)
-			sp.parm.capture.readbuffers = cam->nreadbuffers;
+	case VIDIOC_QUERYCAP:
+		return sn9c102_vidioc_querycap(cam, arg);
 
-		if (sp.parm.capture.readbuffers > SN9C102_MAX_FRAMES)
-			sp.parm.capture.readbuffers = SN9C102_MAX_FRAMES;
+	case VIDIOC_ENUMINPUT:
+		return sn9c102_vidioc_enuminput(cam, arg);
 
-		if (copy_to_user(arg, &sp, sizeof(sp)))
-			return -EFAULT;
+	case VIDIOC_G_INPUT:
+	case VIDIOC_S_INPUT:
+		return sn9c102_vidioc_gs_input(cam, arg);
 
-		cam->nreadbuffers = sp.parm.capture.readbuffers;
+	case VIDIOC_QUERYCTRL:
+		return sn9c102_vidioc_query_ctrl(cam, arg);
 
-		return 0;
-	}
+	case VIDIOC_G_CTRL:
+		return sn9c102_vidioc_g_ctrl(cam, arg);
+
+	case VIDIOC_S_CTRL_OLD:
+	case VIDIOC_S_CTRL:
+		return sn9c102_vidioc_s_ctrl(cam, arg);
+
+	case VIDIOC_CROPCAP_OLD:
+	case VIDIOC_CROPCAP:
+		return sn9c102_vidioc_cropcap(cam, arg);
+
+	case VIDIOC_G_CROP:
+		return sn9c102_vidioc_g_crop(cam, arg);
+
+	case VIDIOC_S_CROP:
+		return sn9c102_vidioc_s_crop(cam, arg);
+
+	case VIDIOC_ENUM_FMT:
+		return sn9c102_vidioc_enum_fmt(cam, arg);
+
+	case VIDIOC_G_FMT:
+		return sn9c102_vidioc_g_fmt(cam, arg);
+
+	case VIDIOC_TRY_FMT:
+	case VIDIOC_S_FMT:
+		return sn9c102_vidioc_try_s_fmt(cam, cmd, arg);
+
+	case VIDIOC_G_JPEGCOMP:
+		return sn9c102_vidioc_g_jpegcomp(cam, arg);
+
+	case VIDIOC_S_JPEGCOMP:
+		return sn9c102_vidioc_s_jpegcomp(cam, arg);
+
+	case VIDIOC_REQBUFS:
+		return sn9c102_vidioc_reqbufs(cam, arg);
+
+	case VIDIOC_QUERYBUF:
+		return sn9c102_vidioc_querybuf(cam, arg);
+
+	case VIDIOC_QBUF:
+		return sn9c102_vidioc_qbuf(cam, arg);
+
+	case VIDIOC_DQBUF:
+		return sn9c102_vidioc_dqbuf(cam, filp, arg);
+
+	case VIDIOC_STREAMON:
+		return sn9c102_vidioc_streamon(cam, arg);
+
+	case VIDIOC_STREAMOFF:
+		return sn9c102_vidioc_streamoff(cam, arg);
+
+	case VIDIOC_G_PARM:
+		return sn9c102_vidioc_g_parm(cam, arg);
+
+	case VIDIOC_S_PARM_OLD:
+	case VIDIOC_S_PARM:
+		return sn9c102_vidioc_s_parm(cam, arg);
 
 	case VIDIOC_G_STD:
 	case VIDIOC_S_STD:
@@ -2499,17 +2659,20 @@ static int sn9c102_ioctl(struct inode* i
 		return -ERESTARTSYS;
 
 	if (cam->state & DEV_DISCONNECTED) {
-		DBG(1, "Device not present")
+		DBG(1, "Device not present");
 		up(&cam->fileop_sem);
 		return -ENODEV;
 	}
 
 	if (cam->state & DEV_MISCONFIGURED) {
-		DBG(1, "The camera is misconfigured. Close and open it again.")
+		DBG(1, "The camera is misconfigured. Close and open it "
+		       "again.");
 		up(&cam->fileop_sem);
 		return -EIO;
 	}
 
+	V4LDBG(3, "sn9c102", cmd);
+
 	err = sn9c102_ioctl_v4l2(inode, filp, cmd, (void __user *)arg);
 
 	up(&cam->fileop_sem);
@@ -2517,9 +2680,10 @@ static int sn9c102_ioctl(struct inode* i
 	return err;
 }
 
+/*****************************************************************************/
 
 static struct file_operations sn9c102_fops = {
-	.owner =   THIS_MODULE,
+	.owner = THIS_MODULE,
 	.open =    sn9c102_open,
 	.release = sn9c102_release,
 	.ioctl =   sn9c102_ioctl,
@@ -2538,36 +2702,22 @@ sn9c102_usb_probe(struct usb_interface* 
 	struct usb_device *udev = interface_to_usbdev(intf);
 	struct sn9c102_device* cam;
 	static unsigned int dev_nr = 0;
-	unsigned int i, n;
+	unsigned int i;
 	int err = 0, r;
 
-	n = ARRAY_SIZE(sn9c102_id_table);
-	for (i = 0; i < n-1; i++)
-		if (le16_to_cpu(udev->descriptor.idVendor) == 
-		    sn9c102_id_table[i].idVendor &&
-		    le16_to_cpu(udev->descriptor.idProduct) ==
-		    sn9c102_id_table[i].idProduct)
-			break;
-	if (i == n-1)
-		return -ENODEV;
-
-	if (!(cam = kmalloc(sizeof(struct sn9c102_device), GFP_KERNEL)))
+	if (!(cam = kzalloc(sizeof(struct sn9c102_device), GFP_KERNEL)))
 		return -ENOMEM;
-	memset(cam, 0, sizeof(*cam));
 
 	cam->usbdev = udev;
 
-	memcpy(&cam->dev, &udev->dev, sizeof(struct device));
-
-	if (!(cam->control_buffer = kmalloc(8, GFP_KERNEL))) {
-		DBG(1, "kmalloc() failed")
+	if (!(cam->control_buffer = kzalloc(8, GFP_KERNEL))) {
+		DBG(1, "kmalloc() failed");
 		err = -ENOMEM;
 		goto fail;
 	}
-	memset(cam->control_buffer, 0, 8);
 
 	if (!(cam->v4ldev = video_device_alloc())) {
-		DBG(1, "video_device_alloc() failed")
+		DBG(1, "video_device_alloc() failed");
 		err = -ENOMEM;
 		goto fail;
 	}
@@ -2577,25 +2727,22 @@ sn9c102_usb_probe(struct usb_interface* 
 	r = sn9c102_read_reg(cam, 0x00);
 	if (r < 0 || r != 0x10) {
 		DBG(1, "Sorry, this is not a SN9C10x based camera "
-		       "(vid/pid 0x%04X/0x%04X)",
-		    sn9c102_id_table[i].idVendor,sn9c102_id_table[i].idProduct)
+		       "(vid/pid 0x%04X/0x%04X)", id->idVendor, id->idProduct);
 		err = -ENODEV;
 		goto fail;
 	}
 
-	cam->bridge = (sn9c102_id_table[i].idProduct & 0xffc0) == 0x6080 ?
+	cam->bridge = (id->idProduct & 0xffc0) == 0x6080 ?
 	              BRIDGE_SN9C103 : BRIDGE_SN9C102;
 	switch (cam->bridge) {
 	case BRIDGE_SN9C101:
 	case BRIDGE_SN9C102:
 		DBG(2, "SN9C10[12] PC Camera Controller detected "
-		       "(vid/pid 0x%04X/0x%04X)", sn9c102_id_table[i].idVendor,
-		    sn9c102_id_table[i].idProduct)
+		       "(vid/pid 0x%04X/0x%04X)", id->idVendor, id->idProduct);
 		break;
 	case BRIDGE_SN9C103:
 		DBG(2, "SN9C103 PC Camera Controller detected "
-		       "(vid/pid 0x%04X/0x%04X)", sn9c102_id_table[i].idVendor,
-		    sn9c102_id_table[i].idProduct)
+		       "(vid/pid 0x%04X/0x%04X)", id->idVendor, id->idProduct);
 		break;
 	}
 
@@ -2606,24 +2753,24 @@ sn9c102_usb_probe(struct usb_interface* 
 	}
 
 	if (!err && cam->sensor) {
-		DBG(2, "%s image sensor detected", cam->sensor->name)
+		DBG(2, "%s image sensor detected", cam->sensor->name);
 		DBG(3, "Support for %s maintained by %s",
-		    cam->sensor->name, cam->sensor->maintainer)
+		    cam->sensor->name, cam->sensor->maintainer);
 	} else {
-		DBG(1, "No supported image sensor detected")
+		DBG(1, "No supported image sensor detected");
 		err = -ENODEV;
 		goto fail;
 	}
 
 	if (sn9c102_init(cam)) {
-		DBG(1, "Initialization failed. I will retry on open().")
+		DBG(1, "Initialization failed. I will retry on open().");
 		cam->state |= DEV_MISCONFIGURED;
 	}
 
 	strcpy(cam->v4ldev->name, "SN9C10x PC Camera");
 	cam->v4ldev->owner = THIS_MODULE;
 	cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
-	cam->v4ldev->hardware = VID_HARDWARE_SN9C102;
+	cam->v4ldev->hardware = 0;
 	cam->v4ldev->fops = &sn9c102_fops;
 	cam->v4ldev->minor = video_nr[dev_nr];
 	cam->v4ldev->release = video_device_release;
@@ -2634,23 +2781,25 @@ sn9c102_usb_probe(struct usb_interface* 
 	err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
 	                            video_nr[dev_nr]);
 	if (err) {
-		DBG(1, "V4L2 device registration failed")
+		DBG(1, "V4L2 device registration failed");
 		if (err == -ENFILE && video_nr[dev_nr] == -1)
-			DBG(1, "Free /dev/videoX node not found")
+			DBG(1, "Free /dev/videoX node not found");
 		video_nr[dev_nr] = -1;
 		dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
 		up(&cam->dev_sem);
 		goto fail;
 	}
 
-	DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor)
+	DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor);
 
 	cam->module_param.force_munmap = force_munmap[dev_nr];
 
 	dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
 
+#ifdef CONFIG_VIDEO_ADV_DEBUG
 	sn9c102_create_sysfs(cam);
-	DBG(2, "Optional device control through 'sysfs' interface ready")
+	DBG(2, "Optional device control through 'sysfs' interface ready");
+#endif
 
 	usb_set_intfdata(intf, cam);
 
@@ -2680,14 +2829,14 @@ static void sn9c102_usb_disconnect(struc
 
 	down(&cam->dev_sem); 
 
-	DBG(2, "Disconnecting %s...", cam->v4ldev->name)
+	DBG(2, "Disconnecting %s...", cam->v4ldev->name);
 
 	wake_up_interruptible_all(&cam->open);
 
 	if (cam->users) {
 		DBG(2, "Device /dev/video%d is open! Deregistration and "
 		       "memory deallocation are deferred on close.",
-		    cam->v4ldev->minor)
+		    cam->v4ldev->minor);
 		cam->state |= DEV_MISCONFIGURED;
 		sn9c102_stop_transfer(cam);
 		cam->state |= DEV_DISCONNECTED;
@@ -2720,11 +2869,11 @@ static int __init sn9c102_module_init(vo
 {
 	int err = 0;
 
-	KDBG(2, SN9C102_MODULE_NAME " v" SN9C102_MODULE_VERSION)
-	KDBG(3, SN9C102_MODULE_AUTHOR)
+	KDBG(2, SN9C102_MODULE_NAME " v" SN9C102_MODULE_VERSION);
+	KDBG(3, SN9C102_MODULE_AUTHOR);
 
 	if ((err = usb_register(&sn9c102_usb_driver)))
-		KDBG(1, "usb_register() failed")
+		KDBG(1, "usb_register() failed");
 
 	return err;
 }
diff --git a/drivers/usb/media/sn9c102_hv7131d.c b/drivers/usb/media/sn9c102_hv7131d.c
index 18070d5..46c12ec 100644
--- a/drivers/usb/media/sn9c102_hv7131d.c
+++ b/drivers/usb/media/sn9c102_hv7131d.c
@@ -2,7 +2,7 @@
  * Plug-in for HV7131D image sensor connected to the SN9C10x PC Camera     *
  * Controllers                                                             *
  *                                                                         *
- * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it>  *
+ * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it>  *
  *                                                                         *
  * This program is free software; you can redistribute it and/or modify    *
  * it under the terms of the GNU General Public License as published by    *
diff --git a/drivers/usb/media/sn9c102_mi0343.c b/drivers/usb/media/sn9c102_mi0343.c
index 86676ab..d9aa7a6 100644
--- a/drivers/usb/media/sn9c102_mi0343.c
+++ b/drivers/usb/media/sn9c102_mi0343.c
@@ -2,7 +2,7 @@
  * Plug-in for MI-0343 image sensor connected to the SN9C10x PC Camera     *
  * Controllers                                                             *
  *                                                                         *
- * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it>  *
+ * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it>  *
  *                                                                         *
  * This program is free software; you can redistribute it and/or modify    *
  * it under the terms of the GNU General Public License as published by    *
diff --git a/drivers/usb/media/sn9c102_ov7630.c b/drivers/usb/media/sn9c102_ov7630.c
index d27c5ae..4a36519 100644
--- a/drivers/usb/media/sn9c102_ov7630.c
+++ b/drivers/usb/media/sn9c102_ov7630.c
@@ -2,7 +2,7 @@
  * Plug-in for OV7630 image sensor connected to the SN9C10x PC Camera      *
  * Controllers                                                             *
  *                                                                         *
- * Copyright (C) 2005 by Luca Risolia <luca.risolia@studio.unibo.it>       *
+ * Copyright (C) 2005-2006 by Luca Risolia <luca.risolia@studio.unibo.it>  *
  *                                                                         *
  * This program is free software; you can redistribute it and/or modify    *
  * it under the terms of the GNU General Public License as published by    *
@@ -375,8 +375,10 @@ int sn9c102_probe_ov7630(struct sn9c102_
 
 	sn9c102_attach_sensor(cam, &ov7630);
 
-	if (le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x608f &&
-	    le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x602c)
+	if (le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x602c &&
+	    le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x602d &&
+	    le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x608f &&
+	    le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x60b0)
 		return -ENODEV;
 
 	err += sn9c102_write_reg(cam, 0x01, 0x01);
diff --git a/drivers/usb/media/sn9c102_pas106b.c b/drivers/usb/media/sn9c102_pas106b.c
index 48e3ec3..b1dee78 100644
--- a/drivers/usb/media/sn9c102_pas106b.c
+++ b/drivers/usb/media/sn9c102_pas106b.c
@@ -2,7 +2,7 @@
  * Plug-in for PAS106B image sensor connected to the SN9C10x PC Camera     *
  * Controllers                                                             *
  *                                                                         *
- * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it>  *
+ * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it>  *
  *                                                                         *
  * This program is free software; you can redistribute it and/or modify    *
  * it under the terms of the GNU General Public License as published by    *
diff --git a/drivers/usb/media/sn9c102_sensor.h b/drivers/usb/media/sn9c102_sensor.h
index a45166c..7d953b2 100644
--- a/drivers/usb/media/sn9c102_sensor.h
+++ b/drivers/usb/media/sn9c102_sensor.h
@@ -1,7 +1,7 @@
 /***************************************************************************
  * API for image sensors connected to the SN9C10x PC Camera Controllers    *
  *                                                                         *
- * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it>  *
+ * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it>  *
  *                                                                         *
  * This program is free software; you can redistribute it and/or modify    *
  * it under the terms of the GNU General Public License as published by    *
@@ -92,7 +92,18 @@ extern void 
 sn9c102_attach_sensor(struct sn9c102_device* cam,
                       struct sn9c102_sensor* sensor);
 
-/* Each SN9C10X camera has proper PID/VID identifiers. Add them here in case.*/
+/*
+   Each SN9C10x camera has proper PID/VID identifiers.
+   SN9C103 supports multiple interfaces, but we only handle the video class
+   interface.
+*/
+#define SN9C102_USB_DEVICE(vend, prod, intclass)                              \
+	.match_flags = USB_DEVICE_ID_MATCH_DEVICE |                           \
+	               USB_DEVICE_ID_MATCH_INT_CLASS,                         \
+	.idVendor = (vend),                                                   \
+	.idProduct = (prod),                                                  \
+	.bInterfaceClass = (intclass)
+
 #define SN9C102_ID_TABLE                                                      \
 static const struct usb_device_id sn9c102_id_table[] = {                      \
 	{ USB_DEVICE(0x0c45, 0x6001), }, /* TAS5110C1B */                     \
@@ -107,33 +118,34 @@ static const struct usb_device_id sn9c10
 	{ USB_DEVICE(0x0c45, 0x602b), }, /* MI-0343 */                        \
 	{ USB_DEVICE(0x0c45, 0x602c), }, /* OV7630 */                         \
 	{ USB_DEVICE(0x0c45, 0x602d), },                                      \
+	{ USB_DEVICE(0x0c45, 0x602e), }, /* OV7630 */                         \
 	{ USB_DEVICE(0x0c45, 0x6030), }, /* MI03x */                          \
-	{ USB_DEVICE(0x0c45, 0x6080), },                                      \
-	{ USB_DEVICE(0x0c45, 0x6082), }, /* MI0343 and MI0360 */              \
-	{ USB_DEVICE(0x0c45, 0x6083), }, /* HV7131[D|E1] */                   \
-	{ USB_DEVICE(0x0c45, 0x6088), },                                      \
-	{ USB_DEVICE(0x0c45, 0x608a), },                                      \
-	{ USB_DEVICE(0x0c45, 0x608b), },                                      \
-	{ USB_DEVICE(0x0c45, 0x608c), }, /* HV7131x */                        \
-	{ USB_DEVICE(0x0c45, 0x608e), }, /* CIS-VF10 */                       \
-	{ USB_DEVICE(0x0c45, 0x608f), }, /* OV7630 */                         \
-	{ USB_DEVICE(0x0c45, 0x60a0), },                                      \
-	{ USB_DEVICE(0x0c45, 0x60a2), },                                      \
-	{ USB_DEVICE(0x0c45, 0x60a3), },                                      \
-	{ USB_DEVICE(0x0c45, 0x60a8), }, /* PAS106B */                        \
-	{ USB_DEVICE(0x0c45, 0x60aa), }, /* TAS5130D1B */                     \
-	{ USB_DEVICE(0x0c45, 0x60ab), }, /* TAS5110C1B */                     \
-	{ USB_DEVICE(0x0c45, 0x60ac), },                                      \
-	{ USB_DEVICE(0x0c45, 0x60ae), },                                      \
-	{ USB_DEVICE(0x0c45, 0x60af), }, /* PAS202BCB */                      \
-	{ USB_DEVICE(0x0c45, 0x60b0), },                                      \
-	{ USB_DEVICE(0x0c45, 0x60b2), },                                      \
-	{ USB_DEVICE(0x0c45, 0x60b3), },                                      \
-	{ USB_DEVICE(0x0c45, 0x60b8), },                                      \
-	{ USB_DEVICE(0x0c45, 0x60ba), },                                      \
-	{ USB_DEVICE(0x0c45, 0x60bb), },                                      \
-	{ USB_DEVICE(0x0c45, 0x60bc), },                                      \
-	{ USB_DEVICE(0x0c45, 0x60be), },                                      \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x6080, 0xff), },                        \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x6082, 0xff), }, /* MI0343 & MI0360 */  \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x6083, 0xff), }, /* HV7131[D|E1] */     \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x6088, 0xff), },                        \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x608a, 0xff), },                        \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x608b, 0xff), },                        \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x608c, 0xff), }, /* HV7131x */          \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x608e, 0xff), }, /* CIS-VF10 */         \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x608f, 0xff), }, /* OV7630 */           \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x60a0, 0xff), },                        \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x60a2, 0xff), },                        \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x60a3, 0xff), },                        \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x60a8, 0xff), }, /* PAS106B */          \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x60aa, 0xff), }, /* TAS5130D1B */       \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x60ab, 0xff), }, /* TAS5110C1B */       \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x60ac, 0xff), },                        \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x60ae, 0xff), },                        \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x60af, 0xff), }, /* PAS202BCB */        \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x60b0, 0xff), }, /* OV7630 (?) */       \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x60b2, 0xff), },                        \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x60b3, 0xff), },                        \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x60b8, 0xff), },                        \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x60ba, 0xff), },                        \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x60bb, 0xff), },                        \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x60bc, 0xff), },                        \
+	{ SN9C102_USB_DEVICE(0x0c45, 0x60be, 0xff), },                        \
 	{ }                                                                   \
 };
 
@@ -177,16 +189,18 @@ extern int sn9c102_i2c_write(struct sn9c
 extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address);
 
 /* I/O on registers in the bridge. Could be used by the sensor methods too */
+extern int sn9c102_write_regs(struct sn9c102_device*, u8* buff, u16 index);
 extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index);
 extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index);
 
 /*
    NOTE: there are no exported debugging functions. To uniform the output you
    must use the dev_info()/dev_warn()/dev_err() macros defined in device.h,
-   already included here, the argument being the struct device 'dev' of the
-   sensor structure. Do NOT use these macros before the sensor is attached or
-   the kernel will crash! However, you should not need to notify the user about
-   common errors or other messages, since this is done by the master module.
+   already included here, the argument being the struct device '&usbdev->dev'
+   of the sensor structure. Do NOT use these macros before the sensor is
+   attached or the kernel will crash! However, you should not need to notify
+   the user about common errors or other messages, since this is done by the
+   master module.
 */
 
 /*****************************************************************************/
@@ -345,13 +359,6 @@ struct sn9c102_sensor {
 	   error code without rolling back.
 	*/
 
-	const struct device* dev;
-	/*
-	   This is the argument for dev_err(), dev_info() and dev_warn(). It
-	   is used for debugging purposes. You must not access the struct
-	   before the sensor is attached.
-	*/
-
 	const struct usb_device* usbdev;
 	/*
 	   Points to the usb_device struct after the sensor is attached.
diff --git a/drivers/usb/media/sn9c102_tas5110c1b.c b/drivers/usb/media/sn9c102_tas5110c1b.c
index 8775999..32ddf23 100644
--- a/drivers/usb/media/sn9c102_tas5110c1b.c
+++ b/drivers/usb/media/sn9c102_tas5110c1b.c
@@ -2,7 +2,7 @@
  * Plug-in for TAS5110C1B image sensor connected to the SN9C10x PC Camera  *
  * Controllers                                                             *
  *                                                                         *
- * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it>  *
+ * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it>  *
  *                                                                         *
  * This program is free software; you can redistribute it and/or modify    *
  * it under the terms of the GNU General Public License as published by    *
diff --git a/drivers/usb/media/sn9c102_tas5130d1b.c b/drivers/usb/media/sn9c102_tas5130d1b.c
index 927eafd..a0728f0 100644
--- a/drivers/usb/media/sn9c102_tas5130d1b.c
+++ b/drivers/usb/media/sn9c102_tas5130d1b.c
@@ -2,7 +2,7 @@
  * Plug-in for TAS5130D1B image sensor connected to the SN9C10x PC Camera  *
  * Controllers                                                             *
  *                                                                         *
- * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it>  *
+ * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it>  *
  *                                                                         *
  * This program is free software; you can redistribute it and/or modify    *
  * it under the terms of the GNU General Public License as published by    *
diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c
index bff9434..9937fc6 100644
--- a/drivers/usb/media/w9968cf.c
+++ b/drivers/usb/media/w9968cf.c
@@ -62,7 +62,6 @@ MODULE_LICENSE(W9968CF_MODULE_LICENSE);
 MODULE_SUPPORTED_DEVICE("Video");
 
 static int ovmod_load = W9968CF_OVMOD_LOAD;
-static int vppmod_load = W9968CF_VPPMOD_LOAD;
 static unsigned short simcams = W9968CF_SIMCAMS;
 static short video_nr[]={[0 ... W9968CF_MAX_DEVICES-1] = -1}; /*-1=first free*/
 static unsigned int packet_size[] = {[0 ... W9968CF_MAX_DEVICES-1] = 
@@ -107,7 +106,6 @@ static unsigned int param_nv[24]; /* num
 
 #ifdef CONFIG_KMOD
 module_param(ovmod_load, bool, 0644);
-module_param(vppmod_load, bool, 0444);
 #endif
 module_param(simcams, ushort, 0644);
 module_param_array(video_nr, short, &param_nv[0], 0444);
@@ -150,18 +148,6 @@ MODULE_PARM_DESC(ovmod_load, 
                  "\ninto memory."
                  "\nDefault value is "__MODULE_STRING(W9968CF_OVMOD_LOAD)"."
                  "\n");
-MODULE_PARM_DESC(vppmod_load, 
-                 "\n<0|1> Automatic 'w9968cf-vpp' module loading."
-                 "\n0 disabled, 1 enabled."
-                 "\nIf enabled, every time an application attempts to open a"
-                 "\ncamera, 'insmod' searches for the video post-processing"
-                 "\nmodule in the system and loads it automatically (if"
-                 "\npresent). The optional 'w9968cf-vpp' module adds extra"
-                 "\n image manipulation functions to the 'w9968cf' module,like"
-                 "\nsoftware up-scaling,colour conversions and video decoding"
-                 "\nfor very high frame rates."
-                 "\nDefault value is "__MODULE_STRING(W9968CF_VPPMOD_LOAD)"."
-                 "\n");
 #endif
 MODULE_PARM_DESC(simcams, 
                  "\n<n> Number of cameras allowed to stream simultaneously."
@@ -492,10 +478,6 @@ static void w9968cf_push_frame(struct w9
 static void w9968cf_pop_frame(struct w9968cf_device*,struct w9968cf_frame_t**);
 static void w9968cf_release_resources(struct w9968cf_device*);
 
-/* Intermodule communication */
-static int w9968cf_vppmod_detect(struct w9968cf_device*);
-static void w9968cf_vppmod_release(struct w9968cf_device*);
-
 
 
 /****************************************************************************
@@ -2737,9 +2719,7 @@ static int w9968cf_open(struct inode* in
 	cam->streaming = 0;
 	cam->misconfigured = 0;
 
-	if (!w9968cf_vpp)
-		if ((err = w9968cf_vppmod_detect(cam)))
-			goto out;
+	w9968cf_adjust_configuration(cam);
 
 	if ((err = w9968cf_allocate_memory(cam)))
 		goto deallocate_memory;
@@ -2766,7 +2746,6 @@ static int w9968cf_open(struct inode* in
 
 deallocate_memory:
 	w9968cf_deallocate_memory(cam);
-out:
 	DBG(2, "Failed to open the video device")
 	up(&cam->dev_sem);
 	up_read(&w9968cf_disconnect);
@@ -2784,8 +2763,6 @@ static int w9968cf_release(struct inode*
 
 	w9968cf_stop_transfer(cam);
 
-	w9968cf_vppmod_release(cam);
-
 	if (cam->disconnected) {
 		w9968cf_release_resources(cam);
 		up(&cam->dev_sem);
@@ -3681,106 +3658,6 @@ static struct usb_driver w9968cf_usb_dri
  * Module init, exit and intermodule communication                          *
  ****************************************************************************/
 
-static int w9968cf_vppmod_detect(struct w9968cf_device* cam)
-{
-	if (!w9968cf_vpp)
-		if (vppmod_load)
-			request_module("w9968cf-vpp");
-
-	down(&w9968cf_vppmod_lock);
-
-	if (!w9968cf_vpp) {
-		DBG(4, "Video post-processing module not detected")
-		w9968cf_adjust_configuration(cam);
-		goto out;
-	}
-
-	if (!try_module_get(w9968cf_vpp->owner)) {
-		DBG(1, "Couldn't increment the reference count of "
-		       "the video post-processing module")
-		up(&w9968cf_vppmod_lock);
-		return -ENOSYS;
-	}
-
-	w9968cf_vpp->busy++;
-
-	DBG(5, "Video post-processing module detected")
-
-out:
-	up(&w9968cf_vppmod_lock);
-	return 0;
-}
-
-
-static void w9968cf_vppmod_release(struct w9968cf_device* cam)
-{
-	down(&w9968cf_vppmod_lock);
-
-	if (w9968cf_vpp && w9968cf_vpp->busy) {
-		module_put(w9968cf_vpp->owner);
-		w9968cf_vpp->busy--;
-		wake_up(&w9968cf_vppmod_wait);
-		DBG(5, "Video post-processing module released")
-	}
-
-	up(&w9968cf_vppmod_lock);
-}
-
-
-int w9968cf_vppmod_register(struct w9968cf_vpp_t* vpp)
-{
-	down(&w9968cf_vppmod_lock);
-
-	if (w9968cf_vpp) {
-		KDBG(1, "Video post-processing module already registered")
-		up(&w9968cf_vppmod_lock);
-		return -EINVAL;
-	}
-
-	w9968cf_vpp = vpp;
-	w9968cf_vpp->busy = 0;
-
-	KDBG(2, "Video post-processing module registered")
-	up(&w9968cf_vppmod_lock);
-	return 0;
-}
-
-
-int w9968cf_vppmod_deregister(struct w9968cf_vpp_t* vpp)
-{
-	down(&w9968cf_vppmod_lock);
-
-	if (!w9968cf_vpp) {
-		up(&w9968cf_vppmod_lock);
-		return -EINVAL;
-	}
-
-	if (w9968cf_vpp != vpp) {
-		KDBG(1, "Only the owner can unregister the video "
-		        "post-processing module")
-		up(&w9968cf_vppmod_lock);
-		return -EINVAL;
-	}
-
-	if (w9968cf_vpp->busy) {
-		KDBG(2, "Video post-processing module busy. Wait for it to be "
-		        "released...")
-		up(&w9968cf_vppmod_lock);
-		wait_event(w9968cf_vppmod_wait, !w9968cf_vpp->busy);
-		w9968cf_vpp = NULL;
-		goto out;
-	}
-
-	w9968cf_vpp = NULL;
-
-	up(&w9968cf_vppmod_lock);
-
-out:
-	KDBG(2, "Video post-processing module unregistered")
-	return 0;
-}
-
-
 static int __init w9968cf_module_init(void)
 {
 	int err;
@@ -3810,6 +3687,3 @@ static void __exit w9968cf_module_exit(v
 module_init(w9968cf_module_init);
 module_exit(w9968cf_module_exit);
 
-
-EXPORT_SYMBOL(w9968cf_vppmod_register);
-EXPORT_SYMBOL(w9968cf_vppmod_deregister);
diff --git a/drivers/usb/media/w9968cf.h b/drivers/usb/media/w9968cf.h
index 8acbfe2..47a6ff7 100644
--- a/drivers/usb/media/w9968cf.h
+++ b/drivers/usb/media/w9968cf.h
@@ -195,7 +195,6 @@ enum w9968cf_vpp_flag {
 };
 
 static struct w9968cf_vpp_t* w9968cf_vpp;
-static DECLARE_MUTEX(w9968cf_vppmod_lock);
 static DECLARE_WAIT_QUEUE_HEAD(w9968cf_vppmod_wait);
 
 static LIST_HEAD(w9968cf_dev_list); /* head of V4L registered cameras list */
diff --git a/drivers/usb/media/w9968cf_vpp.h b/drivers/usb/media/w9968cf_vpp.h
index 3f5317d..f3b91b7 100644
--- a/drivers/usb/media/w9968cf_vpp.h
+++ b/drivers/usb/media/w9968cf_vpp.h
@@ -37,7 +37,4 @@ struct w9968cf_vpp_t {
 	u8 busy; /* read-only flag: module is/is not in use */
 };
 
-extern int w9968cf_vppmod_register(struct w9968cf_vpp_t*);
-extern int w9968cf_vppmod_deregister(struct w9968cf_vpp_t*);
-
 #endif /* _W9968CF_VPP_H_ */
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
index 449b250..ad2f4cc 100644
--- a/drivers/usb/misc/auerswald.c
+++ b/drivers/usb/misc/auerswald.c
@@ -2093,6 +2093,8 @@ static void auerswald_disconnect (struct
 static struct usb_device_id auerswald_ids [] = {
 	{ USB_DEVICE (ID_AUERSWALD, 0x00C0) },          /* COMpact 2104 USB */
 	{ USB_DEVICE (ID_AUERSWALD, 0x00DB) },          /* COMpact 4410/2206 USB */
+	{ USB_DEVICE (ID_AUERSWALD, 0x00DC) }, /* COMpact 4406 DSL */
+	{ USB_DEVICE (ID_AUERSWALD, 0x00DD) }, /* COMpact 2204 USB */
 	{ USB_DEVICE (ID_AUERSWALD, 0x00F1) },          /* Comfort 2000 System Telephone */
 	{ USB_DEVICE (ID_AUERSWALD, 0x00F2) },          /* Comfort 1200 System Telephone */
         { }			                        /* Terminating entry */
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c
index 981d8a5..331d4ae 100644
--- a/drivers/usb/misc/ldusb.c
+++ b/drivers/usb/misc/ldusb.c
@@ -593,7 +593,7 @@ static struct file_operations ld_usb_fop
 
 /*
  * usb class driver info in order to get a minor number from the usb core,
- * and to have the device registered with devfs and the driver core
+ * and to have the device registered with the driver core
  */
 static struct usb_class_driver ld_usb_class = {
 	.name =		"ldusb%d",
diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c
index 5411816..3094970 100644
--- a/drivers/usb/net/asix.c
+++ b/drivers/usb/net/asix.c
@@ -916,6 +916,10 @@ static const struct usb_device_id	produc
 	// Linksys USB200M Rev 2
 	USB_DEVICE (0x13b1, 0x0018),
 	.driver_info = (unsigned long) &ax88772_info,
+}, {
+	// 0Q0 cable ethernet
+	USB_DEVICE (0x1557, 0x7720),
+	.driver_info = (unsigned long) &ax88772_info,
 },
 	{ },		// END
 };
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
index da46b35..dc7a069 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp2101.c
@@ -32,7 +32,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.05"
+#define DRIVER_VERSION "v0.06"
 #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver"
 
 /*
@@ -55,11 +55,15 @@ static int debug;
 
 static struct usb_device_id id_table [] = {
 	{ USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */
-	{ USB_DEVICE(0x10C4, 0xEA60) },	/* Silicon Labs factory default */
-	{ USB_DEVICE(0x10C4, 0x80CA) },	/* Degree Controls Inc */
-	{ USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */
 	{ USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */
-	{ USB_DEVICE(0x10AB, 0x10C5) },	/* Siemens MC60 Cable */
+	{ USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */
+	{ USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */
+	{ USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */
+	{ USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */
+	{ USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */
+	{ USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */
+	{ USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
+	{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
 	{ USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
 	{ } /* Terminating Entry */
 };
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 10bc1bf..f2b4ca8 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -476,10 +476,16 @@ static struct usb_device_id id_table_com
 	{ USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HRC_PID) },
 	{ USB_DEVICE(KOBIL_VID, KOBIL_CONV_B1_PID) },
 	{ USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) },
 	{ USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_TTUSB_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_777_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_8900F_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) },
 	{ },					/* Optional parameter entry */
 	{ }					/* Terminating entry */
 };
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index 00d45f8..ca40f16 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -31,9 +31,14 @@
 #define FTDI_NF_RIC_VID	0x0DCD	/* Vendor Id */
 #define FTDI_NF_RIC_PID	0x0001	/* Product Id */
 
+
 /* www.irtrans.de device */
 #define FTDI_IRTRANS_PID 0xFC60 /* Product Id */
 
+
+/* www.thoughttechnology.com/ TT-USB provide with procomp use ftdi_sio */
+#define FTDI_TTUSB_PID 0xFF20 /* Product Id */
+
 /* www.crystalfontz.com devices - thanx for providing free devices for evaluation ! */
 /* they use the ftdi chipset for the USB interface and the vendor id is the same */
 #define FTDI_XF_632_PID 0xFC08	/* 632: 16x2 Character Display */
@@ -51,6 +56,12 @@
 #define FTDI_VNHCPCUSB_D_PID 0xfe38 /* Product Id */
 
 /*
+ * PCDJ use ftdi based dj-controllers.  The following PID is for their DAC-2 device
+ * http://www.pcdjhardware.com/DAC2.asp (PID sent by Wouter Paesen)
+ * (the VID is the standard ftdi vid (FTDI_VID) */
+#define FTDI_PCDJ_DAC2_PID 0xFA88
+
+/*
  * The following are the values for the Matrix Orbital LCD displays,
  * which are the FT232BM ( similar to the 8U232AM )
  */
@@ -215,8 +226,10 @@
  * Definitions for ATIK Instruments astronomical USB based cameras
  * Check it at http://www.atik-instruments.com/
  */
-#define FTDI_ATIK_ATK16_PID	0xDF30	/* ATIK ATK-16 Camera */
-#define FTDI_ATIK_ATK16HR_PID	0xDF31	/* ATIK ATK-16HR Camera */
+#define FTDI_ATIK_ATK16_PID	0xDF30	/* ATIK ATK-16 Grayscale Camera */
+#define FTDI_ATIK_ATK16C_PID	0xDF32	/* ATIK ATK-16C Colour Camera */
+#define FTDI_ATIK_ATK16HR_PID	0xDF31	/* ATIK ATK-16HR Grayscale Camera */
+#define FTDI_ATIK_ATK16HRC_PID	0xDF33	/* ATIK ATK-16HRC Colour Camera */
 
 /*
  * Protego product ids
@@ -365,6 +378,12 @@
 #define POSIFLEX_VID		0x0d3a  /* Vendor ID */
 #define POSIFLEX_PP7000_PID	0x0300  /* PP-7000II thermal printer */
 
+/*
+ * Westrex International devices submitted by Cory Lee
+ */
+#define FTDI_WESTREX_MODEL_777_PID	0xDC00	/* Model 777 */
+#define FTDI_WESTREX_MODEL_8900F_PID	0xDC01	/* Model 8900F */
+
 /* Commands */
 #define FTDI_SIO_RESET 		0 /* Reset the port */
 #define FTDI_SIO_MODEM_CTRL 	1 /* Set the modem control register */
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 0eb883f..e8e575e 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -73,7 +73,9 @@ static struct usb_device_id id_table [] 
 	{ USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65) },
 	{ USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X75) },
 	{ USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) },
-	{ USB_DEVICE( NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID ) },
+	{ USB_DEVICE(NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID ) },
+	{ USB_DEVICE(CA_42_CA42_VENDOR_ID, CA_42_CA42_PRODUCT_ID ) },
+	{ USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_PRODUCT_ID) },
 	{ }					/* Terminating entry */
 };
 
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
index 21d434d..1807087 100644
--- a/drivers/usb/serial/pl2303.h
+++ b/drivers/usb/serial/pl2303.h
@@ -64,3 +64,10 @@
 /* Nokia CA-42 Cable */
 #define NOKIA_CA42_VENDOR_ID	0x078b
 #define NOKIA_CA42_PRODUCT_ID	0x1234
+
+/* CA-42 CLONE Cable www.ca-42.com chipset: Prolific Technology Inc */
+#define CA_42_CA42_VENDOR_ID	0x10b5
+#define CA_42_CA42_PRODUCT_ID	0xac70
+
+#define SAGEM_VENDOR_ID		0x079b
+#define SAGEM_PRODUCT_ID	0x0027
diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c
index 5b06f92..ab173b3 100644
--- a/drivers/usb/storage/initializers.c
+++ b/drivers/usb/storage/initializers.c
@@ -45,6 +45,12 @@
 #include "debug.h"
 #include "transport.h"
 
+#define RIO_MSC 0x08
+#define RIOP_INIT "RIOP\x00\x01\x08"
+#define RIOP_INIT_LEN 7
+#define RIO_SEND_LEN 40
+#define RIO_RECV_LEN 0x200
+
 /* This places the Shuttle/SCM USB<->SCSI bridge devices in multi-target
  * mode */
 int usb_stor_euscsi_init(struct us_data *us)
@@ -91,3 +97,70 @@ int usb_stor_ucr61s2b_init(struct us_dat
 
 	return (res ? -1 : 0);
 }
+
+/* Place the Rio Karma into mass storage mode.
+ *
+ * The initialization begins by sending 40 bytes starting
+ * RIOP\x00\x01\x08\x00, which the device will ack with a 512-byte
+ * packet with the high four bits set and everything else null.
+ *
+ * Next, we send RIOP\x80\x00\x08\x00.  Each time, a 512 byte response
+ * must be read, but we must loop until byte 5 in the response is 0x08,
+ * indicating success.  */
+int rio_karma_init(struct us_data *us)
+{
+	int result, partial;
+	char *recv;
+	unsigned long timeout;
+
+	// us->iobuf is big enough to hold cmd but not receive
+	if (!(recv = kmalloc(RIO_RECV_LEN, GFP_KERNEL)))
+		goto die_nomem;
+
+	US_DEBUGP("Initializing Karma...\n");
+
+	memset(us->iobuf, 0, RIO_SEND_LEN);
+	memcpy(us->iobuf, RIOP_INIT, RIOP_INIT_LEN);
+
+	result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+		us->iobuf, RIO_SEND_LEN, &partial);
+	if (result != USB_STOR_XFER_GOOD)
+		goto die;
+
+	result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+		recv, RIO_RECV_LEN, &partial);
+	if (result != USB_STOR_XFER_GOOD)
+		goto die;
+
+	us->iobuf[4] = 0x80;
+	us->iobuf[5] = 0;
+	timeout = jiffies + msecs_to_jiffies(3000);
+	for (;;) {
+		US_DEBUGP("Sending init command\n");
+		result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+			us->iobuf, RIO_SEND_LEN, &partial);
+		if (result != USB_STOR_XFER_GOOD)
+			goto die;
+
+		result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+			recv, RIO_RECV_LEN, &partial);
+		if (result != USB_STOR_XFER_GOOD)
+			goto die;
+
+		if (recv[5] == RIO_MSC)
+			break;
+		if (time_after(jiffies, timeout))
+			goto die;
+		msleep(10);
+	}
+	US_DEBUGP("Karma initialized.\n");
+	kfree(recv);
+	return 0;
+
+die:
+	kfree(recv);
+die_nomem:
+	US_DEBUGP("Could not initialize karma.\n");
+	return USB_STOR_TRANSPORT_FAILED;
+}
+
diff --git a/drivers/usb/storage/initializers.h b/drivers/usb/storage/initializers.h
index 4c1b2bd..f9907a5 100644
--- a/drivers/usb/storage/initializers.h
+++ b/drivers/usb/storage/initializers.h
@@ -48,3 +48,4 @@ int usb_stor_euscsi_init(struct us_data 
 /* This function is required to activate all four slots on the UCR-61S2B
  * flash reader */
 int usb_stor_ucr61s2b_init(struct us_data *us);
+int rio_karma_init(struct us_data *us);
diff --git a/drivers/usb/storage/libusual.c b/drivers/usb/storage/libusual.c
index b28151d..b1ec4a7 100644
--- a/drivers/usb/storage/libusual.c
+++ b/drivers/usb/storage/libusual.c
@@ -116,7 +116,7 @@ EXPORT_SYMBOL_GPL(usb_usual_check_type);
 static int usu_probe(struct usb_interface *intf,
 			 const struct usb_device_id *id)
 {
-	int type;
+	unsigned long type;
 	int rc;
 	unsigned long flags;
 
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index dc301e5..ee958f9 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -145,6 +145,11 @@ UNUSUAL_DEV(  0x0451, 0x5416, 0x0100, 0x
 		US_SC_DEVICE, US_PR_BULK, NULL,
 		US_FL_NEED_OVERRIDE ),
 
+UNUSUAL_DEV(  0x045a, 0x5210, 0x0101, 0x0101,
+		"Rio",
+		"Rio Karma",
+		US_SC_SCSI, US_PR_BULK, rio_karma_init, 0),
+
 /* Patch submitted by Philipp Friedrich <philipp@void.at> */
 UNUSUAL_DEV(  0x0482, 0x0100, 0x0100, 0x0100,
 		"Kyocera",
@@ -424,11 +429,11 @@ UNUSUAL_DEV(  0x054c, 0x0010, 0x0106, 0x
 		US_FL_SINGLE_LUN | US_FL_NOT_LOCKABLE | US_FL_NO_WP_DETECT ),
 
 /* This entry is needed because the device reports Sub=ff */
-UNUSUAL_DEV(  0x054c, 0x0010, 0x0500, 0x0500, 
-               "Sony",
-               "DSC-T1", 
-               US_SC_8070, US_PR_DEVICE, NULL,
-               US_FL_SINGLE_LUN ),
+UNUSUAL_DEV(  0x054c, 0x0010, 0x0500, 0x0600,
+		"Sony",
+		"DSC-T1/T5",
+		US_SC_8070, US_PR_DEVICE, NULL,
+		US_FL_SINGLE_LUN ),
 
 
 /* Reported by wim@geeks.nl */
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
index 5d02f16..4de9fb5 100644
--- a/drivers/usb/usb-skeleton.c
+++ b/drivers/usb/usb-skeleton.c
@@ -234,7 +234,7 @@ static struct file_operations skel_fops 
 
 /* 
  * usb class driver info in order to get a minor number from the usb core,
- * and to have the device registered with devfs and the driver core
+ * and to have the device registered with the driver core
  */
 static struct usb_class_driver skel_class = {
 	.name =		"skel%d",
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
index b218717..6761b68 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/amba-clcd.c
@@ -116,9 +116,10 @@ clcdfb_set_bitfields(struct clcd_fb *fb,
 	int ret = 0;
 
 	memset(&var->transp, 0, sizeof(var->transp));
-	memset(&var->red, 0, sizeof(var->red));
-	memset(&var->green, 0, sizeof(var->green));
-	memset(&var->blue, 0, sizeof(var->blue));
+
+	var->red.msb_right = 0;
+	var->green.msb_right = 0;
+	var->blue.msb_right = 0;
 
 	switch (var->bits_per_pixel) {
 	case 1:
@@ -133,34 +134,20 @@ clcdfb_set_bitfields(struct clcd_fb *fb,
 		var->blue.offset	= 0;
 		break;
 	case 16:
-		var->red.length		= 5;
-		var->green.length	= 6;
-		var->blue.length	= 5;
-		if (fb->panel->cntl & CNTL_BGR) {
-			var->red.offset		= 11;
-			var->green.offset	= 5;
-			var->blue.offset	= 0;
-		} else {
-			var->red.offset		= 0;
-			var->green.offset	= 5;
-			var->blue.offset	= 11;
-		}
+		var->red.length = 5;
+		var->blue.length = 5;
+		/*
+		 * Green length can be 5 or 6 depending whether
+		 * we're operating in RGB555 or RGB565 mode.
+		 */
+		if (var->green.length != 5 && var->green.length != 6)
+			var->green.length = 6;
 		break;
 	case 32:
 		if (fb->panel->cntl & CNTL_LCDTFT) {
 			var->red.length		= 8;
 			var->green.length	= 8;
 			var->blue.length	= 8;
-
-			if (fb->panel->cntl & CNTL_BGR) {
-				var->red.offset		= 16;
-				var->green.offset	= 8;
-				var->blue.offset	= 0;
-			} else {
-				var->red.offset		= 0;
-				var->green.offset	= 8;
-				var->blue.offset	= 16;
-			}
 			break;
 		}
 	default:
@@ -168,6 +155,23 @@ clcdfb_set_bitfields(struct clcd_fb *fb,
 		break;
 	}
 
+	/*
+	 * >= 16bpp displays have separate colour component bitfields
+	 * encoded in the pixel data.  Calculate their position from
+	 * the bitfield length defined above.
+	 */
+	if (ret == 0 && var->bits_per_pixel >= 16) {
+		if (fb->panel->cntl & CNTL_BGR) {
+			var->blue.offset = 0;
+			var->green.offset = var->blue.offset + var->blue.length;
+			var->red.offset = var->green.offset + var->green.length;
+		} else {
+			var->red.offset = 0;
+			var->green.offset = var->red.offset + var->red.length;
+			var->blue.offset = var->green.offset + var->green.length;
+		}
+	}
+
 	return ret;
 }
 
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 996d543..9d996f2 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -50,3 +50,11 @@ config BACKLIGHT_CORGI
 	  If you have a Sharp Zaurus SL-C7xx, say y to enable the
 	  backlight driver.
 
+config BACKLIGHT_HP680
+	tristate "HP Jornada 680 Backlight Driver"
+	depends on BACKLIGHT_DEVICE && SH_HP6XX
+	default y
+	help
+	  If you have a HP Jornada 680, say y to enable the
+	  backlight driver.
+
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 4af321f..744210c 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -3,4 +3,5 @@
 obj-$(CONFIG_LCD_CLASS_DEVICE)     += lcd.o
 obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
 obj-$(CONFIG_BACKLIGHT_CORGI)	+= corgi_bl.o
+obj-$(CONFIG_BACKLIGHT_HP680)	+= hp680_bl.o
 obj-$(CONFIG_SHARP_LOCOMO)	+= locomolcd.o
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c
new file mode 100644
index 0000000..95da4c9
--- /dev/null
+++ b/drivers/video/backlight/hp680_bl.c
@@ -0,0 +1,189 @@
+/*
+ *  Backlight Driver for HP Jornada 680
+ *
+ *  Copyright (c) 2005 Andriy Skulysh
+ *
+ *  Based on Sharp's Corgi Backlight Driver
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/spinlock.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+
+#include <asm/cpu/dac.h>
+#include <asm/hp6xx/hp6xx.h>
+#include <asm/hd64461/hd64461.h>
+
+#define HP680_MAX_INTENSITY 255
+#define HP680_DEFAULT_INTENSITY 10
+
+static int hp680bl_powermode = FB_BLANK_UNBLANK;
+static int current_intensity = 0;
+static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED;
+
+static void hp680bl_send_intensity(int intensity)
+{
+	unsigned long flags;
+
+	if (hp680bl_powermode != FB_BLANK_UNBLANK)
+		intensity = 0;
+
+	spin_lock_irqsave(&bl_lock, flags);
+	sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS);
+	spin_unlock_irqrestore(&bl_lock, flags);
+}
+
+static void hp680bl_blank(int blank)
+{
+	u16 v;
+
+	switch(blank) {
+
+	case FB_BLANK_NORMAL:
+	case FB_BLANK_VSYNC_SUSPEND:
+	case FB_BLANK_HSYNC_SUSPEND:
+	case FB_BLANK_POWERDOWN:
+		if (hp680bl_powermode == FB_BLANK_UNBLANK) {
+			hp680bl_send_intensity(0);
+			hp680bl_powermode = blank;
+			sh_dac_disable(DAC_LCD_BRIGHTNESS);
+			v = inw(HD64461_GPBDR);
+			v |= HD64461_GPBDR_LCDOFF;
+			outw(v, HD64461_GPBDR);
+		}
+		break;
+	case FB_BLANK_UNBLANK:
+		if (hp680bl_powermode != FB_BLANK_UNBLANK) {
+			sh_dac_enable(DAC_LCD_BRIGHTNESS);
+			v = inw(HD64461_GPBDR);
+			v &= ~HD64461_GPBDR_LCDOFF;
+			outw(v, HD64461_GPBDR);
+			hp680bl_powermode = blank;
+			hp680bl_send_intensity(current_intensity);
+		}
+		break;
+	}
+}
+
+#ifdef CONFIG_PM
+static int hp680bl_suspend(struct device *dev, pm_message_t state, u32 level)
+{
+	if (level == SUSPEND_POWER_DOWN)
+		hp680bl_blank(FB_BLANK_POWERDOWN);
+	return 0;
+}
+
+static int hp680bl_resume(struct device *dev, u32 level)
+{
+	if (level == RESUME_POWER_ON)
+		hp680bl_blank(FB_BLANK_UNBLANK);
+	return 0;
+}
+#else
+#define hp680bl_suspend	NULL
+#define hp680bl_resume	NULL
+#endif
+
+
+static int hp680bl_set_power(struct backlight_device *bd, int state)
+{
+	hp680bl_blank(state);
+	return 0;
+}
+
+static int hp680bl_get_power(struct backlight_device *bd)
+{
+	return hp680bl_powermode;
+}
+
+static int hp680bl_set_intensity(struct backlight_device *bd, int intensity)
+{
+	if (intensity > HP680_MAX_INTENSITY)
+		intensity = HP680_MAX_INTENSITY;
+	hp680bl_send_intensity(intensity);
+	current_intensity = intensity;
+	return 0;
+}
+
+static int hp680bl_get_intensity(struct backlight_device *bd)
+{
+	return current_intensity;
+}
+
+static struct backlight_properties hp680bl_data = {
+	.owner		= THIS_MODULE,
+	.get_power      = hp680bl_get_power,
+	.set_power      = hp680bl_set_power,
+	.max_brightness = HP680_MAX_INTENSITY,
+	.get_brightness = hp680bl_get_intensity,
+	.set_brightness = hp680bl_set_intensity,
+};
+
+static struct backlight_device *hp680_backlight_device;
+
+static int __init hp680bl_probe(struct device *dev)
+{
+	hp680_backlight_device = backlight_device_register ("hp680-bl",
+		NULL, &hp680bl_data);
+	if (IS_ERR (hp680_backlight_device))
+		return PTR_ERR (hp680_backlight_device);
+
+	hp680bl_set_intensity(NULL, HP680_DEFAULT_INTENSITY);
+
+	return 0;
+}
+
+static int hp680bl_remove(struct device *dev)
+{
+	backlight_device_unregister(hp680_backlight_device);
+
+	return 0;
+}
+
+static struct device_driver hp680bl_driver = {
+	.name		= "hp680-bl",
+	.bus		= &platform_bus_type,
+	.probe		= hp680bl_probe,
+	.remove		= hp680bl_remove,
+	.suspend	= hp680bl_suspend,
+	.resume		= hp680bl_resume,
+};
+
+static struct platform_device hp680bl_device = {
+	.name	= "hp680-bl",
+	.id	= -1,
+};
+
+static int __init hp680bl_init(void)
+{
+	int ret;
+
+	ret=driver_register(&hp680bl_driver);
+	if (!ret) {
+		ret = platform_device_register(&hp680bl_device);
+		if (ret)
+			driver_unregister(&hp680bl_driver);
+	}
+	return ret;
+}
+
+static void __exit hp680bl_exit(void)
+{
+	platform_device_unregister(&hp680bl_device);
+ 	driver_unregister(&hp680bl_driver);
+}
+
+module_init(hp680bl_init);
+module_exit(hp680bl_exit);
+
+MODULE_AUTHOR("Andriy Skulysh <askulysh@image.kiev.ua>");
+MODULE_DESCRIPTION("HP Jornada 680 Backlight Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/cyblafb.c b/drivers/video/cyblafb.c
index 2b97246..0ae0a97 100644
--- a/drivers/video/cyblafb.c
+++ b/drivers/video/cyblafb.c
@@ -1665,7 +1665,6 @@ static int __devinit cyblafb_init(void)
 		}
 #endif
 	output("CyblaFB version %s initializing\n", VERSION);
-	return pci_module_init(&cyblafb_pci_driver);
 	return pci_register_driver(&cyblafb_pci_driver);
 }
 
diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c
index bd410e0..e3c8b5f 100644
--- a/drivers/video/i810/i810-i2c.c
+++ b/drivers/video/i810/i810-i2c.c
@@ -191,11 +191,11 @@ int i810_probe_i2c_connector(struct fb_i
         u8 *edid = NULL;
         int i;
 
-	DPRINTK("i810-i2c: Probe DDC%i Bus\n", conn);
-	if (conn < 4) {
+	DPRINTK("i810-i2c: Probe DDC%i Bus\n", conn+1);
+	if (conn < par->ddc_num) {
 		for (i = 0; i < 3; i++) {
 			/* Do the real work */
-			edid = i810_do_probe_i2c_edid(&par->chan[conn-1]);
+			edid = i810_do_probe_i2c_edid(&par->chan[conn]);
 			if (edid)
 				break;
 		}
diff --git a/drivers/video/i810/i810.h b/drivers/video/i810/i810.h
index 6c187d5..579195c 100644
--- a/drivers/video/i810/i810.h
+++ b/drivers/video/i810/i810.h
@@ -280,6 +280,7 @@ struct i810fb_par {
 	u32 blit_bpp;
 	u32 ovract;
 	u32 cur_state;
+	u32 ddc_num;
 	int mtrr_reg;
 	u16 bltcntl;
 	u8 interlace;
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index 266d0ab..d8467c0 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -149,6 +149,7 @@ static int vyres      __devinitdata;
 static int sync       __devinitdata;
 static int extvga     __devinitdata;
 static int dcolor     __devinitdata;
+static int ddc3       __devinitdata = 2;
 
 /*------------------------------------------------------------*/
 
@@ -1763,6 +1764,8 @@ static void __devinit i810_init_defaults
 	if (sync) 
 		par->dev_flags |= ALWAYS_SYNC;
 
+	par->ddc_num = ddc3;
+
 	if (bpp < 8)
 		bpp = 8;
 	
@@ -1885,7 +1888,7 @@ static void __devinit i810fb_find_init_m
 	int found = 0;
 #ifdef CONFIG_FB_I810_I2C
 	int i;
-	int err;
+	int err = 1;
 	struct i810fb_par *par = info->par;
 #endif
 
@@ -1895,8 +1898,8 @@ static void __devinit i810fb_find_init_m
 #ifdef CONFIG_FB_I810_I2C
 	i810_create_i2c_busses(par);
 
-	for (i = 0; i < 4; i++) {
-		err = i810_probe_i2c_connector(info, &par->edid, i+1);
+	for (i = 0; i < par->ddc_num + 1; i++) {
+		err = i810_probe_i2c_connector(info, &par->edid, i);
 		if (!err)
 			break;
 	}
@@ -1983,6 +1986,8 @@ static int __devinit i810fb_setup(char *
 			vsync2 = simple_strtoul(this_opt+7, NULL, 0);
 		else if (!strncmp(this_opt, "dcolor", 6))
 			dcolor = 1;
+		else if (!strncmp(this_opt, "ddc3", 4))
+			ddc3 = 3;
 		else
 			mode_option = this_opt;
 	}
@@ -2190,6 +2195,8 @@ MODULE_PARM_DESC(sync, "wait for accel e
 module_param(dcolor, bool, 0);
 MODULE_PARM_DESC(dcolor, "use DirectColor visuals"
 		 " (default = 0 = TrueColor)");
+module_param(ddc3, bool, 0);
+MODULE_PARM_DESC(ddc3, "Probe DDC bus 3 (default = 0 = no)");
 module_param(mode_option, charp, 0);
 MODULE_PARM_DESC(mode_option, "Specify initial video mode");
 
diff --git a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c
index 55e6e2d..a4d7cc5 100644
--- a/drivers/video/sbuslib.c
+++ b/drivers/video/sbuslib.c
@@ -199,8 +199,7 @@ struct  fbcmap32 {
 #define FBIOPUTCMAP32	_IOW('F', 3, struct fbcmap32)
 #define FBIOGETCMAP32	_IOW('F', 4, struct fbcmap32)
 
-static int fbiogetputcmap(struct file *file, struct fb_info *info,
-		unsigned int cmd, unsigned long arg)
+static int fbiogetputcmap(struct fb_info *info, unsigned int cmd, unsigned long arg)
 {
 	struct fbcmap32 __user *argp = (void __user *)arg;
 	struct fbcmap __user *p = compat_alloc_user_space(sizeof(*p));
@@ -236,8 +235,7 @@ struct fbcursor32 {
 #define FBIOSCURSOR32	_IOW('F', 24, struct fbcursor32)
 #define FBIOGCURSOR32	_IOW('F', 25, struct fbcursor32)
 
-static int fbiogscursor(struct file *file, struct fb_info *info,
-		unsigned long arg)
+static int fbiogscursor(struct fb_info *info, unsigned long arg)
 {
 	struct fbcursor __user *p = compat_alloc_user_space(sizeof(*p));
 	struct fbcursor32 __user *argp =  (void __user *)arg;
@@ -263,8 +261,7 @@ static int fbiogscursor(struct file *fil
 	return info->fbops->fb_ioctl(info, FBIOSCURSOR, (unsigned long)p);
 }
 
-long sbusfb_compat_ioctl(struct fb_info *info, unsigned int cmd,
-		unsigned long arg)
+int sbusfb_compat_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
 {
 	switch (cmd) {
 	case FBIOGTYPE:
diff --git a/drivers/video/sbuslib.h b/drivers/video/sbuslib.h
index f753939..492828c 100644
--- a/drivers/video/sbuslib.h
+++ b/drivers/video/sbuslib.h
@@ -20,7 +20,7 @@ extern int sbusfb_mmap_helper(struct sbu
 int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg,
 			struct fb_info *info,
 			int type, int fb_depth, unsigned long fb_size);
-long sbusfb_compat_ioctl(struct fb_info *info, unsigned int cmd,
+int sbusfb_compat_ioctl(struct fb_info *info, unsigned int cmd,
 		unsigned long arg);
 
 #endif /* _SBUSLIB_H */
diff --git a/fs/9p/Makefile b/fs/9p/Makefile
index 3d02308..2f4ce43 100644
--- a/fs/9p/Makefile
+++ b/fs/9p/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_9P_FS) := 9p2000.o
 	conv.o \
 	vfs_super.o \
 	vfs_inode.o \
+	vfs_addr.o \
 	vfs_file.o \
 	vfs_dir.o \
 	vfs_dentry.o \
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
index c78502a..69cf290 100644
--- a/fs/9p/v9fs_vfs.h
+++ b/fs/9p/v9fs_vfs.h
@@ -39,6 +39,7 @@
  */
 
 extern struct file_system_type v9fs_fs_type;
+extern struct address_space_operations v9fs_addr_operations;
 extern struct file_operations v9fs_file_operations;
 extern struct file_operations v9fs_dir_operations;
 extern struct dentry_operations v9fs_dentry_operations;
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c
new file mode 100644
index 0000000..8100fb5
--- /dev/null
+++ b/fs/9p/vfs_addr.c
@@ -0,0 +1,109 @@
+/*
+ *  linux/fs/9p/vfs_addr.c
+ *
+ * This file contians vfs address (mmap) ops for 9P2000.
+ *
+ *  Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com>
+ *  Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
+ *
+ *  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:
+ *  Free Software Foundation
+ *  51 Franklin Street, Fifth Floor
+ *  Boston, MA  02111-1301  USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/stat.h>
+#include <linux/string.h>
+#include <linux/smp_lock.h>
+#include <linux/inet.h>
+#include <linux/version.h>
+#include <linux/pagemap.h>
+#include <linux/idr.h>
+
+#include "debug.h"
+#include "v9fs.h"
+#include "9p.h"
+#include "v9fs_vfs.h"
+#include "fid.h"
+
+/**
+ * v9fs_vfs_readpage - read an entire page in from 9P
+ *
+ * @file: file being read
+ * @page: structure to page
+ *
+ */
+
+static int v9fs_vfs_readpage(struct file *filp, struct page *page)
+{
+	char *buffer = NULL;
+	int retval = -EIO;
+	loff_t offset = page_offset(page);
+	int count = PAGE_CACHE_SIZE;
+	struct inode *inode = filp->f_dentry->d_inode;
+	struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
+	int rsize = v9ses->maxdata - V9FS_IOHDRSZ;
+	struct v9fs_fid *v9f = filp->private_data;
+	struct v9fs_fcall *fcall = NULL;
+	int fid = v9f->fid;
+	int total = 0;
+	int result = 0;
+
+	buffer = kmap(page);
+	do {
+		if (count < rsize)
+			rsize = count;
+
+		result = v9fs_t_read(v9ses, fid, offset, rsize, &fcall);
+
+		if (result < 0) {
+			printk(KERN_ERR "v9fs_t_read returned %d\n",
+			       result);
+
+			kfree(fcall);
+			goto UnmapAndUnlock;
+		} else
+			offset += result;
+
+		memcpy(buffer, fcall->params.rread.data, result);
+
+		count -= result;
+		buffer += result;
+		total += result;
+
+		kfree(fcall);
+
+		if (result < rsize)
+			break;
+	} while (count);
+
+	memset(buffer, 0, count);
+	flush_dcache_page(page);
+	SetPageUptodate(page);
+	retval = 0;
+
+UnmapAndUnlock:
+	kunmap(page);
+	unlock_page(page);
+	return retval;
+}
+
+struct address_space_operations v9fs_addr_operations = {
+      .readpage = v9fs_vfs_readpage,
+};
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 6852f0e..c7e14d9 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -289,6 +289,9 @@ v9fs_file_write(struct file *filp, const
 		total += result;
 	} while (count);
 
+	if(inode->i_mapping->nrpages)
+		invalidate_inode_pages2(inode->i_mapping);
+
 	return total;
 }
 
@@ -299,4 +302,5 @@ struct file_operations v9fs_file_operati
 	.open = v9fs_file_open,
 	.release = v9fs_dir_release,
 	.lock = v9fs_file_lock,
+	.mmap = generic_file_mmap,
 };
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index a17b288..91f5524 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -177,6 +177,7 @@ struct inode *v9fs_get_inode(struct supe
 		inode->i_blocks = 0;
 		inode->i_rdev = 0;
 		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+		inode->i_mapping->a_ops = &v9fs_addr_operations;
 
 		switch (mode & S_IFMT) {
 		case S_IFIFO:
diff --git a/fs/Kconfig b/fs/Kconfig
index ef78e3a..93b5dc4 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -1327,7 +1327,7 @@ config UFS_FS
 
 config UFS_FS_WRITE
 	bool "UFS file system write support (DANGEROUS)"
-	depends on UFS_FS && EXPERIMENTAL
+	depends on UFS_FS && EXPERIMENTAL && BROKEN
 	help
 	  Say Y here if you want to try writing to UFS partitions. This is
 	  experimental, so you should back up your UFS partitions beforehand.
diff --git a/fs/bio.c b/fs/bio.c
index bbc442b..1f3bb50 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -411,6 +411,7 @@ static int __bio_add_page(request_queue_
 
 /**
  *	bio_add_pc_page	-	attempt to add page to bio
+ *	@q: the target queue
  *	@bio: destination bio
  *	@page: page to add
  *	@len: vec entry length
diff --git a/fs/buffer.c b/fs/buffer.c
index 3dc712f..5e4a90e 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1022,6 +1022,7 @@ try_again:
 
 		bh->b_state = 0;
 		atomic_set(&bh->b_count, 0);
+		bh->b_private = NULL;
 		bh->b_size = size;
 
 		/* Link the buffer to its page */
@@ -3050,6 +3051,66 @@ asmlinkage long sys_bdflush(int func, lo
 }
 
 /*
+ * Migration function for pages with buffers. This function can only be used
+ * if the underlying filesystem guarantees that no other references to "page"
+ * exist.
+ */
+#ifdef CONFIG_MIGRATION
+int buffer_migrate_page(struct page *newpage, struct page *page)
+{
+	struct address_space *mapping = page->mapping;
+	struct buffer_head *bh, *head;
+
+	if (!mapping)
+		return -EAGAIN;
+
+	if (!page_has_buffers(page))
+		return migrate_page(newpage, page);
+
+	head = page_buffers(page);
+
+	if (migrate_page_remove_references(newpage, page, 3))
+		return -EAGAIN;
+
+	bh = head;
+	do {
+		get_bh(bh);
+		lock_buffer(bh);
+		bh = bh->b_this_page;
+
+	} while (bh != head);
+
+	ClearPagePrivate(page);
+	set_page_private(newpage, page_private(page));
+	set_page_private(page, 0);
+	put_page(page);
+	get_page(newpage);
+
+	bh = head;
+	do {
+		set_bh_page(bh, newpage, bh_offset(bh));
+		bh = bh->b_this_page;
+
+	} while (bh != head);
+
+	SetPagePrivate(newpage);
+
+	migrate_page_copy(newpage, page);
+
+	bh = head;
+	do {
+		unlock_buffer(bh);
+ 		put_bh(bh);
+		bh = bh->b_this_page;
+
+	} while (bh != head);
+
+	return 0;
+}
+EXPORT_SYMBOL(buffer_migrate_page);
+#endif
+
+/*
  * Buffer-head allocation
  */
 static kmem_cache_t *bh_cachep;
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 943ef9b..d335015 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,3 +1,11 @@
+Version 1.40
+------------
+Use fsuid (fsgid) more consistently instead of uid (gid). Improve performance
+of readpages by eliminating one extra memcpy. Allow update of file size
+from remote server even if file is open for write as long as mount is
+directio.  Recognize share mode security and send NTLM encrypted password
+on tree connect if share mode negotiated.
+
 Version 1.39
 ------------
 Defer close of a file handle slightly if pending writes depend on that handle
@@ -7,6 +15,8 @@ Fix SFU style symlinks and mknod needed 
 CIFS Unix Extensions.  Fix setfacl/getfacl on bigendian. Timeout negative
 dentries so files that the client sees as deleted but that later get created
 on the server will be recognized.  Add client side permission check on setattr.
+Timeout stuck requests better (where server has never responded or sent corrupt
+responses)
 
 Version 1.38
 ------------
diff --git a/fs/cifs/README b/fs/cifs/README
index e5d09a2..b0070d1 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -436,7 +436,17 @@ A partial list of the supported mount op
 		SFU does).  In the future the bottom 9 bits of the mode
 		mode also will be emulated using queries of the security
 		descriptor (ACL).
-		
+sec		Security mode.  Allowed values are:
+			none	attempt to connection as a null user (no name)
+			krb5    Use Kerberos version 5 authentication
+			krb5i   Use Kerberos authentication and packet signing
+			ntlm    Use NTLM password hashing (default)
+			ntlmi   Use NTLM password hashing with signing (if
+				/proc/fs/cifs/PacketSigningEnabled on or if
+				server requires signing also can be the default) 
+			ntlmv2  Use NTLMv2 password hashing      
+			ntlmv2i Use NTLMv2 password hashing with packet signing
+
 The mount.cifs mount helper also accepts a few mount options before -o
 including:
 
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 22a444a..f4124a3 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -219,6 +219,10 @@ cifs_stats_write(struct file *file, cons
 
         if (c == '1' || c == 'y' || c == 'Y' || c == '0') {
 		read_lock(&GlobalSMBSeslock);
+#ifdef CONFIG_CIFS_STATS2
+		atomic_set(&totBufAllocCount, 0);
+		atomic_set(&totSmBufAllocCount, 0);
+#endif /* CONFIG_CIFS_STATS2 */
 		list_for_each(tmp, &GlobalTreeConnectionList) {
 			tcon = list_entry(tmp, struct cifsTconInfo,
 					cifsConnectionList);
@@ -276,6 +280,14 @@ cifs_stats_read(char *buf, char **beginB
 			smBufAllocCount.counter,cifs_min_small);
 	length += item_length;
 	buf += item_length;
+#ifdef CONFIG_CIFS_STATS2
+        item_length = sprintf(buf, "Total Large %d Small %d Allocations\n",
+				atomic_read(&totBufAllocCount),
+		                atomic_read(&totSmBufAllocCount));
+	length += item_length;
+	buf += item_length;
+#endif /* CONFIG_CIFS_STATS2 */
+
 	item_length = 
 		sprintf(buf,"Operations (MIDs): %d\n",
 			midCount.counter);
@@ -389,8 +401,8 @@ static read_proc_t ntlmv2_enabled_read;
 static write_proc_t ntlmv2_enabled_write;
 static read_proc_t packet_signing_enabled_read;
 static write_proc_t packet_signing_enabled_write;
-static read_proc_t quotaEnabled_read;
-static write_proc_t quotaEnabled_write;
+static read_proc_t experimEnabled_read;
+static write_proc_t experimEnabled_write;
 static read_proc_t linuxExtensionsEnabled_read;
 static write_proc_t linuxExtensionsEnabled_write;
 
@@ -430,9 +442,9 @@ cifs_proc_init(void)
 		pde->write_proc = oplockEnabled_write;
 
 	pde = create_proc_read_entry("Experimental", 0, proc_fs_cifs,
-				quotaEnabled_read, NULL);
+				experimEnabled_read, NULL);
 	if (pde)
-		pde->write_proc = quotaEnabled_write;
+		pde->write_proc = experimEnabled_write;
 
 	pde = create_proc_read_entry("LinuxExtensionsEnabled", 0, proc_fs_cifs,
 				linuxExtensionsEnabled_read, NULL);
@@ -574,14 +586,13 @@ oplockEnabled_write(struct file *file, c
 }
 
 static int
-quotaEnabled_read(char *page, char **start, off_t off,
+experimEnabled_read(char *page, char **start, off_t off,
                    int count, int *eof, void *data)
 {
         int len;
 
         len = sprintf(page, "%d\n", experimEnabled);
-/* could also check if quotas are enabled in kernel
-	as a whole first */
+
         len -= off;
         *start = page + off;
 
@@ -596,21 +607,23 @@ quotaEnabled_read(char *page, char **sta
         return len;
 }
 static int
-quotaEnabled_write(struct file *file, const char __user *buffer,
+experimEnabled_write(struct file *file, const char __user *buffer,
                     unsigned long count, void *data)
 {
-        char c;
-        int rc;
+	char c;
+	int rc;
 
-        rc = get_user(c, buffer);
-        if (rc)
-                return rc;
-        if (c == '0' || c == 'n' || c == 'N')
-                experimEnabled = 0;
-        else if (c == '1' || c == 'y' || c == 'Y')
-                experimEnabled = 1;
+	rc = get_user(c, buffer);
+	if (rc)
+		return rc;
+	if (c == '0' || c == 'n' || c == 'N')
+		experimEnabled = 0;
+	else if (c == '1' || c == 'y' || c == 'Y')
+		experimEnabled = 1;
+	else if (c == '2')
+		experimEnabled = 2;
 
-        return count;
+	return count;
 }
 
 static int
@@ -620,8 +633,6 @@ linuxExtensionsEnabled_read(char *page, 
         int len;
 
         len = sprintf(page, "%d\n", linuxExtEnabled);
-/* could also check if quotas are enabled in kernel
-	as a whole first */
         len -= off;
         *start = page + off;
 
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index f799f6f..ad58eb0 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -24,9 +24,10 @@
 #define CIFS_MOUNT_DIRECT_IO    8 /* do not write nor read through page cache */
 #define CIFS_MOUNT_NO_XATTR  0x10 /* if set - disable xattr support */
 #define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */
-#define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible. */
-#define CIFS_MOUNT_UNX_EMUL    0x80 /* Network compat with SFUnix emulation */
+#define CIFS_MOUNT_POSIX_PATHS	0x40 /* Negotiate posix pathnames if possible. */
+#define CIFS_MOUNT_UNX_EMUL	0x80 /* Network compat with SFUnix emulation */
 #define CIFS_MOUNT_NO_BRL	0x100 /* No sending byte range locks to srv */
+#define CIFS_MOUNT_CIFS_ACL	0x200 /* send ACL requests to non-POSIX srv */
 
 struct cifs_sb_info {
 	struct cifsTconInfo *tcon;	/* primary mount */
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h
new file mode 100644
index 0000000..d0776ac
--- /dev/null
+++ b/fs/cifs/cifsacl.h
@@ -0,0 +1,38 @@
+/*
+ *   fs/cifs/cifsacl.h
+ *
+ *   Copyright (c) International Business Machines  Corp., 2005
+ *   Author(s): Steve French (sfrench@us.ibm.com)
+ *
+ *   This library is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published
+ *   by the Free Software Foundation; either version 2.1 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This library 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 Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _CIFSACL_H
+#define _CIFSACL_H
+
+struct cifs_sid {
+	__u8 revision; /* revision level */
+	__u8 num_subauths;
+	__u8 authority[6];
+	__u32 sub_auth[4];
+	/* next sub_auth if any ... */
+} __attribute__((packed));
+
+/* everyone */
+extern const struct cifs_sid sid_everyone;
+/* group users */
+extern const struct cifs_sid sid_user;
+
+#endif /* _CIFSACL_H */
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index fe2bb7c..a2c2485 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -1,7 +1,7 @@
 /*
  *   fs/cifs/cifsencrypt.c
  *
- *   Copyright (C) International Business Machines  Corp., 2003
+ *   Copyright (C) International Business Machines  Corp., 2005
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
  *   This library is free software; you can redistribute it and/or modify
@@ -82,6 +82,59 @@ int cifs_sign_smb(struct smb_hdr * cifs_
 	return rc;
 }
 
+static int cifs_calc_signature2(const struct kvec * iov, int n_vec,
+				const char * key, char * signature)
+{
+        struct  MD5Context context;
+
+        if((iov == NULL) || (signature == NULL))
+                return -EINVAL;
+
+        MD5Init(&context);
+        MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16);
+
+/*        MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length); */ /* BB FIXME BB */
+
+        MD5Final(signature,&context);
+
+	return -EOPNOTSUPP;
+/*        return 0; */
+}
+
+
+int cifs_sign_smb2(struct kvec * iov, int n_vec, struct TCP_Server_Info *server,
+		   __u32 * pexpected_response_sequence_number)
+{
+	int rc = 0;
+	char smb_signature[20];
+	struct smb_hdr * cifs_pdu = iov[0].iov_base;
+
+	if((cifs_pdu == NULL) || (server == NULL))
+		return -EINVAL;
+
+	if((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0)
+		return rc;
+
+        spin_lock(&GlobalMid_Lock);
+        cifs_pdu->Signature.Sequence.SequenceNumber = 
+				cpu_to_le32(server->sequence_number);
+        cifs_pdu->Signature.Sequence.Reserved = 0;
+
+        *pexpected_response_sequence_number = server->sequence_number++;
+        server->sequence_number++;
+        spin_unlock(&GlobalMid_Lock);
+
+        rc = cifs_calc_signature2(iov, n_vec, server->mac_signing_key,
+				      smb_signature);
+        if(rc)
+                memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
+        else
+                memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
+
+        return rc;
+
+}
+
 int cifs_verify_signature(struct smb_hdr * cifs_pdu, const char * mac_key,
 	__u32 expected_sequence_number)
 {
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index e10213b..79eeccd 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -513,6 +513,17 @@ static ssize_t cifs_file_aio_write(struc
 	return written;
 }
 
+static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
+{
+	/* origin == SEEK_END => we must revalidate the cached file length */
+	if (origin == 2) {
+		int retval = cifs_revalidate(file->f_dentry);
+		if (retval < 0)
+			return (loff_t)retval;
+	}
+	return remote_llseek(file, offset, origin);
+}
+
 static struct file_system_type cifs_fs_type = {
 	.owner = THIS_MODULE,
 	.name = "cifs",
@@ -586,6 +597,7 @@ struct file_operations cifs_file_ops = {
 	.flush = cifs_flush,
 	.mmap  = cifs_file_mmap,
 	.sendfile = generic_file_sendfile,
+	.llseek = cifs_llseek,
 #ifdef CONFIG_CIFS_POSIX
 	.ioctl	= cifs_ioctl,
 #endif /* CONFIG_CIFS_POSIX */
@@ -609,7 +621,7 @@ struct file_operations cifs_file_direct_
 #ifdef CONFIG_CIFS_POSIX
 	.ioctl  = cifs_ioctl,
 #endif /* CONFIG_CIFS_POSIX */
-
+	.llseek = cifs_llseek,
 #ifdef CONFIG_CIFS_EXPERIMENTAL
 	.dir_notify = cifs_dir_notify,
 #endif /* CONFIG_CIFS_EXPERIMENTAL */
@@ -627,6 +639,7 @@ struct file_operations cifs_file_nobrl_o
 	.flush = cifs_flush,
 	.mmap  = cifs_file_mmap,
 	.sendfile = generic_file_sendfile,
+	.llseek = cifs_llseek,
 #ifdef CONFIG_CIFS_POSIX
 	.ioctl	= cifs_ioctl,
 #endif /* CONFIG_CIFS_POSIX */
@@ -649,7 +662,7 @@ struct file_operations cifs_file_direct_
 #ifdef CONFIG_CIFS_POSIX
 	.ioctl  = cifs_ioctl,
 #endif /* CONFIG_CIFS_POSIX */
-
+	.llseek = cifs_llseek,
 #ifdef CONFIG_CIFS_EXPERIMENTAL
 	.dir_notify = cifs_dir_notify,
 #endif /* CONFIG_CIFS_EXPERIMENTAL */
@@ -733,7 +746,7 @@ cifs_init_request_bufs(void)
 		kmem_cache_destroy(cifs_req_cachep);
 		return -ENOMEM;
 	}
-	/* 256 (MAX_CIFS_HDR_SIZE bytes is enough for most SMB responses and
+	/* MAX_CIFS_SMALL_BUFFER_SIZE bytes is enough for most SMB responses and
 	almost all handle based requests (but not write response, nor is it
 	sufficient for path based requests).  A smaller size would have
 	been more efficient (compacting multiple slab items on one 4k page) 
@@ -742,7 +755,8 @@ cifs_init_request_bufs(void)
 	efficient to alloc 1 per page off the slab compared to 17K (5page) 
 	alloc of large cifs buffers even when page debugging is on */
 	cifs_sm_req_cachep = kmem_cache_create("cifs_small_rq",
-			MAX_CIFS_HDR_SIZE, 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
+			MAX_CIFS_SMALL_BUFFER_SIZE, 0, SLAB_HWCACHE_ALIGN, 
+			NULL, NULL);
 	if (cifs_sm_req_cachep == NULL) {
 		mempool_destroy(cifs_req_poolp);
 		kmem_cache_destroy(cifs_req_cachep);
@@ -954,6 +968,12 @@ init_cifs(void)
 	atomic_set(&tconInfoReconnectCount, 0);
 
 	atomic_set(&bufAllocCount, 0);
+	atomic_set(&smBufAllocCount, 0);
+#ifdef CONFIG_CIFS_STATS2
+	atomic_set(&totBufAllocCount, 0);
+	atomic_set(&totSmBufAllocCount, 0);
+#endif /* CONFIG_CIFS_STATS2 */
+
 	atomic_set(&midCount, 0);
 	GlobalCurrentXid = 0;
 	GlobalTotalActiveXid = 0;
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 9ec40e0..821a8eb 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -99,5 +99,5 @@ extern ssize_t	cifs_getxattr(struct dent
 extern ssize_t	cifs_listxattr(struct dentry *, char *, size_t);
 extern int cifs_ioctl (struct inode * inode, struct file * filep,
 		       unsigned int command, unsigned long arg);
-#define CIFS_VERSION   "1.39"
+#define CIFS_VERSION   "1.40"
 #endif				/* _CIFSFS_H */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 1ba08f8..7bed276 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -233,6 +233,8 @@ struct cifsTconInfo {
 	atomic_t num_hardlinks;
 	atomic_t num_symlinks;
 	atomic_t num_locks;
+	atomic_t num_acl_get;
+	atomic_t num_acl_set;
 #ifdef CONFIG_CIFS_STATS2
 	unsigned long long time_writes;
 	unsigned long long time_reads;
@@ -285,6 +287,7 @@ struct cifs_search_info {
 	unsigned endOfSearch:1;
 	unsigned emptyDir:1;
 	unsigned unicode:1;
+	unsigned smallBuf:1; /* so we know which buf_release function to call */
 };
 
 struct cifsFileInfo {
@@ -420,7 +423,12 @@ struct dir_notify_req {
 #define   MID_RESPONSE_RECEIVED 4
 #define   MID_RETRY_NEEDED      8 /* session closed while this request out */
 #define   MID_NO_RESP_NEEDED 0x10
-#define   MID_SMALL_BUFFER   0x20 /* 112 byte response buffer instead of 4K */
+
+/* Types of response buffer returned from SendReceive2 */
+#define   CIFS_NO_BUFFER        0    /* Response buffer not returned */
+#define   CIFS_SMALL_BUFFER     1
+#define   CIFS_LARGE_BUFFER     2
+#define   CIFS_IOVEC            4    /* array of response buffers */
 
 /*
  *****************************************************************
@@ -505,8 +513,12 @@ GLOBAL_EXTERN atomic_t tcpSesReconnectCo
 GLOBAL_EXTERN atomic_t tconInfoReconnectCount;
 
 /* Various Debug counters to remove someday (BB) */
-GLOBAL_EXTERN atomic_t bufAllocCount;
-GLOBAL_EXTERN atomic_t smBufAllocCount;      
+GLOBAL_EXTERN atomic_t bufAllocCount;    /* current number allocated  */
+#ifdef CONFIG_CIFS_STATS2
+GLOBAL_EXTERN atomic_t totBufAllocCount; /* total allocated over all time */
+GLOBAL_EXTERN atomic_t totSmBufAllocCount;
+#endif
+GLOBAL_EXTERN atomic_t smBufAllocCount;
 GLOBAL_EXTERN atomic_t midCount;
 
 /* Misc globals */
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index 33e1859..cc24710 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -1,7 +1,7 @@
 /*
  *   fs/cifs/cifspdu.h
  *
- *   Copyright (c) International Business Machines  Corp., 2002
+ *   Copyright (c) International Business Machines  Corp., 2002,2005
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
  *   This library is free software; you can redistribute it and/or modify
@@ -80,7 +80,11 @@
 #define NT_TRANSACT_GET_USER_QUOTA    0x07
 #define NT_TRANSACT_SET_USER_QUOTA    0x08
 
-#define MAX_CIFS_HDR_SIZE 256	/* is future chained NTCreateXReadX bigger? */
+#define MAX_CIFS_SMALL_BUFFER_SIZE 448 /* big enough for most */
+/* future chained NTCreateXReadX bigger, but for time being NTCreateX biggest */
+/* among the requests (NTCreateX response is bigger with wct of 34) */
+#define MAX_CIFS_HDR_SIZE 0x58 /* 4 len + 32 hdr + (2*24 wct) + 2 bct + 2 pad */
+#define CIFS_SMALL_PATH 120 /* allows for (448-88)/3 */
 
 /* internal cifs vfs structures */
 /*****************************************************************
@@ -524,7 +528,7 @@ typedef union smb_com_session_setup_andx
 		/* STRING PrimaryDomain */
 		/* STRING NativeOS */
 		/* STRING NativeLanMan */
-	} __attribute__((packed)) old_req;		/* pre-NTLM (LANMAN2.1) request format */
+	} __attribute__((packed)) old_req; /* pre-NTLM (LANMAN2.1) req format */
 
 	struct {		/* default (NTLM) response format */
 		struct smb_hdr hdr;	/* wct = 3 */
@@ -536,7 +540,7 @@ typedef union smb_com_session_setup_andx
 		unsigned char NativeOS[1];	/* followed by */
 /*	unsigned char * NativeLanMan; */
 /*      unsigned char * PrimaryDomain; */
-	} __attribute__((packed)) old_resp;		/* pre-NTLM (LANMAN2.1) response format */
+	} __attribute__((packed)) old_resp; /* pre-NTLM (LANMAN2.1) response */
 } __attribute__((packed)) SESSION_SETUP_ANDX;
 
 #define CIFS_NETWORK_OPSYS "CIFS VFS Client for Linux"
@@ -1003,10 +1007,49 @@ typedef struct smb_com_setattr_rsp {
 
 /* empty wct response to setattr */
 
-/***************************************************/
-/* NT Transact structure defintions follow         */
-/* Currently only ioctl and notify are implemented */
-/***************************************************/
+/*******************************************************/
+/* NT Transact structure defintions follow             */
+/* Currently only ioctl, acl (get security descriptor) */  
+/* and notify are implemented                          */
+/*******************************************************/
+typedef struct smb_com_ntransact_req {
+        struct smb_hdr hdr; /* wct >= 19 */
+        __u8 MaxSetupCount;
+        __u16 Reserved;
+        __le32 TotalParameterCount;
+        __le32 TotalDataCount;
+        __le32 MaxParameterCount;
+        __le32 MaxDataCount;
+        __le32 ParameterCount;
+        __le32 ParameterOffset;
+        __le32 DataCount;
+        __le32 DataOffset;
+        __u8 SetupCount; /* four setup words follow subcommand */
+        /* SNIA spec incorrectly included spurious pad here */
+        __le16 SubCommand; /* 2 = IOCTL/FSCTL */
+	/* SetupCount words follow then */ 
+        __le16 ByteCount;
+        __u8 Pad[3];
+        __u8 Parms[0];
+} __attribute__((packed)) NTRANSACT_REQ;
+
+typedef struct smb_com_ntransact_rsp {
+	struct smb_hdr hdr;     /* wct = 18 */
+	__u8 Reserved[3];
+	__le32 TotalParameterCount;
+	__le32 TotalDataCount;
+	__le32 ParameterCount;
+	__le32 ParameterOffset;
+	__le32 ParameterDisplacement;
+	__le32 DataCount;
+	__le32 DataOffset;
+	__le32 DataDisplacement;
+	__u8 SetupCount;   /* 0 */
+	__u16 ByteCount;
+        /* __u8 Pad[3]; */
+	/* parms and data follow */
+} __attribute__((packed)) NTRANSACT_RSP;
+
 typedef struct smb_com_transaction_ioctl_req {
 	struct smb_hdr hdr;	/* wct = 23 */
 	__u8 MaxSetupCount;
@@ -1021,11 +1064,11 @@ typedef struct smb_com_transaction_ioctl
 	__le32 DataOffset;
 	__u8 SetupCount; /* four setup words follow subcommand */
 	/* SNIA spec incorrectly included spurious pad here */
-	__le16 SubCommand;/* 2 = IOCTL/FSCTL */
+	__le16 SubCommand; /* 2 = IOCTL/FSCTL */
 	__le32 FunctionCode;
 	__u16 Fid;
-	__u8 IsFsctl;    /* 1 = File System Control, 0 = device control (IOCTL)*/
-	__u8 IsRootFlag; /* 1 = apply command to root of share (must be DFS share)*/
+	__u8 IsFsctl;  /* 1 = File System Control 0 = device control (IOCTL) */
+	__u8 IsRootFlag; /* 1 = apply command to root of share (must be DFS) */
 	__le16 ByteCount;
 	__u8 Pad[3];
 	__u8 Data[1];
@@ -1045,9 +1088,35 @@ typedef struct smb_com_transaction_ioctl
 	__u8 SetupCount;	/* 1 */
 	__le16 ReturnedDataLen;
 	__u16 ByteCount;
-	__u8 Pad[3];
 } __attribute__((packed)) TRANSACT_IOCTL_RSP;
 
+#define CIFS_ACL_OWNER 1
+#define CIFS_ACL_GROUP 2
+#define CIFS_ACL_DACL  4
+#define CIFS_ACL_SACL  8
+
+typedef struct smb_com_transaction_qsec_req {
+	struct smb_hdr hdr;     /* wct = 19 */
+	__u8 MaxSetupCount;
+	__u16 Reserved;
+	__le32 TotalParameterCount;
+	__le32 TotalDataCount;
+	__le32 MaxParameterCount;
+	__le32 MaxDataCount;
+	__le32 ParameterCount;
+	__le32 ParameterOffset;
+	__le32 DataCount;
+	__le32 DataOffset;
+	__u8 SetupCount; /* no setup words follow subcommand */
+	/* SNIA spec incorrectly included spurious pad here */
+	__le16 SubCommand; /* 6 = QUERY_SECURITY_DESC */
+	__le16 ByteCount; /* bcc = 3 + 8 */
+	__u8 Pad[3];
+	__u16 Fid;
+	__u16 Reserved2;
+	__le32 AclFlags;
+} __attribute__((packed)) QUERY_SEC_DESC_REQ;
+
 typedef struct smb_com_transaction_change_notify_req {
 	struct smb_hdr hdr;     /* wct = 23 */
 	__u8 MaxSetupCount;
@@ -1068,10 +1137,12 @@ typedef struct smb_com_transaction_chang
 	__u8 WatchTree;  /* 1 = Monitor subdirectories */
 	__u8 Reserved2;
 	__le16 ByteCount;
-/* __u8 Pad[3];*/
+/* 	__u8 Pad[3];*/
 /*	__u8 Data[1];*/
 } __attribute__((packed)) TRANSACT_CHANGE_NOTIFY_REQ;
 
+/* BB eventually change to use generic ntransact rsp struct 
+      and validation routine */
 typedef struct smb_com_transaction_change_notify_rsp {
 	struct smb_hdr hdr;	/* wct = 18 */
 	__u8 Reserved[3];
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 1b73f4f..3c03aad 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -48,8 +48,8 @@ extern int SendReceive(const unsigned in
 			struct smb_hdr * /* out */ ,
 			int * /* bytes returned */ , const int long_op);
 extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
-			struct kvec *, int /* nvec */,
-			int * /* bytes returned */ , const int long_op);
+			struct kvec *, int /* nvec to send */, 
+			int * /* type of buf returned */ , const int long_op);
 extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid);
 extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length);
 extern int is_valid_oplock_break(struct smb_hdr *smb);
@@ -93,11 +93,12 @@ extern int CIFSTCon(unsigned int xid, st
 			const struct nls_table *);
 
 extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
-            const char *searchName, const struct nls_table *nls_codepage,
-            __u16 *searchHandle, struct cifs_search_info * psrch_inf, int map, const char dirsep);
+		const char *searchName, const struct nls_table *nls_codepage,
+		__u16 *searchHandle, struct cifs_search_info * psrch_inf, 
+		int map, const char dirsep);
 
 extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
-            __u16 searchHandle, struct cifs_search_info * psrch_inf);
+		__u16 searchHandle, struct cifs_search_info * psrch_inf);
 
 extern int CIFSFindClose(const int, struct cifsTconInfo *tcon,
 			const __u16 search_handle);
@@ -230,19 +231,18 @@ extern int CIFSSMBClose(const int xid, s
 			const int smb_file_id);
 
 extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
-			const int netfid, unsigned int count,
-			const __u64 lseek, unsigned int *nbytes, char **buf);
+                        const int netfid, unsigned int count,
+                        const __u64 lseek, unsigned int *nbytes, char **buf,
+			int * return_buf_type);
 extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
 			const int netfid, const unsigned int count,
 			const __u64 lseek, unsigned int *nbytes,
 			const char *buf, const char __user *ubuf, 
 			const int long_op);
-#ifdef CONFIG_CIFS_EXPERIMENTAL
 extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
 			const int netfid, const unsigned int count,
 			const __u64 offset, unsigned int *nbytes, 
 			struct kvec *iov, const int nvec, const int long_op);
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
 extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
 			const unsigned char *searchName, __u64 * inode_number,
 			const struct nls_table *nls_codepage, 
@@ -269,6 +269,8 @@ extern void tconInfoFree(struct cifsTcon
 extern int cifs_reconnect(struct TCP_Server_Info *server);
 
 extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *,__u32 *);
+extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
+			  __u32 *);
 extern int cifs_verify_signature(struct smb_hdr *, const char * mac_key,
 	__u32 expected_sequence_number);
 extern int cifs_calculate_mac_key(char * key,const char * rn,const char * pass);
@@ -297,6 +299,9 @@ extern int CIFSSMBSetEA(const int xid, s
 		const char *fileName, const char * ea_name, 
 		const void * ea_value, const __u16 ea_value_len, 
 		const struct nls_table *nls_codepage, int remap_special_chars);
+extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon,
+			__u16 fid, char *acl_inf, const int buflen,
+			const int acl_type /* ACCESS vs. DEFAULT */);
 extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
 		const unsigned char *searchName,
 		char *acl_inf, const int buflen,const int acl_type,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 6867e55..217323b 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -37,6 +37,7 @@
 #include "cifsproto.h"
 #include "cifs_unicode.h"
 #include "cifs_debug.h"
+#include "cifsacl.h"
 
 #ifdef CONFIG_CIFS_POSIX
 static struct {
@@ -372,8 +373,10 @@ CIFSSMBNegotiate(unsigned int xid, struc
 	rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
 	if (rc == 0) {
-		server->secMode = pSMBr->SecurityMode;	
-		server->secType = NTLM; /* BB override default for 
+		server->secMode = pSMBr->SecurityMode;
+		if((server->secMode & SECMODE_USER) == 0)
+			cFYI(1,("share mode security"));
+		server->secType = NTLM; /* BB override default for
 					   NTLMv2 or kerberos v5 */
 		/* one byte - no need to convert this or EncryptionKeyLen
 		   from little endian */
@@ -383,7 +386,7 @@ CIFSSMBNegotiate(unsigned int xid, struc
 			min(le32_to_cpu(pSMBr->MaxBufferSize),
 			(__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE);
 		server->maxRw = le32_to_cpu(pSMBr->MaxRawSize);
-		cFYI(0, ("Max buf = %d ", ses->server->maxBuf));
+		cFYI(0, ("Max buf = %d", ses->server->maxBuf));
 		GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey);
 		server->capabilities = le32_to_cpu(pSMBr->Capabilities);
 		server->timeZone = le16_to_cpu(pSMBr->ServerTimeZone);	
@@ -411,8 +414,7 @@ CIFSSMBNegotiate(unsigned int xid, struc
 						(server->server_GUID,
 						pSMBr->u.extended_response.
 						GUID, 16) != 0) {
-						cFYI(1,
-						     ("UID of server does not match previous connection to same ip address"));
+						cFYI(1, ("server UID changed"));
 						memcpy(server->
 							server_GUID,
 							pSMBr->u.
@@ -958,21 +960,19 @@ openRetry:
 	return rc;
 }
 
-/* If no buffer passed in, then caller wants to do the copy
-	as in the case of readpages so the SMB buffer must be
-	freed by the caller */
-
 int
 CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
-	    const int netfid, const unsigned int count,
-	    const __u64 lseek, unsigned int *nbytes, char **buf)
+            const int netfid, const unsigned int count,
+            const __u64 lseek, unsigned int *nbytes, char **buf,
+	    int * pbuf_type)
 {
 	int rc = -EACCES;
 	READ_REQ *pSMB = NULL;
 	READ_RSP *pSMBr = NULL;
 	char *pReadData = NULL;
-	int bytes_returned;
 	int wct;
+	int resp_buf_type = 0;
+	struct kvec iov[1];
 
 	cFYI(1,("Reading %d bytes on fid %d",count,netfid));
 	if(tcon->ses->capabilities & CAP_LARGE_FILES)
@@ -981,8 +981,7 @@ CIFSSMBRead(const int xid, struct cifsTc
 		wct = 10; /* old style read */
 
 	*nbytes = 0;
-	rc = smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB,
-		      (void **) &pSMBr);
+	rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
 	if (rc)
 		return rc;
 
@@ -990,13 +989,13 @@ CIFSSMBRead(const int xid, struct cifsTc
 	if (tcon->ses->server == NULL)
 		return -ECONNABORTED;
 
-	pSMB->AndXCommand = 0xFF;	/* none */
+	pSMB->AndXCommand = 0xFF;       /* none */
 	pSMB->Fid = netfid;
 	pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF);
 	if(wct == 12)
 		pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);
-        else if((lseek >> 32) > 0) /* can not handle this big offset for old */
-                return -EIO;
+	else if((lseek >> 32) > 0) /* can not handle this big offset for old */
+		return -EIO;
 
 	pSMB->Remaining = 0;
 	pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
@@ -1005,14 +1004,18 @@ CIFSSMBRead(const int xid, struct cifsTc
 		pSMB->ByteCount = 0;  /* no need to do le conversion since 0 */
 	else {
 		/* old style read */
-		struct smb_com_readx_req * pSMBW = 
+		struct smb_com_readx_req * pSMBW =
 			(struct smb_com_readx_req *)pSMB;
-		pSMBW->ByteCount = 0;	
+		pSMBW->ByteCount = 0;
 	}
-	
-	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+
+	iov[0].iov_base = (char *)pSMB;
+	iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
+	rc = SendReceive2(xid, tcon->ses, iov, 
+			  1 /* num iovecs */,
+			  &resp_buf_type, 0); 
 	cifs_stats_inc(&tcon->num_reads);
+	pSMBr = (READ_RSP *)iov[0].iov_base;
 	if (rc) {
 		cERROR(1, ("Send error in read = %d", rc));
 	} else {
@@ -1022,33 +1025,43 @@ CIFSSMBRead(const int xid, struct cifsTc
 		*nbytes = data_length;
 
 		/*check that DataLength would not go beyond end of SMB */
-		if ((data_length > CIFSMaxBufSize) 
+		if ((data_length > CIFSMaxBufSize)
 				|| (data_length > count)) {
 			cFYI(1,("bad length %d for count %d",data_length,count));
 			rc = -EIO;
 			*nbytes = 0;
 		} else {
-			pReadData =
-			    (char *) (&pSMBr->hdr.Protocol) +
+			pReadData = (char *) (&pSMBr->hdr.Protocol) +
 			    le16_to_cpu(pSMBr->DataOffset);
-/*			if(rc = copy_to_user(buf, pReadData, data_length)) {
-				cERROR(1,("Faulting on read rc = %d",rc));
-				rc = -EFAULT;
-			}*/ /* can not use copy_to_user when using page cache*/
+/*                      if(rc = copy_to_user(buf, pReadData, data_length)) {
+                                cERROR(1,("Faulting on read rc = %d",rc));
+                                rc = -EFAULT;
+                        }*/ /* can not use copy_to_user when using page cache*/
 			if(*buf)
-			    memcpy(*buf,pReadData,data_length);
+				memcpy(*buf,pReadData,data_length);
 		}
 	}
-	if(*buf)
-		cifs_buf_release(pSMB);
-	else
-		*buf = (char *)pSMB;
 
-	/* Note: On -EAGAIN error only caller can retry on handle based calls 
+	cifs_small_buf_release(pSMB);
+	if(*buf) {
+		if(resp_buf_type == CIFS_SMALL_BUFFER)
+			cifs_small_buf_release(iov[0].iov_base);
+		else if(resp_buf_type == CIFS_LARGE_BUFFER)
+			cifs_buf_release(iov[0].iov_base);
+	} else /* return buffer to caller to free */ /* BB FIXME how do we tell caller if it is not a large buffer */ {
+		*buf = iov[0].iov_base;
+		if(resp_buf_type == CIFS_SMALL_BUFFER)
+			*pbuf_type = CIFS_SMALL_BUFFER;
+		else if(resp_buf_type == CIFS_LARGE_BUFFER)
+			*pbuf_type = CIFS_LARGE_BUFFER;
+	}
+
+	/* Note: On -EAGAIN error only caller can retry on handle based calls
 		since file handle passed in no longer valid */
 	return rc;
 }
 
+
 int
 CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
 	     const int netfid, const unsigned int count,
@@ -1155,7 +1168,6 @@ CIFSSMBWrite(const int xid, struct cifsT
 	return rc;
 }
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
 int
 CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
 	     const int netfid, const unsigned int count,
@@ -1164,10 +1176,10 @@ CIFSSMBWrite2(const int xid, struct cifs
 {
 	int rc = -EACCES;
 	WRITE_REQ *pSMB = NULL;
-	int bytes_returned, wct;
+	int wct;
 	int smb_hdr_len;
+	int resp_buf_type = 0;
 
-	/* BB removeme BB */
 	cFYI(1,("write2 at %lld %d bytes", (long long)offset, count));
 
 	if(tcon->ses->capabilities & CAP_LARGE_FILES)
@@ -1210,22 +1222,34 @@ CIFSSMBWrite2(const int xid, struct cifs
 		pSMBW->ByteCount = cpu_to_le16(count + 5);
 	}
 	iov[0].iov_base = pSMB;
-	iov[0].iov_len = smb_hdr_len + 4;
+	if(wct == 14)
+		iov[0].iov_len = smb_hdr_len + 4;
+	else /* wct == 12 pad bigger by four bytes */
+		iov[0].iov_len = smb_hdr_len + 8;
+	
 
-	rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &bytes_returned,
+	rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type,
 			  long_op);
 	cifs_stats_inc(&tcon->num_writes);
 	if (rc) {
 		cFYI(1, ("Send error Write2 = %d", rc));
 		*nbytes = 0;
+	} else if(resp_buf_type == 0) {
+		/* presumably this can not happen, but best to be safe */
+		rc = -EIO;
+		*nbytes = 0;
 	} else {
-		WRITE_RSP * pSMBr = (WRITE_RSP *)pSMB;
+		WRITE_RSP * pSMBr = (WRITE_RSP *)iov[0].iov_base;
 		*nbytes = le16_to_cpu(pSMBr->CountHigh);
 		*nbytes = (*nbytes) << 16;
 		*nbytes += le16_to_cpu(pSMBr->Count);
-	}
+	} 
 
 	cifs_small_buf_release(pSMB);
+	if(resp_buf_type == CIFS_SMALL_BUFFER)
+		cifs_small_buf_release(iov[0].iov_base);
+	else if(resp_buf_type == CIFS_LARGE_BUFFER)
+		cifs_buf_release(iov[0].iov_base);
 
 	/* Note: On -EAGAIN error only caller can retry on handle based calls 
 		since file handle passed in no longer valid */
@@ -1234,8 +1258,6 @@ CIFSSMBWrite2(const int xid, struct cifs
 }
 
 
-#endif /* CIFS_EXPERIMENTAL */
-
 int
 CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
 	    const __u16 smb_file_id, const __u64 len,
@@ -1906,6 +1928,90 @@ querySymLinkRetry:
 	return rc;
 }
 
+/* Initialize NT TRANSACT SMB into small smb request buffer.
+   This assumes that all NT TRANSACTS that we init here have
+   total parm and data under about 400 bytes (to fit in small cifs
+   buffer size), which is the case so far, it easily fits. NB:
+	Setup words themselves and ByteCount
+	MaxSetupCount (size of returned setup area) and
+	MaxParameterCount (returned parms size) must be set by caller */
+static int 
+smb_init_ntransact(const __u16 sub_command, const int setup_count,
+		   const int parm_len, struct cifsTconInfo *tcon,
+		   void ** ret_buf)
+{
+	int rc;
+	__u32 temp_offset;
+	struct smb_com_ntransact_req * pSMB;
+
+	rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
+				(void **)&pSMB);
+	if (rc)
+		return rc;
+	*ret_buf = (void *)pSMB;
+	pSMB->Reserved = 0;
+	pSMB->TotalParameterCount = cpu_to_le32(parm_len);
+	pSMB->TotalDataCount  = 0;
+	pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
+					  MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
+	pSMB->ParameterCount = pSMB->TotalParameterCount;
+	pSMB->DataCount  = pSMB->TotalDataCount;
+	temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
+			(setup_count * 2) - 4 /* for rfc1001 length itself */;
+	pSMB->ParameterOffset = cpu_to_le32(temp_offset);
+	pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
+	pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
+	pSMB->SubCommand = cpu_to_le16(sub_command);
+	return 0;
+}
+
+static int
+validate_ntransact(char * buf, char ** ppparm, char ** ppdata,
+		   int * pdatalen, int * pparmlen)
+{
+	char * end_of_smb;
+	__u32 data_count, data_offset, parm_count, parm_offset;
+	struct smb_com_ntransact_rsp * pSMBr;
+
+	if(buf == NULL)
+		return -EINVAL;
+
+	pSMBr = (struct smb_com_ntransact_rsp *)buf;
+
+	/* ByteCount was converted from little endian in SendReceive */
+	end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount + 
+			(char *)&pSMBr->ByteCount;
+
+		
+	data_offset = le32_to_cpu(pSMBr->DataOffset);
+	data_count = le32_to_cpu(pSMBr->DataCount);
+        parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
+	parm_count = le32_to_cpu(pSMBr->ParameterCount);
+
+	*ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
+	*ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
+
+	/* should we also check that parm and data areas do not overlap? */
+	if(*ppparm > end_of_smb) {
+		cFYI(1,("parms start after end of smb"));
+		return -EINVAL;
+	} else if(parm_count + *ppparm > end_of_smb) {
+		cFYI(1,("parm end after end of smb"));
+		return -EINVAL;
+	} else if(*ppdata > end_of_smb) {
+		cFYI(1,("data starts after end of smb"));
+		return -EINVAL;
+	} else if(data_count + *ppdata > end_of_smb) {
+		cFYI(1,("data %p + count %d (%p) ends after end of smb %p start %p",
+			*ppdata, data_count, (data_count + *ppdata), end_of_smb, pSMBr));  /* BB FIXME */
+		return -EINVAL;
+	} else if(parm_count + data_count > pSMBr->ByteCount) {
+		cFYI(1,("parm count and data count larger than SMB"));
+		return -EINVAL;
+	}
+	return 0;
+}
+
 int
 CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
 			const unsigned char *searchName,
@@ -1928,7 +2034,8 @@ CIFSSMBQueryReparseLinkInfo(const int xi
 	pSMB->TotalDataCount = 0;
 	pSMB->MaxParameterCount = cpu_to_le32(2);
 	/* BB find exact data count max from sess structure BB */
-	pSMB->MaxDataCount = cpu_to_le32(4000);
+	pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
+					  MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
 	pSMB->MaxSetupCount = 4;
 	pSMB->Reserved = 0;
 	pSMB->ParameterOffset = 0;
@@ -1955,7 +2062,9 @@ CIFSSMBQueryReparseLinkInfo(const int xi
 			rc = -EIO;	/* bad smb */
 		else {
 			if(data_count && (data_count < 2048)) {
-				char * end_of_smb = pSMBr->ByteCount + (char *)&pSMBr->ByteCount;
+				char * end_of_smb = 2 /* sizeof byte count */ +
+						pSMBr->ByteCount +
+						(char *)&pSMBr->ByteCount;
 
 				struct reparse_data * reparse_buf = (struct reparse_data *)
 					((char *)&pSMBr->hdr.Protocol + data_offset);
@@ -2199,6 +2308,7 @@ queryAclRetry:
 
 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
 		(struct smb_hdr *) pSMBr, &bytes_returned, 0);
+	cifs_stats_inc(&tcon->num_acl_get);
 	if (rc) {
 		cFYI(1, ("Send error in Query POSIX ACL = %d", rc));
 	} else {
@@ -2386,6 +2496,92 @@ GetExtAttrOut:
 
 #endif /* CONFIG_POSIX */
 
+
+/* security id for everyone */
+const struct cifs_sid sid_everyone = {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}};
+/* group users */
+const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}};
+
+/* Convert CIFS ACL to POSIX form */
+static int parse_sec_desc(struct cifs_sid * psec_desc, int acl_len)
+{
+	return 0;
+}
+
+/* Get Security Descriptor (by handle) from remote server for a file or dir */
+int
+CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
+         /*  BB fix up return info */ char *acl_inf, const int buflen, 
+		  const int acl_type /* ACCESS/DEFAULT not sure implication */)
+{
+	int rc = 0;
+	int buf_type = 0;
+	QUERY_SEC_DESC_REQ * pSMB;
+	struct kvec iov[1];
+
+	cFYI(1, ("GetCifsACL"));
+
+	rc = smb_init_ntransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0, 
+			8 /* parm len */, tcon, (void **) &pSMB);
+	if (rc)
+		return rc;
+
+	pSMB->MaxParameterCount = cpu_to_le32(4);
+	/* BB TEST with big acls that might need to be e.g. larger than 16K */
+	pSMB->MaxSetupCount = 0;
+	pSMB->Fid = fid; /* file handle always le */
+	pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
+				     CIFS_ACL_DACL);
+	pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
+	pSMB->hdr.smb_buf_length += 11;
+	iov[0].iov_base = (char *)pSMB;
+	iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
+
+	rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 0);
+	cifs_stats_inc(&tcon->num_acl_get);
+	if (rc) {
+		cFYI(1, ("Send error in QuerySecDesc = %d", rc));
+	} else {                /* decode response */
+		struct cifs_sid * psec_desc;
+		__le32 * parm;
+		int parm_len;
+		int data_len;
+		int acl_len;
+		struct smb_com_ntransact_rsp * pSMBr;
+
+/* validate_nttransact */
+		rc = validate_ntransact(iov[0].iov_base, (char **)&parm, 
+					(char **)&psec_desc,
+					&parm_len, &data_len);
+		
+		if(rc)
+			goto qsec_out;
+		pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
+
+		cERROR(1,("smb %p parm %p data %p",pSMBr,parm,psec_desc));  /* BB removeme BB */
+
+		if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
+			rc = -EIO;      /* bad smb */
+			goto qsec_out;
+		}
+
+/* BB check that data area is minimum length and as big as acl_len */
+
+		acl_len = le32_to_cpu(*(__le32 *)parm);
+		/* BB check if(acl_len > bufsize) */
+
+		parse_sec_desc(psec_desc, acl_len);
+	}
+qsec_out:
+	if(buf_type == CIFS_SMALL_BUFFER)
+		cifs_small_buf_release(iov[0].iov_base);
+	else if(buf_type == CIFS_LARGE_BUFFER)
+		cifs_buf_release(iov[0].iov_base);
+	cifs_small_buf_release(pSMB);
+	return rc;
+}
+
+
 /* Legacy Query Path Information call for lookup to old servers such
    as Win9x/WinME */
 int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
@@ -4284,7 +4480,7 @@ int CIFSSMBNotify(const int xid, struct 
 {
 	int rc = 0;
 	struct smb_com_transaction_change_notify_req * pSMB = NULL;
-	struct smb_com_transaction_change_notify_rsp * pSMBr = NULL;
+	struct smb_com_ntransaction_change_notify_rsp * pSMBr = NULL;
 	struct dir_notify_req *dnotify_req;
 	int bytes_returned;
 
@@ -4299,6 +4495,10 @@ int CIFSSMBNotify(const int xid, struct 
 	pSMB->MaxParameterCount = cpu_to_le32(2);
 	/* BB find exact data count max from sess structure BB */
 	pSMB->MaxDataCount = 0; /* same in little endian or be */
+/* BB VERIFY verify which is correct for above BB */
+	pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
+					     MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
+
 	pSMB->MaxSetupCount = 4;
 	pSMB->Reserved = 0;
 	pSMB->ParameterOffset = 0;
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index c467de8..e488603 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -76,12 +76,19 @@ struct smb_vol {
 	unsigned setuids:1;
 	unsigned noperm:1;
 	unsigned no_psx_acl:1; /* set if posix acl support should be disabled */
+	unsigned cifs_acl:1;
 	unsigned no_xattr:1;   /* set if xattr (EA) support should be disabled*/
 	unsigned server_ino:1; /* use inode numbers from server ie UniqueId */
 	unsigned direct_io:1;
 	unsigned remap:1;   /* set to remap seven reserved chars in filenames */
 	unsigned posix_paths:1;   /* unset to not ask for posix pathnames. */
 	unsigned sfu_emul:1;
+	unsigned krb5:1;
+	unsigned ntlm:1;
+	unsigned ntlmv2:1;
+	unsigned nullauth:1; /* attempt to authenticate with null user */
+	unsigned sign:1;
+	unsigned seal:1;     /* encrypt */
 	unsigned nocase;     /* request case insensitive filenames */
 	unsigned nobrl;      /* disable sending byte range locks to srv */
 	unsigned int rsize;
@@ -508,7 +515,7 @@ cifs_demultiplex_thread(struct TCP_Serve
 		/* else length ok */
 		reconnect = 0;
 
-		if(pdu_length > MAX_CIFS_HDR_SIZE - 4) {
+		if(pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
 			isLargeBuf = TRUE;
 			memcpy(bigbuf, smallbuf, 4);
 			smb_buffer = bigbuf;
@@ -777,7 +784,7 @@ cifs_parse_mount_options(char *options, 
 
 	/* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
 	vol->rw = TRUE;
-
+	vol->ntlm = TRUE;
 	/* default is always to request posix paths. */
 	vol->posix_paths = 1;
 
@@ -903,6 +910,39 @@ cifs_parse_mount_options(char *options, 
 				printk(KERN_WARNING "CIFS: ip address too long\n");
 				return 1;
 			}
+                } else if (strnicmp(data, "sec", 3) == 0) { 
+                        if (!value || !*value) {
+				cERROR(1,("no security value specified"));
+                                continue;
+                        } else if (strnicmp(value, "krb5i", 5) == 0) {
+				vol->sign = 1;
+				vol->krb5 = 1;
+			} else if (strnicmp(value, "krb5p", 5) == 0) {
+				/* vol->seal = 1; 
+				   vol->krb5 = 1; */
+				cERROR(1,("Krb5 cifs privacy not supported"));
+				return 1;
+			} else if (strnicmp(value, "krb5", 4) == 0) {
+				vol->krb5 = 1;
+			} else if (strnicmp(value, "ntlmv2i", 7) == 0) {
+				vol->ntlmv2 = 1;
+				vol->sign = 1;
+			} else if (strnicmp(value, "ntlmv2", 6) == 0) {
+				vol->ntlmv2 = 1;
+			} else if (strnicmp(value, "ntlmi", 5) == 0) {
+				vol->ntlm = 1;
+				vol->sign = 1;
+			} else if (strnicmp(value, "ntlm", 4) == 0) {
+				/* ntlm is default so can be turned off too */
+				vol->ntlm = 1;
+			} else if (strnicmp(value, "nontlm", 6) == 0) {
+				vol->ntlm = 0;
+			} else if (strnicmp(value, "none", 4) == 0) {
+				vol->nullauth = 1; 
+                        } else {
+                                cERROR(1,("bad security option: %s", value));
+                                return 1;
+                        }
 		} else if ((strnicmp(data, "unc", 3) == 0)
 			   || (strnicmp(data, "target", 6) == 0)
 			   || (strnicmp(data, "path", 4) == 0)) {
@@ -1120,6 +1160,10 @@ cifs_parse_mount_options(char *options, 
 			vol->server_ino = 1;
 		} else if (strnicmp(data, "noserverino",9) == 0) {
 			vol->server_ino = 0;
+		} else if (strnicmp(data, "cifsacl",7) == 0) {
+			vol->cifs_acl = 1;
+		} else if (strnicmp(data, "nocifsacl", 9) == 0) {
+			vol->cifs_acl = 0;
 		} else if (strnicmp(data, "acl",3) == 0) {
 			vol->no_psx_acl = 0;
 		} else if (strnicmp(data, "noacl",5) == 0) {
@@ -1546,7 +1590,7 @@ cifs_mount(struct super_block *sb, struc
 		cFYI(1, ("Username: %s ", volume_info.username));
 
 	} else {
-		cifserror("No username specified ");
+		cifserror("No username specified");
         /* In userspace mount helper we can get user name from alternate
            locations such as env variables and files on disk */
 		kfree(volume_info.UNC);
@@ -1587,7 +1631,7 @@ cifs_mount(struct super_block *sb, struc
 		return -EINVAL;
 	} else /* which servers DFS root would we conect to */ {
 		cERROR(1,
-		       ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified  "));
+		       ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified"));
 		kfree(volume_info.UNC);
 		kfree(volume_info.password);
 		FreeXid(xid);
@@ -1626,7 +1670,7 @@ cifs_mount(struct super_block *sb, struc
 
 
 	if (srvTcp) {
-		cFYI(1, ("Existing tcp session with server found "));                
+		cFYI(1, ("Existing tcp session with server found"));                
 	} else {	/* create socket */
 		if(volume_info.port)
 			sin_server.sin_port = htons(volume_info.port);
@@ -1689,11 +1733,11 @@ cifs_mount(struct super_block *sb, struc
 
 	if (existingCifsSes) {
 		pSesInfo = existingCifsSes;
-		cFYI(1, ("Existing smb sess found "));
+		cFYI(1, ("Existing smb sess found"));
 		kfree(volume_info.password);
 		/* volume_info.UNC freed at end of function */
 	} else if (!rc) {
-		cFYI(1, ("Existing smb sess not found "));
+		cFYI(1, ("Existing smb sess not found"));
 		pSesInfo = sesInfoAlloc();
 		if (pSesInfo == NULL)
 			rc = -ENOMEM;
@@ -1741,7 +1785,16 @@ cifs_mount(struct super_block *sb, struc
 		} else if(volume_info.wsize)
 			cifs_sb->wsize = volume_info.wsize;
 		else
-			cifs_sb->wsize = CIFSMaxBufSize; /* default */
+			cifs_sb->wsize = 
+				min_t(const int, PAGEVEC_SIZE * PAGE_CACHE_SIZE,
+					127*1024);
+			/* old default of CIFSMaxBufSize was too small now
+			   that SMB Write2 can send multiple pages in kvec.   
+			   RFC1001 does not describe what happens when frame
+			   bigger than 128K is sent so use that as max in
+			   conjunction with 52K kvec constraint on arch with 4K
+			   page size  */
+
 		if(cifs_sb->rsize < PAGE_CACHE_SIZE) {
 			cifs_sb->rsize = PAGE_CACHE_SIZE; 
 			/* Windows ME does this */
@@ -1751,7 +1804,8 @@ cifs_mount(struct super_block *sb, struc
 		cifs_sb->mnt_gid = volume_info.linux_gid;
 		cifs_sb->mnt_file_mode = volume_info.file_mode;
 		cifs_sb->mnt_dir_mode = volume_info.dir_mode;
-		cFYI(1,("file mode: 0x%x  dir mode: 0x%x",cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode));
+		cFYI(1,("file mode: 0x%x  dir mode: 0x%x",
+			cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode));
 
 		if(volume_info.noperm)
 			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
@@ -1767,6 +1821,8 @@ cifs_mount(struct super_block *sb, struc
 			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
 		if(volume_info.nobrl)
 			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
+		if(volume_info.cifs_acl)
+			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
 
 		if(volume_info.direct_io) {
 			cFYI(1,("mounting share using direct i/o"));
@@ -1777,7 +1833,7 @@ cifs_mount(struct super_block *sb, struc
 		    find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
 			     volume_info.username);
 		if (tcon) {
-			cFYI(1, ("Found match on UNC path "));
+			cFYI(1, ("Found match on UNC path"));
 			/* we can have only one retry value for a connection
 			   to a share so for resources mounted more than once
 			   to the same server share the last value passed in 
@@ -1926,7 +1982,7 @@ CIFSSessSetup(unsigned int xid, struct c
 	__u32 capabilities;
 	__u16 count;
 
-	cFYI(1, ("In sesssetup "));
+	cFYI(1, ("In sesssetup"));
 	if(ses == NULL)
 		return -EINVAL;
 	user = ses->userName;
@@ -3202,9 +3258,26 @@ CIFSTCon(unsigned int xid, struct cifsSe
 
 	pSMB->AndXCommand = 0xFF;
 	pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
-	pSMB->PasswordLength = cpu_to_le16(1);	/* minimum */
 	bcc_ptr = &pSMB->Password[0];
-	bcc_ptr++;		/* skip password */
+	if((ses->server->secMode) & SECMODE_USER) {
+		pSMB->PasswordLength = cpu_to_le16(1);	/* minimum */
+		bcc_ptr++;              /* skip password */
+	} else {
+		pSMB->PasswordLength = cpu_to_le16(CIFS_SESSION_KEY_SIZE);
+		/* BB FIXME add code to fail this if NTLMv2 or Kerberos
+		   specified as required (when that support is added to
+		   the vfs in the future) as only NTLM or the much
+		   weaker LANMAN (which we do not send) is accepted
+		   by Samba (not sure whether other servers allow
+		   NTLMv2 password here) */
+		SMBNTencrypt(ses->password,
+			     ses->server->cryptKey,
+			     bcc_ptr);
+
+		bcc_ptr += CIFS_SESSION_KEY_SIZE;
+		*bcc_ptr = 0;
+		bcc_ptr++; /* align */
+	}
 
 	if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
 		smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
@@ -3222,7 +3295,6 @@ CIFSTCon(unsigned int xid, struct cifsSe
 		bcc_ptr += 2 * length;	/* convert num of 16 bit words to bytes */
 		bcc_ptr += 2;	/* skip trailing null */
 	} else {		/* ASCII */
-
 		strcpy(bcc_ptr, tree);
 		bcc_ptr += strlen(tree) + 1;
 	}
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 32cc96c..fed55e3 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -3,7 +3,7 @@
  *
  *   vfs operations that deal with dentries
  * 
- *   Copyright (C) International Business Machines  Corp., 2002,2003
+ *   Copyright (C) International Business Machines  Corp., 2002,2005
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
  *   This library is free software; you can redistribute it and/or modify
@@ -200,8 +200,8 @@ cifs_create(struct inode *inode, struct 
 			(oplock & CIFS_CREATE_ACTION))
 			if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
 				CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
-					(__u64)current->euid,
-					(__u64)current->egid,
+					(__u64)current->fsuid,
+					(__u64)current->fsgid,
 					0 /* dev */,
 					cifs_sb->local_nls, 
 					cifs_sb->mnt_cifs_flags & 
@@ -325,7 +325,7 @@ int cifs_mknod(struct inode *inode, stru
 	else if (pTcon->ses->capabilities & CAP_UNIX) {
 		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
 			rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path,
-				mode,(__u64)current->euid,(__u64)current->egid,
+				mode,(__u64)current->fsuid,(__u64)current->fsgid,
 				device_number, cifs_sb->local_nls,
 				cifs_sb->mnt_cifs_flags & 
 					CIFS_MOUNT_MAP_SPECIAL_CHR);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 5ade53d..d17c97d 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -553,13 +553,13 @@ int cifs_closedir(struct inode *inode, s
 		}
 		ptmp = pCFileStruct->srch_inf.ntwrk_buf_start;
 		if (ptmp) {
-   /* BB removeme BB */	cFYI(1, ("freeing smb buf in srch struct in closedir"));
+			cFYI(1, ("closedir free smb buf in srch struct"));
 			pCFileStruct->srch_inf.ntwrk_buf_start = NULL;
 			cifs_buf_release(ptmp);
 		}
 		ptmp = pCFileStruct->search_resume_name;
 		if (ptmp) {
-   /* BB removeme BB */	cFYI(1, ("freeing resume name in closedir"));
+			cFYI(1, ("closedir free resume name"));
 			pCFileStruct->search_resume_name = NULL;
 			kfree(ptmp);
 		}
@@ -868,10 +868,9 @@ static ssize_t cifs_write(struct file *f
 				if (rc != 0)
 					break;
 			}
-#ifdef CONFIG_CIFS_EXPERIMENTAL
 			/* BB FIXME We can not sign across two buffers yet */
-			if((experimEnabled) && ((pTcon->ses->server->secMode & 
-			 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0)) {
+			if((pTcon->ses->server->secMode & 
+			 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0) {
 				struct kvec iov[2];
 				unsigned int len;
 
@@ -887,7 +886,6 @@ static ssize_t cifs_write(struct file *f
 						iov, 1, long_op);
 			} else
 			/* BB FIXME fixup indentation of line below */
-#endif			
 			rc = CIFSSMBWrite(xid, pTcon,
 				 open_file->netfid,
 				 min_t(const int, cifs_sb->wsize, 
@@ -1024,7 +1022,6 @@ static int cifs_partialpagewrite(struct 
 	return rc;
 }
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
 static int cifs_writepages(struct address_space *mapping,
 			   struct writeback_control *wbc)
 {
@@ -1193,7 +1190,6 @@ retry:
 					/* BB what if continued retry is
 					   requested via mount flags? */
 					set_bit(AS_EIO, &mapping->flags);
-					SetPageError(page);
 				} else {
 					cifs_stats_bytes_written(cifs_sb->tcon,
 								 bytes_written);
@@ -1201,6 +1197,13 @@ retry:
 			}
 			for (i = 0; i < n_iov; i++) {
 				page = pvec.pages[first + i];
+				/* Should we also set page error on
+				success rc but too little data written? */
+				/* BB investigate retry logic on temporary
+				server crash cases and how recovery works
+				when page marked as error */ 
+				if(rc)
+					SetPageError(page);
 				kunmap(page);
 				unlock_page(page);
 				page_cache_release(page);
@@ -1227,7 +1230,6 @@ retry:
 
 	return rc;
 }
-#endif
 
 static int cifs_writepage(struct page* page, struct writeback_control *wbc)
 {
@@ -1426,6 +1428,7 @@ ssize_t cifs_user_read(struct file *file
 		rc = -EAGAIN;
 		smb_read_data = NULL;
 		while (rc == -EAGAIN) {
+			int buf_type = CIFS_NO_BUFFER;
 			if ((open_file->invalidHandle) && 
 			    (!open_file->closePend)) {
 				rc = cifs_reopen_file(file->f_dentry->d_inode,
@@ -1434,20 +1437,22 @@ ssize_t cifs_user_read(struct file *file
 					break;
 			}
 			rc = CIFSSMBRead(xid, pTcon,
-					open_file->netfid,
-					current_read_size, *poffset,
-					&bytes_read, &smb_read_data);
+					 open_file->netfid,
+					 current_read_size, *poffset,
+					 &bytes_read, &smb_read_data,
+					 &buf_type);
 			pSMBr = (struct smb_com_read_rsp *)smb_read_data;
 			if (copy_to_user(current_offset, 
 					 smb_read_data + 4 /* RFC1001 hdr */
 					 + le16_to_cpu(pSMBr->DataOffset), 
 					 bytes_read)) {
 				rc = -EFAULT;
-				FreeXid(xid);
-				return rc;
-            }
+			}
 			if (smb_read_data) {
-				cifs_buf_release(smb_read_data);
+				if(buf_type == CIFS_SMALL_BUFFER)
+					cifs_small_buf_release(smb_read_data);
+				else if(buf_type == CIFS_LARGE_BUFFER)
+					cifs_buf_release(smb_read_data);
 				smb_read_data = NULL;
 			}
 		}
@@ -1480,6 +1485,7 @@ static ssize_t cifs_read(struct file *fi
 	int xid;
 	char *current_offset;
 	struct cifsFileInfo *open_file;
+	int buf_type = CIFS_NO_BUFFER;
 
 	xid = GetXid();
 	cifs_sb = CIFS_SB(file->f_dentry->d_sb);
@@ -1516,9 +1522,10 @@ static ssize_t cifs_read(struct file *fi
 					break;
 			}
 			rc = CIFSSMBRead(xid, pTcon,
-					open_file->netfid,
-					current_read_size, *poffset,
-					&bytes_read, &current_offset);
+					 open_file->netfid,
+					 current_read_size, *poffset,
+					 &bytes_read, &current_offset,
+					 &buf_type);
 		}
 		if (rc || (bytes_read == 0)) {
 			if (total_read) {
@@ -1616,6 +1623,7 @@ static int cifs_readpages(struct file *f
 	struct smb_com_read_rsp *pSMBr;
 	struct pagevec lru_pvec;
 	struct cifsFileInfo *open_file;
+	int buf_type = CIFS_NO_BUFFER;
 
 	xid = GetXid();
 	if (file->private_data == NULL) {
@@ -1672,14 +1680,17 @@ static int cifs_readpages(struct file *f
 			}
 
 			rc = CIFSSMBRead(xid, pTcon,
-					open_file->netfid,
-					read_size, offset,
-					&bytes_read, &smb_read_data);
-
+					 open_file->netfid,
+					 read_size, offset,
+					 &bytes_read, &smb_read_data,
+					 &buf_type);
 			/* BB more RC checks ? */
 			if (rc== -EAGAIN) {
 				if (smb_read_data) {
-					cifs_buf_release(smb_read_data);
+					if(buf_type == CIFS_SMALL_BUFFER)
+						cifs_small_buf_release(smb_read_data);
+					else if(buf_type == CIFS_LARGE_BUFFER)
+						cifs_buf_release(smb_read_data);
 					smb_read_data = NULL;
 				}
 			}
@@ -1736,7 +1747,10 @@ static int cifs_readpages(struct file *f
 			break;
 		}
 		if (smb_read_data) {
-			cifs_buf_release(smb_read_data);
+			if(buf_type == CIFS_SMALL_BUFFER)
+				cifs_small_buf_release(smb_read_data);
+			else if(buf_type == CIFS_LARGE_BUFFER)
+				cifs_buf_release(smb_read_data);
 			smb_read_data = NULL;
 		}
 		bytes_read = 0;
@@ -1746,7 +1760,10 @@ static int cifs_readpages(struct file *f
 
 /* need to free smb_read_data buf before exit */
 	if (smb_read_data) {
-		cifs_buf_release(smb_read_data);
+		if(buf_type == CIFS_SMALL_BUFFER)
+			cifs_small_buf_release(smb_read_data);
+		else if(buf_type == CIFS_LARGE_BUFFER)
+			cifs_buf_release(smb_read_data);
 		smb_read_data = NULL;
 	} 
 
@@ -1825,10 +1842,20 @@ int is_size_safe_to_change(struct cifsIn
 		open_file =  find_writable_file(cifsInode);
  
 	if(open_file) {
+		struct cifs_sb_info *cifs_sb;
+
 		/* there is not actually a write pending so let
 		this handle go free and allow it to
 		be closable if needed */
 		atomic_dec(&open_file->wrtPending);
+
+		cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb);
+		if ( cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO ) {
+			/* since no page cache to corrupt on directio 
+			we can change size safely */
+			return 1;
+		}
+
 		return 0;
 	} else
 		return 1;
@@ -1873,9 +1900,7 @@ struct address_space_operations cifs_add
 	.readpage = cifs_readpage,
 	.readpages = cifs_readpages,
 	.writepage = cifs_writepage,
-#ifdef CONFIG_CIFS_EXPERIMENTAL
 	.writepages = cifs_writepages,
-#endif
 	.prepare_write = cifs_prepare_write,
 	.commit_write = cifs_commit_write,
 	.set_page_dirty = __set_page_dirty_nobuffers,
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 3ebce94..5935991 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -229,11 +229,12 @@ static int decode_sfu_inode(struct inode
 			 cifs_sb->mnt_cifs_flags &
 				CIFS_MOUNT_MAP_SPECIAL_CHR);
 	if (rc==0) {
+		int buf_type = CIFS_NO_BUFFER;
 			/* Read header */
 		rc = CIFSSMBRead(xid, pTcon,
 			         netfid,
 				 24 /* length */, 0 /* offset */,
-				 &bytes_read, &pbuf);
+				 &bytes_read, &pbuf, &buf_type);
 		if((rc == 0) && (bytes_read >= 8)) {
 			if(memcmp("IntxBLK", pbuf, 8) == 0) {
 				cFYI(1,("Block device"));
@@ -267,7 +268,7 @@ static int decode_sfu_inode(struct inode
 		} else {
 			inode->i_mode |= S_IFREG; /* then it is a file */
 			rc = -EOPNOTSUPP; /* or some unknown SFU type */	
-		}
+		}		
 		CIFSSMBClose(xid, pTcon, netfid);
 	}
 	return rc;
@@ -750,8 +751,8 @@ int cifs_mkdir(struct inode *inode, stru
 			if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
 				CIFSSMBUnixSetPerms(xid, pTcon, full_path,
 						    mode,
-						    (__u64)current->euid,
-						    (__u64)current->egid,
+						    (__u64)current->fsuid,
+						    (__u64)current->fsgid,
 						    0 /* dev_t */,
 						    cifs_sb->local_nls,
 						    cifs_sb->mnt_cifs_flags &
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 94baf6c..812c6bb 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -1,7 +1,7 @@
 /*
  *   fs/cifs/misc.c
  *
- *   Copyright (C) International Business Machines  Corp., 2002,2004
+ *   Copyright (C) International Business Machines  Corp., 2002,2005
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
  *   This library is free software; you can redistribute it and/or modify
@@ -161,6 +161,9 @@ cifs_buf_get(void)
 	if (ret_buf) {
 		memset(ret_buf, 0, sizeof(struct smb_hdr) + 3);
 		atomic_inc(&bufAllocCount);
+#ifdef CONFIG_CIFS_STATS2
+		atomic_inc(&totBufAllocCount);
+#endif /* CONFIG_CIFS_STATS2 */
 	}
 
 	return ret_buf;
@@ -195,6 +198,10 @@ cifs_small_buf_get(void)
 	/* No need to clear memory here, cleared in header assemble */
 	/*	memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/
 		atomic_inc(&smBufAllocCount);
+#ifdef CONFIG_CIFS_STATS2
+		atomic_inc(&totSmBufAllocCount);
+#endif /* CONFIG_CIFS_STATS2 */
+
 	}
 	return ret_buf;
 }
@@ -292,7 +299,7 @@ header_assemble(struct smb_hdr *buffer, 
 	struct cifsSesInfo * ses;
 	char *temp = (char *) buffer;
 
-	memset(temp,0,MAX_CIFS_HDR_SIZE);
+	memset(temp,0,256); /* bigger than MAX_CIFS_HDR_SIZE */
 
 	buffer->smb_buf_length =
 	    (2 * word_count) + sizeof (struct smb_hdr) -
@@ -348,12 +355,12 @@ header_assemble(struct smb_hdr *buffer, 
 		/*  BB Add support for establishing new tCon and SMB Session  */
 		/*      with userid/password pairs found on the smb session   */ 
 		/*	for other target tcp/ip addresses 		BB    */
-				if(current->uid != treeCon->ses->linux_uid) {
-					cFYI(1,("Multiuser mode and UID did not match tcon uid "));
+				if(current->fsuid != treeCon->ses->linux_uid) {
+					cFYI(1,("Multiuser mode and UID did not match tcon uid"));
 					read_lock(&GlobalSMBSeslock);
 					list_for_each(temp_item, &GlobalSMBSessionList) {
 						ses = list_entry(temp_item, struct cifsSesInfo, cifsSessionList);
-						if(ses->linux_uid == current->uid) {
+						if(ses->linux_uid == current->fsuid) {
 							if(ses->server == treeCon->ses->server) {
 								cFYI(1,("found matching uid substitute right smb_uid"));  
 								buffer->Uid = ses->Suid;
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 9bdaaec..288cc04 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -214,8 +214,7 @@ static void fill_in_inode(struct inode *
 			tmp_inode->i_fop = &cifs_file_nobrl_ops;
 		else
 			tmp_inode->i_fop = &cifs_file_ops;
-		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
-			tmp_inode->i_fop->lock = NULL;
+
 		tmp_inode->i_data.a_ops = &cifs_addr_ops;
 		if((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
 		   (cifs_sb->tcon->ses->server->maxBuf <
@@ -327,12 +326,18 @@ static void unix_fill_in_inode(struct in
 	if (S_ISREG(tmp_inode->i_mode)) {
 		cFYI(1, ("File inode"));
 		tmp_inode->i_op = &cifs_file_inode_ops;
-		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
-			tmp_inode->i_fop = &cifs_file_direct_ops;
+
+		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
+			if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
+				tmp_inode->i_fop = &cifs_file_direct_nobrl_ops;
+			else
+				tmp_inode->i_fop = &cifs_file_direct_ops;
+		
+		} else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
+			tmp_inode->i_fop = &cifs_file_nobrl_ops;
 		else
 			tmp_inode->i_fop = &cifs_file_ops;
-		if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
-			tmp_inode->i_fop->lock = NULL;
+
 		tmp_inode->i_data.a_ops = &cifs_addr_ops;
 		if((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
 		   (cifs_sb->tcon->ses->server->maxBuf < 
diff --git a/fs/cifs/rfc1002pdu.h b/fs/cifs/rfc1002pdu.h
index 9222033..aede606 100644
--- a/fs/cifs/rfc1002pdu.h
+++ b/fs/cifs/rfc1002pdu.h
@@ -24,11 +24,11 @@
 /* NB: unlike smb/cifs packets, the RFC1002 structures are big endian */
 
 	/* RFC 1002 session packet types */
-#define RFC1002_SESSION_MESASAGE 0x00
+#define RFC1002_SESSION_MESSAGE 0x00
 #define RFC1002_SESSION_REQUEST  0x81
 #define RFC1002_POSITIVE_SESSION_RESPONSE 0x82
 #define RFC1002_NEGATIVE_SESSION_RESPONSE 0x83
-#define RFC1002_RETARGET_SESSION_RESPONSE 0x83
+#define RFC1002_RETARGET_SESSION_RESPONSE 0x84
 #define RFC1002_SESSION_KEEP_ALIVE 0x85
 
 	/* RFC 1002 flags (only one defined */
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index f887119..b12cb8a 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -206,7 +206,6 @@ smb_send(struct socket *ssocket, struct 
 	return rc;
 }
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
 static int
 smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
 	  struct sockaddr *sin)
@@ -299,7 +298,7 @@ smb_send2(struct socket *ssocket, struct
 
 int
 SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, 
-	     struct kvec *iov, int n_vec, int *pbytes_returned,
+	     struct kvec *iov, int n_vec, int * pRespBufType /* ret */, 
 	     const int long_op)
 {
 	int rc = 0;
@@ -307,6 +306,8 @@ SendReceive2(const unsigned int xid, str
 	unsigned long timeout;
 	struct mid_q_entry *midQ;
 	struct smb_hdr *in_buf = iov[0].iov_base;
+	
+	*pRespBufType = CIFS_NO_BUFFER;  /* no response buf yet */
 
 	if (ses == NULL) {
 		cERROR(1,("Null smb session"));
@@ -392,8 +393,7 @@ SendReceive2(const unsigned int xid, str
 		return -ENOMEM;
 	}
 
-/* BB FIXME */
-/* 	rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); */
+ 	rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
 
 	midQ->midState = MID_REQUEST_SUBMITTED;
 #ifdef CONFIG_CIFS_STATS2
@@ -489,21 +489,22 @@ SendReceive2(const unsigned int xid, str
 			receive_len, xid));
 		rc = -EIO;
 	} else {		/* rcvd frame is ok */
-
 		if (midQ->resp_buf && 
 			(midQ->midState == MID_RESPONSE_RECEIVED)) {
-			in_buf->smb_buf_length = receive_len;
-			/* BB verify that length would not overrun small buf */
-			memcpy((char *)in_buf + 4,
-			       (char *)midQ->resp_buf + 4,
-			       receive_len);
 
-			dump_smb(in_buf, 80);
+			iov[0].iov_base = (char *)midQ->resp_buf;
+			if(midQ->largeBuf)
+				*pRespBufType = CIFS_LARGE_BUFFER;
+			else
+				*pRespBufType = CIFS_SMALL_BUFFER;
+			iov[0].iov_len = receive_len + 4;
+
+			dump_smb(midQ->resp_buf, 80);
 			/* convert the length into a more usable form */
 			if((receive_len > 24) &&
 			   (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
 					SECMODE_SIGN_ENABLED))) {
-				rc = cifs_verify_signature(in_buf,
+				rc = cifs_verify_signature(midQ->resp_buf,
 						ses->server->mac_signing_key,
 						midQ->sequence_number+1);
 				if(rc) {
@@ -512,18 +513,19 @@ SendReceive2(const unsigned int xid, str
 				}
 			}
 
-			*pbytes_returned = in_buf->smb_buf_length;
-
 			/* BB special case reconnect tid and uid here? */
 			/* BB special case Errbadpassword and pwdexpired here */
-			rc = map_smb_to_linux_error(in_buf);
+			rc = map_smb_to_linux_error(midQ->resp_buf);
 
 			/* convert ByteCount if necessary */
 			if (receive_len >=
 			    sizeof (struct smb_hdr) -
 			    4 /* do not count RFC1001 header */  +
-			    (2 * in_buf->WordCount) + 2 /* bcc */ )
-				BCC(in_buf) = le16_to_cpu(BCC_LE(in_buf));
+			    (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )
+				BCC(midQ->resp_buf) = 
+					le16_to_cpu(BCC_LE(midQ->resp_buf));
+			midQ->resp_buf = NULL;  /* mark it so will not be freed
+						by DeleteMidQEntry */
 		} else {
 			rc = -EIO;
 			cFYI(1,("Bad MID state?"));
@@ -549,7 +551,6 @@ out_unlock2:
 
 	return rc;
 }
-#endif /* CIFS_EXPERIMENTAL */
 
 int
 SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
@@ -790,7 +791,7 @@ SendReceive(const unsigned int xid, stru
 				BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
 		} else {
 			rc = -EIO;
-			cERROR(1,("Bad MID state? "));
+			cERROR(1,("Bad MID state?"));
 		}
 	}
 cifs_no_response_exit:
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index f375f87..777e336 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -254,7 +254,8 @@ ssize_t cifs_getxattr(struct dentry * di
 		rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value,
 			buf_size, cifs_sb->local_nls,
 			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
-	} else if(strncmp(ea_name,POSIX_ACL_XATTR_ACCESS,strlen(POSIX_ACL_XATTR_ACCESS)) == 0) {
+	} else if(strncmp(ea_name,POSIX_ACL_XATTR_ACCESS,
+			  strlen(POSIX_ACL_XATTR_ACCESS)) == 0) {
 #ifdef CONFIG_CIFS_POSIX
 		if(sb->s_flags & MS_POSIXACL)
 			rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
@@ -262,10 +263,27 @@ ssize_t cifs_getxattr(struct dentry * di
 				cifs_sb->local_nls,
 				cifs_sb->mnt_cifs_flags & 
 					CIFS_MOUNT_MAP_SPECIAL_CHR);
+/*		else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
+			__u16 fid;
+			int oplock = FALSE;
+			rc = CIFSSMBOpen(xid, pTcon, full_path,
+					 FILE_OPEN, GENERIC_READ, 0, &fid,
+					 &oplock, NULL, cifs_sb->local_nls,
+					 cifs_sb->mnt_cifs_flags &
+					 CIFS_MOUNT_MAP_SPECIAL_CHR);
+			if(rc == 0) {
+				rc = CIFSSMBGetCIFSACL(xid, pTcon, fid,
+					ea_value, buf_size,
+					ACL_TYPE_ACCESS);
+				CIFSSMBClose(xid, pTcon, fid)
+			}
+		} */  /* BB enable after fixing up return data */
+                  		
 #else 
 		cFYI(1,("query POSIX ACL not supported yet"));
 #endif /* CONFIG_CIFS_POSIX */
-	} else if(strncmp(ea_name,POSIX_ACL_XATTR_DEFAULT,strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
+	} else if(strncmp(ea_name,POSIX_ACL_XATTR_DEFAULT,
+			  strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
 #ifdef CONFIG_CIFS_POSIX
 		if(sb->s_flags & MS_POSIXACL)
 			rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
diff --git a/fs/compat.c b/fs/compat.c
index 2468ac1..70c5af4 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -53,6 +53,8 @@
 #include <asm/mmu_context.h>
 #include <asm/ioctls.h>
 
+extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
+
 /*
  * Not all architectures have sys_utime, so implement this in terms
  * of sys_utimes.
@@ -68,28 +70,33 @@ asmlinkage long compat_sys_utime(char __
 		tv[0].tv_usec = 0;
 		tv[1].tv_usec = 0;
 	}
-	return do_utimes(filename, t ? tv : NULL);
+	return do_utimes(AT_FDCWD, filename, t ? tv : NULL);
 }
 
-asmlinkage long compat_sys_utimes(char __user *filename, struct compat_timeval __user *t)
+asmlinkage long compat_sys_futimesat(unsigned int dfd, char __user *filename, struct compat_timeval __user *t)
 {
 	struct timeval tv[2];
 
-	if (t) { 
+	if (t) {
 		if (get_user(tv[0].tv_sec, &t[0].tv_sec) ||
 		    get_user(tv[0].tv_usec, &t[0].tv_usec) ||
 		    get_user(tv[1].tv_sec, &t[1].tv_sec) ||
 		    get_user(tv[1].tv_usec, &t[1].tv_usec))
-			return -EFAULT; 
-	} 
-	return do_utimes(filename, t ? tv : NULL);
+			return -EFAULT;
+	}
+	return do_utimes(dfd, filename, t ? tv : NULL);
+}
+
+asmlinkage long compat_sys_utimes(char __user *filename, struct compat_timeval __user *t)
+{
+	return compat_sys_futimesat(AT_FDCWD, filename, t);
 }
 
 asmlinkage long compat_sys_newstat(char __user * filename,
 		struct compat_stat __user *statbuf)
 {
 	struct kstat stat;
-	int error = vfs_stat(filename, &stat);
+	int error = vfs_stat_fd(AT_FDCWD, filename, &stat);
 
 	if (!error)
 		error = cp_compat_stat(&stat, statbuf);
@@ -100,13 +107,34 @@ asmlinkage long compat_sys_newlstat(char
 		struct compat_stat __user *statbuf)
 {
 	struct kstat stat;
-	int error = vfs_lstat(filename, &stat);
+	int error = vfs_lstat_fd(AT_FDCWD, filename, &stat);
 
 	if (!error)
 		error = cp_compat_stat(&stat, statbuf);
 	return error;
 }
 
+asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user *filename,
+		struct compat_stat __user *statbuf, int flag)
+{
+	struct kstat stat;
+	int error = -EINVAL;
+
+	if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
+		goto out;
+
+	if (flag & AT_SYMLINK_NOFOLLOW)
+		error = vfs_lstat_fd(dfd, filename, &stat);
+	else
+		error = vfs_stat_fd(dfd, filename, &stat);
+
+	if (!error)
+		error = cp_compat_stat(&stat, statbuf);
+
+out:
+	return error;
+}
+
 asmlinkage long compat_sys_newfstat(unsigned int fd,
 		struct compat_stat __user * statbuf)
 {
@@ -1290,7 +1318,17 @@ out:
 asmlinkage long
 compat_sys_open(const char __user *filename, int flags, int mode)
 {
-	return do_sys_open(filename, flags, mode);
+	return do_sys_open(AT_FDCWD, filename, flags, mode);
+}
+
+/*
+ * Exactly like fs/open.c:sys_openat(), except that it doesn't set the
+ * O_LARGEFILE flag.
+ */
+asmlinkage long
+compat_sys_openat(unsigned int dfd, const char __user *filename, int flags, int mode)
+{
+	return do_sys_open(dfd, filename, flags, mode);
 }
 
 /*
@@ -1621,36 +1659,14 @@ static void select_bits_free(void *bits,
 #define MAX_SELECT_SECONDS \
 	((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
 
-asmlinkage long
-compat_sys_select(int n, compat_ulong_t __user *inp, compat_ulong_t __user *outp,
-		compat_ulong_t __user *exp, struct compat_timeval __user *tvp)
+int compat_core_sys_select(int n, compat_ulong_t __user *inp,
+	compat_ulong_t __user *outp, compat_ulong_t __user *exp, s64 *timeout)
 {
 	fd_set_bits fds;
 	char *bits;
-	long timeout;
 	int size, max_fdset, ret = -EINVAL;
 	struct fdtable *fdt;
 
-	timeout = MAX_SCHEDULE_TIMEOUT;
-	if (tvp) {
-		time_t sec, usec;
-
-		if (!access_ok(VERIFY_READ, tvp, sizeof(*tvp))
-		    || __get_user(sec, &tvp->tv_sec)
-		    || __get_user(usec, &tvp->tv_usec)) {
-			ret = -EFAULT;
-			goto out_nofds;
-		}
-
-		if (sec < 0 || usec < 0)
-			goto out_nofds;
-
-		if ((unsigned long) sec < MAX_SELECT_SECONDS) {
-			timeout = ROUND_UP(usec, 1000000/HZ);
-			timeout += sec * (unsigned long) HZ;
-		}
-	}
-
 	if (n < 0)
 		goto out_nofds;
 
@@ -1687,19 +1703,7 @@ compat_sys_select(int n, compat_ulong_t 
 	zero_fd_set(n, fds.res_out);
 	zero_fd_set(n, fds.res_ex);
 
-	ret = do_select(n, &fds, &timeout);
-
-	if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
-		time_t sec = 0, usec = 0;
-		if (timeout) {
-			sec = timeout / HZ;
-			usec = timeout % HZ;
-			usec *= (1000000/HZ);
-		}
-		if (put_user(sec, &tvp->tv_sec) ||
-		    put_user(usec, &tvp->tv_usec))
-			ret = -EFAULT;
-	}
+	ret = do_select(n, &fds, timeout);
 
 	if (ret < 0)
 		goto out;
@@ -1720,6 +1724,224 @@ out_nofds:
 	return ret;
 }
 
+asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
+	compat_ulong_t __user *outp, compat_ulong_t __user *exp,
+	struct compat_timeval __user *tvp)
+{
+	s64 timeout = -1;
+	struct compat_timeval tv;
+	int ret;
+
+	if (tvp) {
+		if (copy_from_user(&tv, tvp, sizeof(tv)))
+			return -EFAULT;
+
+		if (tv.tv_sec < 0 || tv.tv_usec < 0)
+			return -EINVAL;
+
+		/* Cast to u64 to make GCC stop complaining */
+		if ((u64)tv.tv_sec >= (u64)MAX_INT64_SECONDS)
+			timeout = -1;	/* infinite */
+		else {
+			timeout = ROUND_UP(tv.tv_usec, 1000000/HZ);
+			timeout += tv.tv_sec * HZ;
+		}
+	}
+
+	ret = compat_core_sys_select(n, inp, outp, exp, &timeout);
+
+	if (tvp) {
+		if (current->personality & STICKY_TIMEOUTS)
+			goto sticky;
+		tv.tv_usec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ));
+		tv.tv_sec = timeout;
+		if (copy_to_user(tvp, &tv, sizeof(tv))) {
+sticky:
+			/*
+			 * If an application puts its timeval in read-only
+			 * memory, we don't want the Linux-specific update to
+			 * the timeval to cause a fault after the select has
+			 * completed successfully. However, because we're not
+			 * updating the timeval, we can't restart the system
+			 * call.
+			 */
+			if (ret == -ERESTARTNOHAND)
+				ret = -EINTR;
+		}
+	}
+
+	return ret;
+}
+
+#ifdef TIF_RESTORE_SIGMASK
+asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp,
+	compat_ulong_t __user *outp, compat_ulong_t __user *exp,
+	struct compat_timespec __user *tsp, compat_sigset_t __user *sigmask,
+	compat_size_t sigsetsize)
+{
+	compat_sigset_t ss32;
+	sigset_t ksigmask, sigsaved;
+	s64 timeout = MAX_SCHEDULE_TIMEOUT;
+	struct compat_timespec ts;
+	int ret;
+
+	if (tsp) {
+		if (copy_from_user(&ts, tsp, sizeof(ts)))
+			return -EFAULT;
+
+		if (ts.tv_sec < 0 || ts.tv_nsec < 0)
+			return -EINVAL;
+	}
+
+	if (sigmask) {
+		if (sigsetsize != sizeof(compat_sigset_t))
+			return -EINVAL;
+		if (copy_from_user(&ss32, sigmask, sizeof(ss32)))
+			return -EFAULT;
+		sigset_from_compat(&ksigmask, &ss32);
+
+		sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
+		sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
+	}
+
+	do {
+		if (tsp) {
+			if ((unsigned long)ts.tv_sec < MAX_SELECT_SECONDS) {
+				timeout = ROUND_UP(ts.tv_nsec, 1000000000/HZ);
+				timeout += ts.tv_sec * (unsigned long)HZ;
+				ts.tv_sec = 0;
+				ts.tv_nsec = 0;
+			} else {
+				ts.tv_sec -= MAX_SELECT_SECONDS;
+				timeout = MAX_SELECT_SECONDS * HZ;
+			}
+		}
+
+		ret = compat_core_sys_select(n, inp, outp, exp, &timeout);
+
+	} while (!ret && !timeout && tsp && (ts.tv_sec || ts.tv_nsec));
+
+	if (tsp && !(current->personality & STICKY_TIMEOUTS)) {
+		ts.tv_sec += timeout / HZ;
+		ts.tv_nsec += (timeout % HZ) * (1000000000/HZ);
+		if (ts.tv_nsec >= 1000000000) {
+			ts.tv_sec++;
+			ts.tv_nsec -= 1000000000;
+		}
+		(void)copy_to_user(tsp, &ts, sizeof(ts));
+	}
+
+	if (ret == -ERESTARTNOHAND) {
+		/*
+		 * Don't restore the signal mask yet. Let do_signal() deliver
+		 * the signal on the way back to userspace, before the signal
+		 * mask is restored.
+		 */
+		if (sigmask) {
+			memcpy(&current->saved_sigmask, &sigsaved,
+					sizeof(sigsaved));
+			set_thread_flag(TIF_RESTORE_SIGMASK);
+		}
+	} else if (sigmask)
+		sigprocmask(SIG_SETMASK, &sigsaved, NULL);
+
+	return ret;
+}
+
+asmlinkage long compat_sys_pselect6(int n, compat_ulong_t __user *inp,
+	compat_ulong_t __user *outp, compat_ulong_t __user *exp,
+	struct compat_timespec __user *tsp, void __user *sig)
+{
+	compat_size_t sigsetsize = 0;
+	compat_uptr_t up = 0;
+
+	if (sig) {
+		if (!access_ok(VERIFY_READ, sig,
+				sizeof(compat_uptr_t)+sizeof(compat_size_t)) ||
+		    	__get_user(up, (compat_uptr_t __user *)sig) ||
+		    	__get_user(sigsetsize,
+				(compat_size_t __user *)(sig+sizeof(up))))
+			return -EFAULT;
+	}
+	return compat_sys_pselect7(n, inp, outp, exp, tsp, compat_ptr(up),
+					sigsetsize);
+}
+
+asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
+	unsigned int nfds, struct compat_timespec __user *tsp,
+	const compat_sigset_t __user *sigmask, compat_size_t sigsetsize)
+{
+	compat_sigset_t ss32;
+	sigset_t ksigmask, sigsaved;
+	struct compat_timespec ts;
+	s64 timeout = -1;
+	int ret;
+
+	if (tsp) {
+		if (copy_from_user(&ts, tsp, sizeof(ts)))
+			return -EFAULT;
+
+		/* We assume that ts.tv_sec is always lower than
+		   the number of seconds that can be expressed in
+		   an s64. Otherwise the compiler bitches at us */
+		timeout = ROUND_UP(ts.tv_nsec, 1000000000/HZ);
+		timeout += ts.tv_sec * HZ;
+	}
+
+	if (sigmask) {
+		if (sigsetsize |= sizeof(compat_sigset_t))
+			return -EINVAL;
+		if (copy_from_user(&ss32, sigmask, sizeof(ss32)))
+			return -EFAULT;
+		sigset_from_compat(&ksigmask, &ss32);
+
+		sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
+		sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
+	}
+
+	ret = do_sys_poll(ufds, nfds, &timeout);
+
+	/* We can restart this syscall, usually */
+	if (ret == -EINTR) {
+		/*
+		 * Don't restore the signal mask yet. Let do_signal() deliver
+		 * the signal on the way back to userspace, before the signal
+		 * mask is restored.
+		 */
+		if (sigmask) {
+			memcpy(&current->saved_sigmask, &sigsaved,
+				sizeof(sigsaved));
+			set_thread_flag(TIF_RESTORE_SIGMASK);
+		}
+		ret = -ERESTARTNOHAND;
+	} else if (sigmask)
+		sigprocmask(SIG_SETMASK, &sigsaved, NULL);
+
+	if (tsp && timeout >= 0) {
+		if (current->personality & STICKY_TIMEOUTS)
+			goto sticky;
+		/* Yes, we know it's actually an s64, but it's also positive. */
+		ts.tv_nsec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)) * 1000;
+		ts.tv_sec = timeout;
+		if (copy_to_user(tsp, &ts, sizeof(ts))) {
+sticky:
+			/*
+			 * If an application puts its timeval in read-only
+			 * memory, we don't want the Linux-specific update to
+			 * the timeval to cause a fault after the select has
+			 * completed successfully. However, because we're not
+			 * updating the timeval, we can't restart the system
+			 * call.
+			 */
+			if (ret == -ERESTARTNOHAND && timeout >= 0)
+				ret = -EINTR;
+		}
+	}
+
+	return ret;
+}
+#endif /* TIF_RESTORE_SIGMASK */
+
 #if defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE)
 /* Stuff for NFS server syscalls... */
 struct compat_nfsctl_svc {
diff --git a/fs/exec.c b/fs/exec.c
index 62b40af..055378d 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -477,7 +477,7 @@ struct file *open_exec(const char *name)
 	int err;
 	struct file *file;
 
-	err = path_lookup_open(name, LOOKUP_FOLLOW, &nd, FMODE_READ);
+	err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, FMODE_READ);
 	file = ERR_PTR(err);
 
 	if (!err) {
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
index 5bfe400..b06b54f 100644
--- a/fs/exportfs/expfs.c
+++ b/fs/exportfs/expfs.c
@@ -11,6 +11,33 @@ struct export_operations export_op_defau
 
 #define dprintk(fmt, args...) do{}while(0)
 
+static struct dentry *
+find_acceptable_alias(struct dentry *result,
+		int (*acceptable)(void *context, struct dentry *dentry),
+		void *context)
+{
+	struct dentry *dentry, *toput = NULL;
+
+	spin_lock(&dcache_lock);
+	list_for_each_entry(dentry, &result->d_inode->i_dentry, d_alias) {
+		dget_locked(dentry);
+		spin_unlock(&dcache_lock);
+		if (toput)
+			dput(toput);
+		if (dentry != result && acceptable(context, dentry)) {
+			dput(result);
+			return dentry;
+		}
+		spin_lock(&dcache_lock);
+		toput = dentry;
+	}
+	spin_unlock(&dcache_lock);
+
+	if (toput)
+		dput(toput);
+	return NULL;
+}
+
 /**
  * find_exported_dentry - helper routine to implement export_operations->decode_fh
  * @sb:		The &super_block identifying the filesystem
@@ -52,8 +79,7 @@ find_exported_dentry(struct super_block 
 	struct dentry *target_dir;
 	int err;
 	struct export_operations *nops = sb->s_export_op;
-	struct list_head *le, *head;
-	struct dentry *toput = NULL;
+	struct dentry *alias;
 	int noprogress;
 	char nbuf[NAME_MAX+1];
 
@@ -79,27 +105,10 @@ find_exported_dentry(struct super_block 
 			/* there is no other dentry, so fail */
 			goto err_result;
 		}
-		/* try any other aliases */
-		spin_lock(&dcache_lock);
-		head = &result->d_inode->i_dentry;
-		list_for_each(le, head) {
-			struct dentry *dentry = list_entry(le, struct dentry, d_alias);
-			dget_locked(dentry);
-			spin_unlock(&dcache_lock);
-			if (toput)
-				dput(toput);
-			toput = NULL;
-			if (dentry != result &&
-			    acceptable(context, dentry)) {
-				dput(result);
-				return dentry;
-			}
-			spin_lock(&dcache_lock);
-			toput = dentry;
-		}
-		spin_unlock(&dcache_lock);
-		if (toput)
-			dput(toput);
+
+		alias = find_acceptable_alias(result, acceptable, context);
+		if (alias)
+			return alias;
 	}			
 
 	/* It's a directory, or we are required to confirm the file's
@@ -258,26 +267,10 @@ find_exported_dentry(struct super_block 
 	/* now result is properly connected, it is our best bet */
 	if (acceptable(context, result))
 		return result;
-	/* one last try of the aliases.. */
-	spin_lock(&dcache_lock);
-	toput = NULL;
-	head = &result->d_inode->i_dentry;
-	list_for_each(le, head) {
-		struct dentry *dentry = list_entry(le, struct dentry, d_alias);
-		dget_locked(dentry);
-		spin_unlock(&dcache_lock);
-		if (toput) dput(toput);
-		if (dentry != result &&
-		    acceptable(context, dentry)) {
-			dput(result);
-			return dentry;
-		}
-		spin_lock(&dcache_lock);
-		toput = dentry;
-	}
-	spin_unlock(&dcache_lock);
-	if (toput)
-		dput(toput);
+
+	alias = find_acceptable_alias(result, acceptable, context);
+	if (alias)
+		return alias;
 
 	/* drat - I just cannot find anything acceptable */
 	dput(result);
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index e7d3f05..a717837 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -706,6 +706,7 @@ struct address_space_operations ext2_aop
 	.bmap			= ext2_bmap,
 	.direct_IO		= ext2_direct_IO,
 	.writepages		= ext2_writepages,
+	.migratepage		= buffer_migrate_page,
 };
 
 struct address_space_operations ext2_aops_xip = {
@@ -723,6 +724,7 @@ struct address_space_operations ext2_nob
 	.bmap			= ext2_bmap,
 	.direct_IO		= ext2_direct_IO,
 	.writepages		= ext2_writepages,
+	.migratepage		= buffer_migrate_page,
 };
 
 /*
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 8824e84..3fc4238 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1559,6 +1559,7 @@ static struct address_space_operations e
 	.invalidatepage	= ext3_invalidatepage,
 	.releasepage	= ext3_releasepage,
 	.direct_IO	= ext3_direct_IO,
+	.migratepage	= buffer_migrate_page,
 };
 
 static struct address_space_operations ext3_writeback_aops = {
@@ -1572,6 +1573,7 @@ static struct address_space_operations e
 	.invalidatepage	= ext3_invalidatepage,
 	.releasepage	= ext3_releasepage,
 	.direct_IO	= ext3_direct_IO,
+	.migratepage	= buffer_migrate_page,
 };
 
 static struct address_space_operations ext3_journalled_aops = {
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index a7ef5e7..2963516 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -335,9 +335,14 @@ static void fuse_send_readpages(struct f
 	loff_t pos = page_offset(req->pages[0]);
 	size_t count = req->num_pages << PAGE_CACHE_SHIFT;
 	req->out.page_zeroing = 1;
-	req->end = fuse_readpages_end;
 	fuse_read_fill(req, file, inode, pos, count, FUSE_READ);
-	request_send_background(fc, req);
+	if (fc->async_read) {
+		req->end = fuse_readpages_end;
+		request_send_background(fc, req);
+	} else {
+		request_send(fc, req);
+		fuse_readpages_end(fc, req);
+	}
 }
 
 struct fuse_readpages_data {
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 46cf933..4a83adf 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -272,6 +272,9 @@ struct fuse_conn {
 	    reply, before any other request, and never cleared */
 	unsigned conn_error : 1;
 
+	/** Do readpages asynchronously?  Only set in INIT */
+	unsigned async_read : 1;
+
 	/*
 	 * The following bitfields are only for optimization purposes
 	 * and hence races in setting them will not cause malfunction
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index c755a04..879e6fb 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -473,6 +473,16 @@ static void process_init_reply(struct fu
 	if (req->out.h.error || arg->major != FUSE_KERNEL_VERSION)
 		fc->conn_error = 1;
 	else {
+		unsigned long ra_pages;
+
+		if (arg->minor >= 6) {
+			ra_pages = arg->max_readahead / PAGE_CACHE_SIZE;
+			if (arg->flags & FUSE_ASYNC_READ)
+				fc->async_read = 1;
+		} else
+			ra_pages = fc->max_read / PAGE_CACHE_SIZE;
+
+		fc->bdi.ra_pages = min(fc->bdi.ra_pages, ra_pages);
 		fc->minor = arg->minor;
 		fc->max_write = arg->minor < 5 ? 4096 : arg->max_write;
 	}
@@ -496,6 +506,8 @@ static void fuse_send_init(struct fuse_c
 
 	arg->major = FUSE_KERNEL_VERSION;
 	arg->minor = FUSE_KERNEL_MINOR_VERSION;
+	arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE;
+	arg->flags |= FUSE_ASYNC_READ;
 	req->in.h.opcode = FUSE_INIT;
 	req->in.numargs = 1;
 	req->in.args[0].size = sizeof(*arg);
@@ -552,8 +564,6 @@ static int fuse_fill_super(struct super_
 	fc->user_id = d.user_id;
 	fc->group_id = d.group_id;
 	fc->max_read = d.max_read;
-	if (fc->max_read / PAGE_CACHE_SIZE < fc->bdi.ra_pages)
-		fc->bdi.ra_pages = fc->max_read / PAGE_CACHE_SIZE;
 
 	/* Used by get_root_inode() */
 	sb->s_fs_info = fc;
diff --git a/fs/hfs/bfind.c b/fs/hfs/bfind.c
index 89450ae..f13f149 100644
--- a/fs/hfs/bfind.c
+++ b/fs/hfs/bfind.c
@@ -64,7 +64,6 @@ int __hfs_brec_find(struct hfs_bnode *bn
 		else
 			e = rec - 1;
 	} while (b <= e);
-	//printk("%d: %d,%d,%d\n", bnode->this, b, e, rec);
 	if (rec != e && e >= 0) {
 		len = hfs_brec_lenoff(bnode, e, &off);
 		keylen = hfs_brec_keylen(bnode, e);
@@ -127,7 +126,7 @@ int hfs_brec_find(struct hfs_find_data *
 	return res;
 
 invalid:
-	printk("HFS: inconsistency in B*Tree (%d,%d,%d,%u,%u)\n",
+	printk(KERN_ERR "hfs: inconsistency in B*Tree (%d,%d,%d,%u,%u)\n",
 		height, bnode->height, bnode->type, nidx, parent);
 	res = -EIO;
 release:
diff --git a/fs/hfs/bnode.c b/fs/hfs/bnode.c
index 3d5cdc6..a7a7d77 100644
--- a/fs/hfs/bnode.c
+++ b/fs/hfs/bnode.c
@@ -198,7 +198,7 @@ void hfs_bnode_unlink(struct hfs_bnode *
 
 	// move down?
 	if (!node->prev && !node->next) {
-		printk("hfs_btree_del_level\n");
+		printk(KERN_DEBUG "hfs_btree_del_level\n");
 	}
 	if (!node->parent) {
 		tree->root = 0;
@@ -219,7 +219,7 @@ struct hfs_bnode *hfs_bnode_findhash(str
 	struct hfs_bnode *node;
 
 	if (cnid >= tree->node_count) {
-		printk("HFS: request for non-existent node %d in B*Tree\n", cnid);
+		printk(KERN_ERR "hfs: request for non-existent node %d in B*Tree\n", cnid);
 		return NULL;
 	}
 
@@ -242,7 +242,7 @@ static struct hfs_bnode *__hfs_bnode_cre
 	loff_t off;
 
 	if (cnid >= tree->node_count) {
-		printk("HFS: request for non-existent node %d in B*Tree\n", cnid);
+		printk(KERN_ERR "hfs: request for non-existent node %d in B*Tree\n", cnid);
 		return NULL;
 	}
 
diff --git a/fs/hfs/brec.c b/fs/hfs/brec.c
index 7d8fff2..5c87cf4 100644
--- a/fs/hfs/brec.c
+++ b/fs/hfs/brec.c
@@ -362,7 +362,7 @@ again:
 		end_off = hfs_bnode_read_u16(parent, end_rec_off);
 		if (end_rec_off - end_off < diff) {
 
-			printk("splitting index node...\n");
+			printk(KERN_DEBUG "hfs: splitting index node...\n");
 			fd->bnode = parent;
 			new_node = hfs_bnode_split(fd);
 			if (IS_ERR(new_node))
diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c
index 394725e..7bb11ed 100644
--- a/fs/hfs/btree.c
+++ b/fs/hfs/btree.c
@@ -111,7 +111,7 @@ void hfs_btree_close(struct hfs_btree *t
 		while ((node = tree->node_hash[i])) {
 			tree->node_hash[i] = node->next_hash;
 			if (atomic_read(&node->refcnt))
-				printk("HFS: node %d:%d still has %d user(s)!\n",
+				printk(KERN_ERR "hfs: node %d:%d still has %d user(s)!\n",
 					node->tree->cnid, node->this, atomic_read(&node->refcnt));
 			hfs_bnode_free(node);
 			tree->node_hash_cnt--;
@@ -252,7 +252,7 @@ struct hfs_bnode *hfs_bmap_alloc(struct 
 		kunmap(*pagep);
 		nidx = node->next;
 		if (!nidx) {
-			printk("create new bmap node...\n");
+			printk(KERN_DEBUG "hfs: create new bmap node...\n");
 			next_node = hfs_bmap_new_bmap(node, idx);
 		} else
 			next_node = hfs_bnode_find(tree, nidx);
@@ -292,7 +292,7 @@ void hfs_bmap_free(struct hfs_bnode *nod
 		hfs_bnode_put(node);
 		if (!i) {
 			/* panic */;
-			printk("HFS: unable to free bnode %u. bmap not found!\n", node->this);
+			printk(KERN_CRIT "hfs: unable to free bnode %u. bmap not found!\n", node->this);
 			return;
 		}
 		node = hfs_bnode_find(tree, i);
@@ -300,7 +300,7 @@ void hfs_bmap_free(struct hfs_bnode *nod
 			return;
 		if (node->type != HFS_NODE_MAP) {
 			/* panic */;
-			printk("HFS: invalid bmap found! (%u,%d)\n", node->this, node->type);
+			printk(KERN_CRIT "hfs: invalid bmap found! (%u,%d)\n", node->this, node->type);
 			hfs_bnode_put(node);
 			return;
 		}
@@ -313,7 +313,7 @@ void hfs_bmap_free(struct hfs_bnode *nod
 	m = 1 << (~nidx & 7);
 	byte = data[off];
 	if (!(byte & m)) {
-		printk("HFS: trying to free free bnode %u(%d)\n", node->this, node->type);
+		printk(KERN_CRIT "hfs: trying to free free bnode %u(%d)\n", node->this, node->type);
 		kunmap(page);
 		hfs_bnode_put(node);
 		return;
diff --git a/fs/hfs/catalog.c b/fs/hfs/catalog.c
index 2fcd679..ba85157 100644
--- a/fs/hfs/catalog.c
+++ b/fs/hfs/catalog.c
@@ -184,7 +184,7 @@ int hfs_cat_find_brec(struct super_block
 
 	type = rec.type;
 	if (type != HFS_CDR_THD && type != HFS_CDR_FTH) {
-		printk("HFS-fs: Found bad thread record in catalog\n");
+		printk(KERN_ERR "hfs: found bad thread record in catalog\n");
 		return -EIO;
 	}
 
diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c
index e1f24be..534e5a7 100644
--- a/fs/hfs/dir.c
+++ b/fs/hfs/dir.c
@@ -81,12 +81,12 @@ static int hfs_readdir(struct file *filp
 	case 1:
 		hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength);
 		if (entry.type != HFS_CDR_THD) {
-			printk("HFS: bad catalog folder thread\n");
+			printk(KERN_ERR "hfs: bad catalog folder thread\n");
 			err = -EIO;
 			goto out;
 		}
 		//if (fd.entrylength < HFS_MIN_THREAD_SZ) {
-		//	printk("HFS: truncated catalog thread\n");
+		//	printk(KERN_ERR "hfs: truncated catalog thread\n");
 		//	err = -EIO;
 		//	goto out;
 		//}
@@ -105,7 +105,7 @@ static int hfs_readdir(struct file *filp
 
 	for (;;) {
 		if (be32_to_cpu(fd.key->cat.ParID) != inode->i_ino) {
-			printk("HFS: walked past end of dir\n");
+			printk(KERN_ERR "hfs: walked past end of dir\n");
 			err = -EIO;
 			goto out;
 		}
@@ -114,7 +114,7 @@ static int hfs_readdir(struct file *filp
 		len = hfs_mac2asc(sb, strbuf, &fd.key->cat.CName);
 		if (type == HFS_CDR_DIR) {
 			if (fd.entrylength < sizeof(struct hfs_cat_dir)) {
-				printk("HFS: small dir entry\n");
+				printk(KERN_ERR "hfs: small dir entry\n");
 				err = -EIO;
 				goto out;
 			}
@@ -123,7 +123,7 @@ static int hfs_readdir(struct file *filp
 				break;
 		} else if (type == HFS_CDR_FIL) {
 			if (fd.entrylength < sizeof(struct hfs_cat_file)) {
-				printk("HFS: small file entry\n");
+				printk(KERN_ERR "hfs: small file entry\n");
 				err = -EIO;
 				goto out;
 			}
@@ -131,7 +131,7 @@ static int hfs_readdir(struct file *filp
 				    be32_to_cpu(entry.file.FlNum), DT_REG))
 				break;
 		} else {
-			printk("HFS: bad catalog entry type %d\n", type);
+			printk(KERN_ERR "hfs: bad catalog entry type %d\n", type);
 			err = -EIO;
 			goto out;
 		}
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h
index cc5dcd5..18ce47a 100644
--- a/fs/hfs/hfs_fs.h
+++ b/fs/hfs/hfs_fs.h
@@ -35,9 +35,6 @@
 #define dprint(flg, fmt, args...) \
 	if (flg & DBG_MASK) printk(fmt , ## args)
 
-#define hfs_warn(format, args...) printk(KERN_WARNING format , ## args)
-#define hfs_error(format, args...) printk(KERN_ERR format , ## args)
-
 /*
  * struct hfs_inode_info
  *
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index 050a492..39fd85b 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -95,7 +95,6 @@ static int hfs_releasepage(struct page *
 		} while (--i && nidx < tree->node_count);
 		spin_unlock(&tree->hash_lock);
 	}
-	//printk("releasepage: %lu,%x = %d\n", page->index, mask, res);
 	return res ? try_to_free_buffers(page) : 0;
 }
 
diff --git a/fs/hfs/mdb.c b/fs/hfs/mdb.c
index 0a473f7..b4651e1 100644
--- a/fs/hfs/mdb.c
+++ b/fs/hfs/mdb.c
@@ -47,7 +47,7 @@ static int hfs_get_last_session(struct s
 			*start = (sector_t)te.cdte_addr.lba << 2;
 			return 0;
 		}
-		printk(KERN_ERR "HFS: Invalid session number or type of track\n");
+		printk(KERN_ERR "hfs: invalid session number or type of track\n");
 		return -EINVAL;
 	}
 	ms_info.addr_format = CDROM_LBA;
@@ -100,7 +100,7 @@ int hfs_mdb_get(struct super_block *sb)
 
 	HFS_SB(sb)->alloc_blksz = size = be32_to_cpu(mdb->drAlBlkSiz);
 	if (!size || (size & (HFS_SECTOR_SIZE - 1))) {
-		hfs_warn("hfs_fs: bad allocation block size %d\n", size);
+		printk(KERN_ERR "hfs: bad allocation block size %d\n", size);
 		goto out_bh;
 	}
 
@@ -117,7 +117,7 @@ int hfs_mdb_get(struct super_block *sb)
 		size >>= 1;
 	brelse(bh);
 	if (!sb_set_blocksize(sb, size)) {
-		printk("hfs_fs: unable to set blocksize to %u\n", size);
+		printk(KERN_ERR "hfs: unable to set blocksize to %u\n", size);
 		goto out;
 	}
 
@@ -161,8 +161,8 @@ int hfs_mdb_get(struct super_block *sb)
 	}
 
 	if (!HFS_SB(sb)->alt_mdb) {
-		hfs_warn("hfs_fs: unable to locate alternate MDB\n");
-		hfs_warn("hfs_fs: continuing without an alternate MDB\n");
+		printk(KERN_WARNING "hfs: unable to locate alternate MDB\n");
+		printk(KERN_WARNING "hfs: continuing without an alternate MDB\n");
 	}
 
 	HFS_SB(sb)->bitmap = (__be32 *)__get_free_pages(GFP_KERNEL, PAGE_SIZE < 8192 ? 1 : 0);
@@ -177,7 +177,7 @@ int hfs_mdb_get(struct super_block *sb)
 	while (size) {
 		bh = sb_bread(sb, off >> sb->s_blocksize_bits);
 		if (!bh) {
-			hfs_warn("hfs_fs: unable to read volume bitmap\n");
+			printk(KERN_ERR "hfs: unable to read volume bitmap\n");
 			goto out;
 		}
 		off2 = off & (sb->s_blocksize - 1);
@@ -191,23 +191,23 @@ int hfs_mdb_get(struct super_block *sb)
 
 	HFS_SB(sb)->ext_tree = hfs_btree_open(sb, HFS_EXT_CNID, hfs_ext_keycmp);
 	if (!HFS_SB(sb)->ext_tree) {
-		hfs_warn("hfs_fs: unable to open extent tree\n");
+		printk(KERN_ERR "hfs: unable to open extent tree\n");
 		goto out;
 	}
 	HFS_SB(sb)->cat_tree = hfs_btree_open(sb, HFS_CAT_CNID, hfs_cat_keycmp);
 	if (!HFS_SB(sb)->cat_tree) {
-		hfs_warn("hfs_fs: unable to open catalog tree\n");
+		printk(KERN_ERR "hfs: unable to open catalog tree\n");
 		goto out;
 	}
 
 	attrib = mdb->drAtrb;
 	if (!(attrib & cpu_to_be16(HFS_SB_ATTRIB_UNMNT))) {
-		hfs_warn("HFS-fs warning: Filesystem was not cleanly unmounted, "
+		printk(KERN_WARNING "hfs: filesystem was not cleanly unmounted, "
 			 "running fsck.hfs is recommended.  mounting read-only.\n");
 		sb->s_flags |= MS_RDONLY;
 	}
 	if ((attrib & cpu_to_be16(HFS_SB_ATTRIB_SLOCK))) {
-		hfs_warn("HFS-fs: Filesystem is marked locked, mounting read-only.\n");
+		printk(KERN_WARNING "hfs: filesystem is marked locked, mounting read-only.\n");
 		sb->s_flags |= MS_RDONLY;
 	}
 	if (!(sb->s_flags & MS_RDONLY)) {
@@ -303,7 +303,7 @@ void hfs_mdb_commit(struct super_block *
 		while (size) {
 			bh = sb_bread(sb, block);
 			if (!bh) {
-				hfs_warn("hfs_fs: unable to read volume bitmap\n");
+				printk(KERN_ERR "hfs: unable to read volume bitmap\n");
 				break;
 			}
 			len = min((int)sb->s_blocksize - off, size);
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index c5074ae..1181d11 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -101,12 +101,12 @@ static int hfs_remount(struct super_bloc
 		return 0;
 	if (!(*flags & MS_RDONLY)) {
 		if (!(HFS_SB(sb)->mdb->drAtrb & cpu_to_be16(HFS_SB_ATTRIB_UNMNT))) {
-			printk("HFS-fs warning: Filesystem was not cleanly unmounted, "
+			printk(KERN_WARNING "hfs: filesystem was not cleanly unmounted, "
 			       "running fsck.hfs is recommended.  leaving read-only.\n");
 			sb->s_flags |= MS_RDONLY;
 			*flags |= MS_RDONLY;
 		} else if (HFS_SB(sb)->mdb->drAtrb & cpu_to_be16(HFS_SB_ATTRIB_SLOCK)) {
-			printk("HFS-fs: Filesystem is marked locked, leaving read-only.\n");
+			printk(KERN_WARNING "hfs: filesystem is marked locked, leaving read-only.\n");
 			sb->s_flags |= MS_RDONLY;
 			*flags |= MS_RDONLY;
 		}
@@ -229,21 +229,21 @@ static int parse_options(char *options, 
 		switch (token) {
 		case opt_uid:
 			if (match_int(&args[0], &tmp)) {
-				printk("HFS: uid requires an argument\n");
+				printk(KERN_ERR "hfs: uid requires an argument\n");
 				return 0;
 			}
 			hsb->s_uid = (uid_t)tmp;
 			break;
 		case opt_gid:
 			if (match_int(&args[0], &tmp)) {
-				printk("HFS: gid requires an argument\n");
+				printk(KERN_ERR "hfs: gid requires an argument\n");
 				return 0;
 			}
 			hsb->s_gid = (gid_t)tmp;
 			break;
 		case opt_umask:
 			if (match_octal(&args[0], &tmp)) {
-				printk("HFS: umask requires a value\n");
+				printk(KERN_ERR "hfs: umask requires a value\n");
 				return 0;
 			}
 			hsb->s_file_umask = (umode_t)tmp;
@@ -251,39 +251,39 @@ static int parse_options(char *options, 
 			break;
 		case opt_file_umask:
 			if (match_octal(&args[0], &tmp)) {
-				printk("HFS: file_umask requires a value\n");
+				printk(KERN_ERR "hfs: file_umask requires a value\n");
 				return 0;
 			}
 			hsb->s_file_umask = (umode_t)tmp;
 			break;
 		case opt_dir_umask:
 			if (match_octal(&args[0], &tmp)) {
-				printk("HFS: dir_umask requires a value\n");
+				printk(KERN_ERR "hfs: dir_umask requires a value\n");
 				return 0;
 			}
 			hsb->s_dir_umask = (umode_t)tmp;
 			break;
 		case opt_part:
 			if (match_int(&args[0], &hsb->part)) {
-				printk("HFS: part requires an argument\n");
+				printk(KERN_ERR "hfs: part requires an argument\n");
 				return 0;
 			}
 			break;
 		case opt_session:
 			if (match_int(&args[0], &hsb->session)) {
-				printk("HFS: session requires an argument\n");
+				printk(KERN_ERR "hfs: session requires an argument\n");
 				return 0;
 			}
 			break;
 		case opt_type:
 			if (match_fourchar(&args[0], &hsb->s_type)) {
-				printk("HFS+-fs: type requires a 4 character value\n");
+				printk(KERN_ERR "hfs: type requires a 4 character value\n");
 				return 0;
 			}
 			break;
 		case opt_creator:
 			if (match_fourchar(&args[0], &hsb->s_creator)) {
-				printk("HFS+-fs: creator requires a 4 character value\n");
+				printk(KERN_ERR "hfs: creator requires a 4 character value\n");
 				return 0;
 			}
 			break;
@@ -292,13 +292,13 @@ static int parse_options(char *options, 
 			break;
 		case opt_codepage:
 			if (hsb->nls_disk) {
-				printk("HFS+-fs: unable to change codepage\n");
+				printk(KERN_ERR "hfs: unable to change codepage\n");
 				return 0;
 			}
 			p = match_strdup(&args[0]);
 			hsb->nls_disk = load_nls(p);
 			if (!hsb->nls_disk) {
-				printk("HFS+-fs: unable to load codepage \"%s\"\n", p);
+				printk(KERN_ERR "hfs: unable to load codepage \"%s\"\n", p);
 				kfree(p);
 				return 0;
 			}
@@ -306,13 +306,13 @@ static int parse_options(char *options, 
 			break;
 		case opt_iocharset:
 			if (hsb->nls_io) {
-				printk("HFS: unable to change iocharset\n");
+				printk(KERN_ERR "hfs: unable to change iocharset\n");
 				return 0;
 			}
 			p = match_strdup(&args[0]);
 			hsb->nls_io = load_nls(p);
 			if (!hsb->nls_io) {
-				printk("HFS: unable to load iocharset \"%s\"\n", p);
+				printk(KERN_ERR "hfs: unable to load iocharset \"%s\"\n", p);
 				kfree(p);
 				return 0;
 			}
@@ -326,7 +326,7 @@ static int parse_options(char *options, 
 	if (hsb->nls_disk && !hsb->nls_io) {
 		hsb->nls_io = load_nls_default();
 		if (!hsb->nls_io) {
-			printk("HFS: unable to load default iocharset\n");
+			printk(KERN_ERR "hfs: unable to load default iocharset\n");
 			return 0;
 		}
 	}
@@ -364,7 +364,7 @@ static int hfs_fill_super(struct super_b
 
 	res = -EINVAL;
 	if (!parse_options((char *)data, sbi)) {
-		hfs_warn("hfs_fs: unable to parse mount options.\n");
+		printk(KERN_ERR "hfs: unable to parse mount options.\n");
 		goto bail;
 	}
 
@@ -375,7 +375,7 @@ static int hfs_fill_super(struct super_b
 	res = hfs_mdb_get(sb);
 	if (res) {
 		if (!silent)
-			hfs_warn("VFS: Can't find a HFS filesystem on dev %s.\n",
+			printk(KERN_WARNING "hfs: can't find a HFS filesystem on dev %s.\n",
 				hfs_mdb_name(sb));
 		res = -EINVAL;
 		goto bail;
@@ -407,7 +407,7 @@ static int hfs_fill_super(struct super_b
 bail_iput:
 	iput(root_inode);
 bail_no_root:
-	hfs_warn("hfs_fs: get root inode failed.\n");
+	printk(KERN_ERR "hfs: get root inode failed.\n");
 bail:
 	hfs_mdb_put(sb);
 	return res;
@@ -454,7 +454,7 @@ static void __exit exit_hfs_fs(void)
 {
 	unregister_filesystem(&hfs_fs_type);
 	if (kmem_cache_destroy(hfs_inode_cachep))
-		printk(KERN_INFO "hfs_inode_cache: not all structures were freed\n");
+		printk(KERN_ERR "hfs_inode_cache: not all structures were freed\n");
 }
 
 module_init(init_hfs_fs)
diff --git a/fs/hfsplus/bfind.c b/fs/hfsplus/bfind.c
index 257cdde..5007a41 100644
--- a/fs/hfsplus/bfind.c
+++ b/fs/hfsplus/bfind.c
@@ -64,7 +64,6 @@ int __hfs_brec_find(struct hfs_bnode *bn
 		else
 			e = rec - 1;
 	} while (b <= e);
-	//printk("%d: %d,%d,%d\n", bnode->this, b, e, rec);
 	if (rec != e && e >= 0) {
 		len = hfs_brec_lenoff(bnode, e, &off);
 		keylen = hfs_brec_keylen(bnode, e);
@@ -127,7 +126,7 @@ int hfs_brec_find(struct hfs_find_data *
 	return res;
 
 invalid:
-	printk("HFS+-fs: inconsistency in B*Tree (%d,%d,%d,%u,%u)\n",
+	printk(KERN_ERR "hfs: inconsistency in B*Tree (%d,%d,%d,%u,%u)\n",
 		height, bnode->height, bnode->type, nidx, parent);
 	res = -EIO;
 release:
diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c
index 930cd92..8f07e8f 100644
--- a/fs/hfsplus/bnode.c
+++ b/fs/hfsplus/bnode.c
@@ -358,7 +358,7 @@ void hfs_bnode_unlink(struct hfs_bnode *
 
 	// move down?
 	if (!node->prev && !node->next) {
-		printk("hfs_btree_del_level\n");
+		printk(KERN_DEBUG "hfs_btree_del_level\n");
 	}
 	if (!node->parent) {
 		tree->root = 0;
@@ -379,7 +379,7 @@ struct hfs_bnode *hfs_bnode_findhash(str
 	struct hfs_bnode *node;
 
 	if (cnid >= tree->node_count) {
-		printk("HFS+-fs: request for non-existent node %d in B*Tree\n", cnid);
+		printk(KERN_ERR "hfs: request for non-existent node %d in B*Tree\n", cnid);
 		return NULL;
 	}
 
@@ -402,7 +402,7 @@ static struct hfs_bnode *__hfs_bnode_cre
 	loff_t off;
 
 	if (cnid >= tree->node_count) {
-		printk("HFS+-fs: request for non-existent node %d in B*Tree\n", cnid);
+		printk(KERN_ERR "hfs: request for non-existent node %d in B*Tree\n", cnid);
 		return NULL;
 	}
 
@@ -576,8 +576,9 @@ struct hfs_bnode *hfs_bnode_create(struc
 	node = hfs_bnode_findhash(tree, num);
 	spin_unlock(&tree->hash_lock);
 	if (node) {
-		printk("new node %u already hashed?\n", num);
-		BUG();
+		printk(KERN_CRIT "new node %u already hashed?\n", num);
+		WARN_ON(1);
+		return node;
 	}
 	node = __hfs_bnode_create(tree, num);
 	if (!node)
diff --git a/fs/hfsplus/brec.c b/fs/hfsplus/brec.c
index 0ccef2a..c88e5d7 100644
--- a/fs/hfsplus/brec.c
+++ b/fs/hfsplus/brec.c
@@ -360,7 +360,7 @@ again:
 		end_off = hfs_bnode_read_u16(parent, end_rec_off);
 		if (end_rec_off - end_off < diff) {
 
-			printk("splitting index node...\n");
+			printk(KERN_DEBUG "hfs: splitting index node...\n");
 			fd->bnode = parent;
 			new_node = hfs_bnode_split(fd);
 			if (IS_ERR(new_node))
diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c
index 44326aa..a67edfa 100644
--- a/fs/hfsplus/btree.c
+++ b/fs/hfsplus/btree.c
@@ -31,17 +31,8 @@ struct hfs_btree *hfs_btree_open(struct 
 
 	init_MUTEX(&tree->tree_lock);
 	spin_lock_init(&tree->hash_lock);
-	/* Set the correct compare function */
 	tree->sb = sb;
 	tree->cnid = id;
-	if (id == HFSPLUS_EXT_CNID) {
-		tree->keycmp = hfsplus_ext_cmp_key;
-	} else if (id == HFSPLUS_CAT_CNID) {
-		tree->keycmp = hfsplus_cat_cmp_key;
-	} else {
-		printk("HFS+-fs: unknown B*Tree requested\n");
-		goto free_tree;
-	}
 	tree->inode = iget(sb, id);
 	if (!tree->inode)
 		goto free_tree;
@@ -64,6 +55,20 @@ struct hfs_btree *hfs_btree_open(struct 
 	tree->max_key_len = be16_to_cpu(head->max_key_len);
 	tree->depth = be16_to_cpu(head->depth);
 
+	/* Set the correct compare function */
+	if (id == HFSPLUS_EXT_CNID) {
+		tree->keycmp = hfsplus_ext_cmp_key;
+	} else if (id == HFSPLUS_CAT_CNID) {
+		if ((HFSPLUS_SB(sb).flags & HFSPLUS_SB_HFSX) &&
+		    (head->key_type == HFSPLUS_KEY_BINARY))
+			tree->keycmp = hfsplus_cat_bin_cmp_key;
+		else
+			tree->keycmp = hfsplus_cat_case_cmp_key;
+	} else {
+		printk(KERN_ERR "hfs: unknown B*Tree requested\n");
+		goto fail_page;
+	}
+
 	size = tree->node_size;
 	if (!size || size & (size - 1))
 		goto fail_page;
@@ -99,7 +104,7 @@ void hfs_btree_close(struct hfs_btree *t
 		while ((node = tree->node_hash[i])) {
 			tree->node_hash[i] = node->next_hash;
 			if (atomic_read(&node->refcnt))
-				printk("HFS+: node %d:%d still has %d user(s)!\n",
+				printk(KERN_CRIT "hfs: node %d:%d still has %d user(s)!\n",
 					node->tree->cnid, node->this, atomic_read(&node->refcnt));
 			hfs_bnode_free(node);
 			tree->node_hash_cnt--;
@@ -223,10 +228,6 @@ struct hfs_bnode *hfs_bmap_alloc(struct 
 						tree->free_nodes--;
 						mark_inode_dirty(tree->inode);
 						hfs_bnode_put(node);
-						if (!idx) {
-							printk("unexpected idx %u (%u)\n", idx, node->this);
-							BUG();
-						}
 						return hfs_bnode_create(tree, idx);
 					}
 				}
@@ -242,7 +243,7 @@ struct hfs_bnode *hfs_bmap_alloc(struct 
 		kunmap(*pagep);
 		nidx = node->next;
 		if (!nidx) {
-			printk("create new bmap node...\n");
+			printk(KERN_DEBUG "hfs: create new bmap node...\n");
 			next_node = hfs_bmap_new_bmap(node, idx);
 		} else
 			next_node = hfs_bnode_find(tree, nidx);
@@ -284,7 +285,7 @@ void hfs_bmap_free(struct hfs_bnode *nod
 		hfs_bnode_put(node);
 		if (!i) {
 			/* panic */;
-			printk("HFS: unable to free bnode %u. bmap not found!\n", node->this);
+			printk(KERN_CRIT "hfs: unable to free bnode %u. bmap not found!\n", node->this);
 			return;
 		}
 		node = hfs_bnode_find(tree, i);
@@ -292,7 +293,7 @@ void hfs_bmap_free(struct hfs_bnode *nod
 			return;
 		if (node->type != HFS_NODE_MAP) {
 			/* panic */;
-			printk("HFS: invalid bmap found! (%u,%d)\n", node->this, node->type);
+			printk(KERN_CRIT "hfs: invalid bmap found! (%u,%d)\n", node->this, node->type);
 			hfs_bnode_put(node);
 			return;
 		}
@@ -305,7 +306,7 @@ void hfs_bmap_free(struct hfs_bnode *nod
 	m = 1 << (~nidx & 7);
 	byte = data[off];
 	if (!(byte & m)) {
-		printk("HFS: trying to free free bnode %u(%d)\n", node->this, node->type);
+		printk(KERN_CRIT "hfs: trying to free free bnode %u(%d)\n", node->this, node->type);
 		kunmap(page);
 		hfs_bnode_put(node);
 		return;
diff --git a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c
index 9471279..f2d7c49 100644
--- a/fs/hfsplus/catalog.c
+++ b/fs/hfsplus/catalog.c
@@ -13,7 +13,8 @@
 #include "hfsplus_fs.h"
 #include "hfsplus_raw.h"
 
-int hfsplus_cat_cmp_key(hfsplus_btree_key *k1, hfsplus_btree_key *k2)
+int hfsplus_cat_case_cmp_key(const hfsplus_btree_key *k1,
+			     const hfsplus_btree_key *k2)
 {
 	__be32 k1p, k2p;
 
@@ -22,7 +23,20 @@ int hfsplus_cat_cmp_key(hfsplus_btree_ke
 	if (k1p != k2p)
 		return be32_to_cpu(k1p) < be32_to_cpu(k2p) ? -1 : 1;
 
-	return hfsplus_unistrcmp(&k1->cat.name, &k2->cat.name);
+	return hfsplus_strcasecmp(&k1->cat.name, &k2->cat.name);
+}
+
+int hfsplus_cat_bin_cmp_key(const hfsplus_btree_key *k1,
+			    const hfsplus_btree_key *k2)
+{
+	__be32 k1p, k2p;
+
+	k1p = k1->cat.parent;
+	k2p = k2->cat.parent;
+	if (k1p != k2p)
+		return be32_to_cpu(k1p) < be32_to_cpu(k2p) ? -1 : 1;
+
+	return hfsplus_strcmp(&k1->cat.name, &k2->cat.name);
 }
 
 void hfsplus_cat_build_key(struct super_block *sb, hfsplus_btree_key *key,
@@ -80,8 +94,11 @@ static int hfsplus_cat_build_record(hfsp
 		memset(folder, 0, sizeof(*folder));
 		folder->type = cpu_to_be16(HFSPLUS_FOLDER);
 		folder->id = cpu_to_be32(inode->i_ino);
-		folder->create_date = folder->content_mod_date =
-			folder->attribute_mod_date = folder->access_date = hfsp_now2mt();
+		HFSPLUS_I(inode).create_date =
+			folder->create_date =
+			folder->content_mod_date =
+			folder->attribute_mod_date =
+			folder->access_date = hfsp_now2mt();
 		hfsplus_set_perms(inode, &folder->permissions);
 		if (inode == HFSPLUS_SB(inode->i_sb).hidden_dir)
 			/* invisible and namelocked */
@@ -95,18 +112,27 @@ static int hfsplus_cat_build_record(hfsp
 		file->type = cpu_to_be16(HFSPLUS_FILE);
 		file->flags = cpu_to_be16(HFSPLUS_FILE_THREAD_EXISTS);
 		file->id = cpu_to_be32(cnid);
-		file->create_date = file->content_mod_date =
-			file->attribute_mod_date = file->access_date = hfsp_now2mt();
+		HFSPLUS_I(inode).create_date =
+			file->create_date =
+			file->content_mod_date =
+			file->attribute_mod_date =
+			file->access_date = hfsp_now2mt();
 		if (cnid == inode->i_ino) {
 			hfsplus_set_perms(inode, &file->permissions);
-			file->user_info.fdType = cpu_to_be32(HFSPLUS_SB(inode->i_sb).type);
-			file->user_info.fdCreator = cpu_to_be32(HFSPLUS_SB(inode->i_sb).creator);
+			if (S_ISLNK(inode->i_mode)) {
+				file->user_info.fdType = cpu_to_be32(HFSP_SYMLINK_TYPE);
+				file->user_info.fdCreator = cpu_to_be32(HFSP_SYMLINK_CREATOR);
+			} else {
+				file->user_info.fdType = cpu_to_be32(HFSPLUS_SB(inode->i_sb).type);
+				file->user_info.fdCreator = cpu_to_be32(HFSPLUS_SB(inode->i_sb).creator);
+			}
 			if ((file->permissions.rootflags | file->permissions.userflags) & HFSPLUS_FLG_IMMUTABLE)
 				file->flags |= cpu_to_be16(HFSPLUS_FILE_LOCKED);
 		} else {
 			file->user_info.fdType = cpu_to_be32(HFSP_HARDLINK_TYPE);
 			file->user_info.fdCreator = cpu_to_be32(HFSP_HFSPLUS_CREATOR);
 			file->user_info.fdFlags = cpu_to_be16(0x100);
+			file->create_date = HFSPLUS_I(HFSPLUS_SB(inode->i_sb).hidden_dir).create_date;
 			file->permissions.dev = cpu_to_be32(HFSPLUS_I(inode).dev);
 		}
 		return sizeof(*file);
@@ -139,7 +165,7 @@ int hfsplus_find_cat(struct super_block 
 
 	type = be16_to_cpu(tmp.type);
 	if (type != HFSPLUS_FOLDER_THREAD && type != HFSPLUS_FILE_THREAD) {
-		printk("HFS+-fs: Found bad thread record in catalog\n");
+		printk(KERN_ERR "hfs: found bad thread record in catalog\n");
 		return -EIO;
 	}
 
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index 50c8f44..01a6fe3 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -66,25 +66,32 @@ again:
 		}
 		cnid = be32_to_cpu(entry.file.id);
 		if (entry.file.user_info.fdType == cpu_to_be32(HFSP_HARDLINK_TYPE) &&
-		    entry.file.user_info.fdCreator == cpu_to_be32(HFSP_HFSPLUS_CREATOR)) {
+		    entry.file.user_info.fdCreator == cpu_to_be32(HFSP_HFSPLUS_CREATOR) &&
+		    (entry.file.create_date == HFSPLUS_I(HFSPLUS_SB(sb).hidden_dir).create_date ||
+		     entry.file.create_date == HFSPLUS_I(sb->s_root->d_inode).create_date) &&
+		    HFSPLUS_SB(sb).hidden_dir) {
 			struct qstr str;
 			char name[32];
 
 			if (dentry->d_fsdata) {
-				err = -ENOENT;
-				inode = NULL;
-				goto out;
+				/*
+				 * We found a link pointing to another link,
+				 * so ignore it and treat it as regular file.
+				 */
+				cnid = (unsigned long)dentry->d_fsdata;
+				linkid = 0;
+			} else {
+				dentry->d_fsdata = (void *)(unsigned long)cnid;
+				linkid = be32_to_cpu(entry.file.permissions.dev);
+				str.len = sprintf(name, "iNode%d", linkid);
+				str.name = name;
+				hfsplus_cat_build_key(sb, fd.search_key, HFSPLUS_SB(sb).hidden_dir->i_ino, &str);
+				goto again;
 			}
-			dentry->d_fsdata = (void *)(unsigned long)cnid;
-			linkid = be32_to_cpu(entry.file.permissions.dev);
-			str.len = sprintf(name, "iNode%d", linkid);
-			str.name = name;
-			hfsplus_cat_build_key(sb, fd.search_key, HFSPLUS_SB(sb).hidden_dir->i_ino, &str);
-			goto again;
 		} else if (!dentry->d_fsdata)
 			dentry->d_fsdata = (void *)(unsigned long)cnid;
 	} else {
-		printk("HFS+-fs: Illegal catalog entry type in lookup\n");
+		printk(KERN_ERR "hfs: invalid catalog entry type in lookup\n");
 		err = -EIO;
 		goto fail;
 	}
@@ -132,12 +139,12 @@ static int hfsplus_readdir(struct file *
 	case 1:
 		hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength);
 		if (be16_to_cpu(entry.type) != HFSPLUS_FOLDER_THREAD) {
-			printk("HFS+-fs: bad catalog folder thread\n");
+			printk(KERN_ERR "hfs: bad catalog folder thread\n");
 			err = -EIO;
 			goto out;
 		}
 		if (fd.entrylength < HFSPLUS_MIN_THREAD_SZ) {
-			printk("HFS+-fs: truncated catalog thread\n");
+			printk(KERN_ERR "hfs: truncated catalog thread\n");
 			err = -EIO;
 			goto out;
 		}
@@ -156,7 +163,7 @@ static int hfsplus_readdir(struct file *
 
 	for (;;) {
 		if (be32_to_cpu(fd.key->cat.parent) != inode->i_ino) {
-			printk("HFS+-fs: walked past end of dir\n");
+			printk(KERN_ERR "hfs: walked past end of dir\n");
 			err = -EIO;
 			goto out;
 		}
@@ -168,7 +175,7 @@ static int hfsplus_readdir(struct file *
 			goto out;
 		if (type == HFSPLUS_FOLDER) {
 			if (fd.entrylength < sizeof(struct hfsplus_cat_folder)) {
-				printk("HFS+-fs: small dir entry\n");
+				printk(KERN_ERR "hfs: small dir entry\n");
 				err = -EIO;
 				goto out;
 			}
@@ -180,7 +187,7 @@ static int hfsplus_readdir(struct file *
 				break;
 		} else if (type == HFSPLUS_FILE) {
 			if (fd.entrylength < sizeof(struct hfsplus_cat_file)) {
-				printk("HFS+-fs: small file entry\n");
+				printk(KERN_ERR "hfs: small file entry\n");
 				err = -EIO;
 				goto out;
 			}
@@ -188,7 +195,7 @@ static int hfsplus_readdir(struct file *
 				    be32_to_cpu(entry.file.id), DT_REG))
 				break;
 		} else {
-			printk("HFS+-fs: bad catalog entry type\n");
+			printk(KERN_ERR "hfs: bad catalog entry type\n");
 			err = -EIO;
 			goto out;
 		}
@@ -330,7 +337,8 @@ static int hfsplus_unlink(struct inode *
 	if (res)
 		return res;
 
-	inode->i_nlink--;
+	if (inode->i_nlink > 0)
+		inode->i_nlink--;
 	hfsplus_delete_inode(inode);
 	if (inode->i_ino != cnid && !inode->i_nlink) {
 		if (!atomic_read(&HFSPLUS_I(inode).opencnt)) {
@@ -339,7 +347,8 @@ static int hfsplus_unlink(struct inode *
 				hfsplus_delete_inode(inode);
 		} else
 			inode->i_flags |= S_DEAD;
-	}
+	} else
+		inode->i_nlink = 0;
 	inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 
diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c
index e3ff56a..1a74800 100644
--- a/fs/hfsplus/extents.c
+++ b/fs/hfsplus/extents.c
@@ -16,7 +16,8 @@
 #include "hfsplus_raw.h"
 
 /* Compare two extents keys, returns 0 on same, pos/neg for difference */
-int hfsplus_ext_cmp_key(hfsplus_btree_key *k1, hfsplus_btree_key *k2)
+int hfsplus_ext_cmp_key(const hfsplus_btree_key *k1,
+			const hfsplus_btree_key *k2)
 {
 	__be32 k1id, k2id;
 	__be32 k1s, k2s;
@@ -349,10 +350,9 @@ int hfsplus_file_extend(struct inode *in
 
 	if (HFSPLUS_SB(sb).alloc_file->i_size * 8 < HFSPLUS_SB(sb).total_blocks - HFSPLUS_SB(sb).free_blocks + 8) {
 		// extend alloc file
-		printk("extend alloc file! (%Lu,%u,%u)\n", HFSPLUS_SB(sb).alloc_file->i_size * 8,
+		printk(KERN_ERR "hfs: extend alloc file! (%Lu,%u,%u)\n", HFSPLUS_SB(sb).alloc_file->i_size * 8,
 			HFSPLUS_SB(sb).total_blocks, HFSPLUS_SB(sb).free_blocks);
 		return -ENOSPC;
-		//BUG();
 	}
 
 	down(&HFSPLUS_I(inode).extents_lock);
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index 0fa1ab6..7ae3936 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -36,7 +36,7 @@
 #define HFSPLUS_TYPE_DATA 0x00
 #define HFSPLUS_TYPE_RSRC 0xFF
 
-typedef int (*btree_keycmp)(hfsplus_btree_key *, hfsplus_btree_key *);
+typedef int (*btree_keycmp)(const hfsplus_btree_key *, const hfsplus_btree_key *);
 
 #define NODE_HASH_SIZE	256
 
@@ -149,6 +149,7 @@ struct hfsplus_sb_info {
 #define HFSPLUS_SB_WRITEBACKUP	0x0001
 #define HFSPLUS_SB_NODECOMPOSE	0x0002
 #define HFSPLUS_SB_FORCE	0x0004
+#define HFSPLUS_SB_HFSX		0x0008
 
 
 struct hfsplus_inode_info {
@@ -165,6 +166,7 @@ struct hfsplus_inode_info {
 	struct inode *rsrc_inode;
 	unsigned long flags;
 
+	__be32 create_date;
 	/* Device number in hfsplus_permissions in catalog */
 	u32 dev;
 	/* BSD system and user file flags */
@@ -303,7 +305,8 @@ int hfs_brec_read(struct hfs_find_data *
 int hfs_brec_goto(struct hfs_find_data *, int);
 
 /* catalog.c */
-int hfsplus_cat_cmp_key(hfsplus_btree_key *, hfsplus_btree_key *);
+int hfsplus_cat_case_cmp_key(const hfsplus_btree_key *, const hfsplus_btree_key *);
+int hfsplus_cat_bin_cmp_key(const hfsplus_btree_key *, const hfsplus_btree_key *);
 void hfsplus_cat_build_key(struct super_block *sb, hfsplus_btree_key *, u32, struct qstr *);
 int hfsplus_find_cat(struct super_block *, u32, struct hfs_find_data *);
 int hfsplus_create_cat(u32, struct inode *, struct qstr *, struct inode *);
@@ -312,7 +315,7 @@ int hfsplus_rename_cat(u32, struct inode
 		       struct inode *, struct qstr *);
 
 /* extents.c */
-int hfsplus_ext_cmp_key(hfsplus_btree_key *, hfsplus_btree_key *);
+int hfsplus_ext_cmp_key(const hfsplus_btree_key *, const hfsplus_btree_key *);
 void hfsplus_ext_write_extent(struct inode *);
 int hfsplus_get_block(struct inode *, sector_t, struct buffer_head *, int);
 int hfsplus_free_fork(struct super_block *, u32, struct hfsplus_fork_raw *, int);
@@ -350,7 +353,8 @@ extern u16 hfsplus_decompose_table[];
 extern u16 hfsplus_compose_table[];
 
 /* unicode.c */
-int hfsplus_unistrcmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *);
+int hfsplus_strcasecmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *);
+int hfsplus_strcmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *);
 int hfsplus_uni2asc(struct super_block *, const struct hfsplus_unistr *, char *, int *);
 int hfsplus_asc2uni(struct super_block *, struct hfsplus_unistr *, const char *, int);
 
diff --git a/fs/hfsplus/hfsplus_raw.h b/fs/hfsplus/hfsplus_raw.h
index b4fbed6..4920553 100644
--- a/fs/hfsplus/hfsplus_raw.h
+++ b/fs/hfsplus/hfsplus_raw.h
@@ -22,8 +22,10 @@
 #define HFSPLUS_SECTOR_SHIFT         9
 #define HFSPLUS_VOLHEAD_SECTOR       2
 #define HFSPLUS_VOLHEAD_SIG     0x482b
+#define HFSPLUS_VOLHEAD_SIGX    0x4858
 #define HFSPLUS_SUPER_MAGIC     0x482b
-#define HFSPLUS_CURRENT_VERSION      4
+#define HFSPLUS_MIN_VERSION          4
+#define HFSPLUS_CURRENT_VERSION      5
 
 #define HFSP_WRAP_MAGIC         0x4244
 #define HFSP_WRAP_ATTRIB_SLOCK  0x8000
@@ -41,6 +43,9 @@
 #define HFSP_HARDLINK_TYPE	0x686c6e6b	/* 'hlnk' */
 #define HFSP_HFSPLUS_CREATOR	0x6866732b	/* 'hfs+' */
 
+#define HFSP_SYMLINK_TYPE	0x736c6e6b	/* 'slnk' */
+#define HFSP_SYMLINK_CREATOR	0x72686170	/* 'rhap' */
+
 #define HFSP_MOUNT_VERSION	0x482b4c78	/* 'H+Lx' */
 
 /* Structures used on disk */
@@ -161,7 +166,7 @@ struct hfs_btree_header_rec {
 	u16 reserved1;
 	__be32 clump_size;
 	u8 btree_type;
-	u8 reserved2;
+	u8 key_type;
 	__be32 attributes;
 	u32 reserved3[16];
 } __packed;
@@ -186,6 +191,10 @@ struct hfs_btree_header_rec {
 #define HFSPLUS_EXCH_CNID		15	/* ExchangeFiles temp id */
 #define HFSPLUS_FIRSTUSER_CNID		16	/* first available user id */
 
+/* btree key type */
+#define HFSPLUS_KEY_CASEFOLDING		0xCF	/* case-insensitive */
+#define HFSPLUS_KEY_BINARY		0xBC	/* case-sensitive */
+
 /* HFS+ catalog entry key */
 struct hfsplus_cat_key {
 	__be16 key_len;
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index 7acff6c..12ed2b7 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -18,13 +18,11 @@
 
 static int hfsplus_readpage(struct file *file, struct page *page)
 {
-	//printk("readpage: %lu\n", page->index);
 	return block_read_full_page(page, hfsplus_get_block);
 }
 
 static int hfsplus_writepage(struct page *page, struct writeback_control *wbc)
 {
-	//printk("writepage: %lu\n", page->index);
 	return block_write_full_page(page, hfsplus_get_block, wbc);
 }
 
@@ -92,7 +90,6 @@ static int hfsplus_releasepage(struct pa
 		} while (--i && nidx < tree->node_count);
 		spin_unlock(&tree->hash_lock);
 	}
-	//printk("releasepage: %lu,%x = %d\n", page->index, mask, res);
 	return res ? try_to_free_buffers(page) : 0;
 }
 
@@ -434,7 +431,8 @@ int hfsplus_cat_read_inode(struct inode 
 		inode->i_size = 2 + be32_to_cpu(folder->valence);
 		inode->i_atime = hfsp_mt2ut(folder->access_date);
 		inode->i_mtime = hfsp_mt2ut(folder->content_mod_date);
-		inode->i_ctime = inode->i_mtime;
+		inode->i_ctime = hfsp_mt2ut(folder->attribute_mod_date);
+		HFSPLUS_I(inode).create_date = folder->create_date;
 		HFSPLUS_I(inode).fs_blocks = 0;
 		inode->i_op = &hfsplus_dir_inode_operations;
 		inode->i_fop = &hfsplus_dir_operations;
@@ -465,9 +463,10 @@ int hfsplus_cat_read_inode(struct inode 
 		}
 		inode->i_atime = hfsp_mt2ut(file->access_date);
 		inode->i_mtime = hfsp_mt2ut(file->content_mod_date);
-		inode->i_ctime = inode->i_mtime;
+		inode->i_ctime = hfsp_mt2ut(file->attribute_mod_date);
+		HFSPLUS_I(inode).create_date = file->create_date;
 	} else {
-		printk("HFS+-fs: bad catalog entry used to create inode\n");
+		printk(KERN_ERR "hfs: bad catalog entry used to create inode\n");
 		res = -EIO;
 	}
 	return res;
diff --git a/fs/hfsplus/options.c b/fs/hfsplus/options.c
index 935dafb..dc64fac 100644
--- a/fs/hfsplus/options.c
+++ b/fs/hfsplus/options.c
@@ -83,58 +83,58 @@ int hfsplus_parse_options(char *input, s
 		switch (token) {
 		case opt_creator:
 			if (match_fourchar(&args[0], &sbi->creator)) {
-				printk("HFS+-fs: creator requires a 4 character value\n");
+				printk(KERN_ERR "hfs: creator requires a 4 character value\n");
 				return 0;
 			}
 			break;
 		case opt_type:
 			if (match_fourchar(&args[0], &sbi->type)) {
-				printk("HFS+-fs: type requires a 4 character value\n");
+				printk(KERN_ERR "hfs: type requires a 4 character value\n");
 				return 0;
 			}
 			break;
 		case opt_umask:
 			if (match_octal(&args[0], &tmp)) {
-				printk("HFS+-fs: umask requires a value\n");
+				printk(KERN_ERR "hfs: umask requires a value\n");
 				return 0;
 			}
 			sbi->umask = (umode_t)tmp;
 			break;
 		case opt_uid:
 			if (match_int(&args[0], &tmp)) {
-				printk("HFS+-fs: uid requires an argument\n");
+				printk(KERN_ERR "hfs: uid requires an argument\n");
 				return 0;
 			}
 			sbi->uid = (uid_t)tmp;
 			break;
 		case opt_gid:
 			if (match_int(&args[0], &tmp)) {
-				printk("HFS+-fs: gid requires an argument\n");
+				printk(KERN_ERR "hfs: gid requires an argument\n");
 				return 0;
 			}
 			sbi->gid = (gid_t)tmp;
 			break;
 		case opt_part:
 			if (match_int(&args[0], &sbi->part)) {
-				printk("HFS+-fs: part requires an argument\n");
+				printk(KERN_ERR "hfs: part requires an argument\n");
 				return 0;
 			}
 			break;
 		case opt_session:
 			if (match_int(&args[0], &sbi->session)) {
-				printk("HFS+-fs: session requires an argument\n");
+				printk(KERN_ERR "hfs: session requires an argument\n");
 				return 0;
 			}
 			break;
 		case opt_nls:
 			if (sbi->nls) {
-				printk("HFS+-fs: unable to change nls mapping\n");
+				printk(KERN_ERR "hfs: unable to change nls mapping\n");
 				return 0;
 			}
 			p = match_strdup(&args[0]);
 			sbi->nls = load_nls(p);
 			if (!sbi->nls) {
-				printk("HFS+-fs: unable to load nls mapping \"%s\"\n", p);
+				printk(KERN_ERR "hfs: unable to load nls mapping \"%s\"\n", p);
 				kfree(p);
 				return 0;
 			}
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index d791780..7843f79 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -169,7 +169,7 @@ static void hfsplus_write_super(struct s
 			block = HFSPLUS_SB(sb).blockoffset;
 			block += (HFSPLUS_SB(sb).sect_count - 2) >> (sb->s_blocksize_bits - 9);
 			offset = ((HFSPLUS_SB(sb).sect_count - 2) << 9) & (sb->s_blocksize - 1);
-			printk("backup: %u,%u,%u,%u\n", HFSPLUS_SB(sb).blockoffset,
+			printk(KERN_DEBUG "hfs: backup: %u,%u,%u,%u\n", HFSPLUS_SB(sb).blockoffset,
 				HFSPLUS_SB(sb).sect_count, block, offset);
 			bh = sb_bread(sb, block);
 			if (bh) {
@@ -179,7 +179,7 @@ static void hfsplus_write_super(struct s
 					mark_buffer_dirty(bh);
 					brelse(bh);
 				} else
-					printk("backup not found!\n");
+					printk(KERN_WARNING "hfs: backup not found!\n");
 			}
 		}
 		HFSPLUS_SB(sb).flags &= ~HFSPLUS_SB_WRITEBACKUP;
@@ -240,18 +240,18 @@ static int hfsplus_remount(struct super_
 			return -EINVAL;
 
 		if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) {
-			printk("HFS+-fs warning: Filesystem was not cleanly unmounted, "
+			printk(KERN_WARNING "hfs: filesystem was not cleanly unmounted, "
 			       "running fsck.hfsplus is recommended.  leaving read-only.\n");
 			sb->s_flags |= MS_RDONLY;
 			*flags |= MS_RDONLY;
 		} else if (sbi.flags & HFSPLUS_SB_FORCE) {
 			/* nothing */
 		} else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) {
-			printk("HFS+-fs: Filesystem is marked locked, leaving read-only.\n");
+			printk(KERN_WARNING "hfs: filesystem is marked locked, leaving read-only.\n");
 			sb->s_flags |= MS_RDONLY;
 			*flags |= MS_RDONLY;
 		} else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) {
-			printk("HFS+-fs: Filesystem is marked journaled, leaving read-only.\n");
+			printk(KERN_WARNING "hfs: filesystem is marked journaled, leaving read-only.\n");
 			sb->s_flags |= MS_RDONLY;
 			*flags |= MS_RDONLY;
 		}
@@ -292,8 +292,7 @@ static int hfsplus_fill_super(struct sup
 	INIT_HLIST_HEAD(&sbi->rsrc_inodes);
 	hfsplus_fill_defaults(sbi);
 	if (!hfsplus_parse_options(data, sbi)) {
-		if (!silent)
-			printk("HFS+-fs: unable to parse mount options\n");
+		printk(KERN_ERR "hfs: unable to parse mount options\n");
 		err = -EINVAL;
 		goto cleanup;
 	}
@@ -302,7 +301,7 @@ static int hfsplus_fill_super(struct sup
 	nls = sbi->nls;
 	sbi->nls = load_nls("utf8");
 	if (!sbi->nls) {
-		printk("HFS+: unable to load nls for utf8\n");
+		printk(KERN_ERR "hfs: unable to load nls for utf8\n");
 		err = -EINVAL;
 		goto cleanup;
 	}
@@ -310,17 +309,17 @@ static int hfsplus_fill_super(struct sup
 	/* Grab the volume header */
 	if (hfsplus_read_wrapper(sb)) {
 		if (!silent)
-			printk("HFS+-fs: unable to find HFS+ superblock\n");
+			printk(KERN_WARNING "hfs: unable to find HFS+ superblock\n");
 		err = -EINVAL;
 		goto cleanup;
 	}
 	vhdr = HFSPLUS_SB(sb).s_vhdr;
 
 	/* Copy parts of the volume header into the superblock */
-	sb->s_magic = be16_to_cpu(vhdr->signature);
-	if (be16_to_cpu(vhdr->version) != HFSPLUS_CURRENT_VERSION) {
-		if (!silent)
-			printk("HFS+-fs: wrong filesystem version\n");
+	sb->s_magic = HFSPLUS_VOLHEAD_SIG;
+	if (be16_to_cpu(vhdr->version) < HFSPLUS_MIN_VERSION ||
+	    be16_to_cpu(vhdr->version) > HFSPLUS_CURRENT_VERSION) {
+		printk(KERN_ERR "hfs: wrong filesystem version\n");
 		goto cleanup;
 	}
 	HFSPLUS_SB(sb).total_blocks = be32_to_cpu(vhdr->total_blocks);
@@ -341,20 +340,17 @@ static int hfsplus_fill_super(struct sup
 	sb->s_maxbytes = MAX_LFS_FILESIZE;
 
 	if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) {
-		if (!silent)
-			printk("HFS+-fs warning: Filesystem was not cleanly unmounted, "
-			       "running fsck.hfsplus is recommended.  mounting read-only.\n");
+		printk(KERN_WARNING "hfs: Filesystem was not cleanly unmounted, "
+		       "running fsck.hfsplus is recommended.  mounting read-only.\n");
 		sb->s_flags |= MS_RDONLY;
 	} else if (sbi->flags & HFSPLUS_SB_FORCE) {
 		/* nothing */
 	} else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) {
-		if (!silent)
-			printk("HFS+-fs: Filesystem is marked locked, mounting read-only.\n");
+		printk(KERN_WARNING "hfs: Filesystem is marked locked, mounting read-only.\n");
 		sb->s_flags |= MS_RDONLY;
 	} else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) {
-		if (!silent)
-			printk("HFS+-fs: write access to a jounaled filesystem is not supported, "
-			       "use the force option at your own risk, mounting read-only.\n");
+		printk(KERN_WARNING "hfs: write access to a jounaled filesystem is not supported, "
+		       "use the force option at your own risk, mounting read-only.\n");
 		sb->s_flags |= MS_RDONLY;
 	}
 	sbi->flags &= ~HFSPLUS_SB_FORCE;
@@ -362,21 +358,18 @@ static int hfsplus_fill_super(struct sup
 	/* Load metadata objects (B*Trees) */
 	HFSPLUS_SB(sb).ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID);
 	if (!HFSPLUS_SB(sb).ext_tree) {
-		if (!silent)
-			printk("HFS+-fs: failed to load extents file\n");
+		printk(KERN_ERR "hfs: failed to load extents file\n");
 		goto cleanup;
 	}
 	HFSPLUS_SB(sb).cat_tree = hfs_btree_open(sb, HFSPLUS_CAT_CNID);
 	if (!HFSPLUS_SB(sb).cat_tree) {
-		if (!silent)
-			printk("HFS+-fs: failed to load catalog file\n");
+		printk(KERN_ERR "hfs: failed to load catalog file\n");
 		goto cleanup;
 	}
 
 	HFSPLUS_SB(sb).alloc_file = iget(sb, HFSPLUS_ALLOC_CNID);
 	if (!HFSPLUS_SB(sb).alloc_file) {
-		if (!silent)
-			printk("HFS+-fs: failed to load allocation file\n");
+		printk(KERN_ERR "hfs: failed to load allocation file\n");
 		goto cleanup;
 	}
 
@@ -384,8 +377,7 @@ static int hfsplus_fill_super(struct sup
 	root = iget(sb, HFSPLUS_ROOT_CNID);
 	sb->s_root = d_alloc_root(root);
 	if (!sb->s_root) {
-		if (!silent)
-			printk("HFS+-fs: failed to load root directory\n");
+		printk(KERN_ERR "hfs: failed to load root directory\n");
 		iput(root);
 		goto cleanup;
 	}
@@ -419,7 +411,7 @@ static int hfsplus_fill_super(struct sup
 	sync_dirty_buffer(HFSPLUS_SB(sb).s_vhbh);
 
 	if (!HFSPLUS_SB(sb).hidden_dir) {
-		printk("HFS+: create hidden dir...\n");
+		printk(KERN_DEBUG "hfs: create hidden dir...\n");
 		HFSPLUS_SB(sb).hidden_dir = hfsplus_new_inode(sb, S_IFDIR);
 		hfsplus_create_cat(HFSPLUS_SB(sb).hidden_dir->i_ino, sb->s_root->d_inode,
 				   &str, HFSPLUS_SB(sb).hidden_dir);
@@ -499,7 +491,7 @@ static void __exit exit_hfsplus_fs(void)
 {
 	unregister_filesystem(&hfsplus_fs_type);
 	if (kmem_cache_destroy(hfsplus_inode_cachep))
-		printk(KERN_INFO "hfsplus_inode_cache: not all structures were freed\n");
+		printk(KERN_ERR "hfsplus_inode_cache: not all structures were freed\n");
 }
 
 module_init(init_hfsplus_fs)
diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c
index 060c690..689c8bd 100644
--- a/fs/hfsplus/unicode.c
+++ b/fs/hfsplus/unicode.c
@@ -28,7 +28,8 @@ static inline u16 case_fold(u16 c)
 }
 
 /* Compare unicode strings, return values like normal strcmp */
-int hfsplus_unistrcmp(const struct hfsplus_unistr *s1, const struct hfsplus_unistr *s2)
+int hfsplus_strcasecmp(const struct hfsplus_unistr *s1,
+		       const struct hfsplus_unistr *s2)
 {
 	u16 len1, len2, c1, c2;
 	const hfsplus_unichr *p1, *p2;
@@ -59,6 +60,33 @@ int hfsplus_unistrcmp(const struct hfspl
 	}
 }
 
+/* Compare names as a sequence of 16-bit unsigned integers */
+int hfsplus_strcmp(const struct hfsplus_unistr *s1,
+		   const struct hfsplus_unistr *s2)
+{
+	u16 len1, len2, c1, c2;
+	const hfsplus_unichr *p1, *p2;
+	int len;
+
+	len1 = be16_to_cpu(s1->length);
+	len2 = be16_to_cpu(s2->length);
+	p1 = s1->unicode;
+	p2 = s2->unicode;
+
+	for (len = min(len1, len2); len > 0; len--) {
+		c1 = be16_to_cpu(*p1);
+		c2 = be16_to_cpu(*p2);
+		if (c1 != c2)
+			return c1 < c2 ? -1 : 1;
+		p1++;
+		p2++;
+	}
+
+	return len1 < len2 ? -1 :
+	       len1 > len2 ? 1 : 0;
+}
+
+
 #define Hangul_SBase	0xac00
 #define Hangul_LBase	0x1100
 #define Hangul_VBase	0x1161
diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c
index 95455e8..72cab78 100644
--- a/fs/hfsplus/wrapper.c
+++ b/fs/hfsplus/wrapper.c
@@ -28,8 +28,11 @@ static int hfsplus_read_mdb(void *bufptr
 {
 	u32 extent;
 	u16 attrib;
+	__be16 sig;
 
-	if (be16_to_cpu(*(__be16 *)(bufptr + HFSP_WRAPOFF_EMBEDSIG)) != HFSPLUS_VOLHEAD_SIG)
+	sig = *(__be16 *)(bufptr + HFSP_WRAPOFF_EMBEDSIG);
+	if (sig != cpu_to_be16(HFSPLUS_VOLHEAD_SIG) &&
+	    sig != cpu_to_be16(HFSPLUS_VOLHEAD_SIGX))
 		return 0;
 
 	attrib = be16_to_cpu(*(__be16 *)(bufptr + HFSP_WRAPOFF_ATTRIB));
@@ -70,7 +73,7 @@ static int hfsplus_get_last_session(stru
 			*start = (sector_t)te.cdte_addr.lba << 2;
 			return 0;
 		}
-		printk(KERN_ERR "HFS: Invalid session number or type of track\n");
+		printk(KERN_ERR "hfs: invalid session number or type of track\n");
 		return -EINVAL;
 	}
 	ms_info.addr_format = CDROM_LBA;
@@ -114,6 +117,10 @@ int hfsplus_read_wrapper(struct super_bl
 		}
 		if (vhdr->signature == cpu_to_be16(HFSPLUS_VOLHEAD_SIG))
 			break;
+		if (vhdr->signature == cpu_to_be16(HFSPLUS_VOLHEAD_SIGX)) {
+			HFSPLUS_SB(sb).flags |= HFSPLUS_SB_HFSX;
+			break;
+		}
 		brelse(bh);
 
 		/* check for a partition block
@@ -143,7 +150,7 @@ int hfsplus_read_wrapper(struct super_bl
 		blocksize >>= 1;
 
 	if (sb_set_blocksize(sb, blocksize) != blocksize) {
-		printk("HFS+: unable to blocksize to %u!\n", blocksize);
+		printk(KERN_ERR "hfs: unable to set blocksize to %u!\n", blocksize);
 		return -EINVAL;
 	}
 
@@ -158,7 +165,9 @@ int hfsplus_read_wrapper(struct super_bl
 		return -EIO;
 
 	/* should still be the same... */
-	if (be16_to_cpu(vhdr->signature) != HFSPLUS_VOLHEAD_SIG)
+	if (vhdr->signature != (HFSPLUS_SB(sb).flags & HFSPLUS_SB_HFSX ?
+				cpu_to_be16(HFSPLUS_VOLHEAD_SIGX) :
+				cpu_to_be16(HFSPLUS_VOLHEAD_SIG)))
 		goto error;
 	HFSPLUS_SB(sb).s_vhbh = bh;
 	HFSPLUS_SB(sb).s_vhdr = vhdr;
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index f568102..b351952 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -72,8 +72,8 @@ huge_pages_needed(struct address_space *
 	unsigned long start = vma->vm_start;
 	unsigned long end = vma->vm_end;
 	unsigned long hugepages = (end - start) >> HPAGE_SHIFT;
-	pgoff_t next = vma->vm_pgoff;
-	pgoff_t endpg = next + ((end - start) >> PAGE_SHIFT);
+	pgoff_t next = vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT);
+	pgoff_t endpg = next + hugepages;
 
 	pagevec_init(&pvec, 0);
 	while (next < endpg) {
diff --git a/fs/inode.c b/fs/inode.c
index 108138d..d0be615 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1179,7 +1179,7 @@ EXPORT_SYMBOL(bmap);
 /**
  *	touch_atime	-	update the access time
  *	@mnt: mount the inode is accessed on
- *	@inode: inode accessed
+ *	@dentry: dentry accessed
  *
  *	Update the accessed time on an inode and mark it for writeback.
  *	This function automatically handles read only file systems and media,
diff --git a/fs/inotify.c b/fs/inotify.c
index 2fecb7a..878ccca 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -33,6 +33,7 @@
 #include <linux/list.h>
 #include <linux/writeback.h>
 #include <linux/inotify.h>
+#include <linux/syscalls.h>
 
 #include <asm/ioctls.h>
 
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c
index cb3cef5..e6265a0 100644
--- a/fs/jbd/checkpoint.c
+++ b/fs/jbd/checkpoint.c
@@ -338,7 +338,7 @@ restart:
 	 * done (maybe it's a new transaction, but it fell at the same
 	 * address).
 	 */
- 	if (journal->j_checkpoint_transactions == transaction ||
+ 	if (journal->j_checkpoint_transactions == transaction &&
 			transaction->t_tid == this_tid) {
 		int batch_count = 0;
 		struct buffer_head *bhs[NR_BATCH];
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index 002ad2b..29e62d9 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -829,7 +829,8 @@ restart_loop:
 	journal->j_committing_transaction = NULL;
 	spin_unlock(&journal->j_state_lock);
 
-	if (commit_transaction->t_checkpoint_list == NULL) {
+	if (commit_transaction->t_checkpoint_list == NULL &&
+	    commit_transaction->t_checkpoint_io_list == NULL) {
 		__journal_drop_transaction(journal, commit_transaction);
 	} else {
 		if (journal->j_checkpoint_transactions == NULL) {
diff --git a/fs/namei.c b/fs/namei.c
index 33fb5bd..7ac9fb4 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -30,6 +30,8 @@
 #include <linux/audit.h>
 #include <linux/capability.h>
 #include <linux/file.h>
+#include <linux/fcntl.h>
+#include <linux/namei.h>
 #include <asm/namei.h>
 #include <asm/uaccess.h>
 
@@ -1063,7 +1065,8 @@ set_it:
 }
 
 /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
-int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata *nd)
+static int fastcall do_path_lookup(int dfd, const char *name,
+				unsigned int flags, struct nameidata *nd)
 {
 	int retval = 0;
 
@@ -1083,9 +1086,38 @@ int fastcall path_lookup(const char *nam
 		}
 		nd->mnt = mntget(current->fs->rootmnt);
 		nd->dentry = dget(current->fs->root);
-	} else {
+	} else if (dfd == AT_FDCWD) {
 		nd->mnt = mntget(current->fs->pwdmnt);
 		nd->dentry = dget(current->fs->pwd);
+	} else {
+		struct file *file;
+		int fput_needed;
+		struct dentry *dentry;
+
+		file = fget_light(dfd, &fput_needed);
+		if (!file) {
+			retval = -EBADF;
+			goto out_fail;
+		}
+
+		dentry = file->f_dentry;
+
+		if (!S_ISDIR(dentry->d_inode->i_mode)) {
+			retval = -ENOTDIR;
+			fput_light(file, fput_needed);
+			goto out_fail;
+		}
+
+		retval = file_permission(file, MAY_EXEC);
+		if (retval) {
+			fput_light(file, fput_needed);
+			goto out_fail;
+		}
+
+		nd->mnt = mntget(file->f_vfsmnt);
+		nd->dentry = dget(dentry);
+
+		fput_light(file, fput_needed);
 	}
 	read_unlock(&current->fs->lock);
 	current->total_link_count = 0;
@@ -1094,11 +1126,19 @@ out:
 	if (unlikely(current->audit_context
 		     && nd && nd->dentry && nd->dentry->d_inode))
 		audit_inode(name, nd->dentry->d_inode, flags);
+out_fail:
 	return retval;
 }
 
-static int __path_lookup_intent_open(const char *name, unsigned int lookup_flags,
-		struct nameidata *nd, int open_flags, int create_mode)
+int fastcall path_lookup(const char *name, unsigned int flags,
+			struct nameidata *nd)
+{
+	return do_path_lookup(AT_FDCWD, name, flags, nd);
+}
+
+static int __path_lookup_intent_open(int dfd, const char *name,
+		unsigned int lookup_flags, struct nameidata *nd,
+		int open_flags, int create_mode)
 {
 	struct file *filp = get_empty_filp();
 	int err;
@@ -1108,7 +1148,7 @@ static int __path_lookup_intent_open(con
 	nd->intent.open.file = filp;
 	nd->intent.open.flags = open_flags;
 	nd->intent.open.create_mode = create_mode;
-	err = path_lookup(name, lookup_flags|LOOKUP_OPEN, nd);
+	err = do_path_lookup(dfd, name, lookup_flags|LOOKUP_OPEN, nd);
 	if (IS_ERR(nd->intent.open.file)) {
 		if (err == 0) {
 			err = PTR_ERR(nd->intent.open.file);
@@ -1121,32 +1161,34 @@ static int __path_lookup_intent_open(con
 
 /**
  * path_lookup_open - lookup a file path with open intent
+ * @dfd: the directory to use as base, or AT_FDCWD
  * @name: pointer to file name
  * @lookup_flags: lookup intent flags
  * @nd: pointer to nameidata
  * @open_flags: open intent flags
  */
-int path_lookup_open(const char *name, unsigned int lookup_flags,
+int path_lookup_open(int dfd, const char *name, unsigned int lookup_flags,
 		struct nameidata *nd, int open_flags)
 {
-	return __path_lookup_intent_open(name, lookup_flags, nd,
+	return __path_lookup_intent_open(dfd, name, lookup_flags, nd,
 			open_flags, 0);
 }
 
 /**
  * path_lookup_create - lookup a file path with open + create intent
+ * @dfd: the directory to use as base, or AT_FDCWD
  * @name: pointer to file name
  * @lookup_flags: lookup intent flags
  * @nd: pointer to nameidata
  * @open_flags: open intent flags
  * @create_mode: create intent flags
  */
-static int path_lookup_create(const char *name, unsigned int lookup_flags,
-			      struct nameidata *nd, int open_flags,
-			      int create_mode)
+static int path_lookup_create(int dfd, const char *name,
+			      unsigned int lookup_flags, struct nameidata *nd,
+			      int open_flags, int create_mode)
 {
-	return __path_lookup_intent_open(name, lookup_flags|LOOKUP_CREATE, nd,
-			open_flags, create_mode);
+	return __path_lookup_intent_open(dfd, name, lookup_flags|LOOKUP_CREATE,
+			nd, open_flags, create_mode);
 }
 
 int __user_path_lookup_open(const char __user *name, unsigned int lookup_flags,
@@ -1156,7 +1198,7 @@ int __user_path_lookup_open(const char _
 	int err = PTR_ERR(tmp);
 
 	if (!IS_ERR(tmp)) {
-		err = __path_lookup_intent_open(tmp, lookup_flags, nd, open_flags, 0);
+		err = __path_lookup_intent_open(AT_FDCWD, tmp, lookup_flags, nd, open_flags, 0);
 		putname(tmp);
 	}
 	return err;
@@ -1248,18 +1290,24 @@ access:
  * that namei follows links, while lnamei does not.
  * SMP-safe
  */
-int fastcall __user_walk(const char __user *name, unsigned flags, struct nameidata *nd)
+int fastcall __user_walk_fd(int dfd, const char __user *name, unsigned flags,
+			    struct nameidata *nd)
 {
 	char *tmp = getname(name);
 	int err = PTR_ERR(tmp);
 
 	if (!IS_ERR(tmp)) {
-		err = path_lookup(tmp, flags, nd);
+		err = do_path_lookup(dfd, tmp, flags, nd);
 		putname(tmp);
 	}
 	return err;
 }
 
+int fastcall __user_walk(const char __user *name, unsigned flags, struct nameidata *nd)
+{
+	return __user_walk_fd(AT_FDCWD, name, flags, nd);
+}
+
 /*
  * It's inline, so penalty for filesystems that don't use sticky bit is
  * minimal.
@@ -1518,7 +1566,8 @@ int may_open(struct nameidata *nd, int a
  * for symlinks (where the permissions are checked later).
  * SMP-safe
  */
-int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
+int open_namei(int dfd, const char *pathname, int flag,
+		int mode, struct nameidata *nd)
 {
 	int acc_mode, error;
 	struct path path;
@@ -1540,7 +1589,8 @@ int open_namei(const char * pathname, in
 	 * The simplest case - just a plain lookup.
 	 */
 	if (!(flag & O_CREAT)) {
-		error = path_lookup_open(pathname, lookup_flags(flag), nd, flag);
+		error = path_lookup_open(dfd, pathname, lookup_flags(flag),
+					 nd, flag);
 		if (error)
 			return error;
 		goto ok;
@@ -1549,7 +1599,7 @@ int open_namei(const char * pathname, in
 	/*
 	 * Create - we need to know the parent.
 	 */
-	error = path_lookup_create(pathname, LOOKUP_PARENT, nd, flag, mode);
+	error = path_lookup_create(dfd,pathname,LOOKUP_PARENT,nd,flag,mode);
 	if (error)
 		return error;
 
@@ -1744,7 +1794,8 @@ int vfs_mknod(struct inode *dir, struct 
 	return error;
 }
 
-asmlinkage long sys_mknod(const char __user * filename, int mode, unsigned dev)
+asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode,
+				unsigned dev)
 {
 	int error = 0;
 	char * tmp;
@@ -1757,7 +1808,7 @@ asmlinkage long sys_mknod(const char __u
 	if (IS_ERR(tmp))
 		return PTR_ERR(tmp);
 
-	error = path_lookup(tmp, LOOKUP_PARENT, &nd);
+	error = do_path_lookup(dfd, tmp, LOOKUP_PARENT, &nd);
 	if (error)
 		goto out;
 	dentry = lookup_create(&nd, 0);
@@ -1793,6 +1844,11 @@ out:
 	return error;
 }
 
+asmlinkage long sys_mknod(const char __user *filename, int mode, unsigned dev)
+{
+	return sys_mknodat(AT_FDCWD, filename, mode, dev);
+}
+
 int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 {
 	int error = may_create(dir, dentry, NULL);
@@ -1815,7 +1871,7 @@ int vfs_mkdir(struct inode *dir, struct 
 	return error;
 }
 
-asmlinkage long sys_mkdir(const char __user * pathname, int mode)
+asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode)
 {
 	int error = 0;
 	char * tmp;
@@ -1826,7 +1882,7 @@ asmlinkage long sys_mkdir(const char __u
 		struct dentry *dentry;
 		struct nameidata nd;
 
-		error = path_lookup(tmp, LOOKUP_PARENT, &nd);
+		error = do_path_lookup(dfd, tmp, LOOKUP_PARENT, &nd);
 		if (error)
 			goto out;
 		dentry = lookup_create(&nd, 1);
@@ -1846,6 +1902,11 @@ out:
 	return error;
 }
 
+asmlinkage long sys_mkdir(const char __user *pathname, int mode)
+{
+	return sys_mkdirat(AT_FDCWD, pathname, mode);
+}
+
 /*
  * We try to drop the dentry early: we should have
  * a usage count of 2 if we're the only user of this
@@ -1907,7 +1968,7 @@ int vfs_rmdir(struct inode *dir, struct 
 	return error;
 }
 
-asmlinkage long sys_rmdir(const char __user * pathname)
+static long do_rmdir(int dfd, const char __user *pathname)
 {
 	int error = 0;
 	char * name;
@@ -1918,7 +1979,7 @@ asmlinkage long sys_rmdir(const char __u
 	if(IS_ERR(name))
 		return PTR_ERR(name);
 
-	error = path_lookup(name, LOOKUP_PARENT, &nd);
+	error = do_path_lookup(dfd, name, LOOKUP_PARENT, &nd);
 	if (error)
 		goto exit;
 
@@ -1948,6 +2009,11 @@ exit:
 	return error;
 }
 
+asmlinkage long sys_rmdir(const char __user *pathname)
+{
+	return do_rmdir(AT_FDCWD, pathname);
+}
+
 int vfs_unlink(struct inode *dir, struct dentry *dentry)
 {
 	int error = may_delete(dir, dentry, 0);
@@ -1984,7 +2050,7 @@ int vfs_unlink(struct inode *dir, struct
  * writeout happening, and we don't want to prevent access to the directory
  * while waiting on the I/O.
  */
-asmlinkage long sys_unlink(const char __user * pathname)
+static long do_unlinkat(int dfd, const char __user *pathname)
 {
 	int error = 0;
 	char * name;
@@ -1996,7 +2062,7 @@ asmlinkage long sys_unlink(const char __
 	if(IS_ERR(name))
 		return PTR_ERR(name);
 
-	error = path_lookup(name, LOOKUP_PARENT, &nd);
+	error = do_path_lookup(dfd, name, LOOKUP_PARENT, &nd);
 	if (error)
 		goto exit;
 	error = -EISDIR;
@@ -2031,6 +2097,22 @@ slashes:
 	goto exit2;
 }
 
+asmlinkage long sys_unlinkat(int dfd, const char __user *pathname, int flag)
+{
+	if ((flag & ~AT_REMOVEDIR) != 0)
+		return -EINVAL;
+
+	if (flag & AT_REMOVEDIR)
+		return do_rmdir(dfd, pathname);
+
+	return do_unlinkat(dfd, pathname);
+}
+
+asmlinkage long sys_unlink(const char __user *pathname)
+{
+	return do_unlinkat(AT_FDCWD, pathname);
+}
+
 int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode)
 {
 	int error = may_create(dir, dentry, NULL);
@@ -2052,7 +2134,8 @@ int vfs_symlink(struct inode *dir, struc
 	return error;
 }
 
-asmlinkage long sys_symlink(const char __user * oldname, const char __user * newname)
+asmlinkage long sys_symlinkat(const char __user *oldname,
+			      int newdfd, const char __user *newname)
 {
 	int error = 0;
 	char * from;
@@ -2067,7 +2150,7 @@ asmlinkage long sys_symlink(const char _
 		struct dentry *dentry;
 		struct nameidata nd;
 
-		error = path_lookup(to, LOOKUP_PARENT, &nd);
+		error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd);
 		if (error)
 			goto out;
 		dentry = lookup_create(&nd, 0);
@@ -2085,6 +2168,11 @@ out:
 	return error;
 }
 
+asmlinkage long sys_symlink(const char __user *oldname, const char __user *newname)
+{
+	return sys_symlinkat(oldname, AT_FDCWD, newname);
+}
+
 int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
 {
 	struct inode *inode = old_dentry->d_inode;
@@ -2132,7 +2220,8 @@ int vfs_link(struct dentry *old_dentry, 
  * with linux 2.0, and to avoid hard-linking to directories
  * and other special files.  --ADM
  */
-asmlinkage long sys_link(const char __user * oldname, const char __user * newname)
+asmlinkage long sys_linkat(int olddfd, const char __user *oldname,
+			   int newdfd, const char __user *newname)
 {
 	struct dentry *new_dentry;
 	struct nameidata nd, old_nd;
@@ -2143,10 +2232,10 @@ asmlinkage long sys_link(const char __us
 	if (IS_ERR(to))
 		return PTR_ERR(to);
 
-	error = __user_walk(oldname, 0, &old_nd);
+	error = __user_walk_fd(olddfd, oldname, 0, &old_nd);
 	if (error)
 		goto exit;
-	error = path_lookup(to, LOOKUP_PARENT, &nd);
+	error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd);
 	if (error)
 		goto out;
 	error = -EXDEV;
@@ -2169,6 +2258,11 @@ exit:
 	return error;
 }
 
+asmlinkage long sys_link(const char __user *oldname, const char __user *newname)
+{
+	return sys_linkat(AT_FDCWD, oldname, AT_FDCWD, newname);
+}
+
 /*
  * The worst of all namespace operations - renaming directory. "Perverted"
  * doesn't even start to describe it. Somebody in UCB had a heck of a trip...
@@ -2315,7 +2409,8 @@ int vfs_rename(struct inode *old_dir, st
 	return error;
 }
 
-static int do_rename(const char * oldname, const char * newname)
+static int do_rename(int olddfd, const char *oldname,
+			int newdfd, const char *newname)
 {
 	int error = 0;
 	struct dentry * old_dir, * new_dir;
@@ -2323,11 +2418,11 @@ static int do_rename(const char * oldnam
 	struct dentry * trap;
 	struct nameidata oldnd, newnd;
 
-	error = path_lookup(oldname, LOOKUP_PARENT, &oldnd);
+	error = do_path_lookup(olddfd, oldname, LOOKUP_PARENT, &oldnd);
 	if (error)
 		goto exit;
 
-	error = path_lookup(newname, LOOKUP_PARENT, &newnd);
+	error = do_path_lookup(newdfd, newname, LOOKUP_PARENT, &newnd);
 	if (error)
 		goto exit1;
 
@@ -2391,7 +2486,8 @@ exit:
 	return error;
 }
 
-asmlinkage long sys_rename(const char __user * oldname, const char __user * newname)
+asmlinkage long sys_renameat(int olddfd, const char __user *oldname,
+			     int newdfd, const char __user *newname)
 {
 	int error;
 	char * from;
@@ -2403,13 +2499,18 @@ asmlinkage long sys_rename(const char __
 	to = getname(newname);
 	error = PTR_ERR(to);
 	if (!IS_ERR(to)) {
-		error = do_rename(from,to);
+		error = do_rename(olddfd, from, newdfd, to);
 		putname(to);
 	}
 	putname(from);
 	return error;
 }
 
+asmlinkage long sys_rename(const char __user *oldname, const char __user *newname)
+{
+	return sys_renameat(AT_FDCWD, oldname, AT_FDCWD, newname);
+}
+
 int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen, const char *link)
 {
 	int len;
@@ -2553,6 +2654,7 @@ struct inode_operations page_symlink_ino
 };
 
 EXPORT_SYMBOL(__user_walk);
+EXPORT_SYMBOL(__user_walk_fd);
 EXPORT_SYMBOL(follow_down);
 EXPORT_SYMBOL(follow_up);
 EXPORT_SYMBOL(get_write_access); /* binfmt_aout */
diff --git a/fs/nfsctl.c b/fs/nfsctl.c
index 0b14938..0d4cf94 100644
--- a/fs/nfsctl.c
+++ b/fs/nfsctl.c
@@ -5,6 +5,7 @@
  *
  */
 #include <linux/config.h>
+#include <linux/types.h>
 #include <linux/file.h>
 #include <linux/fs.h>
 #include <linux/sunrpc/svc.h>
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 361b400..a00fe86 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -192,6 +192,14 @@ nfsd4_open(struct svc_rqst *rqstp, struc
 	}
 	if (status)
 		goto out;
+
+	/* Openowner is now set, so sequence id will get bumped.  Now we need
+	 * these checks before we do any creates: */
+	if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
+		return nfserr_grace;
+	if (!nfs4_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
+		return nfserr_no_grace;
+
 	switch (open->op_claim_type) {
 		case NFS4_OPEN_CLAIM_DELEGATE_CUR:
 			status = nfserr_inval;
@@ -210,6 +218,7 @@ nfsd4_open(struct svc_rqst *rqstp, struc
 				goto out;
 			break;
 		case NFS4_OPEN_CLAIM_PREVIOUS:
+			open->op_stateowner->so_confirmed = 1;
 			/*
 			 * The CURRENT_FH is already set to the file being
 			 * opened.  (1) set open->op_cinfo, (2) set
@@ -221,6 +230,7 @@ nfsd4_open(struct svc_rqst *rqstp, struc
 				goto out;
 			break;
              	case NFS4_OPEN_CLAIM_DELEGATE_PREV:
+			open->op_stateowner->so_confirmed = 1;
 			printk("NFSD: unsupported OPEN claim type %d\n",
 				open->op_claim_type);
 			status = nfserr_notsupp;
@@ -584,31 +594,23 @@ nfsd4_setattr(struct svc_rqst *rqstp, st
 {
 	int status = nfs_ok;
 
-	if (!current_fh->fh_dentry)
-		return nfserr_nofilehandle;
-
-	status = nfs_ok;
 	if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
 		nfs4_lock_state();
-		if ((status = nfs4_preprocess_stateid_op(current_fh,
-						&setattr->sa_stateid,
-						CHECK_FH | WR_STATE, NULL))) {
-			dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n");
-			goto out_unlock;
-		}
+		status = nfs4_preprocess_stateid_op(current_fh,
+			&setattr->sa_stateid, CHECK_FH | WR_STATE, NULL);
 		nfs4_unlock_state();
+		if (status) {
+			dprintk("NFSD: nfsd4_setattr: couldn't process stateid!");
+			return status;
+		}
 	}
 	status = nfs_ok;
 	if (setattr->sa_acl != NULL)
 		status = nfsd4_set_nfs4_acl(rqstp, current_fh, setattr->sa_acl);
 	if (status)
-		goto out;
+		return status;
 	status = nfsd_setattr(rqstp, current_fh, &setattr->sa_iattr,
 				0, (time_t)0);
-out:
-	return status;
-out_unlock:
-	nfs4_unlock_state();
 	return status;
 }
 
@@ -626,15 +628,17 @@ nfsd4_write(struct svc_rqst *rqstp, stru
 		return nfserr_inval;
 
 	nfs4_lock_state();
-	if ((status = nfs4_preprocess_stateid_op(current_fh, stateid,
-					CHECK_FH | WR_STATE, &filp))) {
-		dprintk("NFSD: nfsd4_write: couldn't process stateid!\n");
-		goto out;
-	}
+	status = nfs4_preprocess_stateid_op(current_fh, stateid,
+					CHECK_FH | WR_STATE, &filp);
 	if (filp)
 		get_file(filp);
 	nfs4_unlock_state();
 
+	if (status) {
+		dprintk("NFSD: nfsd4_write: couldn't process stateid!\n");
+		return status;
+	}
+
 	write->wr_bytes_written = write->wr_buflen;
 	write->wr_how_written = write->wr_stable_how;
 	p = (u32 *)write->wr_verifier.data;
@@ -650,9 +654,6 @@ nfsd4_write(struct svc_rqst *rqstp, stru
 	if (status == nfserr_symlink)
 		status = nfserr_inval;
 	return status;
-out:
-	nfs4_unlock_state();
-	return status;
 }
 
 /* This routine never returns NFS_OK!  If there are no other errors, it
@@ -768,6 +769,8 @@ nfsd4_proc_compound(struct svc_rqst *rqs
 	while (!status && resp->opcnt < args->opcnt) {
 		op = &args->ops[resp->opcnt++];
 
+		dprintk("nfsv4 compound op #%d: %d\n", resp->opcnt, op->opnum);
+
 		/*
 		 * The XDR decode routines may have pre-set op->status;
 		 * for example, if there is a miscellaneous XDR error
@@ -792,17 +795,13 @@ nfsd4_proc_compound(struct svc_rqst *rqs
 		/* All operations except RENEW, SETCLIENTID, RESTOREFH
 		* SETCLIENTID_CONFIRM, PUTFH and PUTROOTFH
 		* require a valid current filehandle
-		*
-		* SETATTR NOFILEHANDLE error handled in nfsd4_setattr
-		* due to required returned bitmap argument
 		*/
 		if ((!current_fh->fh_dentry) &&
 		   !((op->opnum == OP_PUTFH) || (op->opnum == OP_PUTROOTFH) ||
 		   (op->opnum == OP_SETCLIENTID) ||
 		   (op->opnum == OP_SETCLIENTID_CONFIRM) ||
 		   (op->opnum == OP_RENEW) || (op->opnum == OP_RESTOREFH) ||
-		   (op->opnum == OP_RELEASE_LOCKOWNER) ||
-		   (op->opnum == OP_SETATTR))) {
+		   (op->opnum == OP_RELEASE_LOCKOWNER))) {
 			op->status = nfserr_nofilehandle;
 			goto encode_op;
 		}
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index be963a1..06da750 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -222,8 +222,7 @@ nfsd4_list_rec_dir(struct dentry *dir, r
 
 	nfs4_save_user(&uid, &gid);
 
-	filp = dentry_open(dget(dir), mntget(rec_dir.mnt),
-			O_RDWR);
+	filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY);
 	status = PTR_ERR(filp);
 	if (IS_ERR(filp))
 		goto out;
@@ -400,9 +399,10 @@ nfsd4_init_recdir(char *rec_dirname)
 
 	nfs4_save_user(&uid, &gid);
 
-	status = path_lookup(rec_dirname, LOOKUP_FOLLOW, &rec_dir);
-	if (status == -ENOENT)
-		printk("NFSD: recovery directory %s doesn't exist\n",
+	status = path_lookup(rec_dirname, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
+			&rec_dir);
+	if (status)
+		printk("NFSD: unable to find recovery directory %s\n",
 				rec_dirname);
 
 	if (!status)
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 6bbefd0..1143cfb 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1088,7 +1088,7 @@ alloc_init_open_stateowner(unsigned int 
 	sop->so_seqid = open->op_seqid;
 	sop->so_confirmed = 0;
 	rp = &sop->so_replay;
-	rp->rp_status = NFSERR_SERVERFAULT;
+	rp->rp_status = nfserr_serverfault;
 	rp->rp_buflen = 0;
 	rp->rp_buf = rp->rp_ibuf;
 	return sop;
@@ -1178,7 +1178,6 @@ release_stateid(struct nfs4_stateid *stp
 		locks_remove_posix(filp, (fl_owner_t) stp->st_stateowner);
 	put_nfs4_file(stp->st_file);
 	kmem_cache_free(stateid_slab, stp);
-	stp = NULL;
 }
 
 static void
@@ -1191,22 +1190,6 @@ move_to_close_lru(struct nfs4_stateowner
 	sop->so_time = get_seconds();
 }
 
-static void
-release_state_owner(struct nfs4_stateid *stp, int flag)
-{
-	struct nfs4_stateowner *sop = stp->st_stateowner;
-
-	dprintk("NFSD: release_state_owner\n");
-	release_stateid(stp, flag);
-
-	/* place unused nfs4_stateowners on so_close_lru list to be
-	 * released by the laundromat service after the lease period
-	 * to enable us to handle CLOSE replay
-	 */
-	if (sop->so_confirmed && list_empty(&sop->so_stateids))
-		move_to_close_lru(sop);
-}
-
 static int
 cmp_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner, clientid_t *clid) {
 	return ((sop->so_owner.len == owner->len) && 
@@ -1446,92 +1429,61 @@ static struct lock_manager_operations nf
 };
 
 
-/*
- * nfsd4_process_open1()
- * 	lookup stateowner.
- * 		found:
- * 			check confirmed 
- * 				confirmed:
- * 					check seqid
- * 				not confirmed:
- * 					delete owner
- * 					create new owner
- * 		notfound:
- * 			verify clientid
- * 			create new owner
- *
- * called with nfs4_lock_state() held.
- */
 int
 nfsd4_process_open1(struct nfsd4_open *open)
 {
-	int status;
 	clientid_t *clientid = &open->op_clientid;
 	struct nfs4_client *clp = NULL;
 	unsigned int strhashval;
 	struct nfs4_stateowner *sop = NULL;
 
-	status = nfserr_inval;
 	if (!check_name(open->op_owner))
-		goto out;
+		return nfserr_inval;
 
 	if (STALE_CLIENTID(&open->op_clientid))
 		return nfserr_stale_clientid;
 
 	strhashval = ownerstr_hashval(clientid->cl_id, open->op_owner);
 	sop = find_openstateowner_str(strhashval, open);
-	if (sop) {
-		open->op_stateowner = sop;
-		/* check for replay */
-		if (open->op_seqid == sop->so_seqid - 1){
-			if (sop->so_replay.rp_buflen)
-				return NFSERR_REPLAY_ME;
-			else {
-				/* The original OPEN failed so spectacularly
-				 * that we don't even have replay data saved!
-				 * Therefore, we have no choice but to continue
-				 * processing this OPEN; presumably, we'll
-				 * fail again for the same reason.
-				 */
-				dprintk("nfsd4_process_open1:"
-					" replay with no replay cache\n");
-				goto renew;
-			}
-		} else if (sop->so_confirmed) {
-			if (open->op_seqid == sop->so_seqid)
-				goto renew;
-			status = nfserr_bad_seqid;
-			goto out;
-		} else {
-			/* If we get here, we received an OPEN for an
-			 * unconfirmed nfs4_stateowner. Since the seqid's are
-			 * different, purge the existing nfs4_stateowner, and
-			 * instantiate a new one.
-			 */
-			clp = sop->so_client;
-			release_stateowner(sop);
-		}
-	} else {
-		/* nfs4_stateowner not found.
-		 * Verify clientid and instantiate new nfs4_stateowner.
-		 * If verify fails this is presumably the result of the
-		 * client's lease expiring.
-		 */
-		status = nfserr_expired;
+	open->op_stateowner = sop;
+	if (!sop) {
+		/* Make sure the client's lease hasn't expired. */
 		clp = find_confirmed_client(clientid);
 		if (clp == NULL)
-			goto out;
+			return nfserr_expired;
+		goto renew;
 	}
-	status = nfserr_resource;
-	sop = alloc_init_open_stateowner(strhashval, clp, open);
-	if (sop == NULL)
-		goto out;
-	open->op_stateowner = sop;
+	if (!sop->so_confirmed) {
+		/* Replace unconfirmed owners without checking for replay. */
+		clp = sop->so_client;
+		release_stateowner(sop);
+		open->op_stateowner = NULL;
+		goto renew;
+	}
+	if (open->op_seqid == sop->so_seqid - 1) {
+		if (sop->so_replay.rp_buflen)
+			return NFSERR_REPLAY_ME;
+		/* The original OPEN failed so spectacularly
+		 * that we don't even have replay data saved!
+		 * Therefore, we have no choice but to continue
+		 * processing this OPEN; presumably, we'll
+		 * fail again for the same reason.
+		 */
+		dprintk("nfsd4_process_open1: replay with no replay cache\n");
+		goto renew;
+	}
+	if (open->op_seqid != sop->so_seqid)
+		return nfserr_bad_seqid;
 renew:
-	status = nfs_ok;
+	if (open->op_stateowner == NULL) {
+		sop = alloc_init_open_stateowner(strhashval, clp, open);
+		if (sop == NULL)
+			return nfserr_resource;
+		open->op_stateowner = sop;
+	}
+	list_del_init(&sop->so_close_lru);
 	renew_client(sop->so_client);
-out:
-	return status;
+	return nfs_ok;
 }
 
 static inline int
@@ -1648,7 +1600,7 @@ nfsd4_truncate(struct svc_rqst *rqstp, s
 	if (!open->op_truncate)
 		return 0;
 	if (!(open->op_share_access & NFS4_SHARE_ACCESS_WRITE))
-		return -EINVAL;
+		return nfserr_inval;
 	return nfsd_setattr(rqstp, fh, &iattr, 0, (time_t)0);
 }
 
@@ -1657,26 +1609,26 @@ nfs4_upgrade_open(struct svc_rqst *rqstp
 {
 	struct file *filp = stp->st_vfs_file;
 	struct inode *inode = filp->f_dentry->d_inode;
-	unsigned int share_access;
+	unsigned int share_access, new_writer;
 	int status;
 
 	set_access(&share_access, stp->st_access_bmap);
-	share_access = ~share_access;
-	share_access &= open->op_share_access;
+	new_writer = (~share_access) & open->op_share_access
+			& NFS4_SHARE_ACCESS_WRITE;
 
-	if (!(share_access & NFS4_SHARE_ACCESS_WRITE))
-		return nfsd4_truncate(rqstp, cur_fh, open);
-
-	status = get_write_access(inode);
-	if (status)
-		return nfserrno(status);
+	if (new_writer) {
+		status = get_write_access(inode);
+		if (status)
+			return nfserrno(status);
+	}
 	status = nfsd4_truncate(rqstp, cur_fh, open);
 	if (status) {
-		put_write_access(inode);
+		if (new_writer)
+			put_write_access(inode);
 		return status;
 	}
 	/* remember the open */
-	filp->f_mode = (filp->f_mode | FMODE_WRITE) & ~FMODE_READ;
+	filp->f_mode |= open->op_share_access;
 	set_bit(open->op_share_access, &stp->st_access_bmap);
 	set_bit(open->op_share_deny, &stp->st_deny_bmap);
 
@@ -1780,12 +1732,6 @@ nfsd4_process_open2(struct svc_rqst *rqs
 	struct nfs4_delegation *dp = NULL;
 	int status;
 
-	if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
-		return nfserr_grace;
-
-	if (!nfs4_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
-		return nfserr_no_grace;
-
 	status = nfserr_inval;
 	if (!TEST_ACCESS(open->op_share_access) || !TEST_DENY(open->op_share_deny))
 		goto out;
@@ -2423,15 +2369,19 @@ nfsd4_close(struct svc_rqst *rqstp, stru
 					CHECK_FH | OPEN_STATE | CLOSE_STATE,
 					&close->cl_stateowner, &stp, NULL)))
 		goto out; 
-	/*
-	*  Return success, but first update the stateid.
-	*/
 	status = nfs_ok;
 	update_stateid(&stp->st_stateid);
 	memcpy(&close->cl_stateid, &stp->st_stateid, sizeof(stateid_t));
 
-	/* release_state_owner() calls nfsd_close() if needed */
-	release_state_owner(stp, OPEN_STATE);
+	/* release_stateid() calls nfsd_close() if needed */
+	release_stateid(stp, OPEN_STATE);
+
+	/* place unused nfs4_stateowners on so_close_lru list to be
+	 * released by the laundromat service after the lease period
+	 * to enable us to handle CLOSE replay
+	 */
+	if (list_empty(&close->cl_stateowner->so_stateids))
+		move_to_close_lru(close->cl_stateowner);
 out:
 	if (close->cl_stateowner) {
 		nfs4_get_stateowner(close->cl_stateowner);
@@ -2633,7 +2583,7 @@ alloc_init_lock_stateowner(unsigned int 
 	sop->so_seqid = lock->lk_new_lock_seqid + 1;
 	sop->so_confirmed = 1;
 	rp = &sop->so_replay;
-	rp->rp_status = NFSERR_SERVERFAULT;
+	rp->rp_status = nfserr_serverfault;
 	rp->rp_buflen = 0;
 	rp->rp_buf = rp->rp_ibuf;
 	return sop;
@@ -2700,6 +2650,11 @@ nfsd4_lock(struct svc_rqst *rqstp, struc
 	if (check_lock_length(lock->lk_offset, lock->lk_length))
 		 return nfserr_inval;
 
+	if ((status = fh_verify(rqstp, current_fh, S_IFREG, MAY_LOCK))) {
+		dprintk("NFSD: nfsd4_lock: permission denied!\n");
+		return status;
+	}
+
 	nfs4_lock_state();
 
 	if (lock->lk_is_new) {
@@ -2720,11 +2675,11 @@ nfsd4_lock(struct svc_rqst *rqstp, struc
 				        lock->lk_new_open_seqid,
 		                        &lock->lk_new_open_stateid,
 		                        CHECK_FH | OPEN_STATE,
-		                        &lock->lk_stateowner, &open_stp,
+		                        &lock->lk_replay_owner, &open_stp,
 					lock);
 		if (status)
 			goto out;
-		open_sop = lock->lk_stateowner;
+		open_sop = lock->lk_replay_owner;
 		/* create lockowner and lock stateid */
 		fp = open_stp->st_file;
 		strhashval = lock_ownerstr_hashval(fp->fi_inode, 
@@ -2739,29 +2694,22 @@ nfsd4_lock(struct svc_rqst *rqstp, struc
 		if (lock_sop == NULL)
 			goto out;
 		lock_stp = alloc_init_lock_stateid(lock_sop, fp, open_stp);
-		if (lock_stp == NULL) {
-			release_stateowner(lock_sop);
+		if (lock_stp == NULL)
 			goto out;
-		}
 	} else {
 		/* lock (lock owner + lock stateid) already exists */
 		status = nfs4_preprocess_seqid_op(current_fh,
 				       lock->lk_old_lock_seqid, 
 				       &lock->lk_old_lock_stateid, 
 				       CHECK_FH | LOCK_STATE, 
-				       &lock->lk_stateowner, &lock_stp, lock);
+				       &lock->lk_replay_owner, &lock_stp, lock);
 		if (status)
 			goto out;
-		lock_sop = lock->lk_stateowner;
+		lock_sop = lock->lk_replay_owner;
 	}
-	/* lock->lk_stateowner and lock_stp have been created or found */
+	/* lock->lk_replay_owner and lock_stp have been created or found */
 	filp = lock_stp->st_vfs_file;
 
-	if ((status = fh_verify(rqstp, current_fh, S_IFREG, MAY_LOCK))) {
-		dprintk("NFSD: nfsd4_lock: permission denied!\n");
-		goto out;
-	}
-
 	status = nfserr_grace;
 	if (nfs4_in_grace() && !lock->lk_reclaim)
 		goto out;
@@ -2802,8 +2750,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struc
 	*/
 
 	status = posix_lock_file(filp, &file_lock);
-	if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private)
-		file_lock.fl_ops->fl_release_private(&file_lock);
 	dprintk("NFSD: nfsd4_lock: posix_lock_file status %d\n",status);
 	switch (-status) {
 	case 0: /* success! */
@@ -2815,9 +2761,12 @@ nfsd4_lock(struct svc_rqst *rqstp, struc
 		goto conflicting_lock;
 	case (EDEADLK):
 		status = nfserr_deadlock;
+		dprintk("NFSD: nfsd4_lock: posix_lock_file() failed! status %d\n",status);
+		goto out;
 	default:        
+		status = nfserrno(status);
 		dprintk("NFSD: nfsd4_lock: posix_lock_file() failed! status %d\n",status);
-		goto out_destroy_new_stateid;
+		goto out;
 	}
 
 conflicting_lock:
@@ -2831,20 +2780,12 @@ conflicting_lock:
 		goto out;
 	}
 	nfs4_set_lock_denied(conflock, &lock->lk_denied);
-
-out_destroy_new_stateid:
-	if (lock->lk_is_new) {
-		dprintk("NFSD: nfsd4_lock: destroy new stateid!\n");
-		/*
-		 * An error encountered after instantiation of the new
-		 * stateid has forced us to destroy it.
-		 */
-		release_state_owner(lock_stp, LOCK_STATE);
-	}
 out:
-	if (lock->lk_stateowner) {
-		nfs4_get_stateowner(lock->lk_stateowner);
-		*replay_owner = lock->lk_stateowner;
+	if (status && lock->lk_is_new && lock_sop)
+		release_stateowner(lock_sop);
+	if (lock->lk_replay_owner) {
+		nfs4_get_stateowner(lock->lk_replay_owner);
+		*replay_owner = lock->lk_replay_owner;
 	}
 	nfs4_unlock_state();
 	return status;
@@ -2977,8 +2918,6 @@ nfsd4_locku(struct svc_rqst *rqstp, stru
 	*  Try to unlock the file in the VFS.
 	*/
 	status = posix_lock_file(filp, &file_lock); 
-	if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private)
-		file_lock.fl_ops->fl_release_private(&file_lock);
 	if (status) {
 		dprintk("NFSD: nfs4_locku: posix_lock_file failed!\n");
 		goto out_nfserr;
@@ -3016,9 +2955,10 @@ check_for_locks(struct file *filp, struc
 
 	lock_kernel();
 	for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) {
-		if ((*flpp)->fl_owner == (fl_owner_t)lowner)
+		if ((*flpp)->fl_owner == (fl_owner_t)lowner) {
 			status = 1;
 			goto out;
+		}
 	}
 out:
 	unlock_kernel();
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index dcd6731..69d3501 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -528,7 +528,7 @@ nfsd4_decode_lock(struct nfsd4_compounda
 {
 	DECODE_HEAD;
 
-	lock->lk_stateowner = NULL;
+	lock->lk_replay_owner = NULL;
 	/*
 	* type, reclaim(boolean), offset, length, new_lock_owner(boolean)
 	*/
@@ -1764,10 +1764,11 @@ nfsd4_encode_dirent(struct readdir_cd *c
 		 */
 		if (!(cd->rd_bmval[0] & FATTR4_WORD0_RDATTR_ERROR))
 			goto fail;
-		nfserr = nfserr_toosmall;
 		p = nfsd4_encode_rdattr_error(p, buflen, nfserr);
-		if (p == NULL)
+		if (p == NULL) {
+			nfserr = nfserr_toosmall;
 			goto fail;
+		}
 	}
 	cd->buflen -= (p - cd->buffer);
 	cd->buffer = p;
@@ -1895,7 +1896,6 @@ nfsd4_encode_lock_denied(struct nfsd4_co
 static void
 nfsd4_encode_lock(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_lock *lock)
 {
-
 	ENCODE_SEQID_OP_HEAD;
 
 	if (!nfserr) {
@@ -1906,7 +1906,7 @@ nfsd4_encode_lock(struct nfsd4_compoundr
 	} else if (nfserr == nfserr_denied)
 		nfsd4_encode_lock_denied(resp, &lock->lk_denied);
 
-	ENCODE_SEQID_OP_TAIL(lock->lk_stateowner);
+	ENCODE_SEQID_OP_TAIL(lock->lk_replay_owner);
 }
 
 static void
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 0aa1b96..3e6b75c 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -36,6 +36,22 @@ nfsd_proc_null(struct svc_rqst *rqstp, v
 	return nfs_ok;
 }
 
+static int
+nfsd_return_attrs(int err, struct nfsd_attrstat *resp)
+{
+	if (err) return err;
+	return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt,
+				    resp->fh.fh_dentry,
+				    &resp->stat));
+}
+static int
+nfsd_return_dirop(int err, struct nfsd_diropres *resp)
+{
+	if (err) return err;
+	return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt,
+				    resp->fh.fh_dentry,
+				    &resp->stat));
+}
 /*
  * Get a file's attributes
  * N.B. After this call resp->fh needs an fh_put
@@ -44,10 +60,12 @@ static int
 nfsd_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle  *argp,
 					  struct nfsd_attrstat *resp)
 {
+	int nfserr;
 	dprintk("nfsd: GETATTR  %s\n", SVCFH_fmt(&argp->fh));
 
 	fh_copy(&resp->fh, &argp->fh);
-	return fh_verify(rqstp, &resp->fh, 0, MAY_NOP);
+	nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP);
+	return nfsd_return_attrs(nfserr, resp);
 }
 
 /*
@@ -58,12 +76,14 @@ static int
 nfsd_proc_setattr(struct svc_rqst *rqstp, struct nfsd_sattrargs *argp,
 					  struct nfsd_attrstat  *resp)
 {
+	int nfserr;
 	dprintk("nfsd: SETATTR  %s, valid=%x, size=%ld\n",
 		SVCFH_fmt(&argp->fh),
 		argp->attrs.ia_valid, (long) argp->attrs.ia_size);
 
 	fh_copy(&resp->fh, &argp->fh);
-	return nfsd_setattr(rqstp, &resp->fh, &argp->attrs,0, (time_t)0);
+	nfserr = nfsd_setattr(rqstp, &resp->fh, &argp->attrs,0, (time_t)0);
+	return nfsd_return_attrs(nfserr, resp);
 }
 
 /*
@@ -86,7 +106,7 @@ nfsd_proc_lookup(struct svc_rqst *rqstp,
 				 &resp->fh);
 
 	fh_put(&argp->fh);
-	return nfserr;
+	return nfsd_return_dirop(nfserr, resp);
 }
 
 /*
@@ -142,7 +162,10 @@ nfsd_proc_read(struct svc_rqst *rqstp, s
 			   	  argp->vec, argp->vlen,
 				  &resp->count);
 
-	return nfserr;
+	if (nfserr) return nfserr;
+	return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt,
+				    resp->fh.fh_dentry,
+				    &resp->stat));
 }
 
 /*
@@ -165,7 +188,7 @@ nfsd_proc_write(struct svc_rqst *rqstp, 
 				   argp->vec, argp->vlen,
 				   argp->len,
 				   &stable);
-	return nfserr;
+	return nfsd_return_attrs(nfserr, resp);
 }
 
 /*
@@ -322,7 +345,7 @@ out_unlock:
 
 done:
 	fh_put(dirfhp);
-	return nfserr;
+	return nfsd_return_dirop(nfserr, resp);
 }
 
 static int
@@ -425,7 +448,7 @@ nfsd_proc_mkdir(struct svc_rqst *rqstp, 
 	nfserr = nfsd_create(rqstp, &argp->fh, argp->name, argp->len,
 				    &argp->attrs, S_IFDIR, 0, &resp->fh);
 	fh_put(&argp->fh);
-	return nfserr;
+	return nfsd_return_dirop(nfserr, resp);
 }
 
 /*
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 89ed046..1d163b6 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -64,6 +64,32 @@ struct nfsd_list {
 };
 static struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list);
 
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+static struct svc_stat	nfsd_acl_svcstats;
+static struct svc_version *	nfsd_acl_version[] = {
+	[2] = &nfsd_acl_version2,
+	[3] = &nfsd_acl_version3,
+};
+
+#define NFSD_ACL_MINVERS            2
+#define NFSD_ACL_NRVERS		(sizeof(nfsd_acl_version)/sizeof(nfsd_acl_version[0]))
+static struct svc_version *nfsd_acl_versions[NFSD_ACL_NRVERS];
+
+static struct svc_program	nfsd_acl_program = {
+	.pg_prog		= NFS_ACL_PROGRAM,
+	.pg_nvers		= NFSD_ACL_NRVERS,
+	.pg_vers		= nfsd_acl_versions,
+	.pg_name		= "nfsd",
+	.pg_class		= "nfsd",
+	.pg_stats		= &nfsd_acl_svcstats,
+	.pg_authenticate	= &svc_set_client,
+};
+
+static struct svc_stat	nfsd_acl_svcstats = {
+	.program	= &nfsd_acl_program,
+};
+#endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
+
 static struct svc_version *	nfsd_version[] = {
 	[2] = &nfsd_version2,
 #if defined(CONFIG_NFSD_V3)
@@ -79,6 +105,9 @@ static struct svc_version *	nfsd_version
 static struct svc_version *nfsd_versions[NFSD_NRVERS];
 
 struct svc_program		nfsd_program = {
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+	.pg_next		= &nfsd_acl_program,
+#endif
 	.pg_prog		= NFS_PROGRAM,		/* program number */
 	.pg_nvers		= NFSD_NRVERS,		/* nr of entries in nfsd_version */
 	.pg_vers		= nfsd_versions,	/* version table */
@@ -147,6 +176,26 @@ nfsd_svc(unsigned short port, int nrserv
 				nfsd_program.pg_vers[i] = nfsd_version[i];
 		}
 
+
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+		found_one = 0;
+
+		for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++) {
+			if (NFSCTL_VERISSET(nfsd_versbits, i)) {
+				nfsd_acl_program.pg_vers[i] =
+					nfsd_acl_version[i];
+				found_one = 1;
+			} else
+				nfsd_acl_program.pg_vers[i] = NULL;
+		}
+
+		if (!found_one) {
+			for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++)
+				nfsd_acl_program.pg_vers[i] =
+					nfsd_acl_version[i];
+		}
+#endif
+
 		atomic_set(&nfsd_busy, 0);
 		error = -ENOMEM;
 		nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE);
@@ -411,30 +460,3 @@ nfsd_dispatch(struct svc_rqst *rqstp, u3
 	nfsd_cache_update(rqstp, proc->pc_cachetype, statp + 1);
 	return 1;
 }
-
-#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
-static struct svc_stat	nfsd_acl_svcstats;
-static struct svc_version *	nfsd_acl_version[] = {
-	[2] = &nfsd_acl_version2,
-	[3] = &nfsd_acl_version3,
-};
-
-#define NFSD_ACL_NRVERS		(sizeof(nfsd_acl_version)/sizeof(nfsd_acl_version[0]))
-static struct svc_program	nfsd_acl_program = {
-	.pg_prog		= NFS_ACL_PROGRAM,
-	.pg_nvers		= NFSD_ACL_NRVERS,
-	.pg_vers		= nfsd_acl_version,
-	.pg_name		= "nfsd",
-	.pg_class		= "nfsd",
-	.pg_stats		= &nfsd_acl_svcstats,
-	.pg_authenticate	= &svc_set_client,
-};
-
-static struct svc_stat	nfsd_acl_svcstats = {
-	.program	= &nfsd_acl_program,
-};
-
-#define nfsd_acl_program_p	&nfsd_acl_program
-#else
-#define nfsd_acl_program_p	NULL
-#endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index eef0576..5320e5a 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -710,14 +710,15 @@ static inline int nfsd_dosync(struct fil
 {
 	struct inode *inode = dp->d_inode;
 	int (*fsync) (struct file *, struct dentry *, int);
-	int err = nfs_ok;
+	int err;
 
-	filemap_fdatawrite(inode->i_mapping);
-	if (fop && (fsync = fop->fsync))
-		err=fsync(filp, dp, 0);
-	filemap_fdatawait(inode->i_mapping);
+	err = filemap_fdatawrite(inode->i_mapping);
+	if (err == 0 && fop && (fsync = fop->fsync))
+		err = fsync(filp, dp, 0);
+	if (err == 0)
+		err = filemap_fdatawait(inode->i_mapping);
 
-	return nfserrno(err);
+	return err;
 }
 	
 
@@ -734,10 +735,10 @@ nfsd_sync(struct file *filp)
 	return err;
 }
 
-void
+int
 nfsd_sync_dir(struct dentry *dp)
 {
-	nfsd_dosync(NULL, dp, dp->d_inode->i_fop);
+	return nfsd_dosync(NULL, dp, dp->d_inode->i_fop);
 }
 
 /*
@@ -814,7 +815,7 @@ nfsd_read_actor(read_descriptor_t *desc,
 	return size;
 }
 
-static inline int
+static int
 nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
               loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
 {
@@ -878,7 +879,7 @@ static void kill_suid(struct dentry *den
 	mutex_unlock(&dentry->d_inode->i_mutex);
 }
 
-static inline int
+static int
 nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
 				loff_t offset, struct kvec *vec, int vlen,
 	   			unsigned long cnt, int *stablep)
@@ -890,9 +891,9 @@ nfsd_vfs_write(struct svc_rqst *rqstp, s
 	int			err = 0;
 	int			stable = *stablep;
 
+#ifdef MSNFS
 	err = nfserr_perm;
 
-#ifdef MSNFS
 	if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
 		(!lock_may_write(file->f_dentry->d_inode, offset, cnt)))
 		goto out;
@@ -1064,7 +1065,7 @@ nfsd_commit(struct svc_rqst *rqstp, stru
 		return err;
 	if (EX_ISSYNC(fhp->fh_export)) {
 		if (file->f_op && file->f_op->fsync) {
-			err = nfsd_sync(file);
+			err = nfserrno(nfsd_sync(file));
 		} else {
 			err = nfserr_notsupp;
 		}
@@ -1132,7 +1133,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
 				"nfsd_create: parent %s/%s not locked!\n",
 				dentry->d_parent->d_name.name,
 				dentry->d_name.name);
-			err = -EIO;
+			err = nfserr_io;
 			goto out;
 		}
 	}
@@ -1175,7 +1176,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
 		goto out_nfserr;
 
 	if (EX_ISSYNC(fhp->fh_export)) {
-		nfsd_sync_dir(dentry);
+		err = nfserrno(nfsd_sync_dir(dentry));
 		write_inode_now(dchild->d_inode, 1);
 	}
 
@@ -1185,9 +1186,11 @@ nfsd_create(struct svc_rqst *rqstp, stru
 	 * send along the gid when it tries to implement setgid
 	 * directories via NFS.
 	 */
-	err = 0;
-	if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0)
-		err = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
+	if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) {
+		int err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
+		if (err2)
+			err = err2;
+	}
 	/*
 	 * Update the file handle to get the new inode info.
 	 */
@@ -1306,17 +1309,10 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
 		goto out_nfserr;
 
 	if (EX_ISSYNC(fhp->fh_export)) {
-		nfsd_sync_dir(dentry);
+		err = nfserrno(nfsd_sync_dir(dentry));
 		/* setattr will sync the child (or not) */
 	}
 
-	/*
-	 * Update the filehandle to get the new inode info.
-	 */
-	err = fh_update(resfhp);
-	if (err)
-		goto out;
-
 	if (createmode == NFS3_CREATE_EXCLUSIVE) {
 		/* Cram the verifier into atime/mtime/mode */
 		iap->ia_valid = ATTR_MTIME|ATTR_ATIME
@@ -1337,8 +1333,17 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
 	 * implement setgid directories via NFS. Clear out all that cruft.
 	 */
  set_attr:
-	if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID)) != 0)
- 		err = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
+	if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID)) != 0) {
+ 		int err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
+		if (err2)
+			err = err2;
+	}
+
+	/*
+	 * Update the filehandle to get the new inode info.
+	 */
+	if (!err)
+		err = fh_update(resfhp);
 
  out:
 	fh_unlock(fhp);
@@ -1447,10 +1452,10 @@ nfsd_symlink(struct svc_rqst *rqstp, str
 	} else
 		err = vfs_symlink(dentry->d_inode, dnew, path, mode);
 
-	if (!err) {
+	if (!err)
 		if (EX_ISSYNC(fhp->fh_export))
-			nfsd_sync_dir(dentry);
-	} else
+			err = nfsd_sync_dir(dentry);
+	if (err)
 		err = nfserrno(err);
 	fh_unlock(fhp);
 
@@ -1506,7 +1511,7 @@ nfsd_link(struct svc_rqst *rqstp, struct
 	err = vfs_link(dold, dirp, dnew);
 	if (!err) {
 		if (EX_ISSYNC(ffhp->fh_export)) {
-			nfsd_sync_dir(ddir);
+			err = nfserrno(nfsd_sync_dir(ddir));
 			write_inode_now(dest, 1);
 		}
 	} else {
@@ -1590,13 +1595,14 @@ nfsd_rename(struct svc_rqst *rqstp, stru
 	if ((ffhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
 		((atomic_read(&odentry->d_count) > 1)
 		 || (atomic_read(&ndentry->d_count) > 1))) {
-			err = nfserr_perm;
+			err = -EPERM;
 	} else
 #endif
 	err = vfs_rename(fdir, odentry, tdir, ndentry);
 	if (!err && EX_ISSYNC(tfhp->fh_export)) {
-		nfsd_sync_dir(tdentry);
-		nfsd_sync_dir(fdentry);
+		err = nfsd_sync_dir(tdentry);
+		if (!err)
+			err = nfsd_sync_dir(fdentry);
 	}
 
  out_dput_new:
@@ -1661,7 +1667,7 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
 #ifdef MSNFS
 		if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
 			(atomic_read(&rdentry->d_count) > 1)) {
-			err = nfserr_perm;
+			err = -EPERM;
 		} else
 #endif
 		err = vfs_unlink(dirp, rdentry);
@@ -1671,17 +1677,14 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
 
 	dput(rdentry);
 
-	if (err)
-		goto out_nfserr;
-	if (EX_ISSYNC(fhp->fh_export)) 
-		nfsd_sync_dir(dentry);
-
-out:
-	return err;
+	if (err == 0 &&
+	    EX_ISSYNC(fhp->fh_export))
+			err = nfsd_sync_dir(dentry);
 
 out_nfserr:
 	err = nfserrno(err);
-	goto out;
+out:
+	return err;
 }
 
 /*
diff --git a/fs/open.c b/fs/open.c
index 8e20c1f..70e0230 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -20,6 +20,7 @@
 #include <linux/security.h>
 #include <linux/mount.h>
 #include <linux/vfs.h>
+#include <linux/fcntl.h>
 #include <asm/uaccess.h>
 #include <linux/fs.h>
 #include <linux/personality.h>
@@ -383,7 +384,7 @@ asmlinkage long sys_utime(char __user * 
 
 		error = get_user(newattrs.ia_atime.tv_sec, &times->actime);
 		newattrs.ia_atime.tv_nsec = 0;
-		if (!error) 
+		if (!error)
 			error = get_user(newattrs.ia_mtime.tv_sec, &times->modtime);
 		newattrs.ia_mtime.tv_nsec = 0;
 		if (error)
@@ -414,14 +415,14 @@ out:
  * must be owner or have write permission.
  * Else, update from *times, must be owner or super user.
  */
-long do_utimes(char __user * filename, struct timeval * times)
+long do_utimes(int dfd, char __user *filename, struct timeval *times)
 {
 	int error;
 	struct nameidata nd;
 	struct inode * inode;
 	struct iattr newattrs;
 
-	error = user_path_walk(filename, &nd);
+	error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd);
 
 	if (error)
 		goto out;
@@ -461,13 +462,18 @@ out:
 	return error;
 }
 
-asmlinkage long sys_utimes(char __user * filename, struct timeval __user * utimes)
+asmlinkage long sys_futimesat(int dfd, char __user *filename, struct timeval __user *utimes)
 {
 	struct timeval times[2];
 
 	if (utimes && copy_from_user(&times, utimes, sizeof(times)))
 		return -EFAULT;
-	return do_utimes(filename, utimes ? times : NULL);
+	return do_utimes(dfd, filename, utimes ? times : NULL);
+}
+
+asmlinkage long sys_utimes(char __user *filename, struct timeval __user *utimes)
+{
+	return sys_futimesat(AT_FDCWD, filename, utimes);
 }
 
 
@@ -476,7 +482,7 @@ asmlinkage long sys_utimes(char __user *
  * We do this by temporarily clearing all FS-related capabilities and
  * switching the fsuid/fsgid around to the real ones.
  */
-asmlinkage long sys_access(const char __user * filename, int mode)
+asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode)
 {
 	struct nameidata nd;
 	int old_fsuid, old_fsgid;
@@ -506,7 +512,7 @@ asmlinkage long sys_access(const char __
 	else
 		current->cap_effective = current->cap_permitted;
 
-	res = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
+	res = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
 	if (!res) {
 		res = vfs_permission(&nd, mode);
 		/* SuS v2 requires we report a read only fs too */
@@ -523,6 +529,11 @@ asmlinkage long sys_access(const char __
 	return res;
 }
 
+asmlinkage long sys_access(const char __user *filename, int mode)
+{
+	return sys_faccessat(AT_FDCWD, filename, mode);
+}
+
 asmlinkage long sys_chdir(const char __user * filename)
 {
 	struct nameidata nd;
@@ -635,14 +646,15 @@ out:
 	return err;
 }
 
-asmlinkage long sys_chmod(const char __user * filename, mode_t mode)
+asmlinkage long sys_fchmodat(int dfd, const char __user *filename,
+			     mode_t mode)
 {
 	struct nameidata nd;
 	struct inode * inode;
 	int error;
 	struct iattr newattrs;
 
-	error = user_path_walk(filename, &nd);
+	error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd);
 	if (error)
 		goto out;
 	inode = nd.dentry->d_inode;
@@ -669,6 +681,11 @@ out:
 	return error;
 }
 
+asmlinkage long sys_chmod(const char __user *filename, mode_t mode)
+{
+	return sys_fchmodat(AT_FDCWD, filename, mode);
+}
+
 static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
 {
 	struct inode * inode;
@@ -717,6 +734,26 @@ asmlinkage long sys_chown(const char __u
 	return error;
 }
 
+asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user,
+			     gid_t group, int flag)
+{
+	struct nameidata nd;
+	int error = -EINVAL;
+	int follow;
+
+	if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
+		goto out;
+
+	follow = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
+	error = __user_walk_fd(dfd, filename, follow, &nd);
+	if (!error) {
+		error = chown_common(nd.dentry, user, group);
+		path_release(&nd);
+	}
+out:
+	return error;
+}
+
 asmlinkage long sys_lchown(const char __user * filename, uid_t user, gid_t group)
 {
 	struct nameidata nd;
@@ -820,7 +857,8 @@ cleanup_file:
  * for the internal routines (ie open_namei()/follow_link() etc). 00 is
  * used by symlinks.
  */
-struct file *filp_open(const char * filename, int flags, int mode)
+static struct file *do_filp_open(int dfd, const char *filename, int flags,
+				 int mode)
 {
 	int namei_flags, error;
 	struct nameidata nd;
@@ -829,12 +867,17 @@ struct file *filp_open(const char * file
 	if ((namei_flags+1) & O_ACCMODE)
 		namei_flags++;
 
-	error = open_namei(filename, namei_flags, mode, &nd);
+	error = open_namei(dfd, filename, namei_flags, mode, &nd);
 	if (!error)
 		return nameidata_to_filp(&nd, flags);
 
 	return ERR_PTR(error);
 }
+
+struct file *filp_open(const char *filename, int flags, int mode)
+{
+	return do_filp_open(AT_FDCWD, filename, flags, mode);
+}
 EXPORT_SYMBOL(filp_open);
 
 /**
@@ -991,7 +1034,7 @@ void fastcall put_unused_fd(unsigned int
 EXPORT_SYMBOL(put_unused_fd);
 
 /*
- * Install a file pointer in the fd array.  
+ * Install a file pointer in the fd array.
  *
  * The VFS is full of places where we drop the files lock between
  * setting the open_fds bitmap and installing the file in the file
@@ -1016,7 +1059,7 @@ void fastcall fd_install(unsigned int fd
 
 EXPORT_SYMBOL(fd_install);
 
-long do_sys_open(const char __user *filename, int flags, int mode)
+long do_sys_open(int dfd, const char __user *filename, int flags, int mode)
 {
 	char *tmp = getname(filename);
 	int fd = PTR_ERR(tmp);
@@ -1024,7 +1067,7 @@ long do_sys_open(const char __user *file
 	if (!IS_ERR(tmp)) {
 		fd = get_unused_fd();
 		if (fd >= 0) {
-			struct file *f = filp_open(tmp, flags, mode);
+			struct file *f = do_filp_open(dfd, tmp, flags, mode);
 			if (IS_ERR(f)) {
 				put_unused_fd(fd);
 				fd = PTR_ERR(f);
@@ -1043,10 +1086,20 @@ asmlinkage long sys_open(const char __us
 	if (force_o_largefile())
 		flags |= O_LARGEFILE;
 
-	return do_sys_open(filename, flags, mode);
+	return do_sys_open(AT_FDCWD, filename, flags, mode);
 }
 EXPORT_SYMBOL_GPL(sys_open);
 
+asmlinkage long sys_openat(int dfd, const char __user *filename, int flags,
+			   int mode)
+{
+	if (force_o_largefile())
+		flags |= O_LARGEFILE;
+
+	return do_sys_open(dfd, filename, flags, mode);
+}
+EXPORT_SYMBOL_GPL(sys_openat);
+
 #ifndef __alpha__
 
 /*
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
index 9dd71e8..d71ac65 100644
--- a/fs/reiserfs/dir.c
+++ b/fs/reiserfs/dir.c
@@ -150,18 +150,15 @@ static int reiserfs_readdir(struct file 
 				if (d_reclen <= 32) {
 					local_buf = small_buf;
 				} else {
-					local_buf =
-					    reiserfs_kmalloc(d_reclen, GFP_NOFS,
-							     inode->i_sb);
+					local_buf = kmalloc(d_reclen,
+							    GFP_NOFS);
 					if (!local_buf) {
 						pathrelse(&path_to_entry);
 						ret = -ENOMEM;
 						goto out;
 					}
 					if (item_moved(&tmp_ih, &path_to_entry)) {
-						reiserfs_kfree(local_buf,
-							       d_reclen,
-							       inode->i_sb);
+						kfree(local_buf);
 						goto research;
 					}
 				}
@@ -174,15 +171,12 @@ static int reiserfs_readdir(struct file 
 				    (dirent, local_buf, d_reclen, d_off, d_ino,
 				     DT_UNKNOWN) < 0) {
 					if (local_buf != small_buf) {
-						reiserfs_kfree(local_buf,
-							       d_reclen,
-							       inode->i_sb);
+						kfree(local_buf);
 					}
 					goto end;
 				}
 				if (local_buf != small_buf) {
-					reiserfs_kfree(local_buf, d_reclen,
-						       inode->i_sb);
+					kfree(local_buf);
 				}
 				// next entry should be looked for with such offset
 				next_pos = deh_offset(deh) + 1;
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index ad6fa96..f347317 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -192,6 +192,8 @@ static int reiserfs_allocate_blocks_for_
 
 	allocated_blocks = kmalloc((blocks_to_allocate + will_prealloc) *
 				   sizeof(b_blocknr_t), GFP_NOFS);
+	if (!allocated_blocks)
+		return -ENOMEM;
 
 	/* First we compose a key to point at the writing position, we want to do
 	   that outside of any locking region. */
@@ -1285,6 +1287,23 @@ static ssize_t reiserfs_file_write(struc
 	struct reiserfs_transaction_handle th;
 	th.t_trans_id = 0;
 
+	/* If a filesystem is converted from 3.5 to 3.6, we'll have v3.5 items
+	* lying around (most of the disk, in fact). Despite the filesystem
+	* now being a v3.6 format, the old items still can't support large
+	* file sizes. Catch this case here, as the rest of the VFS layer is
+	* oblivious to the different limitations between old and new items.
+	* reiserfs_setattr catches this for truncates. This chunk is lifted
+	* from generic_write_checks. */
+	if (get_inode_item_key_version (inode) == KEY_FORMAT_3_5 &&
+	    *ppos + count > MAX_NON_LFS) {
+		if (*ppos >= MAX_NON_LFS) {
+			send_sig(SIGXFSZ, current, 0);
+			return -EFBIG;
+		}
+		if (count > MAX_NON_LFS - (unsigned long)*ppos)
+			count = MAX_NON_LFS - (unsigned long)*ppos;
+	}
+
 	if (file->f_flags & O_DIRECT) {	// Direct IO needs treatment
 		ssize_t result, after_file_end = 0;
 		if ((*ppos + count >= inode->i_size)
diff --git a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c
index 4582988..aa22588 100644
--- a/fs/reiserfs/fix_node.c
+++ b/fs/reiserfs/fix_node.c
@@ -2021,38 +2021,6 @@ static int get_neighbors(struct tree_bal
 	return CARRY_ON;
 }
 
-#ifdef CONFIG_REISERFS_CHECK
-void *reiserfs_kmalloc(size_t size, gfp_t flags, struct super_block *s)
-{
-	void *vp;
-	static size_t malloced;
-
-	vp = kmalloc(size, flags);
-	if (vp) {
-		REISERFS_SB(s)->s_kmallocs += size;
-		if (REISERFS_SB(s)->s_kmallocs > malloced + 200000) {
-			reiserfs_warning(s,
-					 "vs-8301: reiserfs_kmalloc: allocated memory %d",
-					 REISERFS_SB(s)->s_kmallocs);
-			malloced = REISERFS_SB(s)->s_kmallocs;
-		}
-	}
-	return vp;
-}
-
-void reiserfs_kfree(const void *vp, size_t size, struct super_block *s)
-{
-	kfree(vp);
-
-	REISERFS_SB(s)->s_kmallocs -= size;
-	if (REISERFS_SB(s)->s_kmallocs < 0)
-		reiserfs_warning(s,
-				 "vs-8302: reiserfs_kfree: allocated memory %d",
-				 REISERFS_SB(s)->s_kmallocs);
-
-}
-#endif
-
 static int get_virtual_node_size(struct super_block *sb, struct buffer_head *bh)
 {
 	int max_num_of_items;
@@ -2086,7 +2054,7 @@ static int get_mem_for_virtual_node(stru
 		/* we have to allocate more memory for virtual node */
 		if (tb->vn_buf) {
 			/* free memory allocated before */
-			reiserfs_kfree(tb->vn_buf, tb->vn_buf_size, tb->tb_sb);
+			kfree(tb->vn_buf);
 			/* this is not needed if kfree is atomic */
 			check_fs = 1;
 		}
@@ -2095,24 +2063,15 @@ static int get_mem_for_virtual_node(stru
 		tb->vn_buf_size = size;
 
 		/* get memory for virtual item */
-		buf =
-		    reiserfs_kmalloc(size, GFP_ATOMIC | __GFP_NOWARN,
-				     tb->tb_sb);
+		buf = kmalloc(size, GFP_ATOMIC | __GFP_NOWARN);
 		if (!buf) {
 			/* getting memory with GFP_KERNEL priority may involve
 			   balancing now (due to indirect_to_direct conversion on
 			   dcache shrinking). So, release path and collected
 			   resources here */
 			free_buffers_in_tb(tb);
-			buf = reiserfs_kmalloc(size, GFP_NOFS, tb->tb_sb);
+			buf = kmalloc(size, GFP_NOFS);
 			if (!buf) {
-#ifdef CONFIG_REISERFS_CHECK
-				reiserfs_warning(tb->tb_sb,
-						 "vs-8345: get_mem_for_virtual_node: "
-						 "kmalloc failed. reiserfs kmalloced %d bytes",
-						 REISERFS_SB(tb->tb_sb)->
-						 s_kmallocs);
-#endif
 				tb->vn_buf_size = 0;
 			}
 			tb->vn_buf = buf;
@@ -2619,7 +2578,6 @@ void unfix_nodes(struct tree_balance *tb
 		}
 	}
 
-	if (tb->vn_buf)
-		reiserfs_kfree(tb->vn_buf, tb->vn_buf_size, tb->tb_sb);
+	kfree(tb->vn_buf);
 
 }
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index ffa34b8..b33d67b 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -2363,6 +2363,13 @@ static int reiserfs_write_full_page(stru
 	int bh_per_page = PAGE_CACHE_SIZE / s->s_blocksize;
 	th.t_trans_id = 0;
 
+	/* no logging allowed when nonblocking or from PF_MEMALLOC */
+	if (checked && (current->flags & PF_MEMALLOC)) {
+		redirty_page_for_writepage(wbc, page);
+		unlock_page(page);
+		return 0;
+	}
+
 	/* The page dirty bit is cleared before writepage is called, which
 	 * means we have to tell create_empty_buffers to make dirty buffers
 	 * The page really should be up to date at this point, so tossing
@@ -2743,6 +2750,7 @@ static int invalidatepage_can_drop(struc
 	int ret = 1;
 	struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb);
 
+	lock_buffer(bh);
 	spin_lock(&j->j_dirty_buffers_lock);
 	if (!buffer_mapped(bh)) {
 		goto free_jh;
@@ -2758,7 +2766,7 @@ static int invalidatepage_can_drop(struc
 		if (buffer_journaled(bh) || buffer_journal_dirty(bh)) {
 			ret = 0;
 		}
-	} else if (buffer_dirty(bh) || buffer_locked(bh)) {
+	} else  if (buffer_dirty(bh)) {
 		struct reiserfs_journal_list *jl;
 		struct reiserfs_jh *jh = bh->b_private;
 
@@ -2784,6 +2792,7 @@ static int invalidatepage_can_drop(struc
 		reiserfs_free_jh(bh);
 	}
 	spin_unlock(&j->j_dirty_buffers_lock);
+	unlock_buffer(bh);
 	return ret;
 }
 
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index 4491fcf..b7a1795 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -152,18 +152,16 @@ static struct reiserfs_bitmap_node *allo
 	struct reiserfs_bitmap_node *bn;
 	static int id;
 
-	bn = reiserfs_kmalloc(sizeof(struct reiserfs_bitmap_node), GFP_NOFS,
-			      p_s_sb);
+	bn = kmalloc(sizeof(struct reiserfs_bitmap_node), GFP_NOFS);
 	if (!bn) {
 		return NULL;
 	}
-	bn->data = reiserfs_kmalloc(p_s_sb->s_blocksize, GFP_NOFS, p_s_sb);
+	bn->data = kzalloc(p_s_sb->s_blocksize, GFP_NOFS);
 	if (!bn->data) {
-		reiserfs_kfree(bn, sizeof(struct reiserfs_bitmap_node), p_s_sb);
+		kfree(bn);
 		return NULL;
 	}
 	bn->id = id++;
-	memset(bn->data, 0, p_s_sb->s_blocksize);
 	INIT_LIST_HEAD(&bn->list);
 	return bn;
 }
@@ -197,8 +195,8 @@ static inline void free_bitmap_node(stru
 	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
 	journal->j_used_bitmap_nodes--;
 	if (journal->j_free_bitmap_nodes > REISERFS_MAX_BITMAP_NODES) {
-		reiserfs_kfree(bn->data, p_s_sb->s_blocksize, p_s_sb);
-		reiserfs_kfree(bn, sizeof(struct reiserfs_bitmap_node), p_s_sb);
+		kfree(bn->data);
+		kfree(bn);
 	} else {
 		list_add(&bn->list, &journal->j_bitmap_nodes);
 		journal->j_free_bitmap_nodes++;
@@ -276,8 +274,8 @@ static int free_bitmap_nodes(struct supe
 	while (next != &journal->j_bitmap_nodes) {
 		bn = list_entry(next, struct reiserfs_bitmap_node, list);
 		list_del(next);
-		reiserfs_kfree(bn->data, p_s_sb->s_blocksize, p_s_sb);
-		reiserfs_kfree(bn, sizeof(struct reiserfs_bitmap_node), p_s_sb);
+		kfree(bn->data);
+		kfree(bn);
 		next = journal->j_bitmap_nodes.next;
 		journal->j_free_bitmap_nodes--;
 	}
@@ -581,7 +579,7 @@ static inline void put_journal_list(stru
 			       jl->j_trans_id, jl->j_refcount);
 	}
 	if (--jl->j_refcount == 0)
-		reiserfs_kfree(jl, sizeof(struct reiserfs_journal_list), s);
+		kfree(jl);
 }
 
 /*
@@ -848,6 +846,14 @@ static int write_ordered_buffers(spinloc
 			spin_lock(lock);
 			goto loop_next;
 		}
+		/* in theory, dirty non-uptodate buffers should never get here,
+		 * but the upper layer io error paths still have a few quirks.
+		 * Handle them here as gracefully as we can
+		 */
+		if (!buffer_uptodate(bh) && buffer_dirty(bh)) {
+			clear_buffer_dirty(bh);
+			ret = -EIO;
+		}
 		if (buffer_dirty(bh)) {
 			list_del_init(&jh->list);
 			list_add(&jh->list, &tmp);
@@ -879,6 +885,19 @@ static int write_ordered_buffers(spinloc
 		if (!buffer_uptodate(bh)) {
 			ret = -EIO;
 		}
+		/* ugly interaction with invalidatepage here.
+		 * reiserfs_invalidate_page will pin any buffer that has a valid
+		 * journal head from an older transaction.  If someone else sets
+		 * our buffer dirty after we write it in the first loop, and
+		 * then someone truncates the page away, nobody will ever write
+		 * the buffer. We're safe if we write the page one last time
+		 * after freeing the journal header.
+		 */
+		if (buffer_dirty(bh) && unlikely(bh->b_page->mapping == NULL)) {
+			spin_unlock(lock);
+			ll_rw_block(WRITE, 1, &bh);
+			spin_lock(lock);
+		}
 		put_bh(bh);
 		cond_resched_lock(lock);
 	}
@@ -977,6 +996,7 @@ static int flush_commit_list(struct supe
 	struct reiserfs_journal *journal = SB_JOURNAL(s);
 	int barrier = 0;
 	int retval = 0;
+	int write_len;
 
 	reiserfs_check_lock_depth(s, "flush_commit_list");
 
@@ -1018,24 +1038,35 @@ static int flush_commit_list(struct supe
 	}
 
 	if (!list_empty(&jl->j_bh_list)) {
+		int ret;
 		unlock_kernel();
-		write_ordered_buffers(&journal->j_dirty_buffers_lock,
-				      journal, jl, &jl->j_bh_list);
+		ret = write_ordered_buffers(&journal->j_dirty_buffers_lock,
+					    journal, jl, &jl->j_bh_list);
+		if (ret < 0 && retval == 0)
+			retval = ret;
 		lock_kernel();
 	}
 	BUG_ON(!list_empty(&jl->j_bh_list));
 	/*
 	 * for the description block and all the log blocks, submit any buffers
-	 * that haven't already reached the disk
+	 * that haven't already reached the disk.  Try to write at least 256
+	 * log blocks. later on, we will only wait on blocks that correspond
+	 * to this transaction, but while we're unplugging we might as well
+	 * get a chunk of data on there.
 	 */
 	atomic_inc(&journal->j_async_throttle);
-	for (i = 0; i < (jl->j_len + 1); i++) {
+	write_len = jl->j_len + 1;
+	if (write_len < 256)
+		write_len = 256;
+	for (i = 0 ; i < write_len ; i++) {
 		bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + (jl->j_start + i) %
 		    SB_ONDISK_JOURNAL_SIZE(s);
 		tbh = journal_find_get_block(s, bn);
-		if (buffer_dirty(tbh))	/* redundant, ll_rw_block() checks */
-			ll_rw_block(SWRITE, 1, &tbh);
-		put_bh(tbh);
+		if (tbh) {
+			if (buffer_dirty(tbh))
+			    ll_rw_block(WRITE, 1, &tbh) ;
+			put_bh(tbh) ;
+		}
 	}
 	atomic_dec(&journal->j_async_throttle);
 
@@ -1818,8 +1849,7 @@ void remove_journal_hash(struct super_bl
 static void free_journal_ram(struct super_block *p_s_sb)
 {
 	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
-	reiserfs_kfree(journal->j_current_jl,
-		       sizeof(struct reiserfs_journal_list), p_s_sb);
+	kfree(journal->j_current_jl);
 	journal->j_num_lists--;
 
 	vfree(journal->j_cnode_free_orig);
@@ -2093,21 +2123,15 @@ static int journal_read_transaction(stru
 	}
 	trans_id = get_desc_trans_id(desc);
 	/* now we know we've got a good transaction, and it was inside the valid time ranges */
-	log_blocks =
-	    reiserfs_kmalloc(get_desc_trans_len(desc) *
-			     sizeof(struct buffer_head *), GFP_NOFS, p_s_sb);
-	real_blocks =
-	    reiserfs_kmalloc(get_desc_trans_len(desc) *
-			     sizeof(struct buffer_head *), GFP_NOFS, p_s_sb);
+	log_blocks = kmalloc(get_desc_trans_len(desc) *
+			     sizeof(struct buffer_head *), GFP_NOFS);
+	real_blocks = kmalloc(get_desc_trans_len(desc) *
+			      sizeof(struct buffer_head *), GFP_NOFS);
 	if (!log_blocks || !real_blocks) {
 		brelse(c_bh);
 		brelse(d_bh);
-		reiserfs_kfree(log_blocks,
-			       get_desc_trans_len(desc) *
-			       sizeof(struct buffer_head *), p_s_sb);
-		reiserfs_kfree(real_blocks,
-			       get_desc_trans_len(desc) *
-			       sizeof(struct buffer_head *), p_s_sb);
+		kfree(log_blocks);
+		kfree(real_blocks);
 		reiserfs_warning(p_s_sb,
 				 "journal-1169: kmalloc failed, unable to mount FS");
 		return -1;
@@ -2145,12 +2169,8 @@ static int journal_read_transaction(stru
 			brelse_array(real_blocks, i);
 			brelse(c_bh);
 			brelse(d_bh);
-			reiserfs_kfree(log_blocks,
-				       get_desc_trans_len(desc) *
-				       sizeof(struct buffer_head *), p_s_sb);
-			reiserfs_kfree(real_blocks,
-				       get_desc_trans_len(desc) *
-				       sizeof(struct buffer_head *), p_s_sb);
+			kfree(log_blocks);
+			kfree(real_blocks);
 			return -1;
 		}
 	}
@@ -2166,12 +2186,8 @@ static int journal_read_transaction(stru
 			brelse_array(real_blocks, get_desc_trans_len(desc));
 			brelse(c_bh);
 			brelse(d_bh);
-			reiserfs_kfree(log_blocks,
-				       get_desc_trans_len(desc) *
-				       sizeof(struct buffer_head *), p_s_sb);
-			reiserfs_kfree(real_blocks,
-				       get_desc_trans_len(desc) *
-				       sizeof(struct buffer_head *), p_s_sb);
+			kfree(log_blocks);
+			kfree(real_blocks);
 			return -1;
 		}
 		memcpy(real_blocks[i]->b_data, log_blocks[i]->b_data,
@@ -2193,12 +2209,8 @@ static int journal_read_transaction(stru
 				     get_desc_trans_len(desc) - i);
 			brelse(c_bh);
 			brelse(d_bh);
-			reiserfs_kfree(log_blocks,
-				       get_desc_trans_len(desc) *
-				       sizeof(struct buffer_head *), p_s_sb);
-			reiserfs_kfree(real_blocks,
-				       get_desc_trans_len(desc) *
-				       sizeof(struct buffer_head *), p_s_sb);
+			kfree(log_blocks);
+			kfree(real_blocks);
 			return -1;
 		}
 		brelse(real_blocks[i]);
@@ -2217,12 +2229,8 @@ static int journal_read_transaction(stru
 	journal->j_trans_id = trans_id + 1;
 	brelse(c_bh);
 	brelse(d_bh);
-	reiserfs_kfree(log_blocks,
-		       le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *),
-		       p_s_sb);
-	reiserfs_kfree(real_blocks,
-		       le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *),
-		       p_s_sb);
+	kfree(log_blocks);
+	kfree(real_blocks);
 	return 0;
 }
 
@@ -2471,14 +2479,8 @@ static int journal_read(struct super_blo
 static struct reiserfs_journal_list *alloc_journal_list(struct super_block *s)
 {
 	struct reiserfs_journal_list *jl;
-      retry:
-	jl = reiserfs_kmalloc(sizeof(struct reiserfs_journal_list), GFP_NOFS,
-			      s);
-	if (!jl) {
-		yield();
-		goto retry;
-	}
-	memset(jl, 0, sizeof(*jl));
+	jl = kzalloc(sizeof(struct reiserfs_journal_list),
+		     GFP_NOFS | __GFP_NOFAIL);
 	INIT_LIST_HEAD(&jl->j_list);
 	INIT_LIST_HEAD(&jl->j_working_list);
 	INIT_LIST_HEAD(&jl->j_tail_bh_list);
@@ -2821,6 +2823,9 @@ int journal_transaction_should_end(struc
 	    journal->j_cnode_free < (journal->j_trans_max * 3)) {
 		return 1;
 	}
+	/* protected by the BKL here */
+	journal->j_len_alloc += new_alloc;
+	th->t_blocks_allocated += new_alloc ;
 	return 0;
 }
 
@@ -3042,14 +3047,12 @@ struct reiserfs_transaction_handle *reis
 		}
 		return th;
 	}
-	th = reiserfs_kmalloc(sizeof(struct reiserfs_transaction_handle),
-			      GFP_NOFS, s);
+	th = kmalloc(sizeof(struct reiserfs_transaction_handle), GFP_NOFS);
 	if (!th)
 		return NULL;
 	ret = journal_begin(th, s, nblocks);
 	if (ret) {
-		reiserfs_kfree(th, sizeof(struct reiserfs_transaction_handle),
-			       s);
+		kfree(th);
 		return NULL;
 	}
 
@@ -3067,8 +3070,7 @@ int reiserfs_end_persistent_transaction(
 		ret = -EIO;
 	if (th->t_refcount == 0) {
 		SB_JOURNAL(s)->j_persistent_trans--;
-		reiserfs_kfree(th, sizeof(struct reiserfs_transaction_handle),
-			       s);
+		kfree(th);
 	}
 	return ret;
 }
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index 8f8d8d0..c812330 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -456,7 +456,7 @@ static int reiserfs_add_entry(struct rei
 	/* get memory for composing the entry */
 	buflen = DEH_SIZE + ROUND_UP(namelen);
 	if (buflen > sizeof(small_buf)) {
-		buffer = reiserfs_kmalloc(buflen, GFP_NOFS, dir->i_sb);
+		buffer = kmalloc(buflen, GFP_NOFS);
 		if (buffer == 0)
 			return -ENOMEM;
 	} else
@@ -490,7 +490,7 @@ static int reiserfs_add_entry(struct rei
 	retval = reiserfs_find_entry(dir, name, namelen, &path, &de);
 	if (retval != NAME_NOT_FOUND) {
 		if (buffer != small_buf)
-			reiserfs_kfree(buffer, buflen, dir->i_sb);
+			kfree(buffer);
 		pathrelse(&path);
 
 		if (retval == IO_ERROR) {
@@ -515,7 +515,7 @@ static int reiserfs_add_entry(struct rei
 		reiserfs_warning(dir->i_sb,
 				 "reiserfs_add_entry: Congratulations! we have got hash function screwed up");
 		if (buffer != small_buf)
-			reiserfs_kfree(buffer, buflen, dir->i_sb);
+			kfree(buffer);
 		pathrelse(&path);
 		return -EBUSY;
 	}
@@ -535,7 +535,7 @@ static int reiserfs_add_entry(struct rei
 					 &entry_key);
 
 			if (buffer != small_buf)
-				reiserfs_kfree(buffer, buflen, dir->i_sb);
+				kfree(buffer);
 			pathrelse(&path);
 			return -EBUSY;
 		}
@@ -546,7 +546,7 @@ static int reiserfs_add_entry(struct rei
 	    reiserfs_paste_into_item(th, &path, &entry_key, dir, buffer,
 				     paste_size);
 	if (buffer != small_buf)
-		reiserfs_kfree(buffer, buflen, dir->i_sb);
+		kfree(buffer);
 	if (retval) {
 		reiserfs_check_path(&path);
 		return retval;
@@ -1065,7 +1065,7 @@ static int reiserfs_symlink(struct inode
 		goto out_failed;
 	}
 
-	name = reiserfs_kmalloc(item_len, GFP_NOFS, parent_dir->i_sb);
+	name = kmalloc(item_len, GFP_NOFS);
 	if (!name) {
 		drop_new_inode(inode);
 		retval = -ENOMEM;
@@ -1079,14 +1079,14 @@ static int reiserfs_symlink(struct inode
 	retval = journal_begin(&th, parent_dir->i_sb, jbegin_count);
 	if (retval) {
 		drop_new_inode(inode);
-		reiserfs_kfree(name, item_len, parent_dir->i_sb);
+		kfree(name);
 		goto out_failed;
 	}
 
 	retval =
 	    reiserfs_new_inode(&th, parent_dir, mode, name, strlen(symname),
 			       dentry, inode);
-	reiserfs_kfree(name, item_len, parent_dir->i_sb);
+	kfree(name);
 	if (retval) {		/* reiserfs_new_inode iputs for us */
 		goto out_failed;
 	}
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c
index fc2f43c..ef6caed 100644
--- a/fs/reiserfs/procfs.c
+++ b/fs/reiserfs/procfs.c
@@ -88,7 +88,6 @@ static int show_super(struct seq_file *m
 	seq_printf(m, "state: \t%s\n"
 		   "mount options: \t%s%s%s%s%s%s%s%s%s%s%s\n"
 		   "gen. counter: \t%i\n"
-		   "s_kmallocs: \t%i\n"
 		   "s_disk_reads: \t%i\n"
 		   "s_disk_writes: \t%i\n"
 		   "s_fix_nodes: \t%i\n"
@@ -128,7 +127,7 @@ static int show_super(struct seq_file *m
 		   "SMALL_TAILS " : "NO_TAILS ",
 		   replay_only(sb) ? "REPLAY_ONLY " : "",
 		   convert_reiserfs(sb) ? "CONV " : "",
-		   atomic_read(&r->s_generation_counter), SF(s_kmallocs),
+		   atomic_read(&r->s_generation_counter),
 		   SF(s_disk_reads), SF(s_disk_writes), SF(s_fix_nodes),
 		   SF(s_do_balance), SF(s_unneeded_left_neighbor),
 		   SF(s_good_search_by_key_reada), SF(s_bmaps),
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 397d959..77891de 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -472,12 +472,6 @@ static void reiserfs_put_super(struct su
 
 	print_statistics(s);
 
-	if (REISERFS_SB(s)->s_kmallocs != 0) {
-		reiserfs_warning(s,
-				 "vs-2004: reiserfs_put_super: allocated memory left %d",
-				 REISERFS_SB(s)->s_kmallocs);
-	}
-
 	if (REISERFS_SB(s)->reserved_blocks != 0) {
 		reiserfs_warning(s,
 				 "green-2005: reiserfs_put_super: reserved blocks left %d",
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index cc061bf..ffb79c4 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -368,15 +368,13 @@ static int __xattr_readdir(struct file *
 		if (d_reclen <= 32) {
 			local_buf = small_buf;
 		} else {
-			local_buf =
-			    reiserfs_kmalloc(d_reclen, GFP_NOFS, inode->i_sb);
+			local_buf = kmalloc(d_reclen, GFP_NOFS);
 			if (!local_buf) {
 				pathrelse(&path_to_entry);
 				return -ENOMEM;
 			}
 			if (item_moved(&tmp_ih, &path_to_entry)) {
-				reiserfs_kfree(local_buf, d_reclen,
-					       inode->i_sb);
+				kfree(local_buf);
 
 				/* sigh, must retry.  Do this same offset again */
 				next_pos = d_off;
@@ -399,13 +397,12 @@ static int __xattr_readdir(struct file *
 		if (filldir(dirent, local_buf, d_reclen, d_off, d_ino,
 			    DT_UNKNOWN) < 0) {
 			if (local_buf != small_buf) {
-				reiserfs_kfree(local_buf, d_reclen,
-					       inode->i_sb);
+				kfree(local_buf);
 			}
 			goto end;
 		}
 		if (local_buf != small_buf) {
-			reiserfs_kfree(local_buf, d_reclen, inode->i_sb);
+			kfree(local_buf);
 		}
 	}			/* while */
 
@@ -1322,109 +1319,44 @@ int reiserfs_xattr_init(struct super_blo
 	return err;
 }
 
-static int
-__reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd,
-		      int need_lock)
+static int reiserfs_check_acl(struct inode *inode, int mask)
 {
-	umode_t mode = inode->i_mode;
-
-	if (mask & MAY_WRITE) {
-		/*
-		 * Nobody gets write access to a read-only fs.
-		 */
-		if (IS_RDONLY(inode) &&
-		    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
-			return -EROFS;
+	struct posix_acl *acl;
+	int error = -EAGAIN; /* do regular unix permission checks by default */
 
-		/*
-		 * Nobody gets write access to an immutable file.
-		 */
-		if (IS_IMMUTABLE(inode))
-			return -EACCES;
-	}
+	reiserfs_read_lock_xattr_i(inode);
+	reiserfs_read_lock_xattrs(inode->i_sb);
 
-	/* We don't do permission checks on the internal objects.
-	 * Permissions are determined by the "owning" object. */
-	if (is_reiserfs_priv_object(inode))
-		return 0;
+	acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS);
 
-	if (current->fsuid == inode->i_uid) {
-		mode >>= 6;
-#ifdef CONFIG_REISERFS_FS_POSIX_ACL
-	} else if (reiserfs_posixacl(inode->i_sb) &&
-		   get_inode_sd_version(inode) != STAT_DATA_V1) {
-		struct posix_acl *acl;
-
-		/* ACL can't contain additional permissions if
-		   the ACL_MASK entry is 0 */
-		if (!(mode & S_IRWXG))
-			goto check_groups;
-
-		if (need_lock) {
-			reiserfs_read_lock_xattr_i(inode);
-			reiserfs_read_lock_xattrs(inode->i_sb);
-		}
-		acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS);
-		if (need_lock) {
-			reiserfs_read_unlock_xattrs(inode->i_sb);
-			reiserfs_read_unlock_xattr_i(inode);
-		}
-		if (IS_ERR(acl)) {
-			if (PTR_ERR(acl) == -ENODATA)
-				goto check_groups;
-			return PTR_ERR(acl);
-		}
+	reiserfs_read_unlock_xattrs(inode->i_sb);
+	reiserfs_read_unlock_xattr_i(inode);
 
-		if (acl) {
-			int err = posix_acl_permission(inode, acl, mask);
+	if (acl) {
+		if (!IS_ERR(acl)) {
+			error = posix_acl_permission(inode, acl, mask);
 			posix_acl_release(acl);
-			if (err == -EACCES) {
-				goto check_capabilities;
-			}
-			return err;
-		} else {
-			goto check_groups;
-		}
-#endif
-	} else {
-	      check_groups:
-		if (in_group_p(inode->i_gid))
-			mode >>= 3;
+		} else if (PTR_ERR(acl) != -ENODATA)
+			error = PTR_ERR(acl);
 	}
 
-	/*
-	 * If the DACs are ok we don't need any capability check.
-	 */
-	if (((mode & mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == mask))
-		return 0;
+	return error;
+}
 
-      check_capabilities:
+int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd)
+{
 	/*
-	 * Read/write DACs are always overridable.
-	 * Executable DACs are overridable if at least one exec bit is set.
+	 * We don't do permission checks on the internal objects.
+	 * Permissions are determined by the "owning" object.
 	 */
-	if (!(mask & MAY_EXEC) ||
-	    (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode))
-		if (capable(CAP_DAC_OVERRIDE))
-			return 0;
+	if (is_reiserfs_priv_object(inode))
+		return 0;
 
 	/*
-	 * Searching includes executable on directories, else just read.
+	 * Stat data v1 doesn't support ACLs.
 	 */
-	if (mask == MAY_READ || (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE)))
-		if (capable(CAP_DAC_READ_SEARCH))
-			return 0;
-
-	return -EACCES;
-}
-
-int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd)
-{
-	return __reiserfs_permission(inode, mask, nd, 1);
-}
-
-int
-reiserfs_permission_locked(struct inode *inode, int mask, struct nameidata *nd)
-{
-	return __reiserfs_permission(inode, mask, nd, 0);
+	if (get_inode_sd_version(inode) == STAT_DATA_V1)
+		return generic_permission(inode, mask, NULL);
+	else
+		return generic_permission(inode, mask, reiserfs_check_acl);
 }
diff --git a/fs/select.c b/fs/select.c
index f10a103..c0f02d3 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -179,12 +179,11 @@ get_max:
 #define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR)
 #define POLLEX_SET (POLLPRI)
 
-int do_select(int n, fd_set_bits *fds, long *timeout)
+int do_select(int n, fd_set_bits *fds, s64 *timeout)
 {
 	struct poll_wqueues table;
 	poll_table *wait;
 	int retval, i;
-	long __timeout = *timeout;
 
 	rcu_read_lock();
 	retval = max_select_fd(n, fds);
@@ -196,11 +195,12 @@ int do_select(int n, fd_set_bits *fds, l
 
 	poll_initwait(&table);
 	wait = &table.pt;
-	if (!__timeout)
+	if (!*timeout)
 		wait = NULL;
 	retval = 0;
 	for (;;) {
 		unsigned long *rinp, *routp, *rexp, *inp, *outp, *exp;
+		long __timeout;
 
 		set_current_state(TASK_INTERRUPTIBLE);
 
@@ -255,22 +255,32 @@ int do_select(int n, fd_set_bits *fds, l
 				*rexp = res_ex;
 		}
 		wait = NULL;
-		if (retval || !__timeout || signal_pending(current))
+		if (retval || !*timeout || signal_pending(current))
 			break;
 		if(table.error) {
 			retval = table.error;
 			break;
 		}
+
+		if (*timeout < 0) {
+			/* Wait indefinitely */
+			__timeout = MAX_SCHEDULE_TIMEOUT;
+		} else if (unlikely(*timeout >= (s64)MAX_SCHEDULE_TIMEOUT - 1)) {
+			/* Wait for longer than MAX_SCHEDULE_TIMEOUT. Do it in a loop */
+			__timeout = MAX_SCHEDULE_TIMEOUT - 1;
+			*timeout -= __timeout;
+		} else {
+			__timeout = *timeout;
+			*timeout = 0;
+		}
 		__timeout = schedule_timeout(__timeout);
+		if (*timeout >= 0)
+			*timeout += __timeout;
 	}
 	__set_current_state(TASK_RUNNING);
 
 	poll_freewait(&table);
 
-	/*
-	 * Up-to-date the caller timeout.
-	 */
-	*timeout = __timeout;
 	return retval;
 }
 
@@ -295,36 +305,14 @@ static void select_bits_free(void *bits,
 #define MAX_SELECT_SECONDS \
 	((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
 
-asmlinkage long
-sys_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, struct timeval __user *tvp)
+static int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,
+			   fd_set __user *exp, s64 *timeout)
 {
 	fd_set_bits fds;
 	char *bits;
-	long timeout;
 	int ret, size, max_fdset;
 	struct fdtable *fdt;
 
-	timeout = MAX_SCHEDULE_TIMEOUT;
-	if (tvp) {
-		time_t sec, usec;
-
-		if (!access_ok(VERIFY_READ, tvp, sizeof(*tvp))
-		    || __get_user(sec, &tvp->tv_sec)
-		    || __get_user(usec, &tvp->tv_usec)) {
-			ret = -EFAULT;
-			goto out_nofds;
-		}
-
-		ret = -EINVAL;
-		if (sec < 0 || usec < 0)
-			goto out_nofds;
-
-		if ((unsigned long) sec < MAX_SELECT_SECONDS) {
-			timeout = ROUND_UP(usec, 1000000/HZ);
-			timeout += sec * (unsigned long) HZ;
-		}
-	}
-
 	ret = -EINVAL;
 	if (n < 0)
 		goto out_nofds;
@@ -362,18 +350,7 @@ sys_select(int n, fd_set __user *inp, fd
 	zero_fd_set(n, fds.res_out);
 	zero_fd_set(n, fds.res_ex);
 
-	ret = do_select(n, &fds, &timeout);
-
-	if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
-		time_t sec = 0, usec = 0;
-		if (timeout) {
-			sec = timeout / HZ;
-			usec = timeout % HZ;
-			usec *= (1000000/HZ);
-		}
-		put_user(sec, &tvp->tv_sec);
-		put_user(usec, &tvp->tv_usec);
-	}
+	ret = do_select(n, &fds, timeout);
 
 	if (ret < 0)
 		goto out;
@@ -395,6 +372,154 @@ out_nofds:
 	return ret;
 }
 
+asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp,
+			fd_set __user *exp, struct timeval __user *tvp)
+{
+	s64 timeout = -1;
+	struct timeval tv;
+	int ret;
+
+	if (tvp) {
+		if (copy_from_user(&tv, tvp, sizeof(tv)))
+			return -EFAULT;
+
+		if (tv.tv_sec < 0 || tv.tv_usec < 0)
+			return -EINVAL;
+
+		/* Cast to u64 to make GCC stop complaining */
+		if ((u64)tv.tv_sec >= (u64)MAX_INT64_SECONDS)
+			timeout = -1;	/* infinite */
+		else {
+			timeout = ROUND_UP(tv.tv_usec, USEC_PER_SEC/HZ);
+			timeout += tv.tv_sec * HZ;
+		}
+	}
+
+	ret = core_sys_select(n, inp, outp, exp, &timeout);
+
+	if (tvp) {
+		if (current->personality & STICKY_TIMEOUTS)
+			goto sticky;
+		tv.tv_usec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ));
+		tv.tv_sec = timeout;
+		if (copy_to_user(tvp, &tv, sizeof(tv))) {
+sticky:
+			/*
+			 * If an application puts its timeval in read-only
+			 * memory, we don't want the Linux-specific update to
+			 * the timeval to cause a fault after the select has
+			 * completed successfully. However, because we're not
+			 * updating the timeval, we can't restart the system
+			 * call.
+			 */
+			if (ret == -ERESTARTNOHAND)
+				ret = -EINTR;
+		}
+	}
+
+	return ret;
+}
+
+#ifdef TIF_RESTORE_SIGMASK
+asmlinkage long sys_pselect7(int n, fd_set __user *inp, fd_set __user *outp,
+		fd_set __user *exp, struct timespec __user *tsp,
+		const sigset_t __user *sigmask, size_t sigsetsize)
+{
+	s64 timeout = MAX_SCHEDULE_TIMEOUT;
+	sigset_t ksigmask, sigsaved;
+	struct timespec ts;
+	int ret;
+
+	if (tsp) {
+		if (copy_from_user(&ts, tsp, sizeof(ts)))
+			return -EFAULT;
+
+		if (ts.tv_sec < 0 || ts.tv_nsec < 0)
+			return -EINVAL;
+
+		/* Cast to u64 to make GCC stop complaining */
+		if ((u64)ts.tv_sec >= (u64)MAX_INT64_SECONDS)
+			timeout = -1;	/* infinite */
+		else {
+			timeout = ROUND_UP(ts.tv_nsec, NSEC_PER_SEC/HZ);
+			timeout += ts.tv_sec * HZ;
+		}
+	}
+
+	if (sigmask) {
+		/* XXX: Don't preclude handling different sized sigset_t's.  */
+		if (sigsetsize != sizeof(sigset_t))
+			return -EINVAL;
+		if (copy_from_user(&ksigmask, sigmask, sizeof(ksigmask)))
+			return -EFAULT;
+
+		sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
+		sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
+	}
+
+	ret = core_sys_select(n, inp, outp, exp, &timeout);
+
+	if (tsp) {
+		if (current->personality & STICKY_TIMEOUTS)
+			goto sticky;
+		ts.tv_nsec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)) * 1000;
+		ts.tv_sec = timeout;
+		if (copy_to_user(tsp, &ts, sizeof(ts))) {
+sticky:
+			/*
+			 * If an application puts its timeval in read-only
+			 * memory, we don't want the Linux-specific update to
+			 * the timeval to cause a fault after the select has
+			 * completed successfully. However, because we're not
+			 * updating the timeval, we can't restart the system
+			 * call.
+			 */
+			if (ret == -ERESTARTNOHAND)
+				ret = -EINTR;
+		}
+	}
+
+	if (ret == -ERESTARTNOHAND) {
+		/*
+		 * Don't restore the signal mask yet. Let do_signal() deliver
+		 * the signal on the way back to userspace, before the signal
+		 * mask is restored.
+		 */
+		if (sigmask) {
+			memcpy(&current->saved_sigmask, &sigsaved,
+					sizeof(sigsaved));
+			set_thread_flag(TIF_RESTORE_SIGMASK);
+		}
+	} else if (sigmask)
+		sigprocmask(SIG_SETMASK, &sigsaved, NULL);
+
+	return ret;
+}
+
+/*
+ * Most architectures can't handle 7-argument syscalls. So we provide a
+ * 6-argument version where the sixth argument is a pointer to a structure
+ * which has a pointer to the sigset_t itself followed by a size_t containing
+ * the sigset size.
+ */
+asmlinkage long sys_pselect6(int n, fd_set __user *inp, fd_set __user *outp,
+	fd_set __user *exp, struct timespec __user *tsp, void __user *sig)
+{
+	size_t sigsetsize = 0;
+	sigset_t __user *up = NULL;
+
+	if (sig) {
+		if (!access_ok(VERIFY_READ, sig, sizeof(void *)+sizeof(size_t))
+		    || __get_user(up, (sigset_t * __user *)sig)
+		    || __get_user(sigsetsize,
+				(size_t * __user)(sig+sizeof(void *))))
+			return -EFAULT;
+	}
+
+	return sys_pselect7(n, inp, outp, exp, tsp, up, sigsetsize);
+}
+#endif /* TIF_RESTORE_SIGMASK */
+
 struct poll_list {
 	struct poll_list *next;
 	int len;
@@ -436,16 +561,19 @@ static void do_pollfd(unsigned int num, 
 }
 
 static int do_poll(unsigned int nfds,  struct poll_list *list,
-			struct poll_wqueues *wait, long timeout)
+		   struct poll_wqueues *wait, s64 *timeout)
 {
 	int count = 0;
 	poll_table* pt = &wait->pt;
 
-	if (!timeout)
+	/* Optimise the no-wait case */
+	if (!(*timeout))
 		pt = NULL;
  
 	for (;;) {
 		struct poll_list *walk;
+		long __timeout;
+
 		set_current_state(TASK_INTERRUPTIBLE);
 		walk = list;
 		while(walk != NULL) {
@@ -453,18 +581,36 @@ static int do_poll(unsigned int nfds,  s
 			walk = walk->next;
 		}
 		pt = NULL;
-		if (count || !timeout || signal_pending(current))
+		if (count || !*timeout || signal_pending(current))
 			break;
 		count = wait->error;
 		if (count)
 			break;
-		timeout = schedule_timeout(timeout);
+
+		if (*timeout < 0) {
+			/* Wait indefinitely */
+			__timeout = MAX_SCHEDULE_TIMEOUT;
+		} else if (unlikely(*timeout >= (s64)MAX_SCHEDULE_TIMEOUT-1)) {
+			/*
+			 * Wait for longer than MAX_SCHEDULE_TIMEOUT. Do it in
+			 * a loop
+			 */
+			__timeout = MAX_SCHEDULE_TIMEOUT - 1;
+			*timeout -= __timeout;
+		} else {
+			__timeout = *timeout;
+			*timeout = 0;
+		}
+
+		__timeout = schedule_timeout(__timeout);
+		if (*timeout >= 0)
+			*timeout += __timeout;
 	}
 	__set_current_state(TASK_RUNNING);
 	return count;
 }
 
-asmlinkage long sys_poll(struct pollfd __user * ufds, unsigned int nfds, long timeout)
+int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout)
 {
 	struct poll_wqueues table;
  	int fdcount, err;
@@ -482,14 +628,6 @@ asmlinkage long sys_poll(struct pollfd _
 	if (nfds > max_fdset && nfds > OPEN_MAX)
 		return -EINVAL;
 
-	if (timeout) {
-		/* Careful about overflow in the intermediate values */
-		if ((unsigned long) timeout < MAX_SCHEDULE_TIMEOUT / HZ)
-			timeout = (unsigned long)(timeout*HZ+999)/1000+1;
-		else /* Negative or overflow */
-			timeout = MAX_SCHEDULE_TIMEOUT;
-	}
-
 	poll_initwait(&table);
 
 	head = NULL;
@@ -519,6 +657,7 @@ asmlinkage long sys_poll(struct pollfd _
 		}
 		i -= pp->len;
 	}
+
 	fdcount = do_poll(nfds, head, &table, timeout);
 
 	/* OK, now copy the revents fields back to user space. */
@@ -547,3 +686,98 @@ out_fds:
 	poll_freewait(&table);
 	return err;
 }
+
+asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds,
+			long timeout_msecs)
+{
+	s64 timeout_jiffies = 0;
+
+	if (timeout_msecs) {
+#if HZ > 1000
+		/* We can only overflow if HZ > 1000 */
+		if (timeout_msecs / 1000 > (s64)0x7fffffffffffffffULL / (s64)HZ)
+			timeout_jiffies = -1;
+		else
+#endif
+			timeout_jiffies = msecs_to_jiffies(timeout_msecs);
+	}
+
+	return do_sys_poll(ufds, nfds, &timeout_jiffies);
+}
+
+#ifdef TIF_RESTORE_SIGMASK
+asmlinkage long sys_ppoll(struct pollfd __user *ufds, unsigned int nfds,
+	struct timespec __user *tsp, const sigset_t __user *sigmask,
+	size_t sigsetsize)
+{
+	sigset_t ksigmask, sigsaved;
+	struct timespec ts;
+	s64 timeout = -1;
+	int ret;
+
+	if (tsp) {
+		if (copy_from_user(&ts, tsp, sizeof(ts)))
+			return -EFAULT;
+
+		/* Cast to u64 to make GCC stop complaining */
+		if ((u64)ts.tv_sec >= (u64)MAX_INT64_SECONDS)
+			timeout = -1;	/* infinite */
+		else {
+			timeout = ROUND_UP(ts.tv_nsec, NSEC_PER_SEC/HZ);
+			timeout += ts.tv_sec * HZ;
+		}
+	}
+
+	if (sigmask) {
+		/* XXX: Don't preclude handling different sized sigset_t's.  */
+		if (sigsetsize != sizeof(sigset_t))
+			return -EINVAL;
+		if (copy_from_user(&ksigmask, sigmask, sizeof(ksigmask)))
+			return -EFAULT;
+
+		sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
+		sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
+	}
+
+	ret = do_sys_poll(ufds, nfds, &timeout);
+
+	/* We can restart this syscall, usually */
+	if (ret == -EINTR) {
+		/*
+		 * Don't restore the signal mask yet. Let do_signal() deliver
+		 * the signal on the way back to userspace, before the signal
+		 * mask is restored.
+		 */
+		if (sigmask) {
+			memcpy(&current->saved_sigmask, &sigsaved,
+					sizeof(sigsaved));
+			set_thread_flag(TIF_RESTORE_SIGMASK);
+		}
+		ret = -ERESTARTNOHAND;
+	} else if (sigmask)
+		sigprocmask(SIG_SETMASK, &sigsaved, NULL);
+
+	if (tsp && timeout >= 0) {
+		if (current->personality & STICKY_TIMEOUTS)
+			goto sticky;
+		/* Yes, we know it's actually an s64, but it's also positive. */
+		ts.tv_nsec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)) * 1000;
+		ts.tv_sec = timeout;
+		if (copy_to_user(tsp, &ts, sizeof(ts))) {
+		sticky:
+			/*
+			 * If an application puts its timeval in read-only
+			 * memory, we don't want the Linux-specific update to
+			 * the timeval to cause a fault after the select has
+			 * completed successfully. However, because we're not
+			 * updating the timeval, we can't restart the system
+			 * call.
+			 */
+			if (ret == -ERESTARTNOHAND && timeout >= 0)
+				ret = -EINTR;
+		}
+	}
+
+	return ret;
+}
+#endif /* TIF_RESTORE_SIGMASK */
diff --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c
index c6c33e1..0424d06 100644
--- a/fs/smbfs/dir.c
+++ b/fs/smbfs/dir.c
@@ -209,6 +209,8 @@ init_cache:
 	ctl.valid  = 1;
 read_really:
 	result = server->ops->readdir(filp, dirent, filldir, &ctl);
+	if (result == -ERESTARTSYS && page)
+		ClearPageUptodate(page);
 	if (ctl.idx == -1)
 		goto invalid_cache;	/* retry */
 	ctl.head.end = ctl.fpos - 1;
@@ -217,7 +219,8 @@ finished:
 	if (page) {
 		cache->head = ctl.head;
 		kunmap(page);
-		SetPageUptodate(page);
+		if (result != -ERESTARTSYS)
+			SetPageUptodate(page);
 		unlock_page(page);
 		page_cache_release(page);
 	}
diff --git a/fs/stat.c b/fs/stat.c
index b8a0e51..24211b0 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -63,12 +63,12 @@ int vfs_getattr(struct vfsmount *mnt, st
 
 EXPORT_SYMBOL(vfs_getattr);
 
-int vfs_stat(char __user *name, struct kstat *stat)
+int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat)
 {
 	struct nameidata nd;
 	int error;
 
-	error = user_path_walk(name, &nd);
+	error = __user_walk_fd(dfd, name, LOOKUP_FOLLOW, &nd);
 	if (!error) {
 		error = vfs_getattr(nd.mnt, nd.dentry, stat);
 		path_release(&nd);
@@ -76,14 +76,19 @@ int vfs_stat(char __user *name, struct k
 	return error;
 }
 
+int vfs_stat(char __user *name, struct kstat *stat)
+{
+	return vfs_stat_fd(AT_FDCWD, name, stat);
+}
+
 EXPORT_SYMBOL(vfs_stat);
 
-int vfs_lstat(char __user *name, struct kstat *stat)
+int vfs_lstat_fd(int dfd, char __user *name, struct kstat *stat)
 {
 	struct nameidata nd;
 	int error;
 
-	error = user_path_walk_link(name, &nd);
+	error = __user_walk_fd(dfd, name, 0, &nd);
 	if (!error) {
 		error = vfs_getattr(nd.mnt, nd.dentry, stat);
 		path_release(&nd);
@@ -91,6 +96,11 @@ int vfs_lstat(char __user *name, struct 
 	return error;
 }
 
+int vfs_lstat(char __user *name, struct kstat *stat)
+{
+	return vfs_lstat_fd(AT_FDCWD, name, stat);
+}
+
 EXPORT_SYMBOL(vfs_lstat);
 
 int vfs_fstat(unsigned int fd, struct kstat *stat)
@@ -151,7 +161,7 @@ static int cp_old_stat(struct kstat *sta
 asmlinkage long sys_stat(char __user * filename, struct __old_kernel_stat __user * statbuf)
 {
 	struct kstat stat;
-	int error = vfs_stat(filename, &stat);
+	int error = vfs_stat_fd(AT_FDCWD, filename, &stat);
 
 	if (!error)
 		error = cp_old_stat(&stat, statbuf);
@@ -161,7 +171,7 @@ asmlinkage long sys_stat(char __user * f
 asmlinkage long sys_lstat(char __user * filename, struct __old_kernel_stat __user * statbuf)
 {
 	struct kstat stat;
-	int error = vfs_lstat(filename, &stat);
+	int error = vfs_lstat_fd(AT_FDCWD, filename, &stat);
 
 	if (!error)
 		error = cp_old_stat(&stat, statbuf);
@@ -229,27 +239,50 @@ static int cp_new_stat(struct kstat *sta
 	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
 }
 
-asmlinkage long sys_newstat(char __user * filename, struct stat __user * statbuf)
+asmlinkage long sys_newstat(char __user *filename, struct stat __user *statbuf)
 {
 	struct kstat stat;
-	int error = vfs_stat(filename, &stat);
+	int error = vfs_stat_fd(AT_FDCWD, filename, &stat);
 
 	if (!error)
 		error = cp_new_stat(&stat, statbuf);
 
 	return error;
 }
-asmlinkage long sys_newlstat(char __user * filename, struct stat __user * statbuf)
+
+asmlinkage long sys_newlstat(char __user *filename, struct stat __user *statbuf)
 {
 	struct kstat stat;
-	int error = vfs_lstat(filename, &stat);
+	int error = vfs_lstat_fd(AT_FDCWD, filename, &stat);
 
 	if (!error)
 		error = cp_new_stat(&stat, statbuf);
 
 	return error;
 }
-asmlinkage long sys_newfstat(unsigned int fd, struct stat __user * statbuf)
+
+asmlinkage long sys_newfstatat(int dfd, char __user *filename,
+				struct stat __user *statbuf, int flag)
+{
+	struct kstat stat;
+	int error = -EINVAL;
+
+	if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
+		goto out;
+
+	if (flag & AT_SYMLINK_NOFOLLOW)
+		error = vfs_lstat_fd(dfd, filename, &stat);
+	else
+		error = vfs_stat_fd(dfd, filename, &stat);
+
+	if (!error)
+		error = cp_new_stat(&stat, statbuf);
+
+out:
+	return error;
+}
+
+asmlinkage long sys_newfstat(unsigned int fd, struct stat __user *statbuf)
 {
 	struct kstat stat;
 	int error = vfs_fstat(fd, &stat);
@@ -260,7 +293,8 @@ asmlinkage long sys_newfstat(unsigned in
 	return error;
 }
 
-asmlinkage long sys_readlink(const char __user * path, char __user * buf, int bufsiz)
+asmlinkage long sys_readlinkat(int dfd, const char __user *path,
+				char __user *buf, int bufsiz)
 {
 	struct nameidata nd;
 	int error;
@@ -268,7 +302,7 @@ asmlinkage long sys_readlink(const char 
 	if (bufsiz <= 0)
 		return -EINVAL;
 
-	error = user_path_walk_link(path, &nd);
+	error = __user_walk_fd(dfd, path, 0, &nd);
 	if (!error) {
 		struct inode * inode = nd.dentry->d_inode;
 
@@ -285,6 +319,12 @@ asmlinkage long sys_readlink(const char 
 	return error;
 }
 
+asmlinkage long sys_readlink(const char __user *path, char __user *buf,
+				int bufsiz)
+{
+	return sys_readlinkat(AT_FDCWD, path, buf, bufsiz);
+}
+
 
 /* ---------- LFS-64 ----------- */
 #ifdef __ARCH_WANT_STAT64
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index d1db8c1..9892268 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -336,24 +336,47 @@ static inline int bio_add_buffer(struct 
 }
 
 /*
- * Submit all of the bios for all of the ioends we have saved up,
- * covering the initial writepage page and also any probed pages.
+ * Submit all of the bios for all of the ioends we have saved up, covering the
+ * initial writepage page and also any probed pages.
+ *
+ * Because we may have multiple ioends spanning a page, we need to start
+ * writeback on all the buffers before we submit them for I/O. If we mark the
+ * buffers as we got, then we can end up with a page that only has buffers
+ * marked async write and I/O complete on can occur before we mark the other
+ * buffers async write.
+ *
+ * The end result of this is that we trip a bug in end_page_writeback() because
+ * we call it twice for the one page as the code in end_buffer_async_write()
+ * assumes that all buffers on the page are started at the same time.
+ *
+ * The fix is two passes across the ioend list - one to start writeback on the
+ * bufferheads, and then the second one submit them for I/O.
  */
 STATIC void
 xfs_submit_ioend(
 	xfs_ioend_t		*ioend)
 {
+	xfs_ioend_t		*head = ioend;
 	xfs_ioend_t		*next;
 	struct buffer_head	*bh;
 	struct bio		*bio;
 	sector_t		lastblock = 0;
 
+	/* Pass 1 - start writeback */
+	do {
+		next = ioend->io_list;
+		for (bh = ioend->io_buffer_head; bh; bh = bh->b_private) {
+			xfs_start_buffer_writeback(bh);
+		}
+	} while ((ioend = next) != NULL);
+
+	/* Pass 2 - submit I/O */
+	ioend = head;
 	do {
 		next = ioend->io_list;
 		bio = NULL;
 
 		for (bh = ioend->io_buffer_head; bh; bh = bh->b_private) {
-			xfs_start_buffer_writeback(bh);
 
 			if (!bio) {
  retry:
@@ -1439,4 +1462,5 @@ struct address_space_operations linvfs_a
 	.commit_write		= generic_commit_write,
 	.bmap			= linvfs_bmap,
 	.direct_IO		= linvfs_direct_IO,
+	.migratepage		= buffer_migrate_page,
 };
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index e44b7c1..bfb4f29 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -822,6 +822,13 @@ xfs_buf_rele(
 
 	XB_TRACE(bp, "rele", bp->b_relse);
 
+	if (unlikely(!hash)) {
+		ASSERT(!bp->b_relse);
+		if (atomic_dec_and_test(&bp->b_hold))
+			xfs_buf_free(bp);
+		return;
+	}
+
 	if (atomic_dec_and_lock(&bp->b_hold, &hash->bh_lock)) {
 		if (bp->b_relse) {
 			atomic_inc(&bp->b_hold);
@@ -1514,6 +1521,7 @@ xfs_mapping_buftarg(
 	struct address_space	*mapping;
 	static struct address_space_operations mapping_aops = {
 		.sync_page = block_sync_page,
+		.migratepage = fail_migrate_page,
 	};
 
 	inode = new_inode(bdev->bd_inode->i_sb);
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 76c6df3..eda7919 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -262,6 +262,31 @@ has_fs_struct(struct task_struct *task)
 	return (task->fs != init_task.fs);
 }
 
+STATIC inline void
+cleanup_inode(
+	vnode_t		*dvp,
+	vnode_t		*vp,
+	struct dentry	*dentry,	
+	int		mode)
+{
+	struct dentry   teardown = {};
+	int             err2;
+
+	/* Oh, the horror.
+	 * If we can't add the ACL or we fail in 
+	 * linvfs_init_security we must back out.
+	 * ENOSPC can hit here, among other things.
+	 */
+	teardown.d_inode = LINVFS_GET_IP(vp);
+	teardown.d_name = dentry->d_name;
+
+	if (S_ISDIR(mode))
+	  	VOP_RMDIR(dvp, &teardown, NULL, err2);
+	else
+		VOP_REMOVE(dvp, &teardown, NULL, err2);
+	VN_RELE(vp);
+}
+
 STATIC int
 linvfs_mknod(
 	struct inode	*dir,
@@ -316,30 +341,19 @@ linvfs_mknod(
 	}
 
 	if (!error)
+	{
 		error = linvfs_init_security(vp, dir);
+		if (error)
+			cleanup_inode(dvp, vp, dentry, mode);
+	}
 
 	if (default_acl) {
 		if (!error) {
 			error = _ACL_INHERIT(vp, &va, default_acl);
-			if (!error) {
+			if (!error) 
 				VMODIFY(vp);
-			} else {
-				struct dentry	teardown = {};
-				int		err2;
-
-				/* Oh, the horror.
-				 * If we can't add the ACL we must back out.
-				 * ENOSPC can hit here, among other things.
-				 */
-				teardown.d_inode = ip = LINVFS_GET_IP(vp);
-				teardown.d_name = dentry->d_name;
-
-				if (S_ISDIR(mode))
-					VOP_RMDIR(dvp, &teardown, NULL, err2);
-				else
-					VOP_REMOVE(dvp, &teardown, NULL, err2);
-				VN_RELE(vp);
-			}
+			else
+				cleanup_inode(dvp, vp, dentry, mode);
 		}
 		_ACL_FREE(default_acl);
 	}
diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h
index 427cff1..e27dc8f 100644
--- a/include/acpi/acconfig.h
+++ b/include/acpi/acconfig.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -61,9 +61,9 @@
  *
  */
 
-/* Version string */
+/* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20050902
+#define ACPI_CA_VERSION                 0x20060127
 
 /*
  * OS name, used for the _OS object.  The _OS object is essentially obsolete,
@@ -83,7 +83,7 @@
 #define ACPI_MAX_OBJECT_CACHE_DEPTH     96	/* Interpreter operand objects */
 
 /*
- * Should the subystem abort the loading of an ACPI table if the
+ * Should the subsystem abort the loading of an ACPI table if the
  * table checksum is incorrect?
  */
 #define ACPI_CHECKSUM_ABORT             FALSE
@@ -98,11 +98,6 @@
 
 #define ACPI_CA_SUPPORT_LEVEL           3
 
-/* String size constants */
-
-#define ACPI_MAX_STRING_LENGTH          512
-#define ACPI_PATHNAME_MAX               256	/* A full namespace pathname */
-
 /* Maximum count for a semaphore object */
 
 #define ACPI_MAX_SEMAPHORE_COUNT        256
@@ -115,6 +110,10 @@
 
 #define ACPI_SYSMEM_REGION_WINDOW_SIZE  4096
 
+/* owner_id tracking. 8 entries allows for 255 owner_ids */
+
+#define ACPI_NUM_OWNERID_MASKS          8
+
 /******************************************************************************
  *
  * ACPI Specification constants (Do not change unless the specification changes)
@@ -134,14 +133,11 @@
 #define ACPI_METHOD_NUM_ARGS            7
 #define ACPI_METHOD_MAX_ARG             6
 
-/* Maximum length of resulting string when converting from a buffer */
-
-#define ACPI_MAX_STRING_CONVERSION      200
-
-/* Length of _HID, _UID, and _CID values */
+/* Length of _HID, _UID, _CID, and UUID values */
 
 #define ACPI_DEVICE_ID_LENGTH           0x09
 #define ACPI_MAX_CID_LENGTH             48
+#define ACPI_UUID_LENGTH                16
 
 /*
  * Operand Stack (in WALK_STATE), Must be large enough to contain METHOD_MAX_ARG
diff --git a/include/acpi/acdebug.h b/include/acpi/acdebug.h
index 70ce3b4..d816709 100644
--- a/include/acpi/acdebug.h
+++ b/include/acpi/acdebug.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/acpi/acdisasm.h b/include/acpi/acdisasm.h
index 3d96dcb..11a8fe3 100644
--- a/include/acpi/acdisasm.h
+++ b/include/acpi/acdisasm.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -57,26 +57,11 @@ struct acpi_external_list {
 };
 
 extern struct acpi_external_list *acpi_gbl_external_list;
-extern const char *acpi_gbl_io_decode[2];
+
+/* Strings used for decoding flags to ASL keywords */
+
 extern const char *acpi_gbl_word_decode[4];
-extern const char *acpi_gbl_consume_decode[2];
-extern const char *acpi_gbl_min_decode[2];
-extern const char *acpi_gbl_max_decode[2];
-extern const char *acpi_gbl_DECdecode[2];
-extern const char *acpi_gbl_RNGdecode[4];
-extern const char *acpi_gbl_MEMdecode[4];
-extern const char *acpi_gbl_RWdecode[2];
 extern const char *acpi_gbl_irq_decode[2];
-extern const char *acpi_gbl_HEdecode[2];
-extern const char *acpi_gbl_LLdecode[2];
-extern const char *acpi_gbl_SHRdecode[2];
-extern const char *acpi_gbl_TYPdecode[4];
-extern const char *acpi_gbl_BMdecode[2];
-extern const char *acpi_gbl_SIZdecode[4];
-extern const char *acpi_gbl_TTPdecode[2];
-extern const char *acpi_gbl_MTPdecode[4];
-extern const char *acpi_gbl_TRSdecode[2];
-
 extern const char *acpi_gbl_lock_rule[ACPI_NUM_LOCK_RULES];
 extern const char *acpi_gbl_access_types[ACPI_NUM_ACCESS_TYPES];
 extern const char *acpi_gbl_update_rules[ACPI_NUM_UPDATE_RULES];
@@ -171,11 +156,19 @@ u8 acpi_dm_is_string_buffer(union acpi_p
 /*
  * dmresrc
  */
+void acpi_dm_dump_integer8(u8 value, char *name);
+
+void acpi_dm_dump_integer16(u16 value, char *name);
+
+void acpi_dm_dump_integer32(u32 value, char *name);
+
+void acpi_dm_dump_integer64(u64 value, char *name);
+
 void
-acpi_dm_resource_descriptor(struct acpi_op_walk_info *info,
-			    u8 * byte_data, u32 byte_count);
+acpi_dm_resource_template(struct acpi_op_walk_info *info,
+			  u8 * byte_data, u32 byte_count);
 
-u8 acpi_dm_is_resource_descriptor(union acpi_parse_object *op);
+u8 acpi_dm_is_resource_template(union acpi_parse_object *op);
 
 void acpi_dm_indent(u32 level);
 
@@ -187,73 +180,69 @@ void acpi_dm_decode_attribute(u8 attribu
  * dmresrcl
  */
 void
-acpi_dm_word_descriptor(struct asl_word_address_desc *resource,
-			u32 length, u32 level);
+acpi_dm_word_descriptor(union aml_resource *resource, u32 length, u32 level);
 
 void
-acpi_dm_dword_descriptor(struct asl_dword_address_desc *resource,
-			 u32 length, u32 level);
+acpi_dm_dword_descriptor(union aml_resource *resource, u32 length, u32 level);
 
 void
-acpi_dm_extended_descriptor(struct asl_extended_address_desc *resource,
+acpi_dm_extended_descriptor(union aml_resource *resource,
 			    u32 length, u32 level);
 
 void
-acpi_dm_qword_descriptor(struct asl_qword_address_desc *resource,
-			 u32 length, u32 level);
+acpi_dm_qword_descriptor(union aml_resource *resource, u32 length, u32 level);
 
 void
-acpi_dm_memory24_descriptor(struct asl_memory_24_desc *resource,
+acpi_dm_memory24_descriptor(union aml_resource *resource,
 			    u32 length, u32 level);
 
 void
-acpi_dm_memory32_descriptor(struct asl_memory_32_desc *resource,
+acpi_dm_memory32_descriptor(union aml_resource *resource,
 			    u32 length, u32 level);
 
 void
-acpi_dm_fixed_mem32_descriptor(struct asl_fixed_memory_32_desc *resource,
-			       u32 length, u32 level);
+acpi_dm_fixed_memory32_descriptor(union aml_resource *resource,
+				  u32 length, u32 level);
 
 void
-acpi_dm_generic_register_descriptor(struct asl_general_register_desc *resource,
+acpi_dm_generic_register_descriptor(union aml_resource *resource,
 				    u32 length, u32 level);
 
 void
-acpi_dm_interrupt_descriptor(struct asl_extended_xrupt_desc *resource,
+acpi_dm_interrupt_descriptor(union aml_resource *resource,
 			     u32 length, u32 level);
 
 void
-acpi_dm_vendor_large_descriptor(struct asl_large_vendor_desc *resource,
+acpi_dm_vendor_large_descriptor(union aml_resource *resource,
 				u32 length, u32 level);
 
+void acpi_dm_vendor_common(char *name, u8 * byte_data, u32 length, u32 level);
+
 /*
  * dmresrcs
  */
 void
-acpi_dm_irq_descriptor(struct asl_irq_format_desc *resource,
-		       u32 length, u32 level);
+acpi_dm_irq_descriptor(union aml_resource *resource, u32 length, u32 level);
 
 void
-acpi_dm_dma_descriptor(struct asl_dma_format_desc *resource,
-		       u32 length, u32 level);
+acpi_dm_dma_descriptor(union aml_resource *resource, u32 length, u32 level);
 
-void
-acpi_dm_io_descriptor(struct asl_io_port_desc *resource, u32 length, u32 level);
+void acpi_dm_io_descriptor(union aml_resource *resource, u32 length, u32 level);
 
 void
-acpi_dm_fixed_io_descriptor(struct asl_fixed_io_port_desc *resource,
+acpi_dm_fixed_io_descriptor(union aml_resource *resource,
 			    u32 length, u32 level);
 
 void
-acpi_dm_start_dependent_descriptor(struct asl_start_dependent_desc *resource,
+acpi_dm_start_dependent_descriptor(union aml_resource *resource,
 				   u32 length, u32 level);
 
 void
-acpi_dm_end_dependent_descriptor(struct asl_start_dependent_desc *resource,
+acpi_dm_end_dependent_descriptor(union aml_resource *resource,
 				 u32 length, u32 level);
 
 void
-acpi_dm_vendor_small_descriptor(struct asl_small_vendor_desc *resource,
+acpi_dm_vendor_small_descriptor(union aml_resource *resource,
 				u32 length, u32 level);
 
 /*
diff --git a/include/acpi/acdispat.h b/include/acpi/acdispat.h
index 065f24a..c41a926 100644
--- a/include/acpi/acdispat.h
+++ b/include/acpi/acdispat.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -201,6 +201,9 @@ acpi_ds_begin_method_execution(struct ac
 			       union acpi_operand_object *obj_desc,
 			       struct acpi_namespace_node *calling_method_node);
 
+acpi_status
+acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state);
+
 /*
  * dsinit
  */
diff --git a/include/acpi/acevents.h b/include/acpi/acevents.h
index bfa5460..f2717be 100644
--- a/include/acpi/acevents.h
+++ b/include/acpi/acevents.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -51,6 +51,8 @@ acpi_status acpi_ev_initialize_events(vo
 
 acpi_status acpi_ev_install_xrupt_handlers(void);
 
+acpi_status acpi_ev_install_fadt_gpes(void);
+
 u32 acpi_ev_fixed_event_detect(void);
 
 /*
@@ -105,6 +107,10 @@ acpi_ev_create_gpe_block(struct acpi_nam
 			 u32 interrupt_number,
 			 struct acpi_gpe_block_info **return_gpe_block);
 
+acpi_status
+acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
+			     struct acpi_gpe_block_info *gpe_block);
+
 acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block);
 
 u32
diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h
index 4f005eb..dc768aa 100644
--- a/include/acpi/acexcep.h
+++ b/include/acpi/acexcep.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h
index 4ab2ca1..734cc77 100644
--- a/include/acpi/acglobal.h
+++ b/include/acpi/acglobal.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -80,6 +80,15 @@ extern u32 acpi_dbg_layer;
 
 extern u32 acpi_gbl_nesting_level;
 
+/* Support for dynamic control method tracing mechanism */
+
+ACPI_EXTERN u32 acpi_gbl_original_dbg_level;
+ACPI_EXTERN u32 acpi_gbl_original_dbg_layer;
+ACPI_EXTERN acpi_name acpi_gbl_trace_method_name;
+ACPI_EXTERN u32 acpi_gbl_trace_dbg_level;
+ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer;
+ACPI_EXTERN u32 acpi_gbl_trace_flags;
+
 /*****************************************************************************
  *
  * Runtime configuration (static defaults that can be overriden at runtime)
@@ -89,11 +98,15 @@ extern u32 acpi_gbl_nesting_level;
 /*
  * Enable "slack" in the AML interpreter?  Default is FALSE, and the
  * interpreter strictly follows the ACPI specification.  Setting to TRUE
- * allows the interpreter to forgive certain bad AML constructs.  Currently:
+ * allows the interpreter to ignore certain errors and/or bad AML constructs.
+ *
+ * Currently, these features are enabled by this flag:
+ *
  * 1) Allow "implicit return" of last value in a control method
- * 2) Allow access beyond end of operation region
+ * 2) Allow access beyond the end of an operation region
  * 3) Allow access to uninitialized locals/args (auto-init to integer 0)
  * 4) Allow ANY object type to be a source operand for the Store() operator
+ * 5) Allow unresolved references (invalid target name) in package objects
  */
 ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_interpreter_slack, FALSE);
 
@@ -211,9 +224,11 @@ ACPI_EXTERN u32 acpi_gbl_original_mode;
 ACPI_EXTERN u32 acpi_gbl_rsdp_original_location;
 ACPI_EXTERN u32 acpi_gbl_ns_lookup_count;
 ACPI_EXTERN u32 acpi_gbl_ps_find_count;
-ACPI_EXTERN u64 acpi_gbl_owner_id_mask;
+ACPI_EXTERN u32 acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS];
 ACPI_EXTERN u16 acpi_gbl_pm1_enable_register_save;
 ACPI_EXTERN u16 acpi_gbl_global_lock_handle;
+ACPI_EXTERN u8 acpi_gbl_last_owner_id_index;
+ACPI_EXTERN u8 acpi_gbl_next_owner_id_offset;
 ACPI_EXTERN u8 acpi_gbl_debugger_configuration;
 ACPI_EXTERN u8 acpi_gbl_global_lock_acquired;
 ACPI_EXTERN u8 acpi_gbl_step_to_next_call;
diff --git a/include/acpi/achware.h b/include/acpi/achware.h
index 3644d72..29b60a8 100644
--- a/include/acpi/achware.h
+++ b/include/acpi/achware.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/acpi/acinterp.h b/include/acpi/acinterp.h
index 2c9c1a1..9f22cfc 100644
--- a/include/acpi/acinterp.h
+++ b/include/acpi/acinterp.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,7 +44,49 @@
 #ifndef __ACINTERP_H__
 #define __ACINTERP_H__
 
-#define ACPI_WALK_OPERANDS       (&(walk_state->operands [walk_state->num_operands -1]))
+#define ACPI_WALK_OPERANDS          (&(walk_state->operands [walk_state->num_operands -1]))
+
+/* Macros for tables used for debug output */
+
+#define ACPI_EXD_OFFSET(f)          (u8) ACPI_OFFSET (union acpi_operand_object,f)
+#define ACPI_EXD_NSOFFSET(f)        (u8) ACPI_OFFSET (struct acpi_namespace_node,f)
+#define ACPI_EXD_TABLE_SIZE(name)   (sizeof(name) / sizeof (struct acpi_exdump_info))
+
+/*
+ * If possible, pack the following structure to byte alignment, since we
+ * don't care about performance for debug output
+ */
+#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED
+#pragma pack(1)
+#endif
+
+typedef const struct acpi_exdump_info {
+	u8 opcode;
+	u8 offset;
+	char *name;
+
+} acpi_exdump_info;
+
+/* Values for the Opcode field above */
+
+#define ACPI_EXD_INIT                   0
+#define ACPI_EXD_TYPE                   1
+#define ACPI_EXD_UINT8                  2
+#define ACPI_EXD_UINT16                 3
+#define ACPI_EXD_UINT32                 4
+#define ACPI_EXD_UINT64                 5
+#define ACPI_EXD_LITERAL                6
+#define ACPI_EXD_POINTER                7
+#define ACPI_EXD_ADDRESS                8
+#define ACPI_EXD_STRING                 9
+#define ACPI_EXD_BUFFER                 10
+#define ACPI_EXD_PACKAGE                11
+#define ACPI_EXD_FIELD                  12
+#define ACPI_EXD_REFERENCE              13
+
+/* restore default alignment */
+
+#pragma pack()
 
 /*
  * exconvrt - object conversion
@@ -327,7 +369,7 @@ acpi_ex_dump_operands(union acpi_operand
 void
 acpi_ex_dump_object_descriptor(union acpi_operand_object *object, u32 flags);
 
-void acpi_ex_dump_node(struct acpi_namespace_node *node, u32 flags);
+void acpi_ex_dump_namespace_node(struct acpi_namespace_node *node, u32 flags);
 #endif				/* ACPI_FUTURE_USAGE */
 
 /*
diff --git a/include/acpi/aclocal.h b/include/acpi/aclocal.h
index 9fba0fd..8361820 100644
--- a/include/acpi/aclocal.h
+++ b/include/acpi/aclocal.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -276,6 +276,37 @@ struct acpi_create_field_info {
 	u8 field_type;
 };
 
+/*
+ * Bitmapped ACPI types.  Used internally only
+ */
+#define ACPI_BTYPE_ANY                  0x00000000
+#define ACPI_BTYPE_INTEGER              0x00000001
+#define ACPI_BTYPE_STRING               0x00000002
+#define ACPI_BTYPE_BUFFER               0x00000004
+#define ACPI_BTYPE_PACKAGE              0x00000008
+#define ACPI_BTYPE_FIELD_UNIT           0x00000010
+#define ACPI_BTYPE_DEVICE               0x00000020
+#define ACPI_BTYPE_EVENT                0x00000040
+#define ACPI_BTYPE_METHOD               0x00000080
+#define ACPI_BTYPE_MUTEX                0x00000100
+#define ACPI_BTYPE_REGION               0x00000200
+#define ACPI_BTYPE_POWER                0x00000400
+#define ACPI_BTYPE_PROCESSOR            0x00000800
+#define ACPI_BTYPE_THERMAL              0x00001000
+#define ACPI_BTYPE_BUFFER_FIELD         0x00002000
+#define ACPI_BTYPE_DDB_HANDLE           0x00004000
+#define ACPI_BTYPE_DEBUG_OBJECT         0x00008000
+#define ACPI_BTYPE_REFERENCE            0x00010000
+#define ACPI_BTYPE_RESOURCE             0x00020000
+
+#define ACPI_BTYPE_COMPUTE_DATA         (ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER)
+
+#define ACPI_BTYPE_DATA                 (ACPI_BTYPE_COMPUTE_DATA  | ACPI_BTYPE_PACKAGE)
+#define ACPI_BTYPE_DATA_REFERENCE       (ACPI_BTYPE_DATA | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE)
+#define ACPI_BTYPE_DEVICE_OBJECTS       (ACPI_BTYPE_DEVICE | ACPI_BTYPE_THERMAL | ACPI_BTYPE_PROCESSOR)
+#define ACPI_BTYPE_OBJECTS_AND_REFS     0x0001FFFF	/* ARG or LOCAL */
+#define ACPI_BTYPE_ALL_OBJECTS          0x0000FFFF
+
 /*****************************************************************************
  *
  * Event typedefs and structs
@@ -385,13 +416,13 @@ struct acpi_field_info {
 #define ACPI_CONTROL_PREDICATE_FALSE         0xC3
 #define ACPI_CONTROL_PREDICATE_TRUE          0xC4
 
-#define ACPI_STATE_COMMON                  /* Two 32-bit fields and a pointer */\
-	u8                                  data_type;          /* To differentiate various internal objs */\
+#define ACPI_STATE_COMMON   /* Two 32-bit fields and a pointer */\
+	u8                                  data_type;  /* To differentiate various internal objs */\
 	u8                                  flags;      \
 	u16                                 value;      \
 	u16                                 state;      \
 	u16                                 reserved;   \
-	void                                *next;      \
+	void                                *next;
 
 struct acpi_common_state {
 ACPI_STATE_COMMON};
@@ -544,8 +575,7 @@ union acpi_parse_value {
 	char                                aml_op_name[16]) /* Op name (debug only) */\
 			   /* NON-DEBUG members below: */\
 	struct acpi_namespace_node          *node;          /* For use by interpreter */\
-	union acpi_parse_value              value;          /* Value or args associated with the opcode */\
-
+	union acpi_parse_value              value;	/* Value or args associated with the opcode */
 
 #define ACPI_DASM_BUFFER        0x00
 #define ACPI_DASM_RESOURCE      0x01
@@ -573,6 +603,8 @@ struct acpi_parse_obj_named {
 
 /* The parse node is the fundamental element of the parse tree */
 
+#define ACPI_MAX_PARSEOP_NAME   20
+
 struct acpi_parse_obj_asl {
 	ACPI_PARSE_COMMON union acpi_parse_object *child;
 	union acpi_parse_object *parent_method;
@@ -597,7 +629,7 @@ struct acpi_parse_obj_asl {
 	u8 aml_opcode_length;
 	u8 aml_pkg_len_bytes;
 	u8 extra;
-	char parse_op_name[12];
+	char parse_op_name[ACPI_MAX_PARSEOP_NAME];
 };
 
 union acpi_parse_object {
@@ -735,44 +767,52 @@ struct acpi_bit_register_info {
 
 /* resource_type values */
 
-#define ACPI_RESOURCE_TYPE_MEMORY_RANGE         0
-#define ACPI_RESOURCE_TYPE_IO_RANGE             1
-#define ACPI_RESOURCE_TYPE_BUS_NUMBER_RANGE     2
+#define ACPI_ADDRESS_TYPE_MEMORY_RANGE          0
+#define ACPI_ADDRESS_TYPE_IO_RANGE              1
+#define ACPI_ADDRESS_TYPE_BUS_NUMBER_RANGE      2
 
 /* Resource descriptor types and masks */
 
-#define ACPI_RDESC_TYPE_LARGE                   0x80
-#define ACPI_RDESC_TYPE_SMALL                   0x00
-
-#define ACPI_RDESC_TYPE_MASK                    0x80
-#define ACPI_RDESC_SMALL_MASK                   0x78	/* Only bits 6:3 contain the type */
+#define ACPI_RESOURCE_NAME_LARGE                0x80
+#define ACPI_RESOURCE_NAME_SMALL                0x00
 
-/*
- * Small resource descriptor types
- * Note: The 3 length bits (2:0) must be zero
- */
-#define ACPI_RDESC_TYPE_IRQ_FORMAT              0x20
-#define ACPI_RDESC_TYPE_DMA_FORMAT              0x28
-#define ACPI_RDESC_TYPE_START_DEPENDENT         0x30
-#define ACPI_RDESC_TYPE_END_DEPENDENT           0x38
-#define ACPI_RDESC_TYPE_IO_PORT                 0x40
-#define ACPI_RDESC_TYPE_FIXED_IO_PORT           0x48
-#define ACPI_RDESC_TYPE_SMALL_VENDOR            0x70
-#define ACPI_RDESC_TYPE_END_TAG                 0x78
-
-/*
- * Large resource descriptor types
- */
-#define ACPI_RDESC_TYPE_MEMORY_24               0x81
-#define ACPI_RDESC_TYPE_GENERAL_REGISTER        0x82
-#define ACPI_RDESC_TYPE_LARGE_VENDOR            0x84
-#define ACPI_RDESC_TYPE_MEMORY_32               0x85
-#define ACPI_RDESC_TYPE_FIXED_MEMORY_32         0x86
-#define ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE     0x87
-#define ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE      0x88
-#define ACPI_RDESC_TYPE_EXTENDED_XRUPT          0x89
-#define ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE     0x8A
-#define ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE  0x8B
+#define ACPI_RESOURCE_NAME_SMALL_MASK           0x78	/* Bits 6:3 contain the type */
+#define ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK    0x07	/* Bits 2:0 contain the length */
+#define ACPI_RESOURCE_NAME_LARGE_MASK           0x7F	/* Bits 6:0 contain the type */
+
+/*
+ * Small resource descriptor "names" as defined by the ACPI specification.
+ * Note: Bits 2:0 are used for the descriptor length
+ */
+#define ACPI_RESOURCE_NAME_IRQ                  0x20
+#define ACPI_RESOURCE_NAME_DMA                  0x28
+#define ACPI_RESOURCE_NAME_START_DEPENDENT      0x30
+#define ACPI_RESOURCE_NAME_END_DEPENDENT        0x38
+#define ACPI_RESOURCE_NAME_IO                   0x40
+#define ACPI_RESOURCE_NAME_FIXED_IO             0x48
+#define ACPI_RESOURCE_NAME_RESERVED_S1          0x50
+#define ACPI_RESOURCE_NAME_RESERVED_S2          0x58
+#define ACPI_RESOURCE_NAME_RESERVED_S3          0x60
+#define ACPI_RESOURCE_NAME_RESERVED_S4          0x68
+#define ACPI_RESOURCE_NAME_VENDOR_SMALL         0x70
+#define ACPI_RESOURCE_NAME_END_TAG              0x78
+
+/*
+ * Large resource descriptor "names" as defined by the ACPI specification.
+ * Note: includes the Large Descriptor bit in bit[7]
+ */
+#define ACPI_RESOURCE_NAME_MEMORY24             0x81
+#define ACPI_RESOURCE_NAME_GENERIC_REGISTER     0x82
+#define ACPI_RESOURCE_NAME_RESERVED_L1          0x83
+#define ACPI_RESOURCE_NAME_VENDOR_LARGE         0x84
+#define ACPI_RESOURCE_NAME_MEMORY32             0x85
+#define ACPI_RESOURCE_NAME_FIXED_MEMORY32       0x86
+#define ACPI_RESOURCE_NAME_ADDRESS32            0x87
+#define ACPI_RESOURCE_NAME_ADDRESS16            0x88
+#define ACPI_RESOURCE_NAME_EXTENDED_IRQ         0x89
+#define ACPI_RESOURCE_NAME_ADDRESS64            0x8A
+#define ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64   0x8B
+#define ACPI_RESOURCE_NAME_LARGE_MAX            0x8B
 
 /*****************************************************************************
  *
@@ -780,7 +820,7 @@ struct acpi_bit_register_info {
  *
  ****************************************************************************/
 
-#define ACPI_ASCII_ZERO                      0x30
+#define ACPI_ASCII_ZERO                         0x30
 
 /*****************************************************************************
  *
diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h
index 702cc4e..f2be2a8 100644
--- a/include/acpi/acmacros.h
+++ b/include/acpi/acmacros.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -60,7 +60,7 @@
 
 /*
  * For 16-bit addresses, we have to assume that the upper 32 bits
- * are zero.
+ * (out of 64) are zero.
  */
 #define ACPI_LODWORD(l)                 ((u32)(l))
 #define ACPI_HIDWORD(l)                 ((u32)(0))
@@ -104,30 +104,38 @@
 #define ACPI_FORMAT_UINT64(i)           ACPI_HIDWORD(i),ACPI_LODWORD(i)
 
 /*
- * Extract a byte of data using a pointer.  Any more than a byte and we
- * get into potential aligment issues -- see the STORE macros below
- */
-#define ACPI_GET8(addr)                 (*(u8*)(addr))
-
-/* Pointer arithmetic */
-
-#define ACPI_PTR_ADD(t,a,b)             (t *) (void *)((char *)(a) + (acpi_native_uint)(b))
-#define ACPI_PTR_DIFF(a,b)              (acpi_native_uint) ((char *)(a) - (char *)(b))
+ * Extract data using a pointer.  Any more than a byte and we
+ * get into potential aligment issues -- see the STORE macros below.
+ * Use with care.
+ */
+#define ACPI_GET8(ptr)                  *ACPI_CAST_PTR (u8, ptr)
+#define ACPI_GET16(ptr)                 *ACPI_CAST_PTR (u16, ptr)
+#define ACPI_GET32(ptr)                 *ACPI_CAST_PTR (u32, ptr)
+#define ACPI_GET64(ptr)                 *ACPI_CAST_PTR (u64, ptr)
+#define ACPI_SET8(ptr)                  *ACPI_CAST_PTR (u8, ptr)
+#define ACPI_SET16(ptr)                 *ACPI_CAST_PTR (u16, ptr)
+#define ACPI_SET32(ptr)                 *ACPI_CAST_PTR (u32, ptr)
+#define ACPI_SET64(ptr)                 *ACPI_CAST_PTR (u64, ptr)
+
+/*
+ * Pointer manipulation
+ */
+#define ACPI_CAST_PTR(t, p)             ((t *) (acpi_uintptr_t) (p))
+#define ACPI_CAST_INDIRECT_PTR(t, p)    ((t **) (acpi_uintptr_t) (p))
+#define ACPI_ADD_PTR(t,a,b)             ACPI_CAST_PTR (t, (ACPI_CAST_PTR (u8,(a)) + (acpi_native_uint)(b)))
+#define ACPI_PTR_DIFF(a,b)              (acpi_native_uint) (ACPI_CAST_PTR (u8,(a)) - ACPI_CAST_PTR (u8,(b)))
 
 /* Pointer/Integer type conversions */
 
-#define ACPI_TO_POINTER(i)              ACPI_PTR_ADD (void, (void *) NULL,(acpi_native_uint)i)
+#define ACPI_TO_POINTER(i)              ACPI_ADD_PTR (void,(void *) NULL,(acpi_native_uint) i)
 #define ACPI_TO_INTEGER(p)              ACPI_PTR_DIFF (p,(void *) NULL)
 #define ACPI_OFFSET(d,f)                (acpi_size) ACPI_PTR_DIFF (&(((d *)0)->f),(void *) NULL)
 #define ACPI_FADT_OFFSET(f)             ACPI_OFFSET (FADT_DESCRIPTOR, f)
 
-#define ACPI_CAST_PTR(t, p)             ((t *)(void *)(p))
-#define ACPI_CAST_INDIRECT_PTR(t, p)    ((t **)(void *)(p))
-
 #if ACPI_MACHINE_WIDTH == 16
 #define ACPI_STORE_POINTER(d,s)         ACPI_MOVE_32_TO_32(d,s)
 #define ACPI_PHYSADDR_TO_PTR(i)         (void *)(i)
-#define ACPI_PTR_TO_PHYSADDR(i)         (u32) (char *)(i)
+#define ACPI_PTR_TO_PHYSADDR(i)         (u32) ACPI_CAST_PTR (u8,(i))
 #else
 #define ACPI_PHYSADDR_TO_PTR(i)         ACPI_TO_POINTER(i)
 #define ACPI_PTR_TO_PHYSADDR(i)         ACPI_TO_INTEGER(i)
@@ -202,7 +210,7 @@
 
 #define ACPI_BUFFER_INDEX(buf_len,buf_offset,byte_gran) (buf_offset)
 
-#ifdef ACPI_MISALIGNED_TRANSFERS
+#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED
 
 /* The hardware supports unaligned transfers, just do the little-endian move */
 
@@ -326,11 +334,19 @@
 #define ACPI_MUL_16(a)                  _ACPI_MUL(a,4)
 #define ACPI_MOD_16(a)                  _ACPI_MOD(a,16)
 
+#define ACPI_DIV_32(a)                  _ACPI_DIV(a,5)
+#define ACPI_MUL_32(a)                  _ACPI_MUL(a,5)
+#define ACPI_MOD_32(a)                  _ACPI_MOD(a,32)
+
 /*
  * Rounding macros (Power of two boundaries only)
  */
-#define ACPI_ROUND_DOWN(value,boundary)      (((acpi_native_uint)(value)) & (~(((acpi_native_uint) boundary)-1)))
-#define ACPI_ROUND_UP(value,boundary)        ((((acpi_native_uint)(value)) + (((acpi_native_uint) boundary)-1)) & (~(((acpi_native_uint) boundary)-1)))
+#define ACPI_ROUND_DOWN(value,boundary)      (((acpi_native_uint)(value)) & \
+												(~(((acpi_native_uint) boundary)-1)))
+
+#define ACPI_ROUND_UP(value,boundary)        ((((acpi_native_uint)(value)) + \
+												(((acpi_native_uint) boundary)-1)) & \
+												(~(((acpi_native_uint) boundary)-1)))
 
 #define ACPI_ROUND_DOWN_TO_32_BITS(a)        ACPI_ROUND_DOWN(a,4)
 #define ACPI_ROUND_DOWN_TO_64_BITS(a)        ACPI_ROUND_DOWN(a,8)
@@ -365,6 +381,14 @@
 #define ACPI_REGISTER_PREPARE_BITS(val, pos, mask)      ((val << pos) & mask)
 #define ACPI_REGISTER_INSERT_VALUE(reg, pos, mask, val)  reg = (reg & (~(mask))) | ACPI_REGISTER_PREPARE_BITS(val, pos, mask)
 
+/* Generate a UUID */
+
+#define ACPI_INIT_UUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
+	(a) & 0xFF, ((a) >> 8) & 0xFF, ((a) >> 16) & 0xFF, ((a) >> 24) & 0xFF, \
+	(b) & 0xFF, ((b) >> 8) & 0xFF, \
+	(c) & 0xFF, ((c) >> 8) & 0xFF, \
+	(d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7)
+
 /*
  * An struct acpi_namespace_node * can appear in some contexts,
  * where a pointer to an union acpi_operand_object    can also
@@ -423,57 +447,52 @@
 #define GET_CURRENT_ARG_TYPE(list)      (list & ((u32) 0x1F))
 #define INCREMENT_ARG_LIST(list)        (list >>= ((u32) ARG_TYPE_WIDTH))
 
+#if defined (ACPI_DEBUG_OUTPUT) || !defined (ACPI_NO_ERROR_MESSAGES)
 /*
- * Reporting macros that are never compiled out
+ * Module name is include in both debug and non-debug versions primarily for
+ * error messages. The __FILE__ macro is not very useful for this, because it
+ * often includes the entire pathname to the module
  */
-#define ACPI_PARAM_LIST(pl)                 pl
+#define ACPI_MODULE_NAME(name)          static char ACPI_UNUSED_VAR *_acpi_module_name = name;
+#else
+#define ACPI_MODULE_NAME(name)
+#endif
 
 /*
- * Error reporting.  These versions add callers module and line#.
- *
- * Since _acpi_module_name gets compiled out when ACPI_DEBUG_OUTPUT
- * isn't defined, only use it in debug mode.
+ * Ascii error messages can be configured out
  */
-#ifdef ACPI_DEBUG_OUTPUT
-
-#define ACPI_REPORT_INFO(fp)                {acpi_ut_report_info(_acpi_module_name,__LINE__,_COMPONENT); \
-												acpi_os_printf ACPI_PARAM_LIST(fp);}
-#define ACPI_REPORT_ERROR(fp)               {acpi_ut_report_error(_acpi_module_name,__LINE__,_COMPONENT); \
-												acpi_os_printf ACPI_PARAM_LIST(fp);}
-#define ACPI_REPORT_WARNING(fp)             {acpi_ut_report_warning(_acpi_module_name,__LINE__,_COMPONENT); \
-												acpi_os_printf ACPI_PARAM_LIST(fp);}
-#define ACPI_REPORT_NSERROR(s,e)            acpi_ns_report_error(_acpi_module_name,__LINE__,_COMPONENT, s, e);
+#ifndef ACPI_NO_ERROR_MESSAGES
+#define AE_INFO                         _acpi_module_name, __LINE__
 
-#define ACPI_REPORT_METHOD_ERROR(s,n,p,e)   acpi_ns_report_method_error(_acpi_module_name,__LINE__,_COMPONENT, s, n, p, e);
+/*
+ * Error reporting. Callers module and line number are inserted by AE_INFO,
+ * the plist contains a set of parens to allow variable-length lists.
+ * These macros are used for both the debug and non-debug versions of the code.
+ */
+#define ACPI_INFO(plist)                acpi_ut_info plist
+#define ACPI_WARNING(plist)             acpi_ut_warning plist
+#define ACPI_EXCEPTION(plist)           acpi_ut_exception plist
+#define ACPI_ERROR(plist)               acpi_ut_error plist
+#define ACPI_ERROR_NAMESPACE(s,e)       acpi_ns_report_error (AE_INFO, s, e);
+#define ACPI_ERROR_METHOD(s,n,p,e)      acpi_ns_report_method_error (AE_INFO, s, n, p, e);
 
 #else
 
-#define ACPI_REPORT_INFO(fp)                {acpi_ut_report_info("ACPI",__LINE__,_COMPONENT); \
-												acpi_os_printf ACPI_PARAM_LIST(fp);}
-#define ACPI_REPORT_ERROR(fp)               {acpi_ut_report_error("ACPI",__LINE__,_COMPONENT); \
-												acpi_os_printf ACPI_PARAM_LIST(fp);}
-#define ACPI_REPORT_WARNING(fp)             {acpi_ut_report_warning("ACPI",__LINE__,_COMPONENT); \
-												acpi_os_printf ACPI_PARAM_LIST(fp);}
-#define ACPI_REPORT_NSERROR(s,e)            acpi_ns_report_error("ACPI",__LINE__,_COMPONENT, s, e);
+/* No error messages */
 
-#define ACPI_REPORT_METHOD_ERROR(s,n,p,e)   acpi_ns_report_method_error("ACPI",__LINE__,_COMPONENT, s, n, p, e);
+#define ACPI_INFO(plist)
+#define ACPI_WARNING(plist)
+#define ACPI_EXCEPTION(plist)
+#define ACPI_ERROR(plist)
+#define ACPI_ERROR_NAMESPACE(s,e)
+#define ACPI_ERROR_METHOD(s,n,p,e)
 
 #endif
 
-/* Error reporting.  These versions pass thru the module and line# */
-
-#define _ACPI_REPORT_INFO(a,b,c,fp)         {acpi_ut_report_info(a,b,c); \
-												acpi_os_printf ACPI_PARAM_LIST(fp);}
-#define _ACPI_REPORT_ERROR(a,b,c,fp)        {acpi_ut_report_error(a,b,c); \
-												acpi_os_printf ACPI_PARAM_LIST(fp);}
-#define _ACPI_REPORT_WARNING(a,b,c,fp)      {acpi_ut_report_warning(a,b,c); \
-												acpi_os_printf ACPI_PARAM_LIST(fp);}
-
 /*
  * Debug macros that are conditionally compiled
  */
 #ifdef ACPI_DEBUG_OUTPUT
-#define ACPI_MODULE_NAME(name)          static char ACPI_UNUSED_VAR *_acpi_module_name = name;
 
 /*
  * Common parameters used for debug output functions:
@@ -509,7 +528,7 @@
 #endif
 
 #define ACPI_FUNCTION_TRACE(a)          ACPI_FUNCTION_NAME(a) \
-											acpi_ut_trace(ACPI_DEBUG_PARAMETERS)
+									  acpi_ut_trace(ACPI_DEBUG_PARAMETERS)
 #define ACPI_FUNCTION_TRACE_PTR(a,b)    ACPI_FUNCTION_NAME(a) \
 											acpi_ut_trace_ptr(ACPI_DEBUG_PARAMETERS,(void *)b)
 #define ACPI_FUNCTION_TRACE_U32(a,b)    ACPI_FUNCTION_NAME(a) \
@@ -525,6 +544,9 @@
  * bad form, but having a separate exit macro is very ugly and difficult to maintain.
  * One of the FUNCTION_TRACE macros above must be used in conjunction with these macros
  * so that "_acpi_function_name" is defined.
+ *
+ * Note: the DO_WHILE0 macro is used to prevent some compilers from complaining
+ * about these constructs.
  */
 #ifdef ACPI_USE_DO_WHILE_0
 #define ACPI_DO_WHILE0(a)               do a while(0)
@@ -532,10 +554,55 @@
 #define ACPI_DO_WHILE0(a)               a
 #endif
 
-#define return_VOID                     ACPI_DO_WHILE0 ({acpi_ut_exit(ACPI_DEBUG_PARAMETERS);return;})
-#define return_ACPI_STATUS(s)           ACPI_DO_WHILE0 ({acpi_ut_status_exit(ACPI_DEBUG_PARAMETERS,(s));return((s));})
-#define return_VALUE(s)                 ACPI_DO_WHILE0 ({acpi_ut_value_exit(ACPI_DEBUG_PARAMETERS,(acpi_integer)(s));return((s));})
-#define return_PTR(s)                   ACPI_DO_WHILE0 ({acpi_ut_ptr_exit(ACPI_DEBUG_PARAMETERS,(u8 *)(s));return((s));})
+#define return_VOID                     ACPI_DO_WHILE0 ({ \
+											acpi_ut_exit (ACPI_DEBUG_PARAMETERS); \
+											return;})
+/*
+ * There are two versions of most of the return macros. The default version is
+ * safer, since it avoids side-effects by guaranteeing that the argument will
+ * not be evaluated twice.
+ *
+ * A less-safe version of the macros is provided for optional use if the
+ * compiler uses excessive CPU stack (for example, this may happen in the
+ * debug case if code optimzation is disabled.)
+ */
+#ifndef ACPI_SIMPLE_RETURN_MACROS
+
+#define return_ACPI_STATUS(s)           ACPI_DO_WHILE0 ({ \
+											register acpi_status _s = (s); \
+											acpi_ut_status_exit (ACPI_DEBUG_PARAMETERS, _s); \
+											return (_s); })
+#define return_PTR(s)                   ACPI_DO_WHILE0 ({ \
+											register void *_s = (void *) (s); \
+											acpi_ut_ptr_exit (ACPI_DEBUG_PARAMETERS, (u8 *) _s); \
+											return (_s); })
+#define return_VALUE(s)                 ACPI_DO_WHILE0 ({ \
+											register acpi_integer _s = (s); \
+											acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, _s); \
+											return (_s); })
+#define return_UINT8(s)                 ACPI_DO_WHILE0 ({ \
+											register u8 _s = (u8) (s); \
+											acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (acpi_integer) _s); \
+											return (_s); })
+#define return_UINT32(s)                ACPI_DO_WHILE0 ({ \
+											register u32 _s = (u32) (s); \
+											acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (acpi_integer) _s); \
+											return (_s); })
+#else				/* Use original less-safe macros */
+
+#define return_ACPI_STATUS(s)           ACPI_DO_WHILE0 ({ \
+											acpi_ut_status_exit (ACPI_DEBUG_PARAMETERS, (s)); \
+											return((s)); })
+#define return_PTR(s)                   ACPI_DO_WHILE0 ({ \
+											acpi_ut_ptr_exit (ACPI_DEBUG_PARAMETERS, (u8 *) (s)); \
+											return((s)); })
+#define return_VALUE(s)                 ACPI_DO_WHILE0 ({ \
+											acpi_ut_value_exit (ACPI_DEBUG_PARAMETERS, (acpi_integer) (s)); \
+											return((s)); })
+#define return_UINT8(s)                 return_VALUE(s)
+#define return_UINT32(s)                return_VALUE(s)
+
+#endif				/* ACPI_SIMPLE_RETURN_MACROS */
 
 /* Conditional execution */
 
@@ -555,18 +622,6 @@
 #define ACPI_DUMP_PATHNAME(a,b,c,d)     acpi_ns_dump_pathname(a,b,c,d)
 #define ACPI_DUMP_RESOURCE_LIST(a)      acpi_rs_dump_resource_list(a)
 #define ACPI_DUMP_BUFFER(a,b)           acpi_ut_dump_buffer((u8 *)a,b,DB_BYTE_DISPLAY,_COMPONENT)
-#define ACPI_BREAK_MSG(a)               acpi_os_signal (ACPI_SIGNAL_BREAKPOINT,(a))
-
-/*
- * Generate INT3 on ACPI_ERROR (Debug only!)
- */
-#define ACPI_ERROR_BREAK
-#ifdef  ACPI_ERROR_BREAK
-#define ACPI_BREAK_ON_ERROR(lvl)        if ((lvl)&ACPI_ERROR) \
-											acpi_os_signal(ACPI_SIGNAL_BREAKPOINT,"Fatal error encountered\n")
-#else
-#define ACPI_BREAK_ON_ERROR(lvl)
-#endif
 
 /*
  * Master debug print macros
@@ -574,17 +629,14 @@
  *    1) Debug print for the current component is enabled
  *    2) Debug error level or trace level for the print statement is enabled
  */
-#define ACPI_DEBUG_PRINT(pl)            acpi_ut_debug_print ACPI_PARAM_LIST(pl)
-#define ACPI_DEBUG_PRINT_RAW(pl)        acpi_ut_debug_print_raw ACPI_PARAM_LIST(pl)
+#define ACPI_DEBUG_PRINT(plist)         acpi_ut_debug_print plist
+#define ACPI_DEBUG_PRINT_RAW(plist)     acpi_ut_debug_print_raw plist
 
 #else
 /*
  * This is the non-debug case -- make everything go away,
  * leaving no executable debug code!
  */
-#define ACPI_MODULE_NAME(name)
-#define _acpi_module_name ""
-
 #define ACPI_DEBUG_EXEC(a)
 #define ACPI_NORMAL_EXEC(a)             a;
 
@@ -607,11 +659,12 @@
 #define ACPI_DUMP_BUFFER(a,b)
 #define ACPI_DEBUG_PRINT(pl)
 #define ACPI_DEBUG_PRINT_RAW(pl)
-#define ACPI_BREAK_MSG(a)
 
 #define return_VOID                     return
 #define return_ACPI_STATUS(s)           return(s)
 #define return_VALUE(s)                 return(s)
+#define return_UINT8(s)                 return(s)
+#define return_UINT32(s)                return(s)
 #define return_PTR(s)                   return(s)
 
 #endif
diff --git a/include/acpi/acnames.h b/include/acpi/acnames.h
index 4f9063f..b67da36 100644
--- a/include/acpi/acnames.h
+++ b/include/acpi/acnames.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/acpi/acnamesp.h b/include/acpi/acnamesp.h
index dd3501f..b667a80 100644
--- a/include/acpi/acnamesp.h
+++ b/include/acpi/acnamesp.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -263,13 +263,11 @@ u32 acpi_ns_local(acpi_object_type type)
 void
 acpi_ns_report_error(char *module_name,
 		     u32 line_number,
-		     u32 component_id,
 		     char *internal_name, acpi_status lookup_status);
 
 void
 acpi_ns_report_method_error(char *module_name,
 			    u32 line_number,
-			    u32 component_id,
 			    char *message,
 			    struct acpi_namespace_node *node,
 			    char *path, acpi_status lookup_status);
diff --git a/include/acpi/acobject.h b/include/acpi/acobject.h
index 4a326ba..d130cfe 100644
--- a/include/acpi/acobject.h
+++ b/include/acpi/acobject.h
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -69,7 +69,7 @@
 	u8                                      type;               /* acpi_object_type */\
 	u16                                     reference_count;    /* For object deletion management */\
 	union acpi_operand_object               *next_object;       /* Objects linked to parent NS node */\
-	u8                                      flags; \
+	u8                                      flags;
 
 /* Values for flag byte above */
 
diff --git a/include/acpi/acopcode.h b/include/acpi/acopcode.h
index 64da429..e6d78bd 100644
--- a/include/acpi/acopcode.h
+++ b/include/acpi/acopcode.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/acpi/acoutput.h b/include/acpi/acoutput.h
index 68d7edf..7785d48 100644
--- a/include/acpi/acoutput.h
+++ b/include/acpi/acoutput.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -137,13 +137,19 @@
 
 /* Exception level -- used in the global "debug_level" */
 
-#define ACPI_DB_ERROR               ACPI_DEBUG_LEVEL (ACPI_LV_ERROR)
-#define ACPI_DB_WARN                ACPI_DEBUG_LEVEL (ACPI_LV_WARN)
 #define ACPI_DB_INIT                ACPI_DEBUG_LEVEL (ACPI_LV_INIT)
 #define ACPI_DB_DEBUG_OBJECT        ACPI_DEBUG_LEVEL (ACPI_LV_DEBUG_OBJECT)
 #define ACPI_DB_INFO                ACPI_DEBUG_LEVEL (ACPI_LV_INFO)
 #define ACPI_DB_ALL_EXCEPTIONS      ACPI_DEBUG_LEVEL (ACPI_LV_ALL_EXCEPTIONS)
 
+/*
+ * These two levels are essentially obsolete, all instances in the
+ * ACPICA core code have been replaced by REPORT_ERROR and REPORT_WARNING
+ * (Kept here because some drivers may still use them)
+ */
+#define ACPI_DB_ERROR               ACPI_DEBUG_LEVEL (ACPI_LV_ERROR)
+#define ACPI_DB_WARN                ACPI_DEBUG_LEVEL (ACPI_LV_WARN)
+
 /* Trace level -- also used in the global "debug_level" */
 
 #define ACPI_DB_INIT_NAMES          ACPI_DEBUG_LEVEL (ACPI_LV_INIT_NAMES)
diff --git a/include/acpi/acparser.h b/include/acpi/acparser.h
index d352d40..5a1ff48 100644
--- a/include/acpi/acparser.h
+++ b/include/acpi/acparser.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/acpi/acpi.h b/include/acpi/acpi.h
index ccf34f9..b9a39d1 100644
--- a/include/acpi/acpi.h
+++ b/include/acpi/acpi.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index c1b4e1f..b425f9b 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -52,8 +52,8 @@
 /* ACPI PCI Interrupt Link (pci_link.c) */
 
 int acpi_irq_penalty_init(void);
-int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *edge_level,
-			       int *active_high_low, char **name);
+int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering,
+			       int *polarity, char **name);
 int acpi_pci_link_free_irq(acpi_handle handle);
 
 /* ACPI PCI Interrupt Routing (pci_irq.c) */
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
index 98e0b8c..970e9a6 100644
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -8,7 +8,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -108,9 +108,9 @@ acpi_status acpi_os_create_lock(acpi_han
 
 void acpi_os_delete_lock(acpi_handle handle);
 
-unsigned long acpi_os_acquire_lock(acpi_handle handle);
+acpi_cpu_flags acpi_os_acquire_lock(acpi_handle handle);
 
-void acpi_os_release_lock(acpi_handle handle, unsigned long flags);
+void acpi_os_release_lock(acpi_handle handle, acpi_cpu_flags flags);
 
 /*
  * Memory allocation and mapping
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 2a9dbc1..66cf2ec 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -149,6 +149,9 @@ acpi_detach_data(acpi_handle obj_handle,
 acpi_status
 acpi_get_data(acpi_handle obj_handle, acpi_object_handler handler, void **data);
 
+acpi_status
+acpi_debug_trace(char *name, u32 debug_level, u32 debug_layer, u32 flags);
+
 /*
  * Object manipulation and enumeration
  */
@@ -269,6 +272,12 @@ acpi_status(*ACPI_WALK_RESOURCE_CALLBACK
 					   void *context);
 
 acpi_status
+acpi_get_vendor_resource(acpi_handle device_handle,
+			 char *name,
+			 struct acpi_vendor_uuid *uuid,
+			 struct acpi_buffer *ret_buffer);
+
+acpi_status
 acpi_get_current_resources(acpi_handle device_handle,
 			   struct acpi_buffer *ret_buffer);
 
@@ -280,7 +289,7 @@ acpi_get_possible_resources(acpi_handle 
 
 acpi_status
 acpi_walk_resources(acpi_handle device_handle,
-		    char *path,
+		    char *name,
 		    ACPI_WALK_RESOURCE_CALLBACK user_function, void *context);
 
 acpi_status
diff --git a/include/acpi/acresrc.h b/include/acpi/acresrc.h
index 38e798b..fa02e80 100644
--- a/include/acpi/acresrc.h
+++ b/include/acpi/acresrc.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,216 +44,284 @@
 #ifndef __ACRESRC_H__
 #define __ACRESRC_H__
 
-/*
- *  Function prototypes called from Acpi* APIs
- */
-acpi_status
-acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer);
-
-acpi_status
-acpi_rs_get_crs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer);
+/* Need the AML resource descriptor structs */
 
-#ifdef	ACPI_FUTURE_USAGE
-acpi_status
-acpi_rs_get_prs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer);
-#endif				/* ACPI_FUTURE_USAGE */
+#include "amlresrc.h"
 
-acpi_status
-acpi_rs_get_method_data(acpi_handle handle,
-			char *path, struct acpi_buffer *ret_buffer);
+/*
+ * If possible, pack the following structures to byte alignment, since we
+ * don't care about performance for debug output
+ */
+#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED
+#pragma pack(1)
+#endif
 
-acpi_status
-acpi_rs_set_srs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer);
+/*
+ * Individual entry for the resource conversion tables
+ */
+typedef const struct acpi_rsconvert_info {
+	u8 opcode;
+	u8 resource_offset;
+	u8 aml_offset;
+	u8 value;
+
+} acpi_rsconvert_info;
+
+/* Resource conversion opcodes */
+
+#define ACPI_RSC_INITGET                0
+#define ACPI_RSC_INITSET                1
+#define ACPI_RSC_FLAGINIT               2
+#define ACPI_RSC_1BITFLAG               3
+#define ACPI_RSC_2BITFLAG               4
+#define ACPI_RSC_COUNT                  5
+#define ACPI_RSC_COUNT16                6
+#define ACPI_RSC_LENGTH                 7
+#define ACPI_RSC_MOVE8                  8
+#define ACPI_RSC_MOVE16                 9
+#define ACPI_RSC_MOVE32                 10
+#define ACPI_RSC_MOVE64                 11
+#define ACPI_RSC_SET8                   12
+#define ACPI_RSC_DATA8                  13
+#define ACPI_RSC_ADDRESS                14
+#define ACPI_RSC_SOURCE                 15
+#define ACPI_RSC_SOURCEX                16
+#define ACPI_RSC_BITMASK                17
+#define ACPI_RSC_BITMASK16              18
+#define ACPI_RSC_EXIT_NE                19
+#define ACPI_RSC_EXIT_LE                20
+
+/* Resource Conversion sub-opcodes */
+
+#define ACPI_RSC_COMPARE_AML_LENGTH     0
+#define ACPI_RSC_COMPARE_VALUE          1
+
+#define ACPI_RSC_TABLE_SIZE(d)          (sizeof (d) / sizeof (struct acpi_rsconvert_info))
+
+#define ACPI_RS_OFFSET(f)               (u8) ACPI_OFFSET (struct acpi_resource,f)
+#define AML_OFFSET(f)                   (u8) ACPI_OFFSET (union aml_resource,f)
+
+typedef const struct acpi_rsdump_info {
+	u8 opcode;
+	u8 offset;
+	char *name;
+	const char **pointer;
+
+} acpi_rsdump_info;
+
+/* Values for the Opcode field above */
+
+#define ACPI_RSD_TITLE                  0
+#define ACPI_RSD_LITERAL                1
+#define ACPI_RSD_STRING                 2
+#define ACPI_RSD_UINT8                  3
+#define ACPI_RSD_UINT16                 4
+#define ACPI_RSD_UINT32                 5
+#define ACPI_RSD_UINT64                 6
+#define ACPI_RSD_1BITFLAG               7
+#define ACPI_RSD_2BITFLAG               8
+#define ACPI_RSD_SHORTLIST              9
+#define ACPI_RSD_LONGLIST               10
+#define ACPI_RSD_DWORDLIST              11
+#define ACPI_RSD_ADDRESS                12
+#define ACPI_RSD_SOURCE                 13
+
+/* restore default alignment */
+
+#pragma pack()
+
+/* Resource tables indexed by internal resource type */
+
+extern const u8 acpi_gbl_aml_resource_sizes[];
+extern struct acpi_rsconvert_info *acpi_gbl_set_resource_dispatch[];
+
+/* Resource tables indexed by raw AML resource descriptor type */
+
+extern const u8 acpi_gbl_resource_struct_sizes[];
+extern struct acpi_rsconvert_info *acpi_gbl_get_resource_dispatch[];
+
+struct acpi_vendor_walk_info {
+	struct acpi_vendor_uuid *uuid;
+	struct acpi_buffer *buffer;
+	acpi_status status;
+};
 
+/*
+ * rscreate
+ */
 acpi_status
-acpi_rs_create_resource_list(union acpi_operand_object *byte_stream_buffer,
+acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer,
 			     struct acpi_buffer *output_buffer);
 
 acpi_status
-acpi_rs_create_byte_stream(struct acpi_resource *linked_list_buffer,
-			   struct acpi_buffer *output_buffer);
+acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer,
+			     struct acpi_buffer *output_buffer);
 
 acpi_status
 acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
 				 struct acpi_buffer *output_buffer);
 
 /*
- * rsdump
- */
-#ifdef	ACPI_FUTURE_USAGE
-void acpi_rs_dump_resource_list(struct acpi_resource *resource);
-
-void acpi_rs_dump_irq_list(u8 * route_table);
-#endif				/* ACPI_FUTURE_USAGE */
-
-/*
- * rscalc
+ * rsutils
  */
 acpi_status
-acpi_rs_get_byte_stream_start(u8 * byte_stream_buffer,
-			      u8 ** byte_stream_start, u32 * size);
-
-acpi_status
-acpi_rs_get_list_length(u8 * byte_stream_buffer,
-			u32 byte_stream_buffer_length, acpi_size * size_needed);
-
-acpi_status
-acpi_rs_get_byte_stream_length(struct acpi_resource *linked_list_buffer,
-			       acpi_size * size_needed);
-
-acpi_status
-acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
-				     acpi_size * buffer_size_needed);
-
-acpi_status
-acpi_rs_byte_stream_to_list(u8 * byte_stream_buffer,
-			    u32 byte_stream_buffer_length, u8 * output_buffer);
-
-acpi_status
-acpi_rs_list_to_byte_stream(struct acpi_resource *linked_list,
-			    acpi_size byte_stream_size_needed,
-			    u8 * output_buffer);
-
-acpi_status
-acpi_rs_io_resource(u8 * byte_stream_buffer,
-		    acpi_size * bytes_consumed,
-		    u8 ** output_buffer, acpi_size * structure_size);
-
-acpi_status
-acpi_rs_fixed_io_resource(u8 * byte_stream_buffer,
-			  acpi_size * bytes_consumed,
-			  u8 ** output_buffer, acpi_size * structure_size);
-
-acpi_status
-acpi_rs_io_stream(struct acpi_resource *linked_list,
-		  u8 ** output_buffer, acpi_size * bytes_consumed);
-
-acpi_status
-acpi_rs_fixed_io_stream(struct acpi_resource *linked_list,
-			u8 ** output_buffer, acpi_size * bytes_consumed);
-
-acpi_status
-acpi_rs_irq_resource(u8 * byte_stream_buffer,
-		     acpi_size * bytes_consumed,
-		     u8 ** output_buffer, acpi_size * structure_size);
-
-acpi_status
-acpi_rs_irq_stream(struct acpi_resource *linked_list,
-		   u8 ** output_buffer, acpi_size * bytes_consumed);
-
-acpi_status
-acpi_rs_dma_resource(u8 * byte_stream_buffer,
-		     acpi_size * bytes_consumed,
-		     u8 ** output_buffer, acpi_size * structure_size);
-
-acpi_status
-acpi_rs_dma_stream(struct acpi_resource *linked_list,
-		   u8 ** output_buffer, acpi_size * bytes_consumed);
-
-acpi_status
-acpi_rs_address16_resource(u8 * byte_stream_buffer,
-			   acpi_size * bytes_consumed,
-			   u8 ** output_buffer, acpi_size * structure_size);
-
-acpi_status
-acpi_rs_address16_stream(struct acpi_resource *linked_list,
-			 u8 ** output_buffer, acpi_size * bytes_consumed);
-
-acpi_status
-acpi_rs_address32_resource(u8 * byte_stream_buffer,
-			   acpi_size * bytes_consumed,
-			   u8 ** output_buffer, acpi_size * structure_size);
-
-acpi_status
-acpi_rs_address32_stream(struct acpi_resource *linked_list,
-			 u8 ** output_buffer, acpi_size * bytes_consumed);
-
-acpi_status
-acpi_rs_address64_resource(u8 * byte_stream_buffer,
-			   acpi_size * bytes_consumed,
-			   u8 ** output_buffer, acpi_size * structure_size);
+acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer);
 
 acpi_status
-acpi_rs_address64_stream(struct acpi_resource *linked_list,
-			 u8 ** output_buffer, acpi_size * bytes_consumed);
+acpi_rs_get_crs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer);
 
+#ifdef	ACPI_FUTURE_USAGE
 acpi_status
-acpi_rs_start_depend_fns_resource(u8 * byte_stream_buffer,
-				  acpi_size * bytes_consumed,
-				  u8 ** output_buffer,
-				  acpi_size * structure_size);
+acpi_rs_get_prs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer);
+#endif				/* ACPI_FUTURE_USAGE */
 
 acpi_status
-acpi_rs_end_depend_fns_resource(u8 * byte_stream_buffer,
-				acpi_size * bytes_consumed,
-				u8 ** output_buffer,
-				acpi_size * structure_size);
+acpi_rs_get_method_data(acpi_handle handle,
+			char *path, struct acpi_buffer *ret_buffer);
 
 acpi_status
-acpi_rs_start_depend_fns_stream(struct acpi_resource *linked_list,
-				u8 ** output_buffer,
-				acpi_size * bytes_consumed);
+acpi_rs_set_srs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer);
 
+/*
+ * rscalc
+ */
 acpi_status
-acpi_rs_end_depend_fns_stream(struct acpi_resource *linked_list,
-			      u8 ** output_buffer, acpi_size * bytes_consumed);
+acpi_rs_get_list_length(u8 * aml_buffer,
+			u32 aml_buffer_length, acpi_size * size_needed);
 
 acpi_status
-acpi_rs_memory24_resource(u8 * byte_stream_buffer,
-			  acpi_size * bytes_consumed,
-			  u8 ** output_buffer, acpi_size * structure_size);
+acpi_rs_get_aml_length(struct acpi_resource *linked_list_buffer,
+		       acpi_size * size_needed);
 
 acpi_status
-acpi_rs_memory24_stream(struct acpi_resource *linked_list,
-			u8 ** output_buffer, acpi_size * bytes_consumed);
+acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
+				     acpi_size * buffer_size_needed);
 
 acpi_status
-acpi_rs_memory32_range_resource(u8 * byte_stream_buffer,
-				acpi_size * bytes_consumed,
-				u8 ** output_buffer,
-				acpi_size * structure_size);
+acpi_rs_convert_aml_to_resources(u8 * aml_buffer,
+				 u32 aml_buffer_length, u8 * output_buffer);
 
 acpi_status
-acpi_rs_fixed_memory32_resource(u8 * byte_stream_buffer,
-				acpi_size * bytes_consumed,
-				u8 ** output_buffer,
-				acpi_size * structure_size);
+acpi_rs_convert_resources_to_aml(struct acpi_resource *resource,
+				 acpi_size aml_size_needed, u8 * output_buffer);
 
-acpi_status
-acpi_rs_memory32_range_stream(struct acpi_resource *linked_list,
-			      u8 ** output_buffer, acpi_size * bytes_consumed);
+/*
+ * rsaddr
+ */
+void
+acpi_rs_set_address_common(union aml_resource *aml,
+			   struct acpi_resource *resource);
+
+u8
+acpi_rs_get_address_common(struct acpi_resource *resource,
+			   union aml_resource *aml);
 
+/*
+ * rsmisc
+ */
 acpi_status
-acpi_rs_fixed_memory32_stream(struct acpi_resource *linked_list,
-			      u8 ** output_buffer, acpi_size * bytes_consumed);
+acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
+				union aml_resource *aml,
+				struct acpi_rsconvert_info *info);
 
 acpi_status
-acpi_rs_extended_irq_resource(u8 * byte_stream_buffer,
-			      acpi_size * bytes_consumed,
-			      u8 ** output_buffer, acpi_size * structure_size);
+acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
+				union aml_resource *aml,
+				struct acpi_rsconvert_info *info);
 
-acpi_status
-acpi_rs_extended_irq_stream(struct acpi_resource *linked_list,
-			    u8 ** output_buffer, acpi_size * bytes_consumed);
+/*
+ * rsutils
+ */
+void
+acpi_rs_move_data(void *destination,
+		  void *source, u16 item_count, u8 move_type);
+
+u8 acpi_rs_decode_bitmask(u16 mask, u8 * list);
+
+u16 acpi_rs_encode_bitmask(u8 * list, u8 count);
+
+acpi_rs_length
+acpi_rs_get_resource_source(acpi_rs_length resource_length,
+			    acpi_rs_length minimum_length,
+			    struct acpi_resource_source *resource_source,
+			    union aml_resource *aml, char *string_ptr);
+
+acpi_rsdesc_size
+acpi_rs_set_resource_source(union aml_resource *aml,
+			    acpi_rs_length minimum_length,
+			    struct acpi_resource_source *resource_source);
+
+void
+acpi_rs_set_resource_header(u8 descriptor_type,
+			    acpi_rsdesc_size total_length,
+			    union aml_resource *aml);
+
+void
+acpi_rs_set_resource_length(acpi_rsdesc_size total_length,
+			    union aml_resource *aml);
 
-acpi_status
-acpi_rs_end_tag_resource(u8 * byte_stream_buffer,
-			 acpi_size * bytes_consumed,
-			 u8 ** output_buffer, acpi_size * structure_size);
+/*
+ * rsdump
+ */
+void acpi_rs_dump_resource_list(struct acpi_resource *resource);
 
-acpi_status
-acpi_rs_end_tag_stream(struct acpi_resource *linked_list,
-		       u8 ** output_buffer, acpi_size * bytes_consumed);
+void acpi_rs_dump_irq_list(u8 * route_table);
 
-acpi_status
-acpi_rs_vendor_resource(u8 * byte_stream_buffer,
-			acpi_size * bytes_consumed,
-			u8 ** output_buffer, acpi_size * structure_size);
+/*
+ * Resource conversion tables
+ */
+extern struct acpi_rsconvert_info acpi_rs_convert_dma[];
+extern struct acpi_rsconvert_info acpi_rs_convert_end_dpf[];
+extern struct acpi_rsconvert_info acpi_rs_convert_io[];
+extern struct acpi_rsconvert_info acpi_rs_convert_fixed_io[];
+extern struct acpi_rsconvert_info acpi_rs_convert_end_tag[];
+extern struct acpi_rsconvert_info acpi_rs_convert_memory24[];
+extern struct acpi_rsconvert_info acpi_rs_convert_generic_reg[];
+extern struct acpi_rsconvert_info acpi_rs_convert_memory32[];
+extern struct acpi_rsconvert_info acpi_rs_convert_fixed_memory32[];
+extern struct acpi_rsconvert_info acpi_rs_convert_address32[];
+extern struct acpi_rsconvert_info acpi_rs_convert_address16[];
+extern struct acpi_rsconvert_info acpi_rs_convert_ext_irq[];
+extern struct acpi_rsconvert_info acpi_rs_convert_address64[];
+extern struct acpi_rsconvert_info acpi_rs_convert_ext_address64[];
+
+/* These resources require separate get/set tables */
+
+extern struct acpi_rsconvert_info acpi_rs_get_irq[];
+extern struct acpi_rsconvert_info acpi_rs_get_start_dpf[];
+extern struct acpi_rsconvert_info acpi_rs_get_vendor_small[];
+extern struct acpi_rsconvert_info acpi_rs_get_vendor_large[];
+
+extern struct acpi_rsconvert_info acpi_rs_set_irq[];
+extern struct acpi_rsconvert_info acpi_rs_set_start_dpf[];
+extern struct acpi_rsconvert_info acpi_rs_set_vendor[];
 
-acpi_status
-acpi_rs_vendor_stream(struct acpi_resource *linked_list,
-		      u8 ** output_buffer, acpi_size * bytes_consumed);
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+/*
+ * rsinfo
+ */
+extern struct acpi_rsdump_info *acpi_gbl_dump_resource_dispatch[];
 
-u8 acpi_rs_get_resource_type(u8 resource_start_byte);
+/*
+ * rsdump
+ */
+extern struct acpi_rsdump_info acpi_rs_dump_irq[];
+extern struct acpi_rsdump_info acpi_rs_dump_dma[];
+extern struct acpi_rsdump_info acpi_rs_dump_start_dpf[];
+extern struct acpi_rsdump_info acpi_rs_dump_end_dpf[];
+extern struct acpi_rsdump_info acpi_rs_dump_io[];
+extern struct acpi_rsdump_info acpi_rs_dump_fixed_io[];
+extern struct acpi_rsdump_info acpi_rs_dump_vendor[];
+extern struct acpi_rsdump_info acpi_rs_dump_end_tag[];
+extern struct acpi_rsdump_info acpi_rs_dump_memory24[];
+extern struct acpi_rsdump_info acpi_rs_dump_memory32[];
+extern struct acpi_rsdump_info acpi_rs_dump_fixed_memory32[];
+extern struct acpi_rsdump_info acpi_rs_dump_address16[];
+extern struct acpi_rsdump_info acpi_rs_dump_address32[];
+extern struct acpi_rsdump_info acpi_rs_dump_address64[];
+extern struct acpi_rsdump_info acpi_rs_dump_ext_address64[];
+extern struct acpi_rsdump_info acpi_rs_dump_ext_irq[];
+extern struct acpi_rsdump_info acpi_rs_dump_generic_reg[];
+#endif
 
 #endif				/* __ACRESRC_H__ */
diff --git a/include/acpi/acstruct.h b/include/acpi/acstruct.h
index 99d2353..d8c1c2c 100644
--- a/include/acpi/acstruct.h
+++ b/include/acpi/acstruct.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/acpi/actables.h b/include/acpi/actables.h
index f92c185..30a4754 100644
--- a/include/acpi/actables.h
+++ b/include/acpi/actables.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h
index a46f406..ed53f84 100644
--- a/include/acpi/actbl.h
+++ b/include/acpi/actbl.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -45,6 +45,12 @@
 #define __ACTBL_H__
 
 /*
+ * Note about bitfields: The u8 type is used for bitfields in ACPI tables.
+ * This is the only type that is even remotely portable. Anything else is not
+ * portable, so do not use any other bitfield types.
+ */
+
+/*
  *  Values for description table header signatures
  */
 #define RSDP_NAME               "RSDP"
diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
index 67312c3..cd428d5 100644
--- a/include/acpi/actbl1.h
+++ b/include/acpi/actbl1.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
index 50305ce..dfc7ac1 100644
--- a/include/acpi/actbl2.h
+++ b/include/acpi/actbl2.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index 6213b27..7ca89cd 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,7 +44,15 @@
 #ifndef __ACTYPES_H__
 #define __ACTYPES_H__
 
-/*! [Begin] no source code translation (keep the typedefs) */
+/*
+ * ACPI_MACHINE_WIDTH must be specified in an OS- or compiler-dependent header
+ * and must be either 16, 32, or 64
+ */
+#ifndef ACPI_MACHINE_WIDTH
+#error ACPI_MACHINE_WIDTH not defined
+#endif
+
+/*! [Begin] no source code translation */
 
 /*
  * Data type ranges
@@ -58,87 +66,150 @@
 #define ACPI_UINT64_MAX                 (UINT64)(~((UINT64) 0))	/* 0xFFFFFFFFFFFFFFFF */
 #define ACPI_ASCII_MAX                  0x7F
 
-#ifdef DEFINE_ALTERNATE_TYPES
 /*
- * Types used only in translated source, defined here to enable
- * cross-platform compilation only.
+ * Architecture-specific ACPICA Subsystem Data Types
+ *
+ * The goal of these types is to provide source code portability across
+ * 16-bit, 32-bit, and 64-bit targets.
+ *
+ * 1) The following types are of fixed size for all targets (16/32/64):
+ *
+ * BOOLEAN      Logical boolean
+ *
+ * UINT8        8-bit  (1 byte) unsigned value
+ * UINT16       16-bit (2 byte) unsigned value
+ * UINT32       32-bit (4 byte) unsigned value
+ * UINT64       64-bit (8 byte) unsigned value
+ *
+ * INT16        16-bit (2 byte) signed value
+ * INT32        32-bit (4 byte) signed value
+ * INT64        64-bit (8 byte) signed value
+ *
+ * COMPILER_DEPENDENT_UINT64/INT64 - These types are defined in the
+ * compiler-dependent header(s) and were introduced because there is no common
+ * 64-bit integer type across the various compilation models, as shown in
+ * the table below.
+ *
+ * Datatype  LP64 ILP64 LLP64 ILP32 LP32 16bit
+ * char      8    8     8     8     8    8
+ * short     16   16    16    16    16   16
+ * _int32         32
+ * int       32   64    32    32    16   16
+ * long      64   64    32    32    32   32
+ * long long            64    64
+ * pointer   64   64    64    32    32   32
+ *
+ * Note: ILP64 and LP32 are currently not supported.
+ *
+ *
+ * 2) These types represent the native word size of the target mode of the
+ * processor, and may be 16-bit, 32-bit, or 64-bit as required. They are
+ * usually used for memory allocation, efficient loop counters, and array
+ * indexes. The types are similar to the size_t type in the C library and are
+ * required because there is no C type that consistently represents the native
+ * data width.
+ *
+ * ACPI_SIZE        16/32/64-bit unsigned value
+ * ACPI_NATIVE_UINT 16/32/64-bit unsigned value
+ * ACPI_NATIVE_INT  16/32/64-bit signed value
+ *
  */
-typedef int s32;
-typedef unsigned char u8;
-typedef unsigned short u16;
-typedef unsigned int u32;
-typedef COMPILER_DEPENDENT_UINT64 u64;
-
-#endif
 
-/*
- * Data types - Fixed across all compilation models (16/32/64)
+/*******************************************************************************
  *
- * BOOLEAN          Logical Boolean.
- * INT8             8-bit  (1 byte) signed value
- * UINT8            8-bit  (1 byte) unsigned value
- * INT16            16-bit (2 byte) signed value
- * UINT16           16-bit (2 byte) unsigned value
- * INT32            32-bit (4 byte) signed value
- * UINT32           32-bit (4 byte) unsigned value
- * INT64            64-bit (8 byte) signed value
- * UINT64           64-bit (8 byte) unsigned value
- * ACPI_NATIVE_INT  32-bit on IA-32, 64-bit on IA-64 signed value
- * ACPI_NATIVE_UINT 32-bit on IA-32, 64-bit on IA-64 unsigned value
- */
+ * Common types for all compilers, all targets
+ *
+ ******************************************************************************/
 
-#ifndef ACPI_MACHINE_WIDTH
-#error ACPI_MACHINE_WIDTH not defined
-#endif
+typedef unsigned char BOOLEAN;
+typedef unsigned char UINT8;
+typedef unsigned short UINT16;
+typedef COMPILER_DEPENDENT_UINT64 UINT64;
+typedef COMPILER_DEPENDENT_INT64 INT64;
+
+/*! [End] no source code translation !*/
+
+/*******************************************************************************
+ *
+ * Types specific to 64-bit targets
+ *
+ ******************************************************************************/
 
 #if ACPI_MACHINE_WIDTH == 64
 
-/*! [Begin] no source code translation (keep the typedefs) */
+/*! [Begin] no source code translation (keep the typedefs as-is) */
 
-/*
- * 64-bit type definitions
- */
-typedef unsigned char UINT8;
-typedef unsigned char BOOLEAN;
-typedef unsigned short UINT16;
-typedef int INT32;
 typedef unsigned int UINT32;
-typedef COMPILER_DEPENDENT_INT64 INT64;
-typedef COMPILER_DEPENDENT_UINT64 UINT64;
+typedef int INT32;
 
 /*! [End] no source code translation !*/
 
-typedef s64 acpi_native_int;
 typedef u64 acpi_native_uint;
+typedef s64 acpi_native_int;
 
 typedef u64 acpi_table_ptr;
 typedef u64 acpi_io_address;
 typedef u64 acpi_physical_address;
-typedef u64 acpi_size;
 
-#define ALIGNED_ADDRESS_BOUNDARY        0x00000008	/* No hardware alignment support in IA64 */
-#define ACPI_USE_NATIVE_DIVIDE	/* Native 64-bit integer support */
 #define ACPI_MAX_PTR                    ACPI_UINT64_MAX
 #define ACPI_SIZE_MAX                   ACPI_UINT64_MAX
 
-#elif ACPI_MACHINE_WIDTH == 16
-
-/*! [Begin] no source code translation (keep the typedefs) */
+#define ALIGNED_ADDRESS_BOUNDARY        0x00000008
+#define ACPI_USE_NATIVE_DIVIDE	/* Has native 64-bit integer support */
 
 /*
- * 16-bit type definitions
+ * In the case of the Itanium Processor Family (IPF), the hardware does not
+ * support misaligned memory transfers. Set the MISALIGNMENT_NOT_SUPPORTED flag
+ * to indicate that special precautions must be taken to avoid alignment faults.
+ * (IA64 or ia64 is currently used by existing compilers to indicate IPF.)
+ *
+ * Note: Em64_t and other X86-64 processors support misaligned transfers,
+ * so there is no need to define this flag.
  */
-typedef unsigned char UINT8;
-typedef unsigned char BOOLEAN;
-typedef unsigned int UINT16;
-typedef long INT32;
-typedef int INT16;
-typedef unsigned long UINT32;
+#if defined (__IA64__) || defined (__ia64__)
+#define ACPI_MISALIGNMENT_NOT_SUPPORTED
+#endif
 
-struct {
-	UINT32 Lo;
-	UINT32 Hi;
-};
+/*******************************************************************************
+ *
+ * Types specific to 32-bit targets
+ *
+ ******************************************************************************/
+
+#elif ACPI_MACHINE_WIDTH == 32
+
+/*! [Begin] no source code translation (keep the typedefs as-is) */
+
+typedef unsigned int UINT32;
+typedef int INT32;
+
+/*! [End] no source code translation !*/
+
+typedef u32 acpi_native_uint;
+typedef s32 acpi_native_int;
+
+typedef u64 acpi_table_ptr;
+typedef u32 acpi_io_address;
+typedef u64 acpi_physical_address;
+
+#define ACPI_MAX_PTR                    ACPI_UINT32_MAX
+#define ACPI_SIZE_MAX                   ACPI_UINT32_MAX
+
+#define ALIGNED_ADDRESS_BOUNDARY        0x00000004
+
+/*******************************************************************************
+ *
+ * Types specific to 16-bit targets
+ *
+ ******************************************************************************/
+
+#elif ACPI_MACHINE_WIDTH == 16
+
+/*! [Begin] no source code translation (keep the typedefs as-is) */
+
+typedef unsigned long UINT32;
+typedef short INT16;
+typedef long INT32;
 
 /*! [End] no source code translation !*/
 
@@ -148,61 +219,84 @@ typedef s16 acpi_native_int;
 typedef u32 acpi_table_ptr;
 typedef u32 acpi_io_address;
 typedef char *acpi_physical_address;
-typedef u16 acpi_size;
 
-#define ALIGNED_ADDRESS_BOUNDARY        0x00000002
-#define ACPI_MISALIGNED_TRANSFERS
-#define ACPI_USE_NATIVE_DIVIDE	/* No 64-bit integers, ok to use native divide */
 #define ACPI_MAX_PTR                    ACPI_UINT16_MAX
 #define ACPI_SIZE_MAX                   ACPI_UINT16_MAX
 
-/*
- * (16-bit only) internal integers must be 32-bits, so
- * 64-bit integers cannot be supported
- */
+#define ALIGNED_ADDRESS_BOUNDARY        0x00000002
+#define ACPI_USE_NATIVE_DIVIDE	/* No 64-bit integers, ok to use native divide */
+
+/* 64-bit integers cannot be supported */
+
 #define ACPI_NO_INTEGER64_SUPPORT
 
-#elif ACPI_MACHINE_WIDTH == 32
+#else
 
-/*! [Begin] no source code translation (keep the typedefs) */
+/* ACPI_MACHINE_WIDTH must be either 64, 32, or 16 */
 
-/*
- * 32-bit type definitions (default)
- */
-typedef unsigned char UINT8;
-typedef unsigned char BOOLEAN;
-typedef unsigned short UINT16;
-typedef int INT32;
-typedef unsigned int UINT32;
-typedef COMPILER_DEPENDENT_INT64 INT64;
-typedef COMPILER_DEPENDENT_UINT64 UINT64;
+#error unknown ACPI_MACHINE_WIDTH
+#endif
 
-/*! [End] no source code translation !*/
+/* Variable-width type, used instead of clib size_t */
 
-typedef s32 acpi_native_int;
-typedef u32 acpi_native_uint;
+typedef acpi_native_uint acpi_size;
 
-typedef u64 acpi_table_ptr;
-typedef u32 acpi_io_address;
-typedef u64 acpi_physical_address;
-typedef u32 acpi_size;
+/*******************************************************************************
+ *
+ * OS- or compiler-dependent types
+ *
+ * If the defaults below are not appropriate for the host system, they can
+ * be defined in the compiler-specific or OS-specific header, and this will
+ * take precedence.
+ *
+ ******************************************************************************/
 
-#define ALIGNED_ADDRESS_BOUNDARY        0x00000004
-#define ACPI_MISALIGNED_TRANSFERS
-#define ACPI_MAX_PTR                    ACPI_UINT32_MAX
-#define ACPI_SIZE_MAX                   ACPI_UINT32_MAX
+/* Use C99 uintptr_t for pointer casting if available, "void *" otherwise */
 
-#else
-#error unknown ACPI_MACHINE_WIDTH
+#ifndef acpi_uintptr_t
+#define acpi_uintptr_t                          void *
 #endif
 
 /*
- * This type is used for bitfields in ACPI tables. The only type that is
- * even remotely portable is u8. Anything else is not portable, so
- * do not add any more bitfield types.
+ * If acpi_cache_t was not defined in the OS-dependent header,
+ * define it now. This is typically the case where the local cache
+ * manager implementation is to be used (ACPI_USE_LOCAL_CACHE)
+ */
+#ifndef acpi_cache_t
+#define acpi_cache_t                            struct acpi_memory_list
+#endif
+
+/*
+ * Allow the CPU flags word to be defined per-OS to simplify the use of the
+ * lock and unlock OSL interfaces.
+ */
+#ifndef acpi_cpu_flags
+#define acpi_cpu_flags                          acpi_native_uint
+#endif
+
+/*
+ * ACPI_PRINTF_LIKE is used to tag functions as "printf-like" because
+ * some compilers can catch printf format string problems
  */
-typedef u8 UINT8_BIT;
-typedef acpi_native_uint ACPI_PTRDIFF;
+#ifndef ACPI_PRINTF_LIKE
+#define ACPI_PRINTF_LIKE(c)
+#endif
+
+/*
+ * Some compilers complain about unused variables. Sometimes we don't want to
+ * use all the variables (for example, _acpi_module_name). This allows us
+ * to to tell the compiler in a per-variable manner that a variable
+ * is unused
+ */
+#ifndef ACPI_UNUSED_VAR
+#define ACPI_UNUSED_VAR
+#endif
+
+/*******************************************************************************
+ *
+ * Independent types
+ *
+ ******************************************************************************/
 
 /*
  * Pointer overlays to avoid lots of typecasting for
@@ -234,18 +328,8 @@ struct acpi_pointer {
 #define ACPI_LOGMODE_PHYSPTR            ACPI_LOGICAL_ADDRESSING  | ACPI_PHYSICAL_POINTER
 #define ACPI_LOGMODE_LOGPTR             ACPI_LOGICAL_ADDRESSING  | ACPI_LOGICAL_POINTER
 
-/*
- * If acpi_cache_t was not defined in the OS-dependent header,
- * define it now. This is typically the case where the local cache
- * manager implementation is to be used (ACPI_USE_LOCAL_CACHE)
- */
-#ifndef acpi_cache_t
-#define acpi_cache_t                            struct acpi_memory_list
-#endif
+/* Logical defines and NULL */
 
-/*
- * Useful defines
- */
 #ifdef FALSE
 #undef FALSE
 #endif
@@ -261,12 +345,12 @@ struct acpi_pointer {
 #endif
 
 /*
- * Local datatypes
+ * Mescellaneous types
  */
 typedef u32 acpi_status;	/* All ACPI Exceptions */
 typedef u32 acpi_name;		/* 4-byte ACPI name */
 typedef char *acpi_string;	/* Null terminated ASCII string */
-typedef void *acpi_handle;	/* Actually a ptr to an Node */
+typedef void *acpi_handle;	/* Actually a ptr to a NS Node */
 
 struct uint64_struct {
 	u32 lo;
@@ -323,7 +407,7 @@ typedef u64 acpi_integer;
 /*
  * Constants with special meanings
  */
-#define ACPI_ROOT_OBJECT                (acpi_handle) ACPI_PTR_ADD (char, NULL, ACPI_MAX_PTR)
+#define ACPI_ROOT_OBJECT                ACPI_ADD_PTR (acpi_handle, NULL, ACPI_MAX_PTR)
 
 /*
  * Initialization sequence
@@ -470,37 +554,6 @@ typedef u32 acpi_object_type;
 #define ACPI_TYPE_NOT_FOUND             0xFF
 
 /*
- * Bitmapped ACPI types.  Used internally only
- */
-#define ACPI_BTYPE_ANY                  0x00000000
-#define ACPI_BTYPE_INTEGER              0x00000001
-#define ACPI_BTYPE_STRING               0x00000002
-#define ACPI_BTYPE_BUFFER               0x00000004
-#define ACPI_BTYPE_PACKAGE              0x00000008
-#define ACPI_BTYPE_FIELD_UNIT           0x00000010
-#define ACPI_BTYPE_DEVICE               0x00000020
-#define ACPI_BTYPE_EVENT                0x00000040
-#define ACPI_BTYPE_METHOD               0x00000080
-#define ACPI_BTYPE_MUTEX                0x00000100
-#define ACPI_BTYPE_REGION               0x00000200
-#define ACPI_BTYPE_POWER                0x00000400
-#define ACPI_BTYPE_PROCESSOR            0x00000800
-#define ACPI_BTYPE_THERMAL              0x00001000
-#define ACPI_BTYPE_BUFFER_FIELD         0x00002000
-#define ACPI_BTYPE_DDB_HANDLE           0x00004000
-#define ACPI_BTYPE_DEBUG_OBJECT         0x00008000
-#define ACPI_BTYPE_REFERENCE            0x00010000
-#define ACPI_BTYPE_RESOURCE             0x00020000
-
-#define ACPI_BTYPE_COMPUTE_DATA         (ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER)
-
-#define ACPI_BTYPE_DATA                 (ACPI_BTYPE_COMPUTE_DATA  | ACPI_BTYPE_PACKAGE)
-#define ACPI_BTYPE_DATA_REFERENCE       (ACPI_BTYPE_DATA | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE)
-#define ACPI_BTYPE_DEVICE_OBJECTS       (ACPI_BTYPE_DEVICE | ACPI_BTYPE_THERMAL | ACPI_BTYPE_PROCESSOR)
-#define ACPI_BTYPE_OBJECTS_AND_REFS     0x0001FFFF	/* ARG or LOCAL */
-#define ACPI_BTYPE_ALL_OBJECTS          0x0000FFFF
-
-/*
  * All I/O
  */
 #define ACPI_READ                       0
@@ -853,6 +906,14 @@ struct acpi_compatible_id_list {
 #define ACPI_VALID_CID                  0x0010
 #define ACPI_VALID_SXDS                 0x0020
 
+/* Flags for _STA method */
+
+#define ACPI_STA_DEVICE_PRESENT         0x01
+#define ACPI_STA_DEVICE_ENABLED         0x02
+#define ACPI_STA_DEVICE_UI              0x04
+#define ACPI_STA_DEVICE_OK              0x08
+#define ACPI_STA_BATTERY_PRESENT        0x10
+
 #define ACPI_COMMON_OBJ_INFO \
 	acpi_object_type                    type;           /* ACPI object type */ \
 	acpi_name                           name	/* ACPI object Name */
@@ -895,6 +956,8 @@ struct acpi_mem_space_context {
 /*
  * Definitions for Resource Attributes
  */
+typedef u16 acpi_rs_length;	/* Resource Length field is fixed at 16 bits */
+typedef u32 acpi_rsdesc_size;	/* Max Resource Descriptor size is (length+3) = (64_k-1)+3 */
 
 /*
  *  Memory Attributes
@@ -916,7 +979,9 @@ struct acpi_mem_space_context {
 #define ACPI_ISA_ONLY_RANGES            (u8) 0x02
 #define ACPI_ENTIRE_RANGE               (ACPI_NON_ISA_ONLY_RANGES | ACPI_ISA_ONLY_RANGES)
 
-#define ACPI_SPARSE_TRANSLATION         (u8) 0x03
+/* Type of translation - 1=Sparse, 0=Dense */
+
+#define ACPI_SPARSE_TRANSLATION         (u8) 0x01
 
 /*
  *  IO Port Descriptor Decode
@@ -927,8 +992,8 @@ struct acpi_mem_space_context {
 /*
  *  IRQ Attributes
  */
-#define ACPI_EDGE_SENSITIVE             (u8) 0x00
-#define ACPI_LEVEL_SENSITIVE            (u8) 0x01
+#define ACPI_LEVEL_SENSITIVE            (u8) 0x00
+#define ACPI_EDGE_SENSITIVE             (u8) 0x01
 
 #define ACPI_ACTIVE_HIGH                (u8) 0x00
 #define ACPI_ACTIVE_LOW                 (u8) 0x01
@@ -975,27 +1040,45 @@ struct acpi_mem_space_context {
 #define ACPI_CONSUMER                   (u8) 0x01
 
 /*
+ * If possible, pack the following structures to byte alignment
+ */
+#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED
+#pragma pack(1)
+#endif
+
+/* UUID data structures for use in vendor-defined resource descriptors */
+
+struct acpi_uuid {
+	u8 data[ACPI_UUID_LENGTH];
+};
+
+struct acpi_vendor_uuid {
+	u8 subtype;
+	u8 data[ACPI_UUID_LENGTH];
+};
+
+/*
  *  Structures used to describe device resources
  */
 struct acpi_resource_irq {
-	u32 edge_level;
-	u32 active_high_low;
-	u32 shared_exclusive;
-	u32 number_of_interrupts;
-	u32 interrupts[1];
+	u8 triggering;
+	u8 polarity;
+	u8 sharable;
+	u8 interrupt_count;
+	u8 interrupts[1];
 };
 
 struct acpi_resource_dma {
-	u32 type;
-	u32 bus_master;
-	u32 transfer;
-	u32 number_of_channels;
-	u32 channels[1];
+	u8 type;
+	u8 bus_master;
+	u8 transfer;
+	u8 channel_count;
+	u8 channels[1];
 };
 
-struct acpi_resource_start_dpf {
-	u32 compatibility_priority;
-	u32 performance_robustness;
+struct acpi_resource_start_dependent {
+	u8 compatibility_priority;
+	u8 performance_robustness;
 };
 
 /*
@@ -1004,179 +1087,217 @@ struct acpi_resource_start_dpf {
  */
 
 struct acpi_resource_io {
-	u32 io_decode;
-	u32 min_base_address;
-	u32 max_base_address;
-	u32 alignment;
-	u32 range_length;
+	u8 io_decode;
+	u8 alignment;
+	u8 address_length;
+	u16 minimum;
+	u16 maximum;
 };
 
 struct acpi_resource_fixed_io {
-	u32 base_address;
-	u32 range_length;
+	u16 address;
+	u8 address_length;
 };
 
 struct acpi_resource_vendor {
-	u32 length;
-	u8 reserved[1];
+	u16 byte_length;
+	u8 byte_data[1];
+};
+
+/* Vendor resource with UUID info (introduced in ACPI 3.0) */
+
+struct acpi_resource_vendor_typed {
+	u16 byte_length;
+	u8 uuid_subtype;
+	u8 uuid[ACPI_UUID_LENGTH];
+	u8 byte_data[1];
 };
 
 struct acpi_resource_end_tag {
 	u8 checksum;
 };
 
-struct acpi_resource_mem24 {
-	u32 read_write_attribute;
-	u32 min_base_address;
-	u32 max_base_address;
-	u32 alignment;
-	u32 range_length;
+struct acpi_resource_memory24 {
+	u8 write_protect;
+	u16 minimum;
+	u16 maximum;
+	u16 alignment;
+	u16 address_length;
 };
 
-struct acpi_resource_mem32 {
-	u32 read_write_attribute;
-	u32 min_base_address;
-	u32 max_base_address;
+struct acpi_resource_memory32 {
+	u8 write_protect;
+	u32 minimum;
+	u32 maximum;
 	u32 alignment;
-	u32 range_length;
+	u32 address_length;
 };
 
-struct acpi_resource_fixed_mem32 {
-	u32 read_write_attribute;
-	u32 range_base_address;
-	u32 range_length;
+struct acpi_resource_fixed_memory32 {
+	u8 write_protect;
+	u32 address;
+	u32 address_length;
 };
 
 struct acpi_memory_attribute {
-	u16 cache_attribute;
-	u16 read_write_attribute;
+	u8 write_protect;
+	u8 caching;
+	u8 range_type;
+	u8 translation;
 };
 
 struct acpi_io_attribute {
-	u16 range_attribute;
-	u16 translation_attribute;
-};
-
-struct acpi_bus_attribute {
-	u16 reserved1;
-	u16 reserved2;
+	u8 range_type;
+	u8 translation;
+	u8 translation_type;
+	u8 reserved1;
 };
 
 union acpi_resource_attribute {
-	struct acpi_memory_attribute memory;
+	struct acpi_memory_attribute mem;
 	struct acpi_io_attribute io;
-	struct acpi_bus_attribute bus;
+
+	/* Used for the *word_space macros */
+
+	u8 type_specific;
 };
 
 struct acpi_resource_source {
-	u32 index;
-	u32 string_length;
+	u8 index;
+	u16 string_length;
 	char *string_ptr;
 };
 
 /* Fields common to all address descriptors, 16/32/64 bit */
 
 #define ACPI_RESOURCE_ADDRESS_COMMON \
-	u32                                 resource_type; \
-	u32                                 producer_consumer; \
-	u32                                 decode; \
-	u32                                 min_address_fixed; \
-	u32                                 max_address_fixed; \
-	union acpi_resource_attribute       attribute;
+	u8                                  resource_type; \
+	u8                                  producer_consumer; \
+	u8                                  decode; \
+	u8                                  min_address_fixed; \
+	u8                                  max_address_fixed; \
+	union acpi_resource_attribute       info;
 
 struct acpi_resource_address {
 ACPI_RESOURCE_ADDRESS_COMMON};
 
 struct acpi_resource_address16 {
-	ACPI_RESOURCE_ADDRESS_COMMON u32 granularity;
-	u32 min_address_range;
-	u32 max_address_range;
-	u32 address_translation_offset;
-	u32 address_length;
+	ACPI_RESOURCE_ADDRESS_COMMON u16 granularity;
+	u16 minimum;
+	u16 maximum;
+	u16 translation_offset;
+	u16 address_length;
 	struct acpi_resource_source resource_source;
 };
 
 struct acpi_resource_address32 {
 	ACPI_RESOURCE_ADDRESS_COMMON u32 granularity;
-	u32 min_address_range;
-	u32 max_address_range;
-	u32 address_translation_offset;
+	u32 minimum;
+	u32 maximum;
+	u32 translation_offset;
 	u32 address_length;
 	struct acpi_resource_source resource_source;
 };
 
 struct acpi_resource_address64 {
 	ACPI_RESOURCE_ADDRESS_COMMON u64 granularity;
-	u64 min_address_range;
-	u64 max_address_range;
-	u64 address_translation_offset;
+	u64 minimum;
+	u64 maximum;
+	u64 translation_offset;
 	u64 address_length;
-	u64 type_specific_attributes;
 	struct acpi_resource_source resource_source;
 };
 
-struct acpi_resource_ext_irq {
-	u32 producer_consumer;
-	u32 edge_level;
-	u32 active_high_low;
-	u32 shared_exclusive;
-	u32 number_of_interrupts;
+struct acpi_resource_extended_address64 {
+	ACPI_RESOURCE_ADDRESS_COMMON u8 revision_iD;
+	u64 granularity;
+	u64 minimum;
+	u64 maximum;
+	u64 translation_offset;
+	u64 address_length;
+	u64 type_specific;
+};
+
+struct acpi_resource_extended_irq {
+	u8 producer_consumer;
+	u8 triggering;
+	u8 polarity;
+	u8 sharable;
+	u8 interrupt_count;
 	struct acpi_resource_source resource_source;
 	u32 interrupts[1];
 };
 
-/* ACPI_RESOURCE_TYPEs */
+struct acpi_resource_generic_register {
+	u8 space_id;
+	u8 bit_width;
+	u8 bit_offset;
+	u8 access_size;
+	u64 address;
+};
 
-#define ACPI_RSTYPE_IRQ                 0
-#define ACPI_RSTYPE_DMA                 1
-#define ACPI_RSTYPE_START_DPF           2
-#define ACPI_RSTYPE_END_DPF             3
-#define ACPI_RSTYPE_IO                  4
-#define ACPI_RSTYPE_FIXED_IO            5
-#define ACPI_RSTYPE_VENDOR              6
-#define ACPI_RSTYPE_END_TAG             7
-#define ACPI_RSTYPE_MEM24               8
-#define ACPI_RSTYPE_MEM32               9
-#define ACPI_RSTYPE_FIXED_MEM32         10
-#define ACPI_RSTYPE_ADDRESS16           11
-#define ACPI_RSTYPE_ADDRESS32           12
-#define ACPI_RSTYPE_ADDRESS64           13
-#define ACPI_RSTYPE_EXT_IRQ             14
+/* ACPI_RESOURCE_TYPEs */
 
-typedef u32 acpi_resource_type;
+#define ACPI_RESOURCE_TYPE_IRQ                  0
+#define ACPI_RESOURCE_TYPE_DMA                  1
+#define ACPI_RESOURCE_TYPE_START_DEPENDENT      2
+#define ACPI_RESOURCE_TYPE_END_DEPENDENT        3
+#define ACPI_RESOURCE_TYPE_IO                   4
+#define ACPI_RESOURCE_TYPE_FIXED_IO             5
+#define ACPI_RESOURCE_TYPE_VENDOR               6
+#define ACPI_RESOURCE_TYPE_END_TAG              7
+#define ACPI_RESOURCE_TYPE_MEMORY24             8
+#define ACPI_RESOURCE_TYPE_MEMORY32             9
+#define ACPI_RESOURCE_TYPE_FIXED_MEMORY32       10
+#define ACPI_RESOURCE_TYPE_ADDRESS16            11
+#define ACPI_RESOURCE_TYPE_ADDRESS32            12
+#define ACPI_RESOURCE_TYPE_ADDRESS64            13
+#define ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64   14	/* ACPI 3.0 */
+#define ACPI_RESOURCE_TYPE_EXTENDED_IRQ         15
+#define ACPI_RESOURCE_TYPE_GENERIC_REGISTER     16
+#define ACPI_RESOURCE_TYPE_MAX                  16
 
 union acpi_resource_data {
 	struct acpi_resource_irq irq;
 	struct acpi_resource_dma dma;
-	struct acpi_resource_start_dpf start_dpf;
+	struct acpi_resource_start_dependent start_dpf;
 	struct acpi_resource_io io;
 	struct acpi_resource_fixed_io fixed_io;
-	struct acpi_resource_vendor vendor_specific;
+	struct acpi_resource_vendor vendor;
+	struct acpi_resource_vendor_typed vendor_typed;
 	struct acpi_resource_end_tag end_tag;
-	struct acpi_resource_mem24 memory24;
-	struct acpi_resource_mem32 memory32;
-	struct acpi_resource_fixed_mem32 fixed_memory32;
-	struct acpi_resource_address address;	/* Common 16/32/64 address fields */
+	struct acpi_resource_memory24 memory24;
+	struct acpi_resource_memory32 memory32;
+	struct acpi_resource_fixed_memory32 fixed_memory32;
 	struct acpi_resource_address16 address16;
 	struct acpi_resource_address32 address32;
 	struct acpi_resource_address64 address64;
-	struct acpi_resource_ext_irq extended_irq;
+	struct acpi_resource_extended_address64 ext_address64;
+	struct acpi_resource_extended_irq extended_irq;
+	struct acpi_resource_generic_register generic_reg;
+
+	/* Common fields */
+
+	struct acpi_resource_address address;	/* Common 16/32/64 address fields */
 };
 
 struct acpi_resource {
-	acpi_resource_type id;
+	u32 type;
 	u32 length;
 	union acpi_resource_data data;
 };
 
-#define ACPI_RESOURCE_LENGTH                12
-#define ACPI_RESOURCE_LENGTH_NO_DATA        8	/* Id + Length fields */
+/* restore default alignment */
+
+#pragma pack()
 
-#define ACPI_SIZEOF_RESOURCE(type)          (ACPI_RESOURCE_LENGTH_NO_DATA + sizeof (type))
+#define ACPI_RS_SIZE_MIN                    12
+#define ACPI_RS_SIZE_NO_DATA                8	/* Id + Length fields */
+#define ACPI_RS_SIZE(type)                  (u32) (ACPI_RS_SIZE_NO_DATA + sizeof (type))
 
 #define ACPI_NEXT_RESOURCE(res)             (struct acpi_resource *)((u8 *) res + res->length)
 
-#ifdef ACPI_MISALIGNED_TRANSFERS
+#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED
 #define ACPI_ALIGN_RESOURCE_SIZE(length)    (length)
 #else
 #define ACPI_ALIGN_RESOURCE_SIZE(length)    ACPI_ROUND_UP_TO_NATIVE_WORD(length)
diff --git a/include/acpi/acutils.h b/include/acpi/acutils.h
index c108645..0927765 100644
--- a/include/acpi/acutils.h
+++ b/include/acpi/acutils.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,6 +44,39 @@
 #ifndef _ACUTILS_H
 #define _ACUTILS_H
 
+extern const u8 acpi_gbl_resource_aml_sizes[];
+
+/* Strings used by the disassembler and debugger resource dump routines */
+
+#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER)
+
+extern const char *acpi_gbl_BMdecode[2];
+extern const char *acpi_gbl_config_decode[4];
+extern const char *acpi_gbl_consume_decode[2];
+extern const char *acpi_gbl_DECdecode[2];
+extern const char *acpi_gbl_HEdecode[2];
+extern const char *acpi_gbl_io_decode[2];
+extern const char *acpi_gbl_LLdecode[2];
+extern const char *acpi_gbl_max_decode[2];
+extern const char *acpi_gbl_MEMdecode[4];
+extern const char *acpi_gbl_min_decode[2];
+extern const char *acpi_gbl_MTPdecode[4];
+extern const char *acpi_gbl_RNGdecode[4];
+extern const char *acpi_gbl_RWdecode[2];
+extern const char *acpi_gbl_SHRdecode[2];
+extern const char *acpi_gbl_SIZdecode[4];
+extern const char *acpi_gbl_TRSdecode[2];
+extern const char *acpi_gbl_TTPdecode[2];
+extern const char *acpi_gbl_TYPdecode[4];
+#endif
+
+/* Types for Resource descriptor entries */
+
+#define ACPI_INVALID_RESOURCE           0
+#define ACPI_FIXED_LENGTH               1
+#define ACPI_VARIABLE_LENGTH            2
+#define ACPI_SMALL_VARIABLE_LENGTH      3
+
 typedef
 acpi_status(*acpi_pkg_callback) (u8 object_type,
 				 union acpi_operand_object * source_object,
@@ -159,7 +192,6 @@ extern const u8 _acpi_ctype[];
 #define ACPI_IS_LOWER(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO))
 #define ACPI_IS_PRINT(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_SP | _ACPI_PU))
 #define ACPI_IS_ALPHA(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP))
-#define ACPI_IS_ASCII(c)  ((c) < 0x80)
 
 #endif				/* ACPI_USE_SYSTEM_CLIBRARY */
 
@@ -243,21 +275,22 @@ acpi_ut_ptr_exit(u32 line_number,
 		 const char *function_name,
 		 char *module_name, u32 component_id, u8 * ptr);
 
-void acpi_ut_report_info(char *module_name, u32 line_number, u32 component_id);
+void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id);
 
-void acpi_ut_report_error(char *module_name, u32 line_number, u32 component_id);
+void acpi_ut_report_error(char *module_name, u32 line_number);
 
-void
-acpi_ut_report_warning(char *module_name, u32 line_number, u32 component_id);
+void acpi_ut_report_info(char *module_name, u32 line_number);
 
-void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id);
+void acpi_ut_report_warning(char *module_name, u32 line_number);
+
+/* Error and message reporting interfaces */
 
 void ACPI_INTERNAL_VAR_XFACE
 acpi_ut_debug_print(u32 requested_debug_level,
 		    u32 line_number,
 		    const char *function_name,
 		    char *module_name,
-		    u32 component_id, char *format, ...) ACPI_PRINTF_LIKE_FUNC;
+		    u32 component_id, char *format, ...) ACPI_PRINTF_LIKE(6);
 
 void ACPI_INTERNAL_VAR_XFACE
 acpi_ut_debug_print_raw(u32 requested_debug_level,
@@ -265,7 +298,24 @@ acpi_ut_debug_print_raw(u32 requested_de
 			const char *function_name,
 			char *module_name,
 			u32 component_id,
-			char *format, ...) ACPI_PRINTF_LIKE_FUNC;
+			char *format, ...) ACPI_PRINTF_LIKE(6);
+
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_error(char *module_name,
+	      u32 line_number, char *format, ...) ACPI_PRINTF_LIKE(3);
+
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_exception(char *module_name,
+		  u32 line_number,
+		  acpi_status status, char *format, ...) ACPI_PRINTF_LIKE(4);
+
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_warning(char *module_name,
+		u32 line_number, char *format, ...) ACPI_PRINTF_LIKE(3);
+
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_info(char *module_name,
+	     u32 line_number, char *format, ...) ACPI_PRINTF_LIKE(3);
 
 /*
  * utdelete - Object deletion and reference counts
@@ -419,7 +469,19 @@ acpi_ut_strtoul64(char *string, u32 base
 
 #define ACPI_ANY_BASE        0
 
-u8 *acpi_ut_get_resource_end_tag(union acpi_operand_object *obj_desc);
+acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index);
+
+u32 acpi_ut_get_descriptor_length(void *aml);
+
+u16 acpi_ut_get_resource_length(void *aml);
+
+u8 acpi_ut_get_resource_header_length(void *aml);
+
+u8 acpi_ut_get_resource_type(void *aml);
+
+acpi_status
+acpi_ut_get_resource_end_tag(union acpi_operand_object *obj_desc,
+			     u8 ** end_tag);
 
 u8 acpi_ut_generate_checksum(u8 * buffer, u32 length);
 
diff --git a/include/acpi/amlcode.h b/include/acpi/amlcode.h
index 7fdf529..37964a5 100644
--- a/include/acpi/amlcode.h
+++ b/include/acpi/amlcode.h
@@ -7,7 +7,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/acpi/amlresrc.h b/include/acpi/amlresrc.h
index 051786e..fb47353 100644
--- a/include/acpi/amlresrc.h
+++ b/include/acpi/amlresrc.h
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -92,182 +92,168 @@ struct asl_resource_node {
 	struct asl_resource_node *next;
 };
 
+/* Macros used to generate AML resource length fields */
+
+#define ACPI_AML_SIZE_LARGE(r)      (sizeof (r) - sizeof (struct aml_resource_large_header))
+#define ACPI_AML_SIZE_SMALL(r)      (sizeof (r) - sizeof (struct aml_resource_small_header))
+
 /*
  * Resource descriptors defined in the ACPI specification.
  *
  * Packing/alignment must be BYTE because these descriptors
- * are used to overlay the AML byte stream.
+ * are used to overlay the raw AML byte stream.
  */
 #pragma pack(1)
 
-struct asl_irq_format_desc {
-	u8 descriptor_type;
-	u16 irq_mask;
+/*
+ * SMALL descriptors
+ */
+#define AML_RESOURCE_SMALL_HEADER_COMMON \
+	u8                                  descriptor_type;
+
+struct aml_resource_small_header {
+AML_RESOURCE_SMALL_HEADER_COMMON};
+
+struct aml_resource_irq {
+	AML_RESOURCE_SMALL_HEADER_COMMON u16 irq_mask;
 	u8 flags;
 };
 
-struct asl_irq_noflags_desc {
-	u8 descriptor_type;
-	u16 irq_mask;
+struct aml_resource_irq_noflags {
+	AML_RESOURCE_SMALL_HEADER_COMMON u16 irq_mask;
 };
 
-struct asl_dma_format_desc {
-	u8 descriptor_type;
-	u8 dma_channel_mask;
+struct aml_resource_dma {
+	AML_RESOURCE_SMALL_HEADER_COMMON u8 dma_channel_mask;
 	u8 flags;
 };
 
-struct asl_start_dependent_desc {
-	u8 descriptor_type;
-	u8 flags;
+struct aml_resource_start_dependent {
+	AML_RESOURCE_SMALL_HEADER_COMMON u8 flags;
 };
 
-struct asl_start_dependent_noprio_desc {
-	u8 descriptor_type;
-};
+struct aml_resource_start_dependent_noprio {
+AML_RESOURCE_SMALL_HEADER_COMMON};
 
-struct asl_end_dependent_desc {
-	u8 descriptor_type;
-};
+struct aml_resource_end_dependent {
+AML_RESOURCE_SMALL_HEADER_COMMON};
 
-struct asl_io_port_desc {
-	u8 descriptor_type;
-	u8 information;
-	u16 address_min;
-	u16 address_max;
+struct aml_resource_io {
+	AML_RESOURCE_SMALL_HEADER_COMMON u8 flags;
+	u16 minimum;
+	u16 maximum;
 	u8 alignment;
-	u8 length;
+	u8 address_length;
 };
 
-struct asl_fixed_io_port_desc {
-	u8 descriptor_type;
-	u16 base_address;
-	u8 length;
+struct aml_resource_fixed_io {
+	AML_RESOURCE_SMALL_HEADER_COMMON u16 address;
+	u8 address_length;
 };
 
-struct asl_small_vendor_desc {
-	u8 descriptor_type;
-	u8 vendor_defined[7];
-};
+struct aml_resource_vendor_small {
+AML_RESOURCE_SMALL_HEADER_COMMON};
 
-struct asl_end_tag_desc {
-	u8 descriptor_type;
-	u8 checksum;
+struct aml_resource_end_tag {
+	AML_RESOURCE_SMALL_HEADER_COMMON u8 checksum;
 };
 
-/* LARGE descriptors */
-
-struct asl_memory_24_desc {
-	u8 descriptor_type;
-	u16 length;
-	u8 information;
-	u16 address_min;
-	u16 address_max;
+/*
+ * LARGE descriptors
+ */
+#define AML_RESOURCE_LARGE_HEADER_COMMON \
+	u8                                  descriptor_type;\
+	u16                                 resource_length;
+
+struct aml_resource_large_header {
+AML_RESOURCE_LARGE_HEADER_COMMON};
+
+struct aml_resource_memory24 {
+	AML_RESOURCE_LARGE_HEADER_COMMON u8 flags;
+	u16 minimum;
+	u16 maximum;
 	u16 alignment;
-	u16 range_length;
+	u16 address_length;
 };
 
-struct asl_large_vendor_desc {
-	u8 descriptor_type;
-	u16 length;
-	u8 vendor_defined[1];
-};
+struct aml_resource_vendor_large {
+AML_RESOURCE_LARGE_HEADER_COMMON};
 
-struct asl_memory_32_desc {
-	u8 descriptor_type;
-	u16 length;
-	u8 information;
-	u32 address_min;
-	u32 address_max;
+struct aml_resource_memory32 {
+	AML_RESOURCE_LARGE_HEADER_COMMON u8 flags;
+	u32 minimum;
+	u32 maximum;
 	u32 alignment;
-	u32 range_length;
+	u32 address_length;
 };
 
-struct asl_fixed_memory_32_desc {
-	u8 descriptor_type;
-	u16 length;
-	u8 information;
-	u32 base_address;
-	u32 range_length;
+struct aml_resource_fixed_memory32 {
+	AML_RESOURCE_LARGE_HEADER_COMMON u8 flags;
+	u32 address;
+	u32 address_length;
 };
 
-struct asl_extended_address_desc {
-	u8 descriptor_type;
-	u16 length;
-	u8 resource_type;
-	u8 flags;
-	u8 specific_flags;
-	u8 revision_iD;
+#define AML_RESOURCE_ADDRESS_COMMON \
+	u8                                  resource_type; \
+	u8                                  flags; \
+	u8                                  specific_flags;
+
+struct aml_resource_address {
+AML_RESOURCE_LARGE_HEADER_COMMON AML_RESOURCE_ADDRESS_COMMON};
+
+struct aml_resource_extended_address64 {
+	AML_RESOURCE_LARGE_HEADER_COMMON
+	    AML_RESOURCE_ADDRESS_COMMON u8 revision_iD;
 	u8 reserved;
 	u64 granularity;
-	u64 address_min;
-	u64 address_max;
+	u64 minimum;
+	u64 maximum;
 	u64 translation_offset;
 	u64 address_length;
-	u64 type_specific_attributes;
-	u8 optional_fields[2];	/* Used for length calculation only */
+	u64 type_specific;
 };
 
-#define ASL_EXTENDED_ADDRESS_DESC_REVISION          1	/* ACPI 3.0 */
+#define AML_RESOURCE_EXTENDED_ADDRESS_REVISION          1	/* ACPI 3.0 */
 
-struct asl_qword_address_desc {
-	u8 descriptor_type;
-	u16 length;
-	u8 resource_type;
-	u8 flags;
-	u8 specific_flags;
-	u64 granularity;
-	u64 address_min;
-	u64 address_max;
+struct aml_resource_address64 {
+	AML_RESOURCE_LARGE_HEADER_COMMON
+	    AML_RESOURCE_ADDRESS_COMMON u64 granularity;
+	u64 minimum;
+	u64 maximum;
 	u64 translation_offset;
 	u64 address_length;
-	u8 optional_fields[2];
 };
 
-struct asl_dword_address_desc {
-	u8 descriptor_type;
-	u16 length;
-	u8 resource_type;
-	u8 flags;
-	u8 specific_flags;
-	u32 granularity;
-	u32 address_min;
-	u32 address_max;
+struct aml_resource_address32 {
+	AML_RESOURCE_LARGE_HEADER_COMMON
+	    AML_RESOURCE_ADDRESS_COMMON u32 granularity;
+	u32 minimum;
+	u32 maximum;
 	u32 translation_offset;
 	u32 address_length;
-	u8 optional_fields[2];
 };
 
-struct asl_word_address_desc {
-	u8 descriptor_type;
-	u16 length;
-	u8 resource_type;
-	u8 flags;
-	u8 specific_flags;
-	u16 granularity;
-	u16 address_min;
-	u16 address_max;
+struct aml_resource_address16 {
+	AML_RESOURCE_LARGE_HEADER_COMMON
+	    AML_RESOURCE_ADDRESS_COMMON u16 granularity;
+	u16 minimum;
+	u16 maximum;
 	u16 translation_offset;
 	u16 address_length;
-	u8 optional_fields[2];
 };
 
-struct asl_extended_xrupt_desc {
-	u8 descriptor_type;
-	u16 length;
-	u8 flags;
-	u8 table_length;
-	u32 interrupt_number[1];
+struct aml_resource_extended_irq {
+	AML_RESOURCE_LARGE_HEADER_COMMON u8 flags;
+	u8 interrupt_count;
+	u32 interrupts[1];
 	/* res_source_index, res_source optional fields follow */
 };
 
-struct asl_general_register_desc {
-	u8 descriptor_type;
-	u16 length;
-	u8 address_space_id;
+struct aml_resource_generic_register {
+	AML_RESOURCE_LARGE_HEADER_COMMON u8 address_space_id;
 	u8 bit_width;
 	u8 bit_offset;
-	u8 access_size;		/* ACPI 3.0, was Reserved */
+	u8 access_size;		/* ACPI 3.0, was previously Reserved */
 	u64 address;
 };
 
@@ -277,26 +263,39 @@ struct asl_general_register_desc {
 
 /* Union of all resource descriptors, so we can allocate the worst case */
 
-union asl_resource_desc {
-	struct asl_irq_format_desc irq;
-	struct asl_dma_format_desc dma;
-	struct asl_start_dependent_desc std;
-	struct asl_end_dependent_desc end;
-	struct asl_io_port_desc iop;
-	struct asl_fixed_io_port_desc fio;
-	struct asl_small_vendor_desc smv;
-	struct asl_end_tag_desc et;
-
-	struct asl_memory_24_desc M24;
-	struct asl_large_vendor_desc lgv;
-	struct asl_memory_32_desc M32;
-	struct asl_fixed_memory_32_desc F32;
-	struct asl_qword_address_desc qas;
-	struct asl_dword_address_desc das;
-	struct asl_word_address_desc was;
-	struct asl_extended_address_desc eas;
-	struct asl_extended_xrupt_desc exx;
-	struct asl_general_register_desc grg;
+union aml_resource {
+	/* Descriptor headers */
+
+	struct aml_resource_small_header small_header;
+	struct aml_resource_large_header large_header;
+
+	/* Small resource descriptors */
+
+	struct aml_resource_irq irq;
+	struct aml_resource_dma dma;
+	struct aml_resource_start_dependent start_dpf;
+	struct aml_resource_end_dependent end_dpf;
+	struct aml_resource_io io;
+	struct aml_resource_fixed_io fixed_io;
+	struct aml_resource_vendor_small vendor_small;
+	struct aml_resource_end_tag end_tag;
+
+	/* Large resource descriptors */
+
+	struct aml_resource_memory24 memory24;
+	struct aml_resource_generic_register generic_reg;
+	struct aml_resource_vendor_large vendor_large;
+	struct aml_resource_memory32 memory32;
+	struct aml_resource_fixed_memory32 fixed_memory32;
+	struct aml_resource_address16 address16;
+	struct aml_resource_address32 address32;
+	struct aml_resource_address64 address64;
+	struct aml_resource_extended_address64 ext_address64;
+	struct aml_resource_extended_irq extended_irq;
+
+	/* Utility overlays */
+
+	struct aml_resource_address address;
 	u32 u32_item;
 	u16 u16_item;
 	u8 U8item;
diff --git a/include/acpi/pdc_intel.h b/include/acpi/pdc_intel.h
index 91f4a12..3fa81d5 100644
--- a/include/acpi/pdc_intel.h
+++ b/include/acpi/pdc_intel.h
@@ -15,9 +15,7 @@
 #define ACPI_PDC_C_C1_FFH		(0x0100)
 
 #define ACPI_PDC_EST_CAPABILITY_SMP	(ACPI_PDC_SMP_C1PT | \
-					 ACPI_PDC_C_C1_HALT)
-
-#define ACPI_PDC_EST_CAPABILITY_SMP_MSR	(ACPI_PDC_EST_CAPABILITY_SMP | \
+					 ACPI_PDC_C_C1_HALT | \
 					 ACPI_PDC_P_FFH)
 
 #define ACPI_PDC_C_CAPABILITY_SMP	(ACPI_PDC_SMP_C2C3 | \
diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h
index 16609c1..223ec64 100644
--- a/include/acpi/platform/acenv.h
+++ b/include/acpi/platform/acenv.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -68,6 +68,7 @@
 #define ACPI_APPLICATION
 #define ACPI_DEBUGGER
 #define ACPI_DISASSEMBLER
+#define ACPI_MUTEX_DEBUG
 #endif
 
 #ifdef ACPI_ASL_COMPILER
@@ -148,6 +149,9 @@
 #elif defined(NETWARE)
 #include "acnetware.h"
 
+#elif defined(__sun)
+#include "acsolaris.h"
+
 #else
 
 /* All other environments */
@@ -157,13 +161,6 @@
 #define COMPILER_DEPENDENT_INT64   long long
 #define COMPILER_DEPENDENT_UINT64  unsigned long long
 
-/*
- * This macro is used to tag functions as "printf-like" because
- * some compilers can catch printf format string problems. MSVC
- * doesn't, so this is proprocessed away.
- */
-#define ACPI_PRINTF_LIKE_FUNC
-
 #endif
 
 /*
@@ -205,6 +202,8 @@
  *
  *****************************************************************************/
 
+#define ACPI_IS_ASCII(c)  ((c) < 0x80)
+
 #ifdef ACPI_USE_SYSTEM_CLIBRARY
 /*
  * Use the standard C library headers.
@@ -234,7 +233,7 @@
 #define ACPI_STRCAT(d,s)        (void) strcat((d), (s))
 #define ACPI_STRNCAT(d,s,n)     strncat((d), (s), (acpi_size)(n))
 #define ACPI_STRTOUL(d,s,n)     strtoul((d), (s), (acpi_size)(n))
-#define ACPI_MEMCMP(s1,s2,n)    memcmp((s1), (s2), (acpi_size)(n))
+#define ACPI_MEMCMP(s1,s2,n)    memcmp((const char *)(s1), (const char *)(s2), (acpi_size)(n))
 #define ACPI_MEMCPY(d,s,n)      (void) memcpy((d), (s), (acpi_size)(n))
 #define ACPI_MEMSET(d,s,n)      (void) memset((d), (s), (acpi_size)(n))
 
@@ -246,7 +245,6 @@
 #define ACPI_IS_UPPER(i)        isupper((int) (i))
 #define ACPI_IS_PRINT(i)        isprint((int) (i))
 #define ACPI_IS_ALPHA(i)        isalpha((int) (i))
-#define ACPI_IS_ASCII(i)        isascii((int) (i))
 
 #else
 
@@ -273,8 +271,8 @@ typedef char *va_list;
 /*
  * Storage alignment properties
  */
-#define  _AUPBND                (sizeof (acpi_native_int) - 1)
-#define  _ADNBND                (sizeof (acpi_native_int) - 1)
+#define  _AUPBND                (sizeof (acpi_native_uint) - 1)
+#define  _ADNBND                (sizeof (acpi_native_uint) - 1)
 
 /*
  * Variable argument list macro definitions
@@ -296,7 +294,7 @@ typedef char *va_list;
 #define ACPI_STRCAT(d,s)        (void) acpi_ut_strcat ((d), (s))
 #define ACPI_STRNCAT(d,s,n)     acpi_ut_strncat ((d), (s), (acpi_size)(n))
 #define ACPI_STRTOUL(d,s,n)     acpi_ut_strtoul ((d), (s), (acpi_size)(n))
-#define ACPI_MEMCMP(s1,s2,n)    acpi_ut_memcmp((s1), (s2), (acpi_size)(n))
+#define ACPI_MEMCMP(s1,s2,n)    acpi_ut_memcmp((const char *)(s1), (const char *)(s2), (acpi_size)(n))
 #define ACPI_MEMCPY(d,s,n)      (void) acpi_ut_memcpy ((d), (s), (acpi_size)(n))
 #define ACPI_MEMSET(d,v,n)      (void) acpi_ut_memset ((d), (v), (acpi_size)(n))
 #define ACPI_TOUPPER            acpi_ut_to_upper
diff --git a/include/acpi/platform/acgcc.h b/include/acpi/platform/acgcc.h
index 4c0e0ba..da80933 100644
--- a/include/acpi/platform/acgcc.h
+++ b/include/acpi/platform/acgcc.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -48,12 +48,14 @@
 
 #define ACPI_GET_FUNCTION_NAME          __FUNCTION__
 
-/* This macro is used to tag functions as "printf-like" because
+/*
+ * This macro is used to tag functions as "printf-like" because
  * some compilers (like GCC) can catch printf format string problems.
  */
-#define ACPI_PRINTF_LIKE_FUNC __attribute__ ((__format__ (__printf__, 6, 7)))
+#define ACPI_PRINTF_LIKE(c) __attribute__ ((__format__ (__printf__, c, c+1)))
 
-/* Some compilers complain about unused variables. Sometimes we don't want to
+/*
+ * Some compilers complain about unused variables. Sometimes we don't want to
  * use all the variables (for example, _acpi_module_name). This allows us
  * to to tell the compiler warning in a per-variable manner that a variable
  * is unused.
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
index c93e656..2e6d545 100644
--- a/include/acpi/platform/aclinux.h
+++ b/include/acpi/platform/aclinux.h
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -71,6 +71,10 @@
 #define acpi_cache_t	kmem_cache_t
 #endif
 
+/* Full namespace pathname length limit - arbitrary */
+
+#define ACPI_PATHNAME_MAX              256
+
 #else				/* !__KERNEL__ */
 
 #include <stdarg.h>
@@ -98,4 +102,6 @@
 
 #include "acgcc.h"
 
+#define acpi_cpu_flags unsigned long
+
 #endif				/* __ACLINUX_H__ */
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 7a00d50..badf027 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -62,9 +62,6 @@ struct acpi_processor_power {
 	u32 bm_activity;
 	int count;
 	struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER];
-
-	/* the _PDC objects passed by the driver, if any */
-	struct acpi_object_list *pdc;
 };
 
 /* Performance Management */
@@ -96,8 +93,6 @@ struct acpi_processor_performance {
 	unsigned int state_count;
 	struct acpi_processor_px *states;
 
-	/* the _PDC objects passed by the driver, if any */
-	struct acpi_object_list *pdc;
 };
 
 /* Throttling Control */
@@ -151,6 +146,9 @@ struct acpi_processor {
 	struct acpi_processor_performance *performance;
 	struct acpi_processor_throttling throttling;
 	struct acpi_processor_limit limit;
+
+	/* the _PDC objects for this processor, if any */
+	struct acpi_object_list *pdc;
 };
 
 struct acpi_processor_errata {
@@ -178,22 +176,12 @@ int acpi_processor_notify_smm(struct mod
 extern struct acpi_processor *processors[NR_CPUS];
 extern struct acpi_processor_errata errata;
 
-int acpi_processor_set_pdc(struct acpi_processor *pr,
-			   struct acpi_object_list *pdc_in);
+void arch_acpi_processor_init_pdc(struct acpi_processor *pr);
 
-#ifdef ARCH_HAS_POWER_PDC_INIT
-void acpi_processor_power_init_pdc(struct acpi_processor_power *pow,
-				   unsigned int cpu);
+#ifdef ARCH_HAS_POWER_INIT
 void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags,
 					unsigned int cpu);
 #else
-static inline void acpi_processor_power_init_pdc(struct acpi_processor_power
-						 *pow, unsigned int cpu)
-{
-	pow->pdc = NULL;
-	return;
-}
-
 static inline void acpi_processor_power_init_bm_check(struct
 						      acpi_processor_flags
 						      *flags, unsigned int cpu)
@@ -235,9 +223,6 @@ static inline int acpi_processor_ppc_has
 /* in processor_throttling.c */
 int acpi_processor_get_throttling_info(struct acpi_processor *pr);
 int acpi_processor_set_throttling(struct acpi_processor *pr, int state);
-ssize_t acpi_processor_write_throttling(struct file *file,
-					const char __user * buffer,
-					size_t count, loff_t * data);
 extern struct file_operations acpi_processor_throttling_fops;
 
 /* in processor_idle.c */
@@ -249,9 +234,6 @@ int acpi_processor_power_exit(struct acp
 
 /* in processor_thermal.c */
 int acpi_processor_get_limit_info(struct acpi_processor *pr);
-ssize_t acpi_processor_write_limit(struct file *file,
-				   const char __user * buffer,
-				   size_t count, loff_t * data);
 extern struct file_operations acpi_processor_limit_fops;
 
 #ifdef CONFIG_CPU_FREQ
diff --git a/include/asm-alpha/dma-mapping.h b/include/asm-alpha/dma-mapping.h
index 9dc7256..62d0d66 100644
--- a/include/asm-alpha/dma-mapping.h
+++ b/include/asm-alpha/dma-mapping.h
@@ -30,6 +30,7 @@
 
 #else	/* no PCI - no IOMMU. */
 
+struct scatterlist;
 void *dma_alloc_coherent(struct device *dev, size_t size,
 			 dma_addr_t *dma_handle, gfp_t gfp);
 int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
diff --git a/include/asm-arm/arch-omap/clock.h b/include/asm-arm/arch-omap/clock.h
index 740c297..46a0402 100644
--- a/include/asm-arm/arch-omap/clock.h
+++ b/include/asm-arm/arch-omap/clock.h
@@ -38,8 +38,6 @@ struct clk {
 struct clk_functions {
 	int		(*clk_enable)(struct clk *clk);
 	void		(*clk_disable)(struct clk *clk);
-	int		(*clk_use)(struct clk *clk);
-	void		(*clk_unuse)(struct clk *clk);
 	long		(*clk_round_rate)(struct clk *clk, unsigned long rate);
 	int		(*clk_set_rate)(struct clk *clk, unsigned long rate);
 	int		(*clk_set_parent)(struct clk *clk, struct clk *parent);
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index dae138b..1409c5b 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -108,6 +108,7 @@
 #define DCSR_STARTINTR	(1 << 1)	/* Start Interrupt (read / write) */
 #define DCSR_BUSERR	(1 << 0)	/* Bus Error Interrupt (read / write) */
 
+#define DALGN		__REG(0x400000a0)  /* DMA Alignment Register */
 #define DINT		__REG(0x400000f0)  /* DMA Interrupt Register */
 
 #define DRCMR(n)	__REG2(0x40000100, (n)<<2)
@@ -1614,8 +1615,21 @@
 #define SSCR0_National	(0x2 << 4)	/* National Microwire */
 #define SSCR0_ECS	(1 << 6)	/* External clock select */
 #define SSCR0_SSE	(1 << 7)	/* Synchronous Serial Port Enable */
+#if defined(CONFIG_PXA25x)
 #define SSCR0_SCR	(0x0000ff00)	/* Serial Clock Rate (mask) */
 #define SSCR0_SerClkDiv(x) ((((x) - 2)/2) << 8) /* Divisor [2..512] */
+#elif defined(CONFIG_PXA27x)
+#define SSCR0_SCR	(0x000fff00)	/* Serial Clock Rate (mask) */
+#define SSCR0_SerClkDiv(x) (((x) - 1) << 8) /* Divisor [1..4096] */
+#define SSCR0_EDSS	(1 << 20)	/* Extended data size select */
+#define SSCR0_NCS	(1 << 21)	/* Network clock select */
+#define SSCR0_RIM	(1 << 22)	/* Receive FIFO overrrun interrupt mask */
+#define SSCR0_TUM	(1 << 23)	/* Transmit FIFO underrun interrupt mask */
+#define SSCR0_FRDC	(0x07000000)	/* Frame rate divider control (mask) */
+#define SSCR0_SlotsPerFrm(c) ((x) - 1)	/* Time slots per frame [1..8] */
+#define SSCR0_ADC	(1 << 30)	/* Audio clock select */
+#define SSCR0_MOD	(1 << 31)	/* Mode (normal or network) */
+#endif
 
 #define SSCR1_RIE	(1 << 0)	/* Receive FIFO Interrupt Enable */
 #define SSCR1_TIE	(1 << 1)	/* Transmit FIFO Interrupt Enable */
diff --git a/include/asm-arm/arch-s3c2410/debug-macro.S b/include/asm-arm/arch-s3c2410/debug-macro.S
index abfbe45..5f8223e 100644
--- a/include/asm-arm/arch-s3c2410/debug-macro.S
+++ b/include/asm-arm/arch-s3c2410/debug-macro.S
@@ -25,7 +25,7 @@
 		.macro addruart, rx
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1
-		ldreq	\rx, = S3C2410_PA_UART
+		ldreq	\rx, = S3C24XX_PA_UART
 		ldrne	\rx, = S3C24XX_VA_UART
 #if CONFIG_DEBUG_S3C2410_UART != 0
 		add	\rx, \rx, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C2410_UART)
@@ -44,7 +44,7 @@
 1003:
 		mrc	p15, 0, \rd, c1, c0
 		tst	\rd, #1
-		addeq	\rd, \rx, #(S3C2410_PA_GPIO - S3C2410_PA_UART)
+		addeq	\rd, \rx, #(S3C24XX_PA_GPIO - S3C24XX_PA_UART)
 		addne	\rd, \rx, #(S3C24XX_VA_GPIO - S3C24XX_VA_UART)
 		bic	\rd, \rd, #0xff000
 		ldr	\rd, [ \rd, # S3C2410_GSTATUS1 - S3C2410_GPIOREG(0) ]
@@ -75,7 +75,7 @@
 1003:
 		mrc	p15, 0, \rd, c1, c0
 		tst	\rd, #1
-		addeq	\rd, \rx, #(S3C2410_PA_GPIO - S3C2410_PA_UART)
+		addeq	\rd, \rx, #(S3C24XX_PA_GPIO - S3C24XX_PA_UART)
 		addne	\rd, \rx, #(S3C24XX_VA_GPIO - S3C24XX_VA_UART)
 		bic	\rd, \rd, #0xff000
 		ldr	\rd, [ \rd, # S3C2410_GSTATUS1 - S3C2410_GPIOREG(0) ]
diff --git a/include/asm-arm/arch-s3c2410/map.h b/include/asm-arm/arch-s3c2410/map.h
index 1833ea5..c380d26 100644
--- a/include/asm-arm/arch-s3c2410/map.h
+++ b/include/asm-arm/arch-s3c2410/map.h
@@ -14,6 +14,7 @@
  *  06-Jan-2003 BJD   Linux 2.6.0 version, moved bast specifics out
  *  10-Feb-2005 BJD   Added CAMIF definition from guillaume.gourat@nexvision.tv
  *  10-Mar-2005 LCVR  Added support to S3C2400, changed {VA,SZ} names
+ *  15-Jan-2006 LCVR  Added S3C24XX_PA macros for common S3C24XX resources
 */
 
 #ifndef __ASM_ARCH_MAP_H
@@ -188,5 +189,42 @@
 
 #define S3C2400_SDRAM_PA    (S3C2400_CS6)
 
+/* Use a single interface for common resources between S3C24XX cpus */
+
+#ifdef CONFIG_CPU_S3C2400
+#define S3C24XX_PA_IRQ      S3C2400_PA_IRQ
+#define S3C24XX_PA_MEMCTRL  S3C2400_PA_MEMCTRL
+#define S3C24XX_PA_USBHOST  S3C2400_PA_USBHOST
+#define S3C24XX_PA_DMA      S3C2400_PA_DMA
+#define S3C24XX_PA_CLKPWR   S3C2400_PA_CLKPWR
+#define S3C24XX_PA_LCD      S3C2400_PA_LCD
+#define S3C24XX_PA_UART     S3C2400_PA_UART
+#define S3C24XX_PA_TIMER    S3C2400_PA_TIMER
+#define S3C24XX_PA_USBDEV   S3C2400_PA_USBDEV
+#define S3C24XX_PA_WATCHDOG S3C2400_PA_WATCHDOG
+#define S3C24XX_PA_IIC      S3C2400_PA_IIC
+#define S3C24XX_PA_IIS      S3C2400_PA_IIS
+#define S3C24XX_PA_GPIO     S3C2400_PA_GPIO
+#define S3C24XX_PA_RTC      S3C2400_PA_RTC
+#define S3C24XX_PA_ADC      S3C2400_PA_ADC
+#define S3C24XX_PA_SPI      S3C2400_PA_SPI
+#else
+#define S3C24XX_PA_IRQ      S3C2410_PA_IRQ
+#define S3C24XX_PA_MEMCTRL  S3C2410_PA_MEMCTRL
+#define S3C24XX_PA_USBHOST  S3C2410_PA_USBHOST
+#define S3C24XX_PA_DMA      S3C2410_PA_DMA
+#define S3C24XX_PA_CLKPWR   S3C2410_PA_CLKPWR
+#define S3C24XX_PA_LCD      S3C2410_PA_LCD
+#define S3C24XX_PA_UART     S3C2410_PA_UART
+#define S3C24XX_PA_TIMER    S3C2410_PA_TIMER
+#define S3C24XX_PA_USBDEV   S3C2410_PA_USBDEV
+#define S3C24XX_PA_WATCHDOG S3C2410_PA_WATCHDOG
+#define S3C24XX_PA_IIC      S3C2410_PA_IIC
+#define S3C24XX_PA_IIS      S3C2410_PA_IIS
+#define S3C24XX_PA_GPIO     S3C2410_PA_GPIO
+#define S3C24XX_PA_RTC      S3C2410_PA_RTC
+#define S3C24XX_PA_ADC      S3C2410_PA_ADC
+#define S3C24XX_PA_SPI      S3C2410_PA_SPI
+#endif
 
 #endif /* __ASM_ARCH_MAP_H */
diff --git a/include/asm-arm/arch-s3c2410/regs-serial.h b/include/asm-arm/arch-s3c2410/regs-serial.h
index ce1bbba..83b0125 100644
--- a/include/asm-arm/arch-s3c2410/regs-serial.h
+++ b/include/asm-arm/arch-s3c2410/regs-serial.h
@@ -39,9 +39,9 @@
 #define S3C24XX_VA_UART1      (S3C24XX_VA_UART + 0x4000 )
 #define S3C24XX_VA_UART2      (S3C24XX_VA_UART + 0x8000 )
 
-#define S3C2410_PA_UART0      (S3C2410_PA_UART)
-#define S3C2410_PA_UART1      (S3C2410_PA_UART + 0x4000 )
-#define S3C2410_PA_UART2      (S3C2410_PA_UART + 0x8000 )
+#define S3C2410_PA_UART0      (S3C24XX_PA_UART)
+#define S3C2410_PA_UART1      (S3C24XX_PA_UART + 0x4000 )
+#define S3C2410_PA_UART2      (S3C24XX_PA_UART + 0x8000 )
 
 #define S3C2410_URXH	  (0x24)
 #define S3C2410_UTXH	  (0x20)
diff --git a/include/asm-arm/arch-s3c2410/uncompress.h b/include/asm-arm/arch-s3c2410/uncompress.h
index ddd1578..4367ec0 100644
--- a/include/asm-arm/arch-s3c2410/uncompress.h
+++ b/include/asm-arm/arch-s3c2410/uncompress.h
@@ -35,13 +35,13 @@
 #undef S3C2410_GPIOREG
 #undef S3C2410_WDOGREG
 
-#define S3C2410_GPIOREG(x) ((S3C2410_PA_GPIO + (x)))
-#define S3C2410_WDOGREG(x) ((S3C2410_PA_WATCHDOG + (x)))
+#define S3C2410_GPIOREG(x) ((S3C24XX_PA_GPIO + (x)))
+#define S3C2410_WDOGREG(x) ((S3C24XX_PA_WATCHDOG + (x)))
 
 /* how many bytes we allow into the FIFO at a time in FIFO mode */
 #define FIFO_MAX	 (14)
 
-#define uart_base S3C2410_PA_UART + (0x4000*CONFIG_S3C2410_LOWLEVEL_UART_PORT)
+#define uart_base S3C24XX_PA_UART + (0x4000*CONFIG_S3C2410_LOWLEVEL_UART_PORT)
 
 static __inline__ void
 uart_wr(unsigned int reg, unsigned int val)
diff --git a/include/asm-arm/mach/map.h b/include/asm-arm/mach/map.h
index 3351b77..e8ea67c 100644
--- a/include/asm-arm/mach/map.h
+++ b/include/asm-arm/mach/map.h
@@ -26,6 +26,7 @@ struct meminfo;
 #define MT_MEMORY		5
 #define MT_ROM			6
 #define MT_IXP2000_DEVICE	7
+#define MT_NONSHARED_DEVICE	8
 
 extern void create_memmap_holes(struct meminfo *);
 extern void memtable_init(struct meminfo *);
diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h
index 5a0d19b..70e00d0 100644
--- a/include/asm-arm/pgtable.h
+++ b/include/asm-arm/pgtable.h
@@ -168,6 +168,7 @@ extern void __pgd_error(const char *file
 #define PMD_SECT_WB		(PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
 #define PMD_SECT_MINICACHE	(PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE)
 #define PMD_SECT_WBWA		(PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
+#define PMD_SECT_NONSHARED_DEV	(PMD_SECT_TEX(2))
 
 /*
  *   - coarse table (not used)
diff --git a/include/asm-arm26/bitops.h b/include/asm-arm26/bitops.h
index 15cc6f2..d87f863 100644
--- a/include/asm-arm26/bitops.h
+++ b/include/asm-arm26/bitops.h
@@ -186,7 +186,7 @@ extern void _change_bit_le(int nr, volat
 extern int _test_and_set_bit_le(int nr, volatile unsigned long * p);
 extern int _test_and_clear_bit_le(int nr, volatile unsigned long * p);
 extern int _test_and_change_bit_le(int nr, volatile unsigned long * p);
-extern int _find_first_zero_bit_le(void * p, unsigned size);
+extern int _find_first_zero_bit_le(const unsigned long * p, unsigned size);
 extern int _find_next_zero_bit_le(void * p, int size, int offset);
 extern int _find_first_bit_le(const unsigned long *p, unsigned size);
 extern int _find_next_bit_le(const unsigned long *p, int size, int offset);
@@ -326,7 +326,7 @@ static inline int sched_find_first_bit(u
 #define minix_test_and_clear_bit(nr,p)		\
 		__test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 #define minix_find_first_zero_bit(p,sz)		\
-		_find_first_zero_bit_le(p,sz)
+		_find_first_zero_bit_le((unsigned long *)(p),sz)
 
 #endif /* __KERNEL__ */
 
diff --git a/include/asm-arm26/hardirq.h b/include/asm-arm26/hardirq.h
index dc28daa..87c19d2 100644
--- a/include/asm-arm26/hardirq.h
+++ b/include/asm-arm26/hardirq.h
@@ -4,6 +4,7 @@
 #include <linux/config.h>
 #include <linux/cache.h>
 #include <linux/threads.h>
+#include <asm/irq.h>
 
 typedef struct {
 	unsigned int __softirq_pending;
@@ -26,13 +27,6 @@ typedef struct {
 
 extern asmlinkage void __do_softirq(void);
 
-#define irq_exit()                                                      \
-        do {                                                            \
-                preempt_count() -= IRQ_EXIT_OFFSET;                     \
-                if (!in_interrupt() && local_softirq_pending())         \
-                        __do_softirq();                                 \
-                preempt_enable_no_resched();                            \
-        } while (0)
 #endif
 
 
diff --git a/include/asm-arm26/posix_types.h b/include/asm-arm26/posix_types.h
index b88344a..f8d1eb4 100644
--- a/include/asm-arm26/posix_types.h
+++ b/include/asm-arm26/posix_types.h
@@ -44,6 +44,7 @@ typedef unsigned int		__kernel_gid32_t;
 
 typedef unsigned short		__kernel_old_uid_t;
 typedef unsigned short		__kernel_old_gid_t;
+typedef unsigned short		__kernel_old_dev_t;
 
 #ifdef __GNUC__
 typedef long long		__kernel_loff_t;
diff --git a/include/asm-arm26/system.h b/include/asm-arm26/system.h
index ca4ccfc..7028849 100644
--- a/include/asm-arm26/system.h
+++ b/include/asm-arm26/system.h
@@ -98,9 +98,8 @@ extern unsigned int user_debug;
  * spin_unlock_irq() and friends are implemented.  This avoids
  * us needlessly decrementing and incrementing the preempt count.
  */
-#define prepare_arch_switch(rq,next)	local_irq_enable()
-#define finish_arch_switch(rq,prev)	spin_unlock(&(rq)->lock)
-#define task_running(rq,p)		((rq)->curr == (p))
+#define prepare_arch_switch(next)	local_irq_enable()
+#define finish_arch_switch(prev)	spin_unlock(&(rq)->lock)
 
 /*
  * switch_to(prev, next) should switch from task `prev' to `next'
diff --git a/include/asm-frv/thread_info.h b/include/asm-frv/thread_info.h
index a5576e0..ea426ab 100644
--- a/include/asm-frv/thread_info.h
+++ b/include/asm-frv/thread_info.h
@@ -129,6 +129,7 @@ register struct thread_info *__current_t
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
 #define TIF_SINGLESTEP		4	/* restore singlestep on return to user mode */
 #define TIF_IRET		5	/* return with iret */
+#define TIF_RESTORE_SIGMASK	6	/* restore signal mask in do_signal() */
 #define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE		17	/* OOM killer killed process */
 
@@ -138,6 +139,7 @@ register struct thread_info *__current_t
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
 #define _TIF_SINGLESTEP		(1 << TIF_SINGLESTEP)
 #define _TIF_IRET		(1 << TIF_IRET)
+#define _TIF_RESTORE_SIGMASK	(1 << TIF_RESTORE_SIGMASK)
 #define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
 
 #define _TIF_WORK_MASK		0x0000FFFE	/* work to do on interrupt/exception return */
diff --git a/include/asm-frv/unistd.h b/include/asm-frv/unistd.h
index cde376a..4d994d2 100644
--- a/include/asm-frv/unistd.h
+++ b/include/asm-frv/unistd.h
@@ -486,6 +486,7 @@ static inline pid_t wait(int * wait_stat
 /* #define __ARCH_WANT_SYS_SIGPENDING */
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
+#define __ARCH_WANT_SYS_RT_SIGSUSPEND
 #endif
 
 /*
diff --git a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h
index df4ed32..55059ab 100644
--- a/include/asm-i386/acpi.h
+++ b/include/asm-i386/acpi.h
@@ -179,7 +179,7 @@ extern void acpi_reserve_bootmem(void);
 
 extern u8 x86_acpiid_to_apicid[];
 
-#define ARCH_HAS_POWER_PDC_INIT	1
+#define ARCH_HAS_POWER_INIT	1
 
 #endif /*__KERNEL__*/
 
diff --git a/include/asm-i386/edac.h b/include/asm-i386/edac.h
new file mode 100644
index 0000000..3e7dd0a
--- /dev/null
+++ b/include/asm-i386/edac.h
@@ -0,0 +1,18 @@
+#ifndef ASM_EDAC_H
+#define ASM_EDAC_H
+
+/* ECC atomic, DMA, SMP and interrupt safe scrub function */
+
+static __inline__ void atomic_scrub(void *va, u32 size)
+{
+	unsigned long *virt_addr = va;
+	u32 i;
+
+	for (i = 0; i < size / 4; i++, virt_addr++)
+		/* Very carefully read and write to memory atomically
+		 * so we are interrupt, DMA and SMP safe.
+		 */
+		__asm__ __volatile__("lock; addl $0, %0"::"m"(*virt_addr));
+}
+
+#endif
diff --git a/include/asm-i386/futex.h b/include/asm-i386/futex.h
index e7a271d..44b9db8 100644
--- a/include/asm-i386/futex.h
+++ b/include/asm-i386/futex.h
@@ -61,7 +61,7 @@ futex_atomic_op_inuser (int encoded_op, 
 	if (op == FUTEX_OP_SET)
 		__futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
 	else {
-#if !defined(CONFIG_X86_BSWAP) && !defined(CONFIG_UML)
+#ifndef CONFIG_X86_BSWAP
 		if (boot_cpu_data.x86 == 3)
 			ret = -ENOSYS;
 		else
diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h
index 73296d9..997ca5d 100644
--- a/include/asm-i386/page.h
+++ b/include/asm-i386/page.h
@@ -110,10 +110,10 @@ extern int page_is_ram(unsigned long pag
 #endif /* __ASSEMBLY__ */
 
 #ifdef __ASSEMBLY__
-#define __PAGE_OFFSET		(0xC0000000)
+#define __PAGE_OFFSET		CONFIG_PAGE_OFFSET
 #define __PHYSICAL_START	CONFIG_PHYSICAL_START
 #else
-#define __PAGE_OFFSET		(0xC0000000UL)
+#define __PAGE_OFFSET		((unsigned long)CONFIG_PAGE_OFFSET)
 #define __PHYSICAL_START	((unsigned long)CONFIG_PHYSICAL_START)
 #endif
 #define __KERNEL_START		(__PAGE_OFFSET + __PHYSICAL_START)
diff --git a/include/asm-i386/signal.h b/include/asm-i386/signal.h
index 76524b4..026fd23 100644
--- a/include/asm-i386/signal.h
+++ b/include/asm-i386/signal.h
@@ -218,7 +218,6 @@ static __inline__ int sigfindinword(unsi
 }
 
 struct pt_regs;
-extern int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset));
 
 #define ptrace_signal_deliver(regs, cookie)		\
 	do {						\
diff --git a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h
index 2493e77..e20e995 100644
--- a/include/asm-i386/thread_info.h
+++ b/include/asm-i386/thread_info.h
@@ -140,6 +140,7 @@ register unsigned long current_stack_poi
 #define TIF_SYSCALL_EMU		6	/* syscall emulation active */
 #define TIF_SYSCALL_AUDIT	7	/* syscall auditing active */
 #define TIF_SECCOMP		8	/* secure computing */
+#define TIF_RESTORE_SIGMASK	9	/* restore signal mask in do_signal() */
 #define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE		17
 
@@ -152,6 +153,7 @@ register unsigned long current_stack_poi
 #define _TIF_SYSCALL_EMU	(1<<TIF_SYSCALL_EMU)
 #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP		(1<<TIF_SECCOMP)
+#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 
 /* work to do on interrupt/exception return */
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
index 481c3c0..597496e 100644
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -300,8 +300,23 @@
 #define __NR_inotify_add_watch	292
 #define __NR_inotify_rm_watch	293
 #define __NR_migrate_pages	294
+#define __NR_openat		295
+#define __NR_mkdirat		296
+#define __NR_mknodat		297
+#define __NR_fchownat		298
+#define __NR_futimesat		299
+#define __NR_newfstatat		300
+#define __NR_unlinkat		301
+#define __NR_renameat		302
+#define __NR_linkat		303
+#define __NR_symlinkat		304
+#define __NR_readlinkat		305
+#define __NR_fchmodat		306
+#define __NR_faccessat		307
+#define __NR_pselect6		308
+#define __NR_ppoll		309
 
-#define NR_syscalls 295
+#define NR_syscalls 310
 
 /*
  * user-visible error numbers are in the range -1 - -128: see
@@ -417,6 +432,7 @@ __syscall_return(type,__res); \
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
+#define __ARCH_WANT_SYS_RT_SIGSUSPEND
 #endif
 
 #ifdef __KERNEL_SYSCALLS__
diff --git a/include/asm-ia64/semaphore.h b/include/asm-ia64/semaphore.h
index bb89062..f483eeb 100644
--- a/include/asm-ia64/semaphore.h
+++ b/include/asm-ia64/semaphore.h
@@ -61,7 +61,7 @@ static inline void
 down (struct semaphore *sem)
 {
 	might_sleep();
-	if (atomic_dec_return(&sem->count) < 0)
+	if (ia64_fetchadd(-1, &sem->count.counter, acq) < 1)
 		__down(sem);
 }
 
@@ -75,7 +75,7 @@ down_interruptible (struct semaphore * s
 	int ret = 0;
 
 	might_sleep();
-	if (atomic_dec_return(&sem->count) < 0)
+	if (ia64_fetchadd(-1, &sem->count.counter, acq) < 1)
 		ret = __down_interruptible(sem);
 	return ret;
 }
@@ -85,7 +85,7 @@ down_trylock (struct semaphore *sem)
 {
 	int ret = 0;
 
-	if (atomic_dec_return(&sem->count) < 0)
+	if (ia64_fetchadd(-1, &sem->count.counter, acq) < 1)
 		ret = __down_trylock(sem);
 	return ret;
 }
@@ -93,7 +93,7 @@ down_trylock (struct semaphore *sem)
 static inline void
 up (struct semaphore * sem)
 {
-	if (atomic_inc_return(&sem->count) <= 0)
+	if (ia64_fetchadd(1, &sem->count.counter, rel) <= -1)
 		__up(sem);
 }
 
diff --git a/include/asm-ia64/sn/sn_feature_sets.h b/include/asm-ia64/sn/sn_feature_sets.h
index e68a808..9ca642c 100644
--- a/include/asm-ia64/sn/sn_feature_sets.h
+++ b/include/asm-ia64/sn/sn_feature_sets.h
@@ -8,7 +8,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2005 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2005-2006 Silicon Graphics, Inc.  All rights reserved.
  */
 
 
@@ -27,14 +27,12 @@ extern int sn_prom_feature_available(int
  * "false" for new features.
  *
  * Use:
- * 		if (sn_prom_feature_available(PRF_FEATURE_XXX))
+ * 		if (sn_prom_feature_available(PRF_XXX))
  * 			...
  */
 
-/*
- * Example: feature XXX
- */
-#define PRF_FEATURE_XXX		0
+#define PRF_PAL_CACHE_FLUSH_SAFE	0
+#define PRF_DEVICE_FLUSH_LIST		1
 
 
 
@@ -51,7 +49,7 @@ extern int sn_prom_feature_available(int
  *
  * By default, features are disabled unless explicitly enabled.
  */
-#define  OSF_MCA_SLV_TO_OS_INIT_SLV		0
-#define  OSF_FEAT_LOG_SBES			1
+#define  OSF_MCA_SLV_TO_OS_INIT_SLV	0
+#define  OSF_FEAT_LOG_SBES		1
 
 #endif /* _ASM_IA64_SN_FEATURE_SETS_H */
diff --git a/include/asm-ia64/sn/xp.h b/include/asm-ia64/sn/xp.h
index 203945a..9bd2f9b 100644
--- a/include/asm-ia64/sn/xp.h
+++ b/include/asm-ia64/sn/xp.h
@@ -18,6 +18,7 @@
 
 #include <linux/cache.h>
 #include <linux/hardirq.h>
+#include <linux/mutex.h>
 #include <asm/sn/types.h>
 #include <asm/sn/bte.h>
 
@@ -359,7 +360,7 @@ typedef void (*xpc_notify_func)(enum xpc
  * the channel.
  */
 struct xpc_registration {
-	struct semaphore sema;
+	struct mutex mutex;
 	xpc_channel_func func;		/* function to call */
 	void *key;			/* pointer to user's key */
 	u16 nentries;			/* #of msg entries in local msg queue */
diff --git a/include/asm-ia64/sn/xpc.h b/include/asm-ia64/sn/xpc.h
index 87e9cd5..0c36928 100644
--- a/include/asm-ia64/sn/xpc.h
+++ b/include/asm-ia64/sn/xpc.h
@@ -19,6 +19,8 @@
 #include <linux/interrupt.h>
 #include <linux/sysctl.h>
 #include <linux/device.h>
+#include <linux/mutex.h>
+#include <linux/completion.h>
 #include <asm/pgtable.h>
 #include <asm/processor.h>
 #include <asm/sn/bte.h>
@@ -335,8 +337,7 @@ struct xpc_openclose_args {
  * and consumed by the intended recipient.
  */
 struct xpc_notify {
-	struct semaphore sema;		/* notify semaphore */
-	volatile u8 type;			/* type of notification */
+	volatile u8 type;		/* type of notification */
 
 	/* the following two fields are only used if type == XPC_N_CALL */
 	xpc_notify_func func;		/* user's notify function */
@@ -465,8 +466,8 @@ struct xpc_channel {
 	xpc_channel_func func;		/* user's channel function */
 	void *key;			/* pointer to user's key */
 
-	struct semaphore msg_to_pull_sema; /* next msg to pull serialization */
-	struct semaphore wdisconnect_sema; /* wait for channel disconnect */
+	struct mutex msg_to_pull_mutex;	/* next msg to pull serialization */
+	struct completion wdisconnect_wait; /* wait for channel disconnect */
 
 	struct xpc_openclose_args *local_openclose_args; /* args passed on */
 					/* opening or closing of channel */
diff --git a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h
index d8aae4d..412ef8e 100644
--- a/include/asm-ia64/topology.h
+++ b/include/asm-ia64/topology.h
@@ -18,6 +18,10 @@
 #include <asm/smp.h>
 
 #ifdef CONFIG_NUMA
+
+/* Nodes w/o CPUs are preferred for memory allocations, see build_zonelists */
+#define PENALTY_FOR_NODE_WITH_CPUS 255
+
 /*
  * Returns the number of the node containing CPU 'cpu'
  */
diff --git a/include/asm-powerpc/kexec.h b/include/asm-powerpc/kexec.h
index 640a645..bda2f21 100644
--- a/include/asm-powerpc/kexec.h
+++ b/include/asm-powerpc/kexec.h
@@ -33,6 +33,7 @@
 
 #ifdef CONFIG_KEXEC
 
+#ifndef __ASSEMBLY__
 #ifdef __powerpc64__
 /*
  * This function is responsible for capturing register states if coming
@@ -104,7 +105,6 @@ static inline void crash_setup_regs(stru
 					struct pt_regs *oldregs) { }
 #endif /* !__powerpc64 __ */
 
-#ifndef __ASSEMBLY__
 #define MAX_NOTE_BYTES 1024
 
 #ifdef __powerpc64__
@@ -121,6 +121,8 @@ extern void default_machine_kexec(struct
 extern int default_machine_kexec_prepare(struct kimage *image);
 extern void default_machine_crash_shutdown(struct pt_regs *regs);
 
+extern void machine_kexec_simple(struct kimage *image);
+
 #endif /* ! __ASSEMBLY__ */
 #endif /* CONFIG_KEXEC */
 #endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/lppaca.h b/include/asm-powerpc/lppaca.h
index cd9f11f..4dc514a 100644
--- a/include/asm-powerpc/lppaca.h
+++ b/include/asm-powerpc/lppaca.h
@@ -31,7 +31,7 @@
 
 /* The Hypervisor barfs if the lppaca crosses a page boundary.  A 1k
  * alignment is sufficient to prevent this */
-struct __attribute__((__aligned__(0x400))) lppaca {
+struct lppaca {
 //=============================================================================
 // CACHE_LINE_1 0x0000 - 0x007F Contains read-only data
 // NOTE: The xDynXyz fields are fields that will be dynamically changed by
@@ -129,7 +129,7 @@ struct __attribute__((__aligned__(0x400)
 // CACHE_LINE_4-5 0x0100 - 0x01FF Contains PMC interrupt data
 //=============================================================================
 	u8	pmc_save_area[256];	// PMC interrupt Area           x00-xFF
-};
+} __attribute__((__aligned__(0x400)));
 
 extern struct lppaca lppaca[];
 
diff --git a/include/asm-powerpc/pmac_pfunc.h b/include/asm-powerpc/pmac_pfunc.h
index d9728c8..cef6130 100644
--- a/include/asm-powerpc/pmac_pfunc.h
+++ b/include/asm-powerpc/pmac_pfunc.h
@@ -167,6 +167,7 @@ struct pmf_irq_client {
 	void			*data;
 	struct module		*owner;
 	struct list_head	link;
+	struct pmf_function	*func;
 };
 
 
@@ -187,9 +188,7 @@ extern int pmf_register_irq_client(struc
 				   const char *name,
 				   struct pmf_irq_client *client);
 
-extern void pmf_unregister_irq_client(struct device_node *np,
-				      const char *name,
-				      struct pmf_irq_client *client);
+extern void pmf_unregister_irq_client(struct pmf_irq_client *client);
 
 /*
  * Called by the handlers when an irq happens
diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h
index 7e09d7c..67cdaf3 100644
--- a/include/asm-powerpc/thread_info.h
+++ b/include/asm-powerpc/thread_info.h
@@ -122,6 +122,7 @@ static inline struct thread_info *curren
 #define TIF_RESTOREALL		12	/* Restore all regs (implies NOERROR) */
 #define TIF_SAVE_NVGPRS		13	/* Save r14-r31 in signal frame */
 #define TIF_NOERROR		14	/* Force successful syscall return */
+#define TIF_RESTORE_SIGMASK	15	/* Restore signal mask in do_signal */
 
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
@@ -138,10 +139,12 @@ static inline struct thread_info *curren
 #define _TIF_RESTOREALL		(1<<TIF_RESTOREALL)
 #define _TIF_SAVE_NVGPRS	(1<<TIF_SAVE_NVGPRS)
 #define _TIF_NOERROR		(1<<TIF_NOERROR)
+#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
 #define _TIF_SYSCALL_T_OR_A	(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
 
 #define _TIF_USER_WORK_MASK	(_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \
-				 _TIF_NEED_RESCHED | _TIF_RESTOREALL)
+				 _TIF_NEED_RESCHED | _TIF_RESTOREALL | \
+				 _TIF_RESTORE_SIGMASK)
 #define _TIF_PERSYSCALL_MASK	(_TIF_RESTOREALL|_TIF_NOERROR|_TIF_SAVE_NVGPRS)
 
 #endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h
index 19eaac3..a40cdff 100644
--- a/include/asm-powerpc/unistd.h
+++ b/include/asm-powerpc/unistd.h
@@ -298,8 +298,10 @@
 #define __NR_inotify_rm_watch	277
 #define __NR_spu_run		278
 #define __NR_spu_create		279
+#define __NR_pselect6		280
+#define __NR_ppoll		281
 
-#define __NR_syscalls		280
+#define __NR_syscalls		282
 
 #ifdef __KERNEL__
 #define __NR__exit __NR_exit
@@ -444,11 +446,13 @@ type name(type1 arg1, type2 arg2, type3 
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
+#define __ARCH_WANT_SYS_RT_SIGSUSPEND
 #ifdef CONFIG_PPC32
 #define __ARCH_WANT_OLD_STAT
 #endif
 #ifdef CONFIG_PPC64
 #define __ARCH_WANT_COMPAT_SYS_TIME
+#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
 #endif
 
 /*
diff --git a/include/asm-s390/dasd.h b/include/asm-s390/dasd.h
index 77b10d6..1630c26 100644
--- a/include/asm-s390/dasd.h
+++ b/include/asm-s390/dasd.h
@@ -8,8 +8,6 @@
  * any future changes wrt the API will result in a change of the APIVERSION reported
  * to userspace by the DASDAPIVER-ioctl
  *
- * $Revision: 1.6 $
- *
  */
 
 #ifndef DASD_H
diff --git a/include/asm-s390/qdio.h b/include/asm-s390/qdio.h
index 7bc15f0..a2f37a9 100644
--- a/include/asm-s390/qdio.h
+++ b/include/asm-s390/qdio.h
@@ -11,8 +11,6 @@
 #ifndef __QDIO_H__
 #define __QDIO_H__
 
-#define VERSION_QDIO_H "$Revision: 1.57 $"
-
 /* note, that most of the typedef's are from ingo. */
 
 #include <linux/interrupt.h>
diff --git a/include/asm-s390/thread_info.h b/include/asm-s390/thread_info.h
index f3797a5..8e0c7ed 100644
--- a/include/asm-s390/thread_info.h
+++ b/include/asm-s390/thread_info.h
@@ -2,7 +2,7 @@
  *  include/asm-s390/thread_info.h
  *
  *  S390 version
- *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Copyright (C) IBM Corp. 2002,2006
  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
  */
 
@@ -88,7 +88,7 @@ static inline struct thread_info *curren
  * thread information flags bit numbers
  */
 #define TIF_SYSCALL_TRACE	0	/* syscall trace active */
-#define TIF_NOTIFY_RESUME	1	/* resumption notification requested */
+#define TIF_RESTORE_SIGMASK	1	/* restore signal mask in do_signal() */
 #define TIF_SIGPENDING		2	/* signal pending */
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
 #define TIF_RESTART_SVC		4	/* restart svc with new svc number */
@@ -102,7 +102,7 @@ static inline struct thread_info *curren
 #define TIF_MEMDIE		19
 
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
-#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
+#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
 #define _TIF_RESTART_SVC	(1<<TIF_RESTART_SVC)
diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h
index 2861cdc..29a9f35 100644
--- a/include/asm-s390/unistd.h
+++ b/include/asm-s390/unistd.h
@@ -279,8 +279,24 @@
 #define __NR_inotify_init	284
 #define __NR_inotify_add_watch	285
 #define __NR_inotify_rm_watch	286
+/* Number 287 is reserved for new sys_migrate_pages */
+#define __NR_openat		288
+#define __NR_mkdirat		289
+#define __NR_mknodat		290
+#define __NR_fchownat		291
+#define __NR_futimesat		292
+#define __NR_newfstatat		293
+#define __NR_unlinkat		294
+#define __NR_renameat		295
+#define __NR_linkat		296
+#define __NR_symlinkat		297
+#define __NR_readlinkat		298
+#define __NR_fchmodat		299
+#define __NR_faccessat		300
+#define __NR_pselect6		301
+#define __NR_ppoll		302
 
-#define NR_syscalls 287
+#define NR_syscalls 303
 
 /* 
  * There are some system calls that are not present on 64 bit, some
@@ -539,11 +555,15 @@ type name(type1 arg1, type2 arg2, type3 
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
+#define __ARCH_WANT_SYS_RT_SIGSUSPEND
 # ifndef CONFIG_64BIT
 #   define __ARCH_WANT_STAT64
 #   define __ARCH_WANT_SYS_TIME
 # endif
-# define __ARCH_WANT_COMPAT_SYS_TIME
+# ifdef CONFIG_COMPAT
+#   define __ARCH_WANT_COMPAT_SYS_TIME
+#   define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
+# endif
 #endif
 
 #ifdef __KERNEL_SYSCALLS__
diff --git a/include/asm-sh/bus-sh.h b/include/asm-sh/bus-sh.h
deleted file mode 100644
index e42d63b..0000000
--- a/include/asm-sh/bus-sh.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * include/asm-sh/bus-sh.h
- *
- * Copyright (C) 2004 Paul Mundt
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-#ifndef __ASM_SH_BUS_SH_H
-#define __ASM_SH_BUS_SH_H
-
-extern struct bus_type sh_bus_types[];
-
-struct sh_dev {
-	struct device	dev;
-	char		*name;
-	unsigned int	dev_id;
-	unsigned int	bus_id;
-	struct resource	res;
-	void		*mapbase;
-	unsigned int	irq[6];
-	u64		*dma_mask;
-	u64		coherent_dma_mask;
-};
-
-#define to_sh_dev(d)	container_of((d), struct sh_dev, dev)
-
-#define sh_get_drvdata(d)	dev_get_drvdata(&(d)->dev)
-#define sh_set_drvdata(d,p)	dev_set_drvdata(&(d)->dev, (p))
-
-struct sh_driver {
-	struct device_driver	drv;
-	unsigned int		dev_id;
-	unsigned int		bus_id;
-	int (*probe)(struct sh_dev *);
-	int (*remove)(struct sh_dev *);
-	int (*suspend)(struct sh_dev *, pm_message_t);
-	int (*resume)(struct sh_dev *);
-};
-
-#define to_sh_driver(d)	container_of((d), struct sh_driver, drv)
-#define sh_name(d)	((d)->dev.driver->name)
-
-/*
- * Device ID numbers for bus types
- */
-enum {
-	SH_DEV_ID_USB_OHCI,
-};
-
-#define SH_NR_BUSES		1
-#define SH_BUS_NAME_VIRT	"shbus"
-
-enum {
-	SH_BUS_VIRT,
-};
-
-/* arch/sh/kernel/cpu/bus.c */
-extern int sh_device_register(struct sh_dev *dev);
-extern void sh_device_unregister(struct sh_dev *dev);
-extern int sh_driver_register(struct sh_driver *drv);
-extern void sh_driver_unregister(struct sh_driver *drv);
-
-#endif /* __ASM_SH_BUS_SH_H */
-
diff --git a/include/asm-sh/cpu-sh3/mmu_context.h b/include/asm-sh/cpu-sh3/mmu_context.h
index 5cfaa6b..a844ea0 100644
--- a/include/asm-sh/cpu-sh3/mmu_context.h
+++ b/include/asm-sh/cpu-sh3/mmu_context.h
@@ -24,5 +24,15 @@
 #define MMU_NTLB_WAYS		4
 #define MMU_CONTROL_INIT	0x007	/* SV=0, TF=1, IX=1, AT=1 */
 
+#define TRA	0xffffffd0
+#define EXPEVT	0xffffffd4
+
+#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
+#define INTEVT	0xa4000000	/* INTEVTE2(0xa4000000) */
+#else
+#define INTEVT	0xffffffd8
+#endif
+
 #endif /* __ASM_CPU_SH3_MMU_CONTEXT_H */
 
diff --git a/include/asm-sh/cpu-sh4/mmu_context.h b/include/asm-sh/cpu-sh4/mmu_context.h
index 5b64d04..ff4c5fb 100644
--- a/include/asm-sh/cpu-sh4/mmu_context.h
+++ b/include/asm-sh/cpu-sh4/mmu_context.h
@@ -23,7 +23,11 @@
 #define MMU_PAGE_ASSOC_BIT	0x80
 
 #define MMU_NTLB_ENTRIES	64	/* for 7750 */
+#ifdef CONFIG_SH_STORE_QUEUES
+#define MMU_CONTROL_INIT	0x05	/* SQMD=0, SV=0, TI=1, AT=1 */
+#else
 #define MMU_CONTROL_INIT	0x205	/* SQMD=1, SV=0, TI=1, AT=1 */
+#endif
 
 #define MMU_ITLB_DATA_ARRAY	0xF3000000
 #define MMU_UTLB_DATA_ARRAY	0xF7000000
@@ -35,5 +39,9 @@
 #define MMU_I_ENTRY_SHIFT	    8
 #define MMU_ITLB_VALID		0x100
 
+#define TRA	0xff000020
+#define EXPEVT	0xff000024
+#define INTEVT	0xff000028
+
 #endif /* __ASM_CPU_SH4_MMU_CONTEXT_H */
 
diff --git a/include/asm-sh/ioctls.h b/include/asm-sh/ioctls.h
index 1866f3f..9d84a2d 100644
--- a/include/asm-sh/ioctls.h
+++ b/include/asm-sh/ioctls.h
@@ -94,6 +94,6 @@
 #define TIOCSERSETMULTI _IOW('T', 91, struct serial_multiport_struct) /* 0x545B */ /* Set multiport config */
 
 #define TIOCMIWAIT	_IO('T', 92) /* 0x545C */	/* wait for a change on serial input line(s) */
-#define TIOCGICOUNT	_IOR('T', 93, struct async_icount) /* 0x545D */	/* read serial port inline interrupt counts */
+#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
 
 #endif /* __ASM_SH_IOCTLS_H */
diff --git a/include/asm-sh/irq-sh73180.h b/include/asm-sh/irq-sh73180.h
index bf2e431..d705252 100644
--- a/include/asm-sh/irq-sh73180.h
+++ b/include/asm-sh/irq-sh73180.h
@@ -25,11 +25,6 @@
 #undef DMA_IPR_POS
 #undef DMA_PRIORITY
 
-#undef NR_IRQS
-
-#undef __irq_demux
-#undef irq_demux
-
 #undef INTC_IMCR0
 #undef INTC_IMCR1
 #undef INTC_IMCR2
@@ -229,33 +224,6 @@
 #define SIU_IPR_POS	1
 #define SIU_PRIORITY	3
 
-
-/* ONCHIP_NR_IRQS */
-#define NR_IRQS 109
-
-/* In a generic kernel, NR_IRQS is an upper bound, and we should use
- * ACTUAL_NR_IRQS (which uses the machine vector) to get the correct value.
- */
-#define ACTUAL_NR_IRQS NR_IRQS
-
-
-extern void disable_irq(unsigned int);
-extern void disable_irq_nosync(unsigned int);
-extern void enable_irq(unsigned int);
-
-/*
- * Simple Mask Register Support
- */
-extern void make_maskreg_irq(unsigned int irq);
-extern unsigned short *irq_mask_register;
-
-/*
- * Function for "on chip support modules".
- */
-extern void make_ipr_irq(unsigned int irq, unsigned int addr,
-			 int pos,  int priority);
-extern void make_imask_irq(unsigned int irq);
-
 #define PORT_PACR	0xA4050100UL
 #define PORT_PBCR	0xA4050102UL
 #define PORT_PCCR	0xA4050104UL
@@ -343,8 +311,6 @@ extern void make_imask_irq(unsigned int 
 #define IRQ6_PRIORITY	1
 #define IRQ7_PRIORITY	1
 
-extern int shmse_irq_demux(int irq);
-#define __irq_demux(irq) shmse_irq_demux(irq)
-#define irq_demux(irq) __irq_demux(irq)
+int shmse_irq_demux(int irq);
 
 #endif /* __ASM_SH_IRQ_SH73180_H */
diff --git a/include/asm-sh/irq-sh7780.h b/include/asm-sh/irq-sh7780.h
index 8c8ca12..7f90315 100644
--- a/include/asm-sh/irq-sh7780.h
+++ b/include/asm-sh/irq-sh7780.h
@@ -299,29 +299,6 @@
 #define	GPIO_IPR_POS	2
 #define	GPIO_PRIORITY	3
 
-/* ONCHIP_NR_IRQS */
-#define NR_IRQS 150	/* 111 + 16 */
-
-/* In a generic kernel, NR_IRQS is an upper bound, and we should use
- * ACTUAL_NR_IRQS (which uses the machine vector) to get the correct value.
- */
-#define ACTUAL_NR_IRQS NR_IRQS
-
-extern void disable_irq(unsigned int);
-extern void disable_irq_nosync(unsigned int);
-extern void enable_irq(unsigned int);
-
-/*
- * Simple Mask Register Support
- */
-extern void make_maskreg_irq(unsigned int irq);
-extern unsigned short *irq_mask_register;
-
-/*
- * Function for "on chip support modules".
- */
-extern void make_imask_irq(unsigned int irq);
-
 #define	INTC_TMU0_MSK	0
 #define	INTC_TMU3_MSK	1
 #define	INTC_RTC_MSK	2
diff --git a/include/asm-sh/irq.h b/include/asm-sh/irq.h
index 060ec3c..42b8394 100644
--- a/include/asm-sh/irq.h
+++ b/include/asm-sh/irq.h
@@ -245,6 +245,7 @@
 #endif /* ST40STB1 */
 
 #endif /* 775x / SH4-202 / ST40STB1 */
+#endif /* 7780 */
 
 /* NR_IRQS is made from three components:
  *   1. ONCHIP_NR_IRQS - number of IRLS + on-chip peripherial modules
@@ -274,8 +275,11 @@
 # define ONCHIP_NR_IRQS 72
 #elif defined(CONFIG_CPU_SUBTYPE_ST40STB1)
 # define ONCHIP_NR_IRQS 144
-#elif defined(CONFIG_CPU_SUBTYPE_SH7300)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7300) || \
+      defined(CONFIG_CPU_SUBTYPE_SH73180)
 # define ONCHIP_NR_IRQS 109
+#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
+# define ONCHIP_NR_IRQS 111
 #elif defined(CONFIG_SH_UNKNOWN)	/* Most be last */
 # define ONCHIP_NR_IRQS 144
 #endif
@@ -306,6 +310,8 @@
 # define OFFCHIP_NR_IRQS 96
 #elif defined (CONFIG_SH_TITAN)
 # define OFFCHIP_NR_IRQS 4
+#elif defined(CONFIG_SH_R7780RP)
+# define OFFCHIP_NR_IRQS 16
 #elif defined(CONFIG_SH_UNKNOWN)
 # define OFFCHIP_NR_IRQS 16	/* Must also be last */
 #else
@@ -550,7 +556,7 @@ extern int ipr_irq_demux(int irq);
 #define INTC_ICR_IRLM	(1<<7)
 #endif
 
-#else
+#ifdef CONFIG_CPU_SUBTYPE_SH7780
 #include <asm/irq-sh7780.h>
 #endif
 
diff --git a/include/asm-sh/microdev.h b/include/asm-sh/microdev.h
new file mode 100644
index 0000000..018332a
--- /dev/null
+++ b/include/asm-sh/microdev.h
@@ -0,0 +1,80 @@
+/*
+ * linux/include/asm-sh/microdev.h
+ *
+ * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
+ *
+ * Definitions for the SuperH SH4-202 MicroDev board.
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ */
+#ifndef __ASM_SH_MICRODEV_H
+#define __ASM_SH_MICRODEV_H
+
+extern void init_microdev_irq(void);
+extern void microdev_print_fpga_intc_status(void);
+
+/*
+ * The following are useful macros for manipulating the interrupt
+ * controller (INTC) on the CPU-board FPGA.  should be noted that there
+ * is an INTC on the FPGA, and a seperate INTC on the SH4-202 core -
+ * these are two different things, both of which need to be prorammed to
+ * correctly route - unfortunately, they have the same name and
+ * abbreviations!
+ */
+#define	MICRODEV_FPGA_INTC_BASE		0xa6110000ul				/* INTC base address on CPU-board FPGA */
+#define	MICRODEV_FPGA_INTENB_REG	(MICRODEV_FPGA_INTC_BASE+0ul)		/* Interrupt Enable Register on INTC on CPU-board FPGA */
+#define	MICRODEV_FPGA_INTDSB_REG	(MICRODEV_FPGA_INTC_BASE+8ul)		/* Interrupt Disable Register on INTC on CPU-board FPGA */
+#define	MICRODEV_FPGA_INTC_MASK(n)	(1ul<<(n))				/* Interupt mask to enable/disable INTC in CPU-board FPGA */
+#define	MICRODEV_FPGA_INTPRI_REG(n)	(MICRODEV_FPGA_INTC_BASE+0x10+((n)/8)*8)/* Interrupt Priority Register on INTC on CPU-board FPGA */
+#define	MICRODEV_FPGA_INTPRI_LEVEL(n,x)	((x)<<(((n)%8)*4))			/* MICRODEV_FPGA_INTPRI_LEVEL(int_number, int_level) */
+#define	MICRODEV_FPGA_INTPRI_MASK(n)	(MICRODEV_FPGA_INTPRI_LEVEL((n),0xful))	/* Interrupt Priority Mask on INTC on CPU-board FPGA */
+#define	MICRODEV_FPGA_INTSRC_REG	(MICRODEV_FPGA_INTC_BASE+0x30ul)	/* Interrupt Source Register on INTC on CPU-board FPGA */
+#define	MICRODEV_FPGA_INTREQ_REG	(MICRODEV_FPGA_INTC_BASE+0x38ul)	/* Interrupt Request Register on INTC on CPU-board FPGA */
+
+
+/*
+ * The following are the IRQ numbers for the Linux Kernel for external
+ * interrupts.  i.e. the numbers seen by 'cat /proc/interrupt'.
+ */
+#define MICRODEV_LINUX_IRQ_KEYBOARD	 1	/* SuperIO Keyboard */
+#define MICRODEV_LINUX_IRQ_SERIAL1	 2	/* SuperIO Serial #1 */
+#define MICRODEV_LINUX_IRQ_ETHERNET	 3	/* on-board Ethnernet */
+#define MICRODEV_LINUX_IRQ_SERIAL2	 4	/* SuperIO Serial #2 */
+#define MICRODEV_LINUX_IRQ_USB_HC	 7	/* on-board USB HC */
+#define MICRODEV_LINUX_IRQ_MOUSE	12	/* SuperIO PS/2 Mouse */
+#define MICRODEV_LINUX_IRQ_IDE2		13	/* SuperIO IDE #2 */
+#define MICRODEV_LINUX_IRQ_IDE1		14	/* SuperIO IDE #1 */
+
+/*
+ * The following are the IRQ numbers for the INTC on the FPGA for
+ * external interrupts.  i.e. the bits in the INTC registers in the
+ * FPGA.
+ */
+#define MICRODEV_FPGA_IRQ_KEYBOARD	 1	/* SuperIO Keyboard */
+#define MICRODEV_FPGA_IRQ_SERIAL1	 3	/* SuperIO Serial #1 */
+#define MICRODEV_FPGA_IRQ_SERIAL2	 4	/* SuperIO Serial #2 */
+#define MICRODEV_FPGA_IRQ_MOUSE		12	/* SuperIO PS/2 Mouse */
+#define MICRODEV_FPGA_IRQ_IDE1		14	/* SuperIO IDE #1 */
+#define MICRODEV_FPGA_IRQ_IDE2		15	/* SuperIO IDE #2 */
+#define MICRODEV_FPGA_IRQ_USB_HC	16	/* on-board USB HC */
+#define MICRODEV_FPGA_IRQ_ETHERNET	18	/* on-board Ethnernet */
+
+#define MICRODEV_IRQ_PCI_INTA		 8
+#define MICRODEV_IRQ_PCI_INTB		 9
+#define MICRODEV_IRQ_PCI_INTC		10
+#define MICRODEV_IRQ_PCI_INTD		11
+
+#define __IO_PREFIX microdev
+#include <asm/io_generic.h>
+
+#if defined(CONFIG_PCI)
+unsigned char  microdev_pci_inb(unsigned long port);
+unsigned short microdev_pci_inw(unsigned long port);
+unsigned long  microdev_pci_inl(unsigned long port);
+void           microdev_pci_outb(unsigned char  data, unsigned long port);
+void           microdev_pci_outw(unsigned short data, unsigned long port);
+void           microdev_pci_outl(unsigned long  data, unsigned long port);
+#endif
+
+#endif /* __ASM_SH_MICRODEV_H */
diff --git a/include/asm-sh/microdev/io.h b/include/asm-sh/microdev/io.h
deleted file mode 100644
index f2ca4ac..0000000
--- a/include/asm-sh/microdev/io.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * linux/include/asm-sh/io_microdev.h
- *
- * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
- *
- * IO functions for the SuperH SH4-202 MicroDev board.
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- */
-
-
-#ifndef _ASM_SH_IO_MICRODEV_H
-#define _ASM_SH_IO_MICRODEV_H
-
-extern unsigned long microdev_isa_port2addr(unsigned long offset);
-
-extern unsigned char microdev_inb(unsigned long port);
-extern unsigned short microdev_inw(unsigned long port);
-extern unsigned int microdev_inl(unsigned long port);
-
-extern void microdev_outb(unsigned char value, unsigned long port);
-extern void microdev_outw(unsigned short value, unsigned long port);
-extern void microdev_outl(unsigned int value, unsigned long port);
-
-extern unsigned char microdev_inb_p(unsigned long port);
-extern unsigned short microdev_inw_p(unsigned long port);
-extern unsigned int microdev_inl_p(unsigned long port);
-
-extern void microdev_outb_p(unsigned char value, unsigned long port);
-extern void microdev_outw_p(unsigned short value, unsigned long port);
-extern void microdev_outl_p(unsigned int value, unsigned long port);
-
-extern void microdev_insb(unsigned long port, void *addr, unsigned long count);
-extern void microdev_insw(unsigned long port, void *addr, unsigned long count);
-extern void microdev_insl(unsigned long port, void *addr, unsigned long count);
-
-extern void microdev_outsb(unsigned long port, const void *addr, unsigned long count);
-extern void microdev_outsw(unsigned long port, const void *addr, unsigned long count);
-extern void microdev_outsl(unsigned long port, const void *addr, unsigned long count);
-
-#if defined(CONFIG_PCI)
-extern unsigned char  microdev_pci_inb(unsigned long port);
-extern unsigned short microdev_pci_inw(unsigned long port);
-extern unsigned long  microdev_pci_inl(unsigned long port);
-extern void           microdev_pci_outb(unsigned char  data, unsigned long port);
-extern void           microdev_pci_outw(unsigned short data, unsigned long port);
-extern void           microdev_pci_outl(unsigned long  data, unsigned long port);
-#endif
-
-#endif /* _ASM_SH_IO_MICRODEV_H */
-
diff --git a/include/asm-sh/microdev/irq.h b/include/asm-sh/microdev/irq.h
deleted file mode 100644
index 47f6f77..0000000
--- a/include/asm-sh/microdev/irq.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * linux/include/asm-sh/irq_microdev.h
- *
- * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
- *
- * IRQ functions for the SuperH SH4-202 MicroDev board.
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- */
-
-
-#ifndef _ASM_SH_IRQ_MICRODEV_H
-#define _ASM_SH_IRQ_MICRODEV_H
-
-extern void init_microdev_irq(void);
-extern void microdev_print_fpga_intc_status(void);
-
-
-	/*
-	 *	The following are useful macros for manipulating the
-	 *	interrupt controller (INTC) on the CPU-board FPGA.
-	 *	It should be noted that there is an INTC on the FPGA,
-	 *	and a seperate INTC on the SH4-202 core - these are
-	 *	two different things, both of which need to be prorammed
-	 *	to correctly route - unfortunately, they have the
-	 *	same name and abbreviations!
-	 */
-#define	MICRODEV_FPGA_INTC_BASE		0xa6110000ul				/* INTC base address on CPU-board FPGA */
-#define	MICRODEV_FPGA_INTENB_REG	(MICRODEV_FPGA_INTC_BASE+0ul)		/* Interrupt Enable Register on INTC on CPU-board FPGA */
-#define	MICRODEV_FPGA_INTDSB_REG	(MICRODEV_FPGA_INTC_BASE+8ul)		/* Interrupt Disable Register on INTC on CPU-board FPGA */
-#define	MICRODEV_FPGA_INTC_MASK(n)	(1ul<<(n))				/* Interupt mask to enable/disable INTC in CPU-board FPGA */
-#define	MICRODEV_FPGA_INTPRI_REG(n)	(MICRODEV_FPGA_INTC_BASE+0x10+((n)/8)*8)/* Interrupt Priority Register on INTC on CPU-board FPGA */
-#define	MICRODEV_FPGA_INTPRI_LEVEL(n,x)	((x)<<(((n)%8)*4))			/* MICRODEV_FPGA_INTPRI_LEVEL(int_number, int_level) */
-#define	MICRODEV_FPGA_INTPRI_MASK(n)	(MICRODEV_FPGA_INTPRI_LEVEL((n),0xful))	/* Interrupt Priority Mask on INTC on CPU-board FPGA */
-#define	MICRODEV_FPGA_INTSRC_REG	(MICRODEV_FPGA_INTC_BASE+0x30ul)	/* Interrupt Source Register on INTC on CPU-board FPGA */
-#define	MICRODEV_FPGA_INTREQ_REG	(MICRODEV_FPGA_INTC_BASE+0x38ul)	/* Interrupt Request Register on INTC on CPU-board FPGA */
-
-
-	/*
-	 *	The following are the IRQ numbers for the Linux Kernel for external interrupts.
-	 *	i.e. the numbers seen by 'cat /proc/interrupt'.
-	 */
-#define MICRODEV_LINUX_IRQ_KEYBOARD	 1	/* SuperIO Keyboard */
-#define MICRODEV_LINUX_IRQ_SERIAL1	 2	/* SuperIO Serial #1 */
-#define MICRODEV_LINUX_IRQ_ETHERNET	 3	/* on-board Ethnernet */
-#define MICRODEV_LINUX_IRQ_SERIAL2	 4	/* SuperIO Serial #2 */
-#define MICRODEV_LINUX_IRQ_USB_HC	 7	/* on-board USB HC */
-#define MICRODEV_LINUX_IRQ_MOUSE	12	/* SuperIO PS/2 Mouse */
-#define MICRODEV_LINUX_IRQ_IDE2		13	/* SuperIO IDE #2 */
-#define MICRODEV_LINUX_IRQ_IDE1		14	/* SuperIO IDE #1 */
-
-	/*
-	 *	The following are the IRQ numbers for the INTC on the FPGA for external interrupts.
-	 *	i.e. the bits in the INTC registers in the FPGA.
-	 */
-#define MICRODEV_FPGA_IRQ_KEYBOARD	 1	/* SuperIO Keyboard */
-#define MICRODEV_FPGA_IRQ_SERIAL1	 3	/* SuperIO Serial #1 */
-#define MICRODEV_FPGA_IRQ_SERIAL2	 4	/* SuperIO Serial #2 */
-#define MICRODEV_FPGA_IRQ_MOUSE		12	/* SuperIO PS/2 Mouse */
-#define MICRODEV_FPGA_IRQ_IDE1		14	/* SuperIO IDE #1 */
-#define MICRODEV_FPGA_IRQ_IDE2		15	/* SuperIO IDE #2 */
-#define MICRODEV_FPGA_IRQ_USB_HC	16	/* on-board USB HC */
-#define MICRODEV_FPGA_IRQ_ETHERNET	18	/* on-board Ethnernet */
-
-#define MICRODEV_IRQ_PCI_INTA		 8
-#define MICRODEV_IRQ_PCI_INTB		 9
-#define MICRODEV_IRQ_PCI_INTC		10
-#define MICRODEV_IRQ_PCI_INTD		11
-
-#endif /* _ASM_SH_IRQ_MICRODEV_H */
diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h
index c490479..fa5bd2d 100644
--- a/include/asm-sh/processor.h
+++ b/include/asm-sh/processor.h
@@ -12,7 +12,6 @@
 #include <asm/page.h>
 #include <asm/types.h>
 #include <asm/cache.h>
-#include <linux/threads.h>
 #include <asm/ptrace.h>
 
 /*
@@ -30,7 +29,7 @@
  *  CPU type and hardware bug flags. Kept separately for each CPU.
  *
  *  Each one of these also needs a CONFIG_CPU_SUBTYPE_xxx entry
- *  in arch/sh/Kconfig, as well as an entry in arch/sh/kernel/setup.c
+ *  in arch/sh/mm/Kconfig, as well as an entry in arch/sh/kernel/setup.c
  *  for parsing the subtype in get_cpu_subtype().
  */
 enum cpu_type {
@@ -44,7 +43,7 @@ enum cpu_type {
 	/* SH-4 types */
 	CPU_SH7750, CPU_SH7750S, CPU_SH7750R, CPU_SH7751, CPU_SH7751R,
 	CPU_SH7760, CPU_ST40RA, CPU_ST40GX1, CPU_SH4_202, CPU_SH4_501,
-	CPU_SH73180,
+	CPU_SH73180, CPU_SH7770, CPU_SH7780, CPU_SH7781,
 
 	/* Unknown subtype */
 	CPU_SH_NONE
@@ -52,14 +51,8 @@ enum cpu_type {
 
 struct sh_cpuinfo {
 	enum cpu_type type;
-	char	hard_math;
 	unsigned long loops_per_jiffy;
 
-	unsigned int cpu_clock, master_clock, bus_clock, module_clock;
-#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
-	unsigned int memory_clock;
-#endif
-
 	struct cache_info icache;
 	struct cache_info dcache;
 
@@ -131,7 +124,7 @@ union sh_fpu_union {
 	struct sh_fpu_soft_struct soft;
 };
 
-/* 
+/*
  * Processor flags
  */
 
@@ -140,6 +133,7 @@ union sh_fpu_union {
 #define CPU_HAS_MMU_PAGE_ASSOC	0x0004	/* SH3: TLB way selection bit support */
 #define CPU_HAS_DSP		0x0008	/* SH-DSP: DSP support */
 #define CPU_HAS_PERF_COUNTER	0x0010	/* Hardware performance counters */
+#define CPU_HAS_PTEA		0x0020	/* PTEA register */
 
 struct thread_struct {
 	unsigned long sp;
@@ -160,10 +154,10 @@ extern int ubc_usercnt;
 #define INIT_THREAD  {						\
 	sizeof(init_stack) + (long) &init_stack, /* sp */	\
 	0,					 /* pc */	\
-	0, 0, 							\
-	0, 							\
-	0, 							\
-	{{{0,}},} 				/* fpu state */	\
+	0, 0,							\
+	0,							\
+	0,							\
+	{{{0,}},}				/* fpu state */	\
 }
 
 /*
@@ -171,7 +165,7 @@ extern int ubc_usercnt;
  */
 #define start_thread(regs, new_pc, new_sp)	 \
 	set_fs(USER_DS);			 \
-	regs->pr = 0;   		 	 \
+	regs->pr = 0;				 \
 	regs->sr = SR_FD;	/* User mode. */ \
 	regs->pc = new_pc;			 \
 	regs->regs[15] = new_sp
@@ -239,16 +233,16 @@ extern void save_fpu(struct task_struct 
 #define save_fpu(tsk)	do { } while (0)
 #endif
 
-#define unlazy_fpu(tsk, regs) do { 				\
+#define unlazy_fpu(tsk, regs) do {			\
 	if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) {	\
-		save_fpu(tsk, regs); 				\
+		save_fpu(tsk, regs);			\
 	}						\
 } while (0)
 
-#define clear_fpu(tsk, regs) do { 					\
-	if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) { 		\
-		clear_tsk_thread_flag(tsk, TIF_USEDFPU); 	\
-		release_fpu(regs);					\
+#define clear_fpu(tsk, regs) do {				\
+	if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) {		\
+		clear_tsk_thread_flag(tsk, TIF_USEDFPU);	\
+		release_fpu(regs);				\
 	}							\
 } while (0)
 
diff --git a/include/asm-sh64/ioctls.h b/include/asm-sh64/ioctls.h
index 08f3c1f..6b0c04f 100644
--- a/include/asm-sh64/ioctls.h
+++ b/include/asm-sh64/ioctls.h
@@ -111,6 +111,6 @@
 #define TIOCSERSETMULTI 0x40a8545b	/* _IOW('T', 91, struct serial_multiport_struct) 0x545B */ /* Set multiport config */
 
 #define TIOCMIWAIT	0x545c		/* _IO('T', 92) wait for a change on serial input line(s) */
-#define TIOCGICOUNT	0x802c545d	/* _IOR('T', 93, struct async_icount) 0x545D */	/* read serial port inline interrupt counts */
+#define TIOCGICOUNT	0x545d		/* read serial port inline interrupt counts */
 
 #endif /* __ASM_SH64_IOCTLS_H */
diff --git a/include/asm-sparc/oplib.h b/include/asm-sparc/oplib.h
index 9594455..d0d76b3 100644
--- a/include/asm-sparc/oplib.h
+++ b/include/asm-sparc/oplib.h
@@ -164,6 +164,7 @@ enum prom_input_device {
 	PROMDEV_IKBD,			/* input from keyboard */
 	PROMDEV_ITTYA,			/* input from ttya */
 	PROMDEV_ITTYB,			/* input from ttyb */
+	PROMDEV_IRSC,			/* input from rsc */
 	PROMDEV_I_UNK,
 };
 
@@ -175,6 +176,7 @@ enum prom_output_device {
 	PROMDEV_OSCREEN,		/* to screen */
 	PROMDEV_OTTYA,			/* to ttya */
 	PROMDEV_OTTYB,			/* to ttyb */
+	PROMDEV_ORSC,			/* to rsc */
 	PROMDEV_O_UNK,
 };
 
diff --git a/include/asm-sparc/thread_info.h b/include/asm-sparc/thread_info.h
index 65f060b..91b9f58 100644
--- a/include/asm-sparc/thread_info.h
+++ b/include/asm-sparc/thread_info.h
@@ -128,9 +128,10 @@ BTFIXUPDEF_CALL(void, free_thread_info, 
  * thread information flag bit numbers
  */
 #define TIF_SYSCALL_TRACE	0	/* syscall trace active */
-#define TIF_NOTIFY_RESUME	1	/* resumption notification requested */
+/* flag bit 1 is available */
 #define TIF_SIGPENDING		2	/* signal pending */
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
+#define TIF_RESTORE_SIGMASK	4	/* restore signal mask in do_signal() */
 #define TIF_USEDFPU		8	/* FPU was used by this task
 					 * this quantum (SMP) */
 #define TIF_POLLING_NRFLAG	9	/* true if poll_idle() is polling
@@ -139,9 +140,9 @@ BTFIXUPDEF_CALL(void, free_thread_info, 
 
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
-#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
+#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
 #define _TIF_USEDFPU		(1<<TIF_USEDFPU)
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 
diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h
index 58dba51..2ac64e6 100644
--- a/include/asm-sparc/unistd.h
+++ b/include/asm-sparc/unistd.h
@@ -300,11 +300,26 @@
 #define __NR_add_key		281
 #define __NR_request_key	282
 #define __NR_keyctl		283
+#define __NR_openat		284
+#define __NR_mkdirat		285
+#define __NR_mknodat		286
+#define __NR_fchownat		287
+#define __NR_futimesat		288
+#define __NR_newfstatat		289
+#define __NR_unlinkat		290
+#define __NR_renameat		291
+#define __NR_linkat		292
+#define __NR_symlinkat		293
+#define __NR_readlinkat		294
+#define __NR_fchmodat		295
+#define __NR_faccessat		296
+#define __NR_pselect6		297
+#define __NR_ppoll		298
 
-/* WARNING: You MAY NOT add syscall numbers larger than 283, since
+/* WARNING: You MAY NOT add syscall numbers larger than 298, since
  *          all of the syscall tables in the Sparc kernel are
- *          sized to have 283 entries (starting at zero).  Therefore
- *          find a free slot in the 0-282 range.
+ *          sized to have 298 entries (starting at zero).  Therefore
+ *          find a free slot in the 0-298 range.
  */
 
 #define _syscall0(type,name) \
@@ -458,6 +473,7 @@ return -1; \
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGSUSPEND
 #endif
 
 #ifdef __KERNEL_SYSCALLS__
diff --git a/include/asm-sparc64/oplib.h b/include/asm-sparc64/oplib.h
index d02f1e8..3c59b26 100644
--- a/include/asm-sparc64/oplib.h
+++ b/include/asm-sparc64/oplib.h
@@ -163,6 +163,7 @@ enum prom_input_device {
 	PROMDEV_IKBD,			/* input from keyboard */
 	PROMDEV_ITTYA,			/* input from ttya */
 	PROMDEV_ITTYB,			/* input from ttyb */
+	PROMDEV_IRSC,			/* input from rsc */
 	PROMDEV_I_UNK,
 };
 
@@ -174,6 +175,7 @@ enum prom_output_device {
 	PROMDEV_OSCREEN,		/* to screen */
 	PROMDEV_OTTYA,			/* to ttya */
 	PROMDEV_OTTYB,			/* to ttyb */
+	PROMDEV_ORSC,			/* to rsc */
 	PROMDEV_O_UNK,
 };
 
diff --git a/include/asm-sparc64/spinlock.h b/include/asm-sparc64/spinlock.h
index ec85d12..508c416 100644
--- a/include/asm-sparc64/spinlock.h
+++ b/include/asm-sparc64/spinlock.h
@@ -131,6 +131,28 @@ static void inline __read_lock(raw_rwloc
 	: "memory");
 }
 
+static int inline __read_trylock(raw_rwlock_t *lock)
+{
+	int tmp1, tmp2;
+
+	__asm__ __volatile__ (
+"1:	ldsw		[%2], %0\n"
+"	brlz,a,pn	%0, 2f\n"
+"	 mov		0, %0\n"
+"	add		%0, 1, %1\n"
+"	cas		[%2], %0, %1\n"
+"	cmp		%0, %1\n"
+"	membar		#StoreLoad | #StoreStore\n"
+"	bne,pn		%%icc, 1b\n"
+"	 mov		1, %0\n"
+"2:"
+	: "=&r" (tmp1), "=&r" (tmp2)
+	: "r" (lock)
+	: "memory");
+
+	return tmp1;
+}
+
 static void inline __read_unlock(raw_rwlock_t *lock)
 {
 	unsigned long tmp1, tmp2;
@@ -211,12 +233,12 @@ static int inline __write_trylock(raw_rw
 }
 
 #define __raw_read_lock(p)	__read_lock(p)
+#define __raw_read_trylock(p)	__read_trylock(p)
 #define __raw_read_unlock(p)	__read_unlock(p)
 #define __raw_write_lock(p)	__write_lock(p)
 #define __raw_write_unlock(p)	__write_unlock(p)
 #define __raw_write_trylock(p)	__write_trylock(p)
 
-#define __raw_read_trylock(lock)	generic__raw_read_trylock(lock)
 #define __raw_read_can_lock(rw)		(!((rw)->lock & 0x80000000UL))
 #define __raw_write_can_lock(rw)	(!(rw)->lock)
 
diff --git a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h
index c94d8b3..ac9d068 100644
--- a/include/asm-sparc64/thread_info.h
+++ b/include/asm-sparc64/thread_info.h
@@ -221,7 +221,7 @@ register struct thread_info *current_thr
  *	 nop
  */
 #define TIF_SYSCALL_TRACE	0	/* syscall trace active */
-#define TIF_NOTIFY_RESUME	1	/* resumption notification requested */
+#define TIF_RESTORE_SIGMASK	1	/* restore signal mask in do_signal() */
 #define TIF_SIGPENDING		2	/* signal pending */
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
 #define TIF_PERFCTR		4	/* performance counters active */
@@ -241,7 +241,6 @@ register struct thread_info *current_thr
 #define TIF_POLLING_NRFLAG	14
 
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
-#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
 #define _TIF_PERFCTR		(1<<TIF_PERFCTR)
@@ -250,11 +249,12 @@ register struct thread_info *current_thr
 #define _TIF_32BIT		(1<<TIF_32BIT)
 #define _TIF_SECCOMP		(1<<TIF_SECCOMP)
 #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
+#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
 #define _TIF_ABI_PENDING	(1<<TIF_ABI_PENDING)
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 
 #define _TIF_USER_WORK_MASK	((0xff << TI_FLAG_WSAVED_SHIFT) | \
-				 (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \
+				 (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | \
 				  _TIF_NEED_RESCHED | _TIF_PERFCTR))
 
 #endif /* __KERNEL__ */
diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h
index 51ec287..84ac2bd 100644
--- a/include/asm-sparc64/unistd.h
+++ b/include/asm-sparc64/unistd.h
@@ -302,11 +302,26 @@
 #define __NR_add_key		281
 #define __NR_request_key	282
 #define __NR_keyctl		283
+#define __NR_openat		284
+#define __NR_mkdirat		285
+#define __NR_mknodat		286
+#define __NR_fchownat		287
+#define __NR_futimesat		288
+#define __NR_newfstatat		289
+#define __NR_unlinkat		290
+#define __NR_renameat		291
+#define __NR_linkat		292
+#define __NR_symlinkat		293
+#define __NR_readlinkat		294
+#define __NR_fchmodat		295
+#define __NR_faccessat		296
+#define __NR_pselect6		297
+#define __NR_ppoll		298
 
-/* WARNING: You MAY NOT add syscall numbers larger than 283, since
+/* WARNING: You MAY NOT add syscall numbers larger than 298, since
  *          all of the syscall tables in the Sparc kernel are
- *          sized to have 283 entries (starting at zero).  Therefore
- *          find a free slot in the 0-282 range.
+ *          sized to have 298 entries (starting at zero).  Therefore
+ *          find a free slot in the 0-298 range.
  */
 
 #define _syscall0(type,name) \
@@ -501,6 +516,8 @@ asmlinkage long sys_rt_sigaction(int sig
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
 #endif
 
 /*
diff --git a/include/asm-um/io.h b/include/asm-um/io.h
index 9067405..1934d93 100644
--- a/include/asm-um/io.h
+++ b/include/asm-um/io.h
@@ -33,4 +33,20 @@ static inline void * phys_to_virt(unsign
  */
 #define xlate_dev_kmem_ptr(p)	p
 
+static inline void writeb(unsigned char b, volatile void __iomem *addr)
+{
+	*(volatile unsigned char __force *) addr = b;
+}
+static inline void writew(unsigned short b, volatile void __iomem *addr)
+{
+	*(volatile unsigned short __force *) addr = b;
+}
+static inline void writel(unsigned int b, volatile void __iomem *addr)
+{
+	*(volatile unsigned int __force *) addr = b;
+}
+#define __raw_writeb writeb
+#define __raw_writew writew
+#define __raw_writel writel
+
 #endif
diff --git a/include/asm-um/ldt-x86_64.h b/include/asm-um/ldt-x86_64.h
index 175722a..96b35aa 100644
--- a/include/asm-um/ldt-x86_64.h
+++ b/include/asm-um/ldt-x86_64.h
@@ -5,8 +5,8 @@
  * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
  */
 
-#ifndef __ASM_LDT_I386_H
-#define __ASM_LDT_I386_H
+#ifndef __ASM_LDT_X86_64_H
+#define __ASM_LDT_X86_64_H
 
 #include "asm/semaphore.h"
 #include "asm/arch/ldt.h"
@@ -39,11 +39,13 @@ typedef struct uml_ldt {
 } uml_ldt_t;
 
 /*
- * macros stolen from include/asm-i386/desc.h
+ * macros stolen from include/asm-x86_64/desc.h
  */
 #define LDT_entry_a(info) \
 	((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
 
+/* Don't allow setting of the lm bit. It is useless anyways because
+ * 64bit system calls require __USER_CS. */
 #define LDT_entry_b(info) \
 	(((info)->base_addr & 0xff000000) | \
 	(((info)->base_addr & 0x00ff0000) >> 16) | \
@@ -54,6 +56,7 @@ typedef struct uml_ldt {
 	((info)->seg_32bit << 22) | \
 	((info)->limit_in_pages << 23) | \
 	((info)->useable << 20) | \
+	/* ((info)->lm << 21) | */ \
 	0x7000)
 
 #define LDT_empty(info) (\
@@ -64,6 +67,7 @@ typedef struct uml_ldt {
 	(info)->seg_32bit	== 0	&& \
 	(info)->limit_in_pages	== 0	&& \
 	(info)->seg_not_present	== 1	&& \
-	(info)->useable		== 0	)
+	(info)->useable		== 0	&& \
+	(info)->lm              == 0)
 
 #endif
diff --git a/include/asm-um/smp.h b/include/asm-um/smp.h
index d879eba..aeda665 100644
--- a/include/asm-um/smp.h
+++ b/include/asm-um/smp.h
@@ -23,6 +23,8 @@ extern inline void smp_cpus_done(unsigne
 {
 }
 
+extern struct task_struct *idle_threads[NR_CPUS];
+
 #endif
 
 #endif
diff --git a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h
index 705c719..17b6b07 100644
--- a/include/asm-um/thread_info.h
+++ b/include/asm-um/thread_info.h
@@ -69,6 +69,7 @@ static inline struct thread_info *curren
 #define TIF_RESTART_BLOCK 	4
 #define TIF_MEMDIE	 	5
 #define TIF_SYSCALL_AUDIT	6
+#define TIF_RESTORE_SIGMASK	7
 
 #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
@@ -76,16 +77,6 @@ static inline struct thread_info *curren
 #define _TIF_POLLING_NRFLAG     (1 << TIF_POLLING_NRFLAG)
 #define _TIF_MEMDIE		(1 << TIF_MEMDIE)
 #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
+#define _TIF_RESTORE_SIGMASK	(1 << TIF_RESTORE_SIGMASK)
 
 #endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/include/asm-um/unistd.h b/include/asm-um/unistd.h
index 6fdde45..afccfca 100644
--- a/include/asm-um/unistd.h
+++ b/include/asm-um/unistd.h
@@ -34,6 +34,7 @@ extern int um_execve(const char *file, c
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
+#define __ARCH_WANT_SYS_RT_SIGSUSPEND
 #endif
 
 #ifdef __KERNEL_SYSCALLS__
diff --git a/include/asm-x86_64/edac.h b/include/asm-x86_64/edac.h
new file mode 100644
index 0000000..cad1cd4
--- /dev/null
+++ b/include/asm-x86_64/edac.h
@@ -0,0 +1,18 @@
+#ifndef ASM_EDAC_H
+#define ASM_EDAC_H
+
+/* ECC atomic, DMA, SMP and interrupt safe scrub function */
+
+static __inline__ void atomic_scrub(void *va, u32 size)
+{
+	unsigned int *virt_addr = va;
+	u32 i;
+
+	for (i = 0; i < size / 4; i++, virt_addr++)
+		/* Very carefully read and write to memory atomically
+		 * so we are interrupt, DMA and SMP safe.
+		 */
+		__asm__ __volatile__("lock; addl $0, %0"::"m"(*virt_addr));
+}
+
+#endif
diff --git a/include/asm-x86_64/ia32_unistd.h b/include/asm-x86_64/ia32_unistd.h
index e884336..9afc0c7 100644
--- a/include/asm-x86_64/ia32_unistd.h
+++ b/include/asm-x86_64/ia32_unistd.h
@@ -300,7 +300,20 @@
 #define __NR_ia32_inotify_add_watch	292
 #define __NR_ia32_inotify_rm_watch	293
 #define __NR_ia32_migrate_pages		294
+#define __NR_ia32_openat		295
+#define __NR_ia32_mkdirat		296
+#define __NR_ia32_mknodat		297
+#define __NR_ia32_fchownat		298
+#define __NR_ia32_futimesat		299
+#define __NR_ia32_newfstatat		300
+#define __NR_ia32_unlinkat		301
+#define __NR_ia32_renameat		302
+#define __NR_ia32_linkat		303
+#define __NR_ia32_symlinkat		304
+#define __NR_ia32_readlinkat		305
+#define __NR_ia32_fchmodat		306
+#define __NR_ia32_faccessat		307
 
-#define IA32_NR_syscalls 295	/* must be > than biggest syscall! */
+#define IA32_NR_syscalls 308	/* must be > than biggest syscall! */
 
 #endif /* _ASM_X86_64_IA32_UNISTD_H_ */
diff --git a/include/asm-x86_64/mpspec.h b/include/asm-x86_64/mpspec.h
index 10248a9..14fc3dd 100644
--- a/include/asm-x86_64/mpspec.h
+++ b/include/asm-x86_64/mpspec.h
@@ -188,7 +188,7 @@ extern void mp_register_lapic_address (u
 extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base);
 extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 gsi);
 extern void mp_config_acpi_legacy_irqs (void);
-extern int mp_register_gsi (u32 gsi, int edge_level, int active_high_low);
+extern int mp_register_gsi (u32 gsi, int triggering, int polarity);
 #endif /*CONFIG_X86_IO_APIC*/
 #endif
 
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
index e6f8961..436d099 100644
--- a/include/asm-x86_64/unistd.h
+++ b/include/asm-x86_64/unistd.h
@@ -573,8 +573,35 @@ __SYSCALL(__NR_inotify_add_watch, sys_in
 __SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch)
 #define __NR_migrate_pages	256
 __SYSCALL(__NR_migrate_pages, sys_migrate_pages)
+#define __NR_openat		257
+__SYSCALL(__NR_openat, sys_openat)
+#define __NR_mkdirat		258
+__SYSCALL(__NR_mkdirat, sys_mkdirat)
+#define __NR_mknodat		259
+__SYSCALL(__NR_mknodat, sys_mknodat)
+#define __NR_fchownat		260
+__SYSCALL(__NR_fchownat, sys_fchownat)
+#define __NR_futimesat		261
+__SYSCALL(__NR_futimesat, sys_futimesat)
+#define __NR_newfstatat		262
+__SYSCALL(__NR_newfstatat, sys_newfstatat)
+#define __NR_unlinkat		263
+__SYSCALL(__NR_unlinkat, sys_unlinkat)
+#define __NR_renameat		264
+__SYSCALL(__NR_renameat, sys_renameat)
+#define __NR_linkat		265
+__SYSCALL(__NR_linkat, sys_linkat)
+#define __NR_symlinkat		266
+__SYSCALL(__NR_symlinkat, sys_symlinkat)
+#define __NR_readlinkat		267
+__SYSCALL(__NR_readlinkat, sys_readlinkat)
+#define __NR_fchmodat		268
+__SYSCALL(__NR_fchmodat, sys_fchmodat)
+#define __NR_faccessat		269
+__SYSCALL(__NR_faccessat, sys_faccessat)
+
+#define __NR_syscall_max __NR_faccessat
 
-#define __NR_syscall_max __NR_migrate_pages
 #ifndef __NO_STUBS
 
 /* user-visible error numbers are in the range -1 - -4095 */
diff --git a/include/asm-xtensa/futex.h b/include/asm-xtensa/futex.h
new file mode 100644
index 0000000..0b74582
--- /dev/null
+++ b/include/asm-xtensa/futex.h
@@ -0,0 +1 @@
+#include <asm-generic/futex.h>
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 026c3c0..84d3d9f 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -435,7 +435,7 @@ extern int sbf_port ;
 
 #endif 	/* !CONFIG_ACPI */
 
-int acpi_register_gsi (u32 gsi, int edge_level, int active_high_low);
+int acpi_register_gsi (u32 gsi, int triggering, int polarity);
 int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
 
 /*
diff --git a/include/linux/agpgart.h b/include/linux/agpgart.h
index 17a17c5..6d59c8e 100644
--- a/include/linux/agpgart.h
+++ b/include/linux/agpgart.h
@@ -111,6 +111,7 @@ typedef struct _agp_unbind {
 } agp_unbind;
 
 #else				/* __KERNEL__ */
+#include <linux/mutex.h>
 
 #define AGPGART_MINOR 175
 
@@ -201,7 +202,7 @@ struct agp_file_private {
 };
 
 struct agp_front_data {
-	struct semaphore agp_mutex;
+	struct mutex agp_mutex;
 	struct agp_controller *current_controller;
 	struct agp_controller *controllers;
 	struct agp_file_private *file_priv_list;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 02a585f..860e7a4 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -392,8 +392,8 @@ struct request_queue
 	unsigned int		nr_congestion_off;
 	unsigned int		nr_batching;
 
-	unsigned short		max_sectors;
-	unsigned short		max_hw_sectors;
+	unsigned int		max_sectors;
+	unsigned int		max_hw_sectors;
 	unsigned short		max_phys_segments;
 	unsigned short		max_hw_segments;
 	unsigned short		hardsect_size;
@@ -697,7 +697,7 @@ extern request_queue_t *blk_init_queue(r
 extern void blk_cleanup_queue(request_queue_t *);
 extern void blk_queue_make_request(request_queue_t *, make_request_fn *);
 extern void blk_queue_bounce_limit(request_queue_t *, u64);
-extern void blk_queue_max_sectors(request_queue_t *, unsigned short);
+extern void blk_queue_max_sectors(request_queue_t *, unsigned int);
 extern void blk_queue_max_phys_segments(request_queue_t *, unsigned short);
 extern void blk_queue_max_hw_segments(request_queue_t *, unsigned short);
 extern void blk_queue_max_segment_size(request_queue_t *, unsigned int);
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index c31650d..17866d7 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -14,6 +14,7 @@
 #ifndef _LINUX_CPUFREQ_H
 #define _LINUX_CPUFREQ_H
 
+#include <linux/mutex.h>
 #include <linux/config.h>
 #include <linux/notifier.h>
 #include <linux/threads.h>
@@ -82,7 +83,7 @@ struct cpufreq_policy {
         unsigned int		policy; /* see above */
 	struct cpufreq_governor	*governor; /* see below */
 
- 	struct semaphore	lock;   /* CPU ->setpolicy or ->target may
+ 	struct mutex		lock;   /* CPU ->setpolicy or ->target may
 					   only be called once a time */
 
 	struct work_struct	update; /* if update_policy() needs to be
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index 83c7d20..51e0e95 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -91,7 +91,7 @@ struct target_type {
 };
 
 struct io_restrictions {
-	unsigned short		max_sectors;
+	unsigned int		max_sectors;
 	unsigned short		max_phys_segments;
 	unsigned short		max_hw_segments;
 	unsigned short		hardsect_size;
diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h
index 8a7c821..c52a637 100644
--- a/include/linux/fcntl.h
+++ b/include/linux/fcntl.h
@@ -23,6 +23,13 @@
 #define DN_ATTRIB	0x00000020	/* File changed attibutes */
 #define DN_MULTISHOT	0x80000000	/* Don't remove notifier */
 
+#define AT_FDCWD		-100    /* Special value used to indicate
+                                           openat should use the current
+                                           working directory. */
+#define AT_SYMLINK_NOFOLLOW	0x100   /* Do not follow symbolic links.  */
+#define AT_REMOVEDIR		0x200   /* Remove directory instead of
+                                           unlinking file.  */
+
 #ifdef __KERNEL__
 
 #ifndef force_o_largefile
diff --git a/include/linux/fs.h b/include/linux/fs.h
index b77f260..e059da9 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -363,6 +363,8 @@ struct address_space_operations {
 			loff_t offset, unsigned long nr_segs);
 	struct page* (*get_xip_page)(struct address_space *, sector_t,
 			int);
+	/* migrate the contents of a page to the specified target */
+	int (*migratepage) (struct page *, struct page *);
 };
 
 struct backing_dev_info;
@@ -1340,7 +1342,8 @@ static inline int break_lease(struct ino
 
 extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
 		       struct file *filp);
-extern long do_sys_open(const char __user *filename, int flags, int mode);
+extern long do_sys_open(int fdf, const char __user *filename, int flags,
+			int mode);
 extern struct file *filp_open(const char *, int, int);
 extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
 extern int filp_close(struct file *, fl_owner_t id);
@@ -1479,7 +1482,7 @@ static inline void allow_write_access(st
 }
 extern int do_pipe(int *);
 
-extern int open_namei(const char *, int, int, struct nameidata *);
+extern int open_namei(int dfd, const char *, int, int, struct nameidata *);
 extern int may_open(struct nameidata *, int, int);
 
 extern int kernel_read(struct file *, unsigned long, char *, unsigned long);
@@ -1677,6 +1680,8 @@ extern int vfs_readdir(struct file *, fi
 
 extern int vfs_stat(char __user *, struct kstat *);
 extern int vfs_lstat(char __user *, struct kstat *);
+extern int vfs_stat_fd(int dfd, char __user *, struct kstat *);
+extern int vfs_lstat_fd(int dfd, char __user *, struct kstat *);
 extern int vfs_fstat(unsigned int, struct kstat *);
 
 extern int vfs_ioctl(struct file *, unsigned int, unsigned int, unsigned long);
@@ -1716,6 +1721,12 @@ extern void simple_release_fs(struct vfs
 
 extern ssize_t simple_read_from_buffer(void __user *, size_t, loff_t *, const void *, size_t);
 
+#ifdef CONFIG_MIGRATION
+extern int buffer_migrate_page(struct page *, struct page *);
+#else
+#define buffer_migrate_page NULL
+#endif
+
 extern int inode_change_ok(struct inode *, struct iattr *);
 extern int __must_check inode_setattr(struct inode *, struct iattr *);
 
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index 528959c..5425b60 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -14,7 +14,7 @@
 #define FUSE_KERNEL_VERSION 7
 
 /** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 5
+#define FUSE_KERNEL_MINOR_VERSION 6
 
 /** The node ID of the root inode */
 #define FUSE_ROOT_ID 1
@@ -58,6 +58,9 @@ struct fuse_kstatfs {
 	__u32	spare[6];
 };
 
+/**
+ * Bitmasks for fuse_setattr_in.valid
+ */
 #define FATTR_MODE	(1 << 0)
 #define FATTR_UID	(1 << 1)
 #define FATTR_GID	(1 << 2)
@@ -75,6 +78,11 @@ struct fuse_kstatfs {
 #define FOPEN_DIRECT_IO		(1 << 0)
 #define FOPEN_KEEP_CACHE	(1 << 1)
 
+/**
+ * INIT request/reply flags
+ */
+#define FUSE_ASYNC_READ		(1 << 0)
+
 enum fuse_opcode {
 	FUSE_LOOKUP	   = 1,
 	FUSE_FORGET	   = 2,  /* no reply */
@@ -247,12 +255,16 @@ struct fuse_access_in {
 struct fuse_init_in {
 	__u32	major;
 	__u32	minor;
+	__u32	max_readahead;
+	__u32	flags;
 };
 
 struct fuse_init_out {
 	__u32	major;
 	__u32	minor;
-	__u32	unused[3];
+	__u32	max_readahead;
+	__u32	flags;
+	__u32	unused;
 	__u32	max_write;
 };
 
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 089bfb1..6361544 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -40,6 +40,7 @@ enum hrtimer_restart {
 enum hrtimer_state {
 	HRTIMER_INACTIVE,	/* Timer is inactive */
 	HRTIMER_EXPIRED,		/* Timer is expired */
+	HRTIMER_RUNNING,		/* Timer is running the callback function */
 	HRTIMER_PENDING,		/* Timer is pending */
 };
 
@@ -100,9 +101,8 @@ struct hrtimer_base {
 /* Exported timer functions: */
 
 /* Initialize timers: */
-extern void hrtimer_init(struct hrtimer *timer, const clockid_t which_clock);
-extern void hrtimer_rebase(struct hrtimer *timer, const clockid_t which_clock);
-
+extern void hrtimer_init(struct hrtimer *timer, clockid_t which_clock,
+			 enum hrtimer_mode mode);
 
 /* Basic timer operations: */
 extern int hrtimer_start(struct hrtimer *timer, ktime_t tim,
diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
index fe26d43..7a92c1c 100644
--- a/include/linux/if_ether.h
+++ b/include/linux/if_ether.h
@@ -72,6 +72,7 @@
 					 * over Ethernet
 					 */
 #define ETH_P_AOE	0x88A2		/* ATA over Ethernet		*/
+#define ETH_P_TIPC	0x88CA		/* TIPC 			*/
 
 /*
  *	Non DIX types. Won't clash for 1500 types.
diff --git a/include/linux/io.h b/include/linux/io.h
new file mode 100644
index 0000000..85533ec
--- /dev/null
+++ b/include/linux/io.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2006 PathScale, Inc.  All Rights Reserved.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _LINUX_IO_H
+#define _LINUX_IO_H
+
+#include <asm/io.h>
+
+void __iowrite32_copy(void __iomem *to, const void *from, size_t count);
+
+#endif /* _LINUX_IO_H */
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 323924e..b49affa 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -185,6 +185,7 @@ extern enum system_states {
 	SYSTEM_HALT,
 	SYSTEM_POWER_OFF,
 	SYSTEM_RESTART,
+	SYSTEM_SUSPEND_DISK,
 } system_state;
 
 #define TAINT_PROPRIETARY_MODULE	(1<<0)
@@ -228,6 +229,7 @@ extern void dump_stack(void);
 	ntohs((addr).s6_addr16[6]), \
 	ntohs((addr).s6_addr16[7])
 #define NIP6_FMT "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
+#define NIP6_SEQFMT "%04x%04x%04x%04x%04x%04x%04x%04x"
 
 #if defined(__LITTLE_ENDIAN)
 #define HIPQUAD(addr) \
diff --git a/include/linux/ktime.h b/include/linux/ktime.h
index 1bd6552..6aca67a 100644
--- a/include/linux/ktime.h
+++ b/include/linux/ktime.h
@@ -10,6 +10,12 @@
  *
  *  Started by: Thomas Gleixner and Ingo Molnar
  *
+ *  Credits:
+ *
+ *  	Roman Zippel provided the ideas and primary code snippets of
+ *  	the ktime_t union and further simplifications of the original
+ *  	code.
+ *
  *  For licencing details see kernel-base/COPYING
  */
 #ifndef _LINUX_KTIME_H
diff --git a/include/linux/libata.h b/include/linux/libata.h
index a43c95f..9e5db29 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -126,16 +126,19 @@ enum {
 
 	ATA_FLAG_SUSPENDED	= (1 << 12), /* port is suspended */
 
+	ATA_FLAG_PIO_LBA48	= (1 << 13), /* Host DMA engine is LBA28 only */
+	ATA_FLAG_IRQ_MASK	= (1 << 14), /* Mask IRQ in PIO xfers */
+
 	ATA_QCFLAG_ACTIVE	= (1 << 1), /* cmd not yet ack'd to scsi lyer */
 	ATA_QCFLAG_SG		= (1 << 3), /* have s/g table? */
 	ATA_QCFLAG_SINGLE	= (1 << 4), /* no s/g, just a single buffer */
 	ATA_QCFLAG_DMAMAP	= ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE,
 
 	/* various lengths of time */
-	ATA_TMOUT_EDD		= 5 * HZ,	/* hueristic */
+	ATA_TMOUT_EDD		= 5 * HZ,	/* heuristic */
 	ATA_TMOUT_PIO		= 30 * HZ,
-	ATA_TMOUT_BOOT		= 30 * HZ,	/* hueristic */
-	ATA_TMOUT_BOOT_QUICK	= 7 * HZ,	/* hueristic */
+	ATA_TMOUT_BOOT		= 30 * HZ,	/* heuristic */
+	ATA_TMOUT_BOOT_QUICK	= 7 * HZ,	/* heuristic */
 	ATA_TMOUT_CDB		= 30 * HZ,
 	ATA_TMOUT_CDB_QUICK	= 5 * HZ,
 	ATA_TMOUT_INTERNAL	= 30 * HZ,
@@ -499,6 +502,8 @@ extern int ata_scsi_slave_config(struct 
 /*
  * Timing helpers
  */
+
+extern unsigned int ata_pio_need_iordy(const struct ata_device *);
 extern int ata_timing_compute(struct ata_device *, unsigned short,
 			      struct ata_timing *, int, int);
 extern void ata_timing_merge(const struct ata_timing *,
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index d6a53ed..bbd2221 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -159,6 +159,7 @@ extern void mpol_rebind_mm(struct mm_str
 extern struct mempolicy default_policy;
 extern struct zonelist *huge_zonelist(struct vm_area_struct *vma,
 		unsigned long addr);
+extern unsigned slab_node(struct mempolicy *policy);
 
 extern int policy_zone;
 
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
index 49cc68a..8ac854f 100644
--- a/include/linux/mm_inline.h
+++ b/include/linux/mm_inline.h
@@ -39,24 +39,3 @@ del_page_from_lru(struct zone *zone, str
 	}
 }
 
-/*
- * Isolate one page from the LRU lists.
- *
- * - zone->lru_lock must be held
- */
-static inline int __isolate_lru_page(struct page *page)
-{
-	if (unlikely(!TestClearPageLRU(page)))
-		return 0;
-
-	if (get_page_testone(page)) {
-		/*
-		 * It is being freed elsewhere
-		 */
-		__put_page(page);
-		SetPageLRU(page);
-		return -ENOENT;
-	}
-
-	return 1;
-}
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 34cbefd..ebfc238 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -91,10 +91,21 @@ struct per_cpu_pageset {
  * be 8 (2 ** 3) zonelists.  GFP_ZONETYPES defines the number of possible
  * combinations of zone modifiers in "zone modifier space".
  *
+ * As an optimisation any zone modifier bits which are only valid when
+ * no other zone modifier bits are set (loners) should be placed in
+ * the highest order bits of this field.  This allows us to reduce the
+ * extent of the zonelists thus saving space.  For example in the case
+ * of three zone modifier bits, we could require up to eight zonelists.
+ * If the left most zone modifier is a "loner" then the highest valid
+ * zonelist would be four allowing us to allocate only five zonelists.
+ * Use the first form for GFP_ZONETYPES when the left most bit is not
+ * a "loner", otherwise use the second.
+ *
  * NOTE! Make sure this matches the zones in <linux/gfp.h>
  */
 #define GFP_ZONEMASK	0x07
-#define GFP_ZONETYPES	5
+/* #define GFP_ZONETYPES       (GFP_ZONEMASK + 1) */           /* Non-loner */
+#define GFP_ZONETYPES  ((GFP_ZONEMASK + 1) / 2 + 1)            /* Loner */
 
 /*
  * On machines where it is needed (eg PCs) we divide physical memory
@@ -149,15 +160,17 @@ struct zone {
 	unsigned long		pages_scanned;	   /* since last reclaim */
 	int			all_unreclaimable; /* All pages pinned */
 
-	/*
-	 * Does the allocator try to reclaim pages from the zone as soon
-	 * as it fails a watermark_ok() in __alloc_pages?
-	 */
-	int			reclaim_pages;
 	/* A count of how many reclaimers are scanning this zone */
 	atomic_t		reclaim_in_progress;
 
 	/*
+	 * timestamp (in jiffies) of the last zone reclaim that did not
+	 * result in freeing of pages. This is used to avoid repeated scans
+	 * if all memory in the zone is in use.
+	 */
+	unsigned long		last_unsuccessful_zone_reclaim;
+
+	/*
 	 * prev_priority holds the scanning priority for this zone.  It is
 	 * defined as the scanning priority at which we achieved our reclaim
 	 * target at the previous try_to_free_pages() or balance_pgdat()
diff --git a/include/linux/namei.h b/include/linux/namei.h
index b699e42..e669801 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -56,10 +56,11 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LA
 #define LOOKUP_ACCESS		(0x0400)
 
 extern int FASTCALL(__user_walk(const char __user *, unsigned, struct nameidata *));
+extern int FASTCALL(__user_walk_fd(int dfd, const char __user *, unsigned, struct nameidata *));
 #define user_path_walk(name,nd) \
-	__user_walk(name, LOOKUP_FOLLOW, nd)
+	__user_walk_fd(AT_FDCWD, name, LOOKUP_FOLLOW, nd)
 #define user_path_walk_link(name,nd) \
-	__user_walk(name, 0, nd)
+	__user_walk_fd(AT_FDCWD, name, 0, nd)
 extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
 extern int FASTCALL(path_walk(const char *, struct nameidata *));
 extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
@@ -67,7 +68,7 @@ extern void path_release(struct nameidat
 extern void path_release_on_umount(struct nameidata *);
 
 extern int __user_path_lookup_open(const char __user *, unsigned lookup_flags, struct nameidata *nd, int open_flags);
-extern int path_lookup_open(const char *, unsigned lookup_flags, struct nameidata *, int open_flags);
+extern int path_lookup_open(int dfd, const char *name, unsigned lookup_flags, struct nameidata *, int open_flags);
 extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
 		int (*open)(struct inode *, struct file *));
 extern struct file *nameidata_to_filp(struct nameidata *nd, int flags);
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 472f048..6500d4e 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -19,7 +19,21 @@ struct xt_get_revision
 /* For standard target */
 #define XT_RETURN (-NF_REPEAT - 1)
 
-#define XT_ALIGN(s) (((s) + (__alignof__(void *)-1)) & ~(__alignof__(void *)-1))
+/* this is a dummy structure to find out the alignment requirement for a struct
+ * containing all the fundamental data types that are used in ipt_entry,
+ * ip6t_entry and arpt_entry.  This sucks, and it is a hack.  It will be my
+ * personal pleasure to remove it -HW
+ */
+struct _xt_align
+{
+	u_int8_t u8;
+	u_int16_t u16;
+	u_int32_t u32;
+	u_int64_t u64;
+};
+
+#define XT_ALIGN(s) (((s) + (__alignof__(struct _xt_align)-1)) 	\
+			& ~(__alignof__(struct _xt_align)-1))
 
 /* Standard return verdict, or do jump. */
 #define XT_STANDARD_TARGET ""
diff --git a/include/linux/netfilter_ipv6/ip6t_ah.h b/include/linux/netfilter_ipv6/ip6t_ah.h
index c4f0793..8531879 100644
--- a/include/linux/netfilter_ipv6/ip6t_ah.h
+++ b/include/linux/netfilter_ipv6/ip6t_ah.h
@@ -18,13 +18,4 @@ struct ip6t_ah
 #define IP6T_AH_INV_LEN		0x02	/* Invert the sense of length. */
 #define IP6T_AH_INV_MASK	0x03	/* All possible flags. */
 
-#define MASK_HOPOPTS    128
-#define MASK_DSTOPTS    64
-#define MASK_ROUTING    32
-#define MASK_FRAGMENT   16
-#define MASK_AH         8
-#define MASK_ESP        4
-#define MASK_NONE       2
-#define MASK_PROTO      1
-
 #endif /*_IP6T_AH_H*/
diff --git a/include/linux/netfilter_ipv6/ip6t_esp.h b/include/linux/netfilter_ipv6/ip6t_esp.h
index 01142b9..a91b6ab 100644
--- a/include/linux/netfilter_ipv6/ip6t_esp.h
+++ b/include/linux/netfilter_ipv6/ip6t_esp.h
@@ -7,15 +7,6 @@ struct ip6t_esp
 	u_int8_t  invflags;			/* Inverse flags */
 };
 
-#define MASK_HOPOPTS    128
-#define MASK_DSTOPTS    64
-#define MASK_ROUTING    32
-#define MASK_FRAGMENT   16
-#define MASK_AH         8
-#define MASK_ESP        4
-#define MASK_NONE       2
-#define MASK_PROTO      1
-
 /* Values for "invflags" field in struct ip6t_esp. */
 #define IP6T_ESP_INV_SPI		0x01	/* Invert the sense of spi. */
 #define IP6T_ESP_INV_MASK	0x01	/* All possible flags. */
diff --git a/include/linux/netfilter_ipv6/ip6t_frag.h b/include/linux/netfilter_ipv6/ip6t_frag.h
index 449a57e..66070a0 100644
--- a/include/linux/netfilter_ipv6/ip6t_frag.h
+++ b/include/linux/netfilter_ipv6/ip6t_frag.h
@@ -21,13 +21,4 @@ struct ip6t_frag
 #define IP6T_FRAG_INV_LEN	0x02	/* Invert the sense of length. */
 #define IP6T_FRAG_INV_MASK	0x03	/* All possible flags. */
 
-#define MASK_HOPOPTS    128
-#define MASK_DSTOPTS    64
-#define MASK_ROUTING    32
-#define MASK_FRAGMENT   16
-#define MASK_AH         8
-#define MASK_ESP        4
-#define MASK_NONE       2
-#define MASK_PROTO      1
-
 #endif /*_IP6T_FRAG_H*/
diff --git a/include/linux/netfilter_ipv6/ip6t_opts.h b/include/linux/netfilter_ipv6/ip6t_opts.h
index e259b62..a07e363 100644
--- a/include/linux/netfilter_ipv6/ip6t_opts.h
+++ b/include/linux/netfilter_ipv6/ip6t_opts.h
@@ -20,13 +20,4 @@ struct ip6t_opts
 #define IP6T_OPTS_INV_LEN	0x01	/* Invert the sense of length. */
 #define IP6T_OPTS_INV_MASK	0x01	/* All possible flags. */
 
-#define MASK_HOPOPTS    128
-#define MASK_DSTOPTS    64
-#define MASK_ROUTING    32
-#define MASK_FRAGMENT   16
-#define MASK_AH         8
-#define MASK_ESP        4
-#define MASK_NONE       2
-#define MASK_PROTO      1
-
 #endif /*_IP6T_OPTS_H*/
diff --git a/include/linux/netfilter_ipv6/ip6t_rt.h b/include/linux/netfilter_ipv6/ip6t_rt.h
index f1070fb..5215602 100644
--- a/include/linux/netfilter_ipv6/ip6t_rt.h
+++ b/include/linux/netfilter_ipv6/ip6t_rt.h
@@ -30,13 +30,4 @@ struct ip6t_rt
 #define IP6T_RT_INV_LEN		0x04	/* Invert the sense of length. */
 #define IP6T_RT_INV_MASK	0x07	/* All possible flags. */
 
-#define MASK_HOPOPTS    128
-#define MASK_DSTOPTS    64
-#define MASK_ROUTING    32
-#define MASK_FRAGMENT   16
-#define MASK_AH         8
-#define MASK_ESP        4
-#define MASK_NONE       2
-#define MASK_PROTO      1
-
 #endif /*_IP6T_RT_H*/
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index 51c231a..ec7c2e8 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -124,7 +124,7 @@ int		nfsd_statfs(struct svc_rqst *, stru
 
 int		nfsd_notify_change(struct inode *, struct iattr *);
 int		nfsd_permission(struct svc_export *, struct dentry *, int);
-void		nfsd_sync_dir(struct dentry *dp);
+int		nfsd_sync_dir(struct dentry *dp);
 
 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
 #ifdef CONFIG_NFSD_V2_ACL
diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h
index 8903688..77adba7 100644
--- a/include/linux/nfsd/xdr4.h
+++ b/include/linux/nfsd/xdr4.h
@@ -145,8 +145,9 @@ struct nfsd4_lock {
 		} ok;
 		struct nfsd4_lock_denied        denied;
 	} u;
-
-	struct nfs4_stateowner *lk_stateowner;
+	/* The lk_replay_owner is the open owner in the open_to_lock_owner
+	 * case and the lock owner otherwise: */
+	struct nfs4_stateowner *lk_replay_owner;
 };
 #define lk_new_open_seqid       v.new.open_seqid
 #define lk_new_open_stateid     v.new.open_stateid
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 0a44072..fe1a2b0 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -406,7 +406,6 @@ struct pci_dev *pci_find_device_reverse 
 struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);
 int pci_find_capability (struct pci_dev *dev, int cap);
 int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap);
-int pci_find_ext_capability (struct pci_dev *dev, int cap);
 struct pci_bus * pci_find_next_bus(const struct pci_bus *from);
 
 struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from);
@@ -626,7 +625,6 @@ static inline int pci_register_driver(st
 static inline void pci_unregister_driver(struct pci_driver *drv) { }
 static inline int pci_find_capability (struct pci_dev *dev, int cap) {return 0; }
 static inline int pci_find_next_capability (struct pci_dev *dev, u8 post, int cap) { return 0; }
-static inline int pci_find_ext_capability (struct pci_dev *dev, int cap) {return 0; }
 static inline const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) { return NULL; }
 
 /* Power management related routines */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 5403257..b0b908f 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -394,14 +394,9 @@
 #define PCI_DEVICE_ID_NS_SC1100_SMI	0x0511
 #define PCI_DEVICE_ID_NS_SC1100_XBUS	0x0515
 #define PCI_DEVICE_ID_NS_87410		0xd001
-#define PCI_DEVICE_ID_NS_CS5535_IDE	0x002d
 
 #define PCI_DEVICE_ID_NS_CS5535_HOST_BRIDGE  0x0028
 #define PCI_DEVICE_ID_NS_CS5535_ISA_BRIDGE   0x002b
-#define PCI_DEVICE_ID_NS_CS5535_IDE          0x002d
-#define PCI_DEVICE_ID_NS_CS5535_AUDIO        0x002e
-#define PCI_DEVICE_ID_NS_CS5535_USB          0x002f
-#define PCI_DEVICE_ID_NS_CS5535_VIDEO        0x0030
 
 #define PCI_VENDOR_ID_TSENG		0x100c
 #define PCI_DEVICE_ID_TSENG_W32P_2	0x3202
@@ -511,8 +506,6 @@
 #define PCI_DEVICE_ID_AMD_CS5536_UOC    0x2097
 #define PCI_DEVICE_ID_AMD_CS5536_IDE    0x209A
 
-#define PCI_DEVICE_ID_AMD_CS5536_IDE	0x209A
-
 #define PCI_DEVICE_ID_AMD_LX_VIDEO  0x2081
 #define PCI_DEVICE_ID_AMD_LX_AES    0x2082
 
@@ -1992,6 +1985,7 @@
 #define PCI_VENDOR_ID_DCI		0x6666
 #define PCI_DEVICE_ID_DCI_PCCOM4	0x0001
 #define PCI_DEVICE_ID_DCI_PCCOM8	0x0002
+#define PCI_DEVICE_ID_DCI_PCCOM2	0x0004
 
 #define PCI_VENDOR_ID_INTEL		0x8086
 #define PCI_DEVICE_ID_INTEL_EESSC	0x0008
@@ -2064,6 +2058,7 @@
 #define PCI_DEVICE_ID_INTEL_82801EB_5	0x24d5
 #define PCI_DEVICE_ID_INTEL_82801EB_6	0x24d6
 #define PCI_DEVICE_ID_INTEL_82801EB_11	0x24db
+#define PCI_DEVICE_ID_INTEL_82801EB_13	0x24dd
 #define PCI_DEVICE_ID_INTEL_ESB_1	0x25a1
 #define PCI_DEVICE_ID_INTEL_ESB_2	0x25a2
 #define PCI_DEVICE_ID_INTEL_ESB_4	0x25a4
@@ -2084,6 +2079,8 @@
 #define PCI_DEVICE_ID_INTEL_82915GM_IG	0x2592
 #define PCI_DEVICE_ID_INTEL_82945G_HB	0x2770
 #define PCI_DEVICE_ID_INTEL_82945G_IG	0x2772
+#define PCI_DEVICE_ID_INTEL_82945GM_HB	0x27A0
+#define PCI_DEVICE_ID_INTEL_82945GM_IG	0x27A2
 #define PCI_DEVICE_ID_INTEL_ICH6_0	0x2640
 #define PCI_DEVICE_ID_INTEL_ICH6_1	0x2641
 #define PCI_DEVICE_ID_INTEL_ICH6_2	0x2642
@@ -2103,6 +2100,13 @@
 #define PCI_DEVICE_ID_INTEL_ICH7_19	0x27dd
 #define PCI_DEVICE_ID_INTEL_ICH7_20	0x27de
 #define PCI_DEVICE_ID_INTEL_ICH7_21	0x27df
+#define PCI_DEVICE_ID_INTEL_ICH8_0	0x2810
+#define PCI_DEVICE_ID_INTEL_ICH8_1	0x2811
+#define PCI_DEVICE_ID_INTEL_ICH8_2	0x2812
+#define PCI_DEVICE_ID_INTEL_ICH8_3	0x2814
+#define PCI_DEVICE_ID_INTEL_ICH8_4	0x2815
+#define PCI_DEVICE_ID_INTEL_ICH8_5	0x283e
+#define PCI_DEVICE_ID_INTEL_ICH8_6	0x2850
 #define PCI_DEVICE_ID_INTEL_82855PM_HB	0x3340
 #define PCI_DEVICE_ID_INTEL_82830_HB	0x3575
 #define PCI_DEVICE_ID_INTEL_82830_CGC	0x3577
@@ -2146,6 +2150,7 @@
 #define PCI_DEVICE_ID_INTEL_82443GX_2	0x71a2
 #define PCI_DEVICE_ID_INTEL_82372FB_1	0x7601
 #define PCI_DEVICE_ID_INTEL_82454GX	0x84c4
+#define PCI_DEVICE_ID_INTEL_82450GX	0x84c5
 #define PCI_DEVICE_ID_INTEL_82451NX	0x84ca
 #define PCI_DEVICE_ID_INTEL_82454NX     0x84cb
 #define PCI_DEVICE_ID_INTEL_84460GX	0x84ea
diff --git a/include/linux/poll.h b/include/linux/poll.h
index f6da702..8e8f609 100644
--- a/include/linux/poll.h
+++ b/include/linux/poll.h
@@ -92,7 +92,11 @@ void zero_fd_set(unsigned long nr, unsig
 	memset(fdset, 0, FDS_BYTES(nr));
 }
 
-extern int do_select(int n, fd_set_bits *fds, long *timeout);
+#define MAX_INT64_SECONDS (((s64)(~((u64)0)>>1)/HZ)-1)
+
+extern int do_select(int n, fd_set_bits *fds, s64 *timeout);
+extern int do_sys_poll(struct pollfd __user * ufds, unsigned int nfds,
+		       s64 *timeout);
 
 #endif /* KERNEL */
 
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
index 54faf52..95572c4 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -84,7 +84,6 @@ struct k_clock {
 void register_posix_clock(const clockid_t clock_id, struct k_clock *new_clock);
 
 /* error handlers for timer_create, nanosleep and settime */
-int do_posix_clock_notimer_create(struct k_itimer *timer);
 int do_posix_clock_nonanosleep(const clockid_t, int flags, struct timespec *,
 			       struct timespec __user *);
 int do_posix_clock_nosettime(const clockid_t, struct timespec *tp);
diff --git a/include/linux/reboot.h b/include/linux/reboot.h
index 7ab2cdb..015297f 100644
--- a/include/linux/reboot.h
+++ b/include/linux/reboot.h
@@ -60,8 +60,7 @@ extern void machine_crash_shutdown(struc
  */
 
 extern void kernel_restart_prepare(char *cmd);
-extern void kernel_halt_prepare(void);
-extern void kernel_power_off_prepare(void);
+extern void kernel_shutdown_prepare(enum system_states state);
 
 extern void kernel_restart(char *cmd);
 extern void kernel_halt(void);
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index e276c5b..7d51149 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -1971,22 +1971,6 @@ extern struct file_operations reiserfs_f
 extern struct address_space_operations reiserfs_address_space_operations;
 
 /* fix_nodes.c */
-#ifdef CONFIG_REISERFS_CHECK
-void *reiserfs_kmalloc(size_t size, gfp_t flags, struct super_block *s);
-void reiserfs_kfree(const void *vp, size_t size, struct super_block *s);
-#else
-static inline void *reiserfs_kmalloc(size_t size, int flags,
-				     struct super_block *s)
-{
-	return kmalloc(size, flags);
-}
-
-static inline void reiserfs_kfree(const void *vp, size_t size,
-				  struct super_block *s)
-{
-	kfree(vp);
-}
-#endif
 
 int fix_nodes(int n_op_mode, struct tree_balance *p_s_tb,
 	      struct item_head *p_s_ins_ih, const void *);
diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h
index 3e68592..31b4c0b 100644
--- a/include/linux/reiserfs_fs_sb.h
+++ b/include/linux/reiserfs_fs_sb.h
@@ -382,7 +382,6 @@ struct reiserfs_sb_info {
 					   on-disk FS format */
 
 	/* session statistics */
-	int s_kmallocs;
 	int s_disk_reads;
 	int s_disk_writes;
 	int s_fix_nodes;
diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h
index c84354e..87280eb 100644
--- a/include/linux/reiserfs_xattr.h
+++ b/include/linux/reiserfs_xattr.h
@@ -43,8 +43,6 @@ int reiserfs_delete_xattrs(struct inode 
 int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs);
 int reiserfs_xattr_init(struct super_block *sb, int mount_flags);
 int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd);
-int reiserfs_permission_locked(struct inode *inode, int mask,
-			       struct nameidata *nd);
 
 int reiserfs_xattr_del(struct inode *, const char *);
 int reiserfs_xattr_get(const struct inode *, const char *, void *, size_t);
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index 9d6fbee..d6b9bcd 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -91,7 +91,8 @@ static inline void page_dup_rmap(struct 
  * Called from mm/vmscan.c to handle paging out
  */
 int page_referenced(struct page *, int is_locked);
-int try_to_unmap(struct page *);
+int try_to_unmap(struct page *, int ignore_refs);
+void remove_from_swap(struct page *page);
 
 /*
  * Called from mm/filemap_xip.c to unmap empty zero page
@@ -111,7 +112,7 @@ unsigned long page_address_in_vma(struct
 #define anon_vma_link(vma)	do {} while (0)
 
 #define page_referenced(page,l) TestClearPageReferenced(page)
-#define try_to_unmap(page)	SWAP_FAIL
+#define try_to_unmap(page, refs) SWAP_FAIL
 
 #endif	/* CONFIG_MMU */
 
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 2df1a1a..0cfcd1c 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -809,6 +809,7 @@ struct task_struct {
 	struct sighand_struct *sighand;
 
 	sigset_t blocked, real_blocked;
+	sigset_t saved_sigmask;		/* To be restored with TIF_RESTORE_SIGMASK */
 	struct sigpending pending;
 
 	unsigned long sas_ss_sp;
diff --git a/include/linux/security.h b/include/linux/security.h
index ef75365..bb1da86 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -2617,6 +2617,25 @@ static inline int security_netlink_recv 
 	return cap_netlink_recv (skb);
 }
 
+static inline struct dentry *securityfs_create_dir(const char *name,
+					struct dentry *parent)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline struct dentry *securityfs_create_file(const char *name,
+						mode_t mode,
+						struct dentry *parent,
+						void *data,
+						struct file_operations *fops)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline void securityfs_remove(struct dentry *dentry)
+{
+}
+
 #endif	/* CONFIG_SECURITY */
 
 #ifdef CONFIG_SECURITY_NETWORK
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index cee302a..73b464f 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -26,7 +26,7 @@ struct plat_serial8250_port {
 	unsigned char	regshift;	/* register shift */
 	unsigned char	iotype;		/* UPIO_* */
 	unsigned char	hub6;
-	unsigned int	flags;		/* UPF_* flags */
+	upf_t		flags;		/* UPF_* flags */
 };
 
 /*
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index ec35100..4041122 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -203,6 +203,8 @@ struct uart_icount {
 	__u32	buf_overrun;
 };
 
+typedef unsigned int __bitwise__ upf_t;
+
 struct uart_port {
 	spinlock_t		lock;			/* port lock */
 	unsigned int		iobase;			/* in/out[bwl] */
@@ -230,36 +232,34 @@ struct uart_port {
 	unsigned long		sysrq;			/* sysrq timeout */
 #endif
 
-	unsigned int		flags;
+	upf_t			flags;
 
-#define UPF_FOURPORT		(1 << 1)
-#define UPF_SAK			(1 << 2)
-#define UPF_SPD_MASK		(0x1030)
-#define UPF_SPD_HI		(0x0010)
-#define UPF_SPD_VHI		(0x0020)
-#define UPF_SPD_CUST		(0x0030)
-#define UPF_SPD_SHI		(0x1000)
-#define UPF_SPD_WARP		(0x1010)
-#define UPF_SKIP_TEST		(1 << 6)
-#define UPF_AUTO_IRQ		(1 << 7)
-#define UPF_HARDPPS_CD		(1 << 11)
-#define UPF_LOW_LATENCY		(1 << 13)
-#define UPF_BUGGY_UART		(1 << 14)
-#define UPF_AUTOPROBE		(1 << 15)
-#define UPF_MAGIC_MULTIPLIER	(1 << 16)
-#define UPF_BOOT_ONLYMCA	(1 << 22)
-#define UPF_CONS_FLOW		(1 << 23)
-#define UPF_SHARE_IRQ		(1 << 24)
-#define UPF_BOOT_AUTOCONF	(1 << 28)
-#define UPF_IOREMAP		(1 << 31)
+#define UPF_FOURPORT		((__force upf_t) (1 << 1))
+#define UPF_SAK			((__force upf_t) (1 << 2))
+#define UPF_SPD_MASK		((__force upf_t) (0x1030))
+#define UPF_SPD_HI		((__force upf_t) (0x0010))
+#define UPF_SPD_VHI		((__force upf_t) (0x0020))
+#define UPF_SPD_CUST		((__force upf_t) (0x0030))
+#define UPF_SPD_SHI		((__force upf_t) (0x1000))
+#define UPF_SPD_WARP		((__force upf_t) (0x1010))
+#define UPF_SKIP_TEST		((__force upf_t) (1 << 6))
+#define UPF_AUTO_IRQ		((__force upf_t) (1 << 7))
+#define UPF_HARDPPS_CD		((__force upf_t) (1 << 11))
+#define UPF_LOW_LATENCY		((__force upf_t) (1 << 13))
+#define UPF_BUGGY_UART		((__force upf_t) (1 << 14))
+#define UPF_MAGIC_MULTIPLIER	((__force upf_t) (1 << 16))
+#define UPF_CONS_FLOW		((__force upf_t) (1 << 23))
+#define UPF_SHARE_IRQ		((__force upf_t) (1 << 24))
+#define UPF_BOOT_AUTOCONF	((__force upf_t) (1 << 28))
+#define UPF_IOREMAP		((__force upf_t) (1 << 31))
 
-#define UPF_CHANGE_MASK		(0x17fff)
-#define UPF_USR_MASK		(UPF_SPD_MASK|UPF_LOW_LATENCY)
+#define UPF_CHANGE_MASK		((__force upf_t) (0x17fff))
+#define UPF_USR_MASK		((__force upf_t) (UPF_SPD_MASK|UPF_LOW_LATENCY))
 
 	unsigned int		mctrl;			/* current modem ctrl settings */
 	unsigned int		timeout;		/* character-based timeout */
 	unsigned int		type;			/* port type */
-	struct uart_ops		*ops;
+	const struct uart_ops	*ops;
 	unsigned int		custom_divisor;
 	unsigned int		line;			/* port index */
 	unsigned long		mapbase;		/* for ioremap */
@@ -289,6 +289,9 @@ struct uart_state {
 };
 
 #define UART_XMIT_SIZE	PAGE_SIZE
+
+typedef unsigned int __bitwise__ uif_t;
+
 /*
  * This is the state information which is only valid when the port
  * is open; it may be freed by the core driver once the device has
@@ -298,17 +301,16 @@ struct uart_state {
 struct uart_info {
 	struct tty_struct	*tty;
 	struct circ_buf		xmit;
-	unsigned int		flags;
+	uif_t			flags;
 
 /*
- * These are the flags that specific to info->flags, and reflect our
- * internal state.  They can not be accessed via port->flags.  Low
- * level drivers must not change these, but may query them instead.
- */
-#define UIF_CHECK_CD		(1 << 25)
-#define UIF_CTS_FLOW		(1 << 26)
-#define UIF_NORMAL_ACTIVE	(1 << 29)
-#define UIF_INITIALIZED		(1 << 31)
+ * Definitions for info->flags.  These are _private_ to serial_core, and
+ * are specific to this structure.  They may be queried by low level drivers.
+ */
+#define UIF_CHECK_CD		((__force uif_t) (1 << 25))
+#define UIF_CTS_FLOW		((__force uif_t) (1 << 26))
+#define UIF_NORMAL_ACTIVE	((__force uif_t) (1 << 29))
+#define UIF_INITIALIZED		((__force uif_t) (1 << 31))
 
 	int			blocked_open;
 
@@ -430,7 +432,7 @@ static inline int uart_handle_break(stru
 		port->sysrq = 0;
 	}
 #endif
-	if (info->flags & UPF_SAK)
+	if (port->flags & UPF_SAK)
 		do_SAK(info->tty);
 	return 0;
 }
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index e5fd66c..ad7cc22 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -926,7 +926,7 @@ static inline int skb_tailroom(const str
  *	Increase the headroom of an empty &sk_buff by reducing the tail
  *	room. This is only allowed for an empty buffer.
  */
-static inline void skb_reserve(struct sk_buff *skb, unsigned int len)
+static inline void skb_reserve(struct sk_buff *skb, int len)
 {
 	skb->data += len;
 	skb->tail += len;
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 1fb77a9..8cf5293 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -76,7 +76,14 @@ struct cache_sizes {
 	kmem_cache_t	*cs_dmacachep;
 };
 extern struct cache_sizes malloc_sizes[];
+
+#ifndef CONFIG_DEBUG_SLAB
 extern void *__kmalloc(size_t, gfp_t);
+#else
+extern void *__kmalloc_track_caller(size_t, gfp_t, void*);
+#define __kmalloc(size, flags) \
+    __kmalloc_track_caller(size, flags, __builtin_return_address(0))
+#endif
 
 static inline void *kmalloc(size_t size, gfp_t flags)
 {
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index e4086ec..50cab2a 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -246,6 +246,7 @@ struct svc_deferred_req {
 	u32			prot;	/* protocol (UDP or TCP) */
 	struct sockaddr_in	addr;
 	struct svc_sock		*svsk;	/* where reply must go */
+	u32			daddr;	/* where reply must come from */
 	struct cache_deferred_req handle;
 	int			argslen;
 	u32			args[0];
diff --git a/include/linux/swap.h b/include/linux/swap.h
index e92054d..f3e17d5 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -167,6 +167,7 @@ extern void FASTCALL(lru_cache_add_activ
 extern void FASTCALL(activate_page(struct page *));
 extern void FASTCALL(mark_page_accessed(struct page *));
 extern void lru_add_drain(void);
+extern int lru_add_drain_all(void);
 extern int rotate_reclaimable_page(struct page *page);
 extern void swap_setup(void);
 
@@ -175,16 +176,35 @@ extern int try_to_free_pages(struct zone
 extern int shrink_all_memory(int);
 extern int vm_swappiness;
 
+#ifdef CONFIG_NUMA
+extern int zone_reclaim_mode;
+extern int zone_reclaim_interval;
+extern int zone_reclaim(struct zone *, gfp_t, unsigned int);
+#else
+#define zone_reclaim_mode 0
+static inline int zone_reclaim(struct zone *z, gfp_t mask, unsigned int order)
+{
+	return 0;
+}
+#endif
+
 #ifdef CONFIG_MIGRATION
 extern int isolate_lru_page(struct page *p);
 extern int putback_lru_pages(struct list_head *l);
+extern int migrate_page(struct page *, struct page *);
+extern void migrate_page_copy(struct page *, struct page *);
+extern int migrate_page_remove_references(struct page *, struct page *, int);
 extern int migrate_pages(struct list_head *l, struct list_head *t,
 		struct list_head *moved, struct list_head *failed);
+extern int fail_migrate_page(struct page *, struct page *);
 #else
 static inline int isolate_lru_page(struct page *p) { return -ENOSYS; }
 static inline int putback_lru_pages(struct list_head *l) { return 0; }
 static inline int migrate_pages(struct list_head *l, struct list_head *t,
 	struct list_head *moved, struct list_head *failed) { return -ENOSYS; }
+/* Possible settings for the migrate_page() method in address_operations */
+#define migrate_page NULL
+#define fail_migrate_page NULL
 #endif
 
 #ifdef CONFIG_MMU
@@ -233,6 +253,7 @@ extern int remove_exclusive_swap_page(st
 struct backing_dev_info;
 
 extern spinlock_t swap_lock;
+extern int remove_vma_swap(struct vm_area_struct *vma, struct page *page);
 
 /* linux/mm/thrash.c */
 extern struct mm_struct * swap_token_mm;
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 3eed473..3877209 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -50,6 +50,8 @@ struct timezone;
 struct tms;
 struct utimbuf;
 struct mq_attr;
+struct compat_stat;
+struct compat_timeval;
 
 #include <linux/config.h>
 #include <linux/types.h>
@@ -510,13 +512,59 @@ asmlinkage long sys_keyctl(int cmd, unsi
 asmlinkage long sys_ioprio_set(int which, int who, int ioprio);
 asmlinkage long sys_ioprio_get(int which, int who);
 asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask,
-					unsigned long maxnode);
+				unsigned long maxnode);
 asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
-			const unsigned long __user *from, const unsigned long __user *to);
+				const unsigned long __user *from,
+				const unsigned long __user *to);
+asmlinkage long sys_mbind(unsigned long start, unsigned long len,
+				unsigned long mode,
+				unsigned long __user *nmask,
+				unsigned long maxnode,
+				unsigned flags);
+asmlinkage long sys_get_mempolicy(int __user *policy,
+				unsigned long __user *nmask,
+				unsigned long maxnode,
+				unsigned long addr, unsigned long flags);
+
+asmlinkage long sys_inotify_init(void);
+asmlinkage long sys_inotify_add_watch(int fd, const char __user *path,
+					u32 mask);
+asmlinkage long sys_inotify_rm_watch(int fd, u32 wd);
 
 asmlinkage long sys_spu_run(int fd, __u32 __user *unpc,
 				 __u32 __user *ustatus);
 asmlinkage long sys_spu_create(const char __user *name,
 		unsigned int flags, mode_t mode);
 
+asmlinkage long sys_mknodat(int dfd, const char __user * filename, int mode,
+			    unsigned dev);
+asmlinkage long sys_mkdirat(int dfd, const char __user * pathname, int mode);
+asmlinkage long sys_unlinkat(int dfd, const char __user * pathname, int flag);
+asmlinkage long sys_symlinkat(const char __user * oldname,
+			      int newdfd, const char __user * newname);
+asmlinkage long sys_linkat(int olddfd, const char __user *oldname,
+			   int newdfd, const char __user *newname);
+asmlinkage long sys_renameat(int olddfd, const char __user * oldname,
+			     int newdfd, const char __user * newname);
+asmlinkage long sys_futimesat(int dfd, char __user *filename,
+			      struct timeval __user *utimes);
+asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode);
+asmlinkage long sys_fchmodat(int dfd, const char __user * filename,
+			     mode_t mode);
+asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user,
+			     gid_t group, int flag);
+asmlinkage long sys_openat(int dfd, const char __user *filename, int flags,
+			   int mode);
+asmlinkage long sys_newfstatat(int dfd, char __user *filename,
+			       struct stat __user *statbuf, int flag);
+asmlinkage long sys_readlinkat(int dfd, const char __user *path, char __user *buf,
+			       int bufsiz);
+asmlinkage long compat_sys_futimesat(unsigned int dfd, char __user *filename,
+				     struct compat_timeval __user *t);
+asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user * filename,
+				      struct compat_stat __user *statbuf,
+				      int flag);
+asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename,
+				   int flags, int mode);
+
 #endif
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 7f47212..32a4139 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -182,6 +182,8 @@ enum
 	VM_SWAP_TOKEN_TIMEOUT=28, /* default time for token time out */
 	VM_DROP_PAGECACHE=29,	/* int: nuke lots of pagecache */
 	VM_PERCPU_PAGELIST_FRACTION=30,/* int: fraction of pages in each percpu_pagelist */
+	VM_ZONE_RECLAIM_MODE=31, /* reclaim local zone memory before going off node */
+	VM_ZONE_RECLAIM_INTERVAL=32, /* time period to wait after reclaim failure */
 };
 
 
diff --git a/include/linux/time.h b/include/linux/time.h
index f2aca7e..7b4dc36 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -48,7 +48,7 @@ extern void set_normalized_timespec(stru
  * Returns true if the timespec is norm, false if denorm:
  */
 #define timespec_valid(ts) \
-	(((ts)->tv_sec >= 0) && (((unsigned) (ts)->tv_nsec) < NSEC_PER_SEC))
+	(((ts)->tv_sec >= 0) && (((unsigned long) (ts)->tv_nsec) < NSEC_PER_SEC))
 
 /*
  * 64-bit nanosec type. Large enough to span 292+ years in nanosecond
@@ -74,7 +74,7 @@ extern void do_gettimeofday(struct timev
 extern int do_settimeofday(struct timespec *tv);
 extern int do_sys_settimeofday(struct timespec *tv, struct timezone *tz);
 #define do_posix_clock_monotonic_gettime(ts) ktime_get_ts(ts)
-extern long do_utimes(char __user *filename, struct timeval *times);
+extern long do_utimes(int dfd, char __user *filename, struct timeval *times);
 struct itimerval;
 extern int do_setitimer(int which, struct itimerval *value,
 			struct itimerval *ovalue);
diff --git a/include/linux/tipc_config.h b/include/linux/tipc_config.h
index a52c8c6..33a6539 100644
--- a/include/linux/tipc_config.h
+++ b/include/linux/tipc_config.h
@@ -168,10 +168,13 @@
 #define TIPC_MAX_LINK_NAME	60	/* format = Z.C.N:interface-Z.C.N:interface */
 
 /*
- * Link priority limits (range from 0 to # priorities - 1)
+ * Link priority limits (min, default, max, media default)
  */
 
-#define TIPC_NUM_LINK_PRI 32
+#define TIPC_MIN_LINK_PRI	0
+#define TIPC_DEF_LINK_PRI	10
+#define TIPC_MAX_LINK_PRI	31
+#define TIPC_MEDIA_LINK_PRI	(TIPC_MAX_LINK_PRI + 1)
 
 /*
  * Link tolerance limits (min, default, max), in ms
diff --git a/include/linux/topology.h b/include/linux/topology.h
index 315a516..e8eb004 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -56,6 +56,14 @@
 #define REMOTE_DISTANCE		20
 #define node_distance(from,to)	((from) == (to) ? LOCAL_DISTANCE : REMOTE_DISTANCE)
 #endif
+#ifndef RECLAIM_DISTANCE
+/*
+ * If the distance between nodes in a system is larger than RECLAIM_DISTANCE
+ * (in whatever arch specific measurement units returned by node_distance())
+ * then switch on zone reclaim on boot.
+ */
+#define RECLAIM_DISTANCE 20
+#endif
 #ifndef PENALTY_FOR_NODE_WITH_CPUS
 #define PENALTY_FOR_NODE_WITH_CPUS	(1)
 #endif
diff --git a/include/linux/types.h b/include/linux/types.h
index 21b9ce8..54ae2d5 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -8,6 +8,8 @@
 	(((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
 #define DECLARE_BITMAP(name,bits) \
 	unsigned long name[BITS_TO_LONGS(bits)]
+
+#define BITS_PER_BYTE 8
 #endif
 
 #include <linux/posix_types.h>
diff --git a/include/linux/usb_ch9.h b/include/linux/usb_ch9.h
index ee21e6b..a2aacfc 100644
--- a/include/linux/usb_ch9.h
+++ b/include/linux/usb_ch9.h
@@ -535,9 +535,11 @@ enum usb_device_state {
 	 */
 	USB_STATE_NOTATTACHED = 0,
 
-	/* the chapter 9 device states */
+	/* chapter 9 and authentication (wireless) device states */
 	USB_STATE_ATTACHED,
-	USB_STATE_POWERED,
+	USB_STATE_POWERED,			/* wired */
+	USB_STATE_UNAUTHENTICATED,		/* auth */
+	USB_STATE_RECONNECTING,			/* auth */
 	USB_STATE_DEFAULT,			/* limited function */
 	USB_STATE_ADDRESS,
 	USB_STATE_CONFIGURED,			/* most functions */
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index ce40675..6f6c697 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -315,6 +315,7 @@ struct v4l2_pix_format
 #define V4L2_PIX_FMT_SN9C10X  v4l2_fourcc('S','9','1','0') /* SN9C10x compression */
 #define V4L2_PIX_FMT_PWC1     v4l2_fourcc('P','W','C','1') /* pwc older webcam */
 #define V4L2_PIX_FMT_PWC2     v4l2_fourcc('P','W','C','2') /* pwc newer webcam */
+#define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E','6','2','5') /* ET61X251 compression */
 
 /*
  *	F O R M A T   E N U M E R A T I O N
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
index df05f46..9a92aef 100644
--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -803,9 +803,9 @@ enum ieee80211_state {
 #define IEEE80211_24GHZ_MAX_CHANNEL 14
 #define IEEE80211_24GHZ_CHANNELS    14
 
-#define IEEE80211_52GHZ_MIN_CHANNEL 36
+#define IEEE80211_52GHZ_MIN_CHANNEL 34
 #define IEEE80211_52GHZ_MAX_CHANNEL 165
-#define IEEE80211_52GHZ_CHANNELS    32
+#define IEEE80211_52GHZ_CHANNELS    131
 
 enum {
 	IEEE80211_CH_PASSIVE_ONLY = (1 << 0),
diff --git a/include/net/ieee80211_crypt.h b/include/net/ieee80211_crypt.h
index 03b766a..cd82c3e 100644
--- a/include/net/ieee80211_crypt.h
+++ b/include/net/ieee80211_crypt.h
@@ -25,6 +25,7 @@
 
 #include <linux/types.h>
 #include <linux/list.h>
+#include <net/ieee80211.h>
 #include <asm/atomic.h>
 
 enum {
diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h
index d67c839..a2c5e0b 100644
--- a/include/net/iw_handler.h
+++ b/include/net/iw_handler.h
@@ -327,7 +327,7 @@ struct iw_handler_def
 	__u16			num_private_args;
 
 	/* Array of handlers for standard ioctls
-	 * We will call dev->wireless_handlers->standard[ioctl - SIOCSIWNAME]
+	 * We will call dev->wireless_handlers->standard[ioctl - SIOCSIWCOMMIT]
 	 */
 	const iw_handler *	standard;
 
diff --git a/include/net/route.h b/include/net/route.h
index e3e5436..9c04f15 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -170,8 +170,8 @@ static inline int ip_route_connect(struc
 	return ip_route_output_flow(rp, &fl, sk, 0);
 }
 
-static inline int ip_route_newports(struct rtable **rp, u16 sport, u16 dport,
-				    struct sock *sk)
+static inline int ip_route_newports(struct rtable **rp, u8 protocol,
+				    u16 sport, u16 dport, struct sock *sk)
 {
 	if (sport != (*rp)->fl.fl_ip_sport ||
 	    dport != (*rp)->fl.fl_ip_dport) {
@@ -180,6 +180,7 @@ static inline int ip_route_newports(stru
 		memcpy(&fl, &(*rp)->fl, sizeof(fl));
 		fl.fl_ip_sport = sport;
 		fl.fl_ip_dport = dport;
+		fl.proto = protocol;
 		ip_rt_put(*rp);
 		*rp = NULL;
 		return ip_route_output_flow(rp, &fl, sk, 0);
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index a553f39..e673b2c 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -175,6 +175,8 @@ void sctp_icmp_frag_needed(struct sock *
 void sctp_icmp_proto_unreachable(struct sock *sk,
 				 struct sctp_association *asoc,
 				 struct sctp_transport *t);
+void sctp_backlog_migrate(struct sctp_association *assoc,
+			  struct sock *oldsk, struct sock *newsk);
 
 /*
  *  Section:  Macros, externs, and inlines
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index f5c22d7..8c522ae 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -127,9 +127,9 @@ extern struct sctp_globals {
 	 * RTO.Alpha		    - 1/8  (3 when converted to right shifts.)
 	 * RTO.Beta		    - 1/4  (2 when converted to right shifts.)
 	 */
-	__u32 rto_initial;
-	__u32 rto_min;
-	__u32 rto_max;
+	unsigned long rto_initial;
+	unsigned long rto_min;
+	unsigned long rto_max;
 
 	/* Note: rto_alpha and rto_beta are really defined as inverse
 	 * powers of two to facilitate integer operations.
@@ -140,12 +140,18 @@ extern struct sctp_globals {
 	/* Max.Burst		    - 4 */
 	int max_burst;
 
-	/* Valid.Cookie.Life	    - 60  seconds  */
-	int valid_cookie_life;
-
 	/* Whether Cookie Preservative is enabled(1) or not(0) */
 	int cookie_preserve_enable;
 
+	/* Valid.Cookie.Life	    - 60  seconds  */
+	unsigned long valid_cookie_life;
+
+	/* Delayed SACK timeout  200ms default*/
+	unsigned long sack_timeout;
+
+	/* HB.interval		    - 30 seconds  */
+	unsigned long hb_interval;
+
 	/* Association.Max.Retrans  - 10 attempts
 	 * Path.Max.Retrans	    - 5	 attempts (per destination address)
 	 * Max.Init.Retransmits	    - 8	 attempts
@@ -168,12 +174,6 @@ extern struct sctp_globals {
 	 */
 	int rcvbuf_policy;
 
-	/* Delayed SACK timeout  200ms default*/
-	int sack_timeout;
-
-	/* HB.interval		    - 30 seconds  */
-	int hb_interval;
-
 	/* The following variables are implementation specific.	 */
 
 	/* Default initialization values to be applied to new associations. */
@@ -405,8 +405,9 @@ struct sctp_cookie {
 /* The format of our cookie that we send to our peer. */
 struct sctp_signed_cookie {
 	__u8 signature[SCTP_SECRET_SIZE];
+	__u32 __pad;		/* force sctp_cookie alignment to 64 bits */
 	struct sctp_cookie c;
-};
+} __attribute__((packed));
 
 /* This is another convenience type to allocate memory for address
  * params for the maximum size and pass such structures around
@@ -827,7 +828,7 @@ struct sctp_transport {
 	__u32 rtt;		/* This is the most recent RTT.	 */
 
 	/* RTO	       : The current retransmission timeout value.  */
-	__u32 rto;
+	unsigned long rto;
 
 	/* RTTVAR      : The current RTT variation.  */
 	__u32 rttvar;
@@ -877,22 +878,10 @@ struct sctp_transport {
 	/* Heartbeat interval: The endpoint sends out a Heartbeat chunk to
 	 * the destination address every heartbeat interval.
 	 */
-	__u32 hbinterval;
-
-	/* This is the max_retrans value for the transport and will
-	 * be initialized from the assocs value.  This can be changed
-	 * using SCTP_SET_PEER_ADDR_PARAMS socket option.
-	 */
-	__u16 pathmaxrxt;
-
-	/* PMTU	      : The current known path MTU.  */
-	__u32 pathmtu;
+	unsigned long hbinterval;
 
 	/* SACK delay timeout */
-	__u32 sackdelay;
-
-	/* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */
-	__u32 param_flags;
+	unsigned long sackdelay;
 
 	/* When was the last time (in jiffies) that we heard from this
 	 * transport?  We use this to pick new active and retran paths.
@@ -904,6 +893,18 @@ struct sctp_transport {
 	 */
 	unsigned long last_time_ecne_reduced;
 
+	/* This is the max_retrans value for the transport and will
+	 * be initialized from the assocs value.  This can be changed
+	 * using SCTP_SET_PEER_ADDR_PARAMS socket option.
+	 */
+	__u16 pathmaxrxt;
+
+	/* PMTU	      : The current known path MTU.  */
+	__u32 pathmtu;
+
+	/* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */
+	__u32 param_flags;
+
 	/* The number of times INIT has been sent on this transport. */
 	int init_sent_count;
 
@@ -1249,6 +1250,14 @@ struct sctp_endpoint {
 	int last_key;
 	int key_changed_at;
 
+ 	/* digest:  This is a digest of the sctp cookie.  This field is
+ 	 * 	    only used on the receive path when we try to validate
+ 	 * 	    that the cookie has not been tampered with.  We put
+ 	 * 	    this here so we pre-allocate this once and can re-use
+ 	 * 	    on every receive.
+ 	 */
+ 	__u8 digest[SCTP_SIGNATURE_SIZE];
+ 
 	/* sendbuf acct. policy.	*/
 	__u32 sndbuf_policy;
 
@@ -1499,9 +1508,9 @@ struct sctp_association {
 	 * These values will be initialized by system defaults, but can
 	 * be modified via the SCTP_RTOINFO socket option.
 	 */
-	__u32 rto_initial;
-	__u32 rto_max;
-	__u32 rto_min;
+	unsigned long rto_initial;
+	unsigned long rto_max;
+	unsigned long rto_min;
 
 	/* Maximum number of new data packets that can be sent in a burst.  */
 	int max_burst;
@@ -1519,13 +1528,13 @@ struct sctp_association {
 	__u16 init_retries;
 
 	/* The largest timeout or RTO value to use in attempting an INIT */
-	__u16 max_init_timeo;
+	unsigned long max_init_timeo;
 
 	/* Heartbeat interval: The endpoint sends out a Heartbeat chunk to
 	 * the destination address every heartbeat interval. This value
 	 * will be inherited by all new transports.
 	 */
-	__u32 hbinterval;
+	unsigned long hbinterval;
 
 	/* This is the max_retrans value for new transports in the
 	 * association.
@@ -1537,13 +1546,14 @@ struct sctp_association {
 	 */
 	__u32 pathmtu;
 
-	/* SACK delay timeout */
-	__u32 sackdelay;
-
 	/* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */
 	__u32 param_flags;
 
-	int timeouts[SCTP_NUM_TIMEOUT_TYPES];
+	/* SACK delay timeout */
+	unsigned long sackdelay;
+
+
+	unsigned long timeouts[SCTP_NUM_TIMEOUT_TYPES];
 	struct timer_list timers[SCTP_NUM_TIMEOUT_TYPES];
 
 	/* Transport to which SHUTDOWN chunk was last sent.  */
@@ -1648,7 +1658,10 @@ struct sctp_association {
 	/* How many duplicated TSNs have we seen?  */
 	int numduptsns;
 
-	/* Number of seconds of idle time before an association is closed.  */
+	/* Number of seconds of idle time before an association is closed.
+	 * In the association context, this is really used as a boolean
+	 * since the real timeout is stored in the timeouts array
+	 */
 	__u32 autoclose;
 
 	/* These are to support
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index e94ca4d..290e3b4 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -275,7 +275,7 @@ extern int scsi_execute_req(struct scsi_
 			    int data_direction, void *buffer, unsigned bufflen,
 			    struct scsi_sense_hdr *, int timeout, int retries);
 extern int scsi_execute_async(struct scsi_device *sdev,
-			      const unsigned char *cmd, int data_direction,
+			      const unsigned char *cmd, int cmd_len, int data_direction,
 			      void *buffer, unsigned bufflen, int use_sg,
 			      int timeout, int retries, void *privdata,
 			      void (*done)(void *, char *, int, int),
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 467274a..8279929 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -554,7 +554,6 @@ struct Scsi_Host {
 	/*
 	 * ordered write support
 	 */
-	unsigned ordered_flush:1;
 	unsigned ordered_tag:1;
 
 	/*
diff --git a/include/scsi/scsi_transport_spi.h b/include/scsi/scsi_transport_spi.h
index 2b5930b..fb5a2ff 100644
--- a/include/scsi/scsi_transport_spi.h
+++ b/include/scsi/scsi_transport_spi.h
@@ -22,6 +22,7 @@
 
 #include <linux/config.h>
 #include <linux/transport_class.h>
+#include <linux/mutex.h>
 
 struct scsi_transport_template;
 struct scsi_target;
diff --git a/kernel/audit.c b/kernel/audit.c
index d13ab7d..0a813d2 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -42,8 +42,8 @@
  */
 
 #include <linux/init.h>
-#include <asm/atomic.h>
 #include <asm/types.h>
+#include <asm/atomic.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/err.h>
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index d8a6850..685c251 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -30,8 +30,8 @@
  */
 
 #include <linux/init.h>
-#include <asm/atomic.h>
 #include <asm/types.h>
+#include <asm/atomic.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/mount.h>
diff --git a/kernel/compat.c b/kernel/compat.c
index 256e5d9..1867290 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -871,3 +871,31 @@ asmlinkage long compat_sys_stime(compat_
 }
 
 #endif /* __ARCH_WANT_COMPAT_SYS_TIME */
+
+#ifdef __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
+asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset, compat_size_t sigsetsize)
+{
+	sigset_t newset;
+	compat_sigset_t newset32;
+
+	/* XXX: Don't preclude handling different sized sigset_t's.  */
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&newset32, unewset, sizeof(compat_sigset_t)))
+		return -EFAULT;
+	sigset_from_compat(&newset, &newset32);
+	sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP));
+
+	spin_lock_irq(&current->sighand->siglock);
+	current->saved_sigmask = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	set_thread_flag(TIF_RESTORE_SIGMASK);
+	return -ERESTARTNOHAND;
+}
+#endif /* __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND */
diff --git a/kernel/fork.c b/kernel/fork.c
index 4ae8cfc..7f0ab5e 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -802,7 +802,7 @@ static inline int copy_signal(unsigned l
 	init_sigpending(&sig->shared_pending);
 	INIT_LIST_HEAD(&sig->posix_timers);
 
-	hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC);
+	hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC, HRTIMER_REL);
 	sig->it_real_incr.tv64 = 0;
 	sig->real_timer.function = it_real_fn;
 	sig->real_timer.data = tsk;
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index f1c4155..2b6e175 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -21,6 +21,12 @@
  *  Credits:
  *	based on kernel/timer.c
  *
+ *	Help, testing, suggestions, bugfixes, improvements were
+ *	provided by:
+ *
+ *	George Anzinger, Andrew Morton, Steven Rostedt, Roman Zippel
+ *	et. al.
+ *
  *  For licencing details see kernel-base/COPYING
  */
 
@@ -66,6 +72,12 @@ EXPORT_SYMBOL_GPL(ktime_get_real);
 
 /*
  * The timer bases:
+ *
+ * Note: If we want to add new timer bases, we have to skip the two
+ * clock ids captured by the cpu-timers. We do this by holding empty
+ * entries rather than doing math adjustment of the clock ids.
+ * This ensures that we capture erroneous accesses to these clock ids
+ * rather than moving them into the range of valid clock id's.
  */
 
 #define MAX_HRTIMER_BASES 2
@@ -483,29 +495,25 @@ ktime_t hrtimer_get_remaining(const stru
 }
 
 /**
- * hrtimer_rebase - rebase an initialized hrtimer to a different base
+ * hrtimer_init - initialize a timer to the given clock
  *
- * @timer:	the timer to be rebased
+ * @timer:	the timer to be initialized
  * @clock_id:	the clock to be used
+ * @mode:	timer mode abs/rel
  */
-void hrtimer_rebase(struct hrtimer *timer, const clockid_t clock_id)
+void hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
+		  enum hrtimer_mode mode)
 {
 	struct hrtimer_base *bases;
 
+	memset(timer, 0, sizeof(struct hrtimer));
+
 	bases = per_cpu(hrtimer_bases, raw_smp_processor_id());
-	timer->base = &bases[clock_id];
-}
 
-/**
- * hrtimer_init - initialize a timer to the given clock
- *
- * @timer:	the timer to be initialized
- * @clock_id:	the clock to be used
- */
-void hrtimer_init(struct hrtimer *timer, const clockid_t clock_id)
-{
-	memset(timer, 0, sizeof(struct hrtimer));
-	hrtimer_rebase(timer, clock_id);
+	if (clock_id == CLOCK_REALTIME && mode != HRTIMER_ABS)
+		clock_id = CLOCK_MONOTONIC;
+
+	timer->base = &bases[clock_id];
 }
 
 /**
@@ -550,6 +558,7 @@ static inline void run_hrtimer_queue(str
 		fn = timer->function;
 		data = timer->data;
 		set_curr_timer(base, timer);
+		timer->state = HRTIMER_RUNNING;
 		__remove_hrtimer(timer, base);
 		spin_unlock_irq(&base->lock);
 
@@ -565,6 +574,10 @@ static inline void run_hrtimer_queue(str
 
 		spin_lock_irq(&base->lock);
 
+		/* Another CPU has added back the timer */
+		if (timer->state != HRTIMER_RUNNING)
+			continue;
+
 		if (restart == HRTIMER_RESTART)
 			enqueue_hrtimer(timer, base);
 		else
@@ -638,8 +651,7 @@ schedule_hrtimer_interruptible(struct hr
 	return schedule_hrtimer(timer, mode);
 }
 
-static long __sched
-nanosleep_restart(struct restart_block *restart, clockid_t clockid)
+static long __sched nanosleep_restart(struct restart_block *restart)
 {
 	struct timespec __user *rmtp;
 	struct timespec tu;
@@ -649,7 +661,7 @@ nanosleep_restart(struct restart_block *
 
 	restart->fn = do_no_restart_syscall;
 
-	hrtimer_init(&timer, clockid);
+	hrtimer_init(&timer, (clockid_t) restart->arg3, HRTIMER_ABS);
 
 	timer.expires.tv64 = ((u64)restart->arg1 << 32) | (u64) restart->arg0;
 
@@ -669,16 +681,6 @@ nanosleep_restart(struct restart_block *
 	return -ERESTART_RESTARTBLOCK;
 }
 
-static long __sched nanosleep_restart_mono(struct restart_block *restart)
-{
-	return nanosleep_restart(restart, CLOCK_MONOTONIC);
-}
-
-static long __sched nanosleep_restart_real(struct restart_block *restart)
-{
-	return nanosleep_restart(restart, CLOCK_REALTIME);
-}
-
 long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
 		       const enum hrtimer_mode mode, const clockid_t clockid)
 {
@@ -687,7 +689,7 @@ long hrtimer_nanosleep(struct timespec *
 	struct timespec tu;
 	ktime_t rem;
 
-	hrtimer_init(&timer, clockid);
+	hrtimer_init(&timer, clockid, mode);
 
 	timer.expires = timespec_to_ktime(*rqtp);
 
@@ -695,7 +697,7 @@ long hrtimer_nanosleep(struct timespec *
 	if (rem.tv64 <= 0)
 		return 0;
 
-	/* Absolute timers do not update the rmtp value: */
+	/* Absolute timers do not update the rmtp value and restart: */
 	if (mode == HRTIMER_ABS)
 		return -ERESTARTNOHAND;
 
@@ -705,11 +707,11 @@ long hrtimer_nanosleep(struct timespec *
 		return -EFAULT;
 
 	restart = &current_thread_info()->restart_block;
-	restart->fn = (clockid == CLOCK_MONOTONIC) ?
-		nanosleep_restart_mono : nanosleep_restart_real;
+	restart->fn = nanosleep_restart;
 	restart->arg0 = timer.expires.tv64 & 0xFFFFFFFF;
 	restart->arg1 = timer.expires.tv64 >> 32;
 	restart->arg2 = (unsigned long) rmtp;
+	restart->arg3 = (unsigned long) timer.base->index;
 
 	return -ERESTART_RESTARTBLOCK;
 }
@@ -736,10 +738,8 @@ static void __devinit init_hrtimers_cpu(
 	struct hrtimer_base *base = per_cpu(hrtimer_bases, cpu);
 	int i;
 
-	for (i = 0; i < MAX_HRTIMER_BASES; i++) {
+	for (i = 0; i < MAX_HRTIMER_BASES; i++, base++)
 		spin_lock_init(&base->lock);
-		base++;
-	}
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
diff --git a/kernel/itimer.c b/kernel/itimer.c
index c2c05c4..379be2f 100644
--- a/kernel/itimer.c
+++ b/kernel/itimer.c
@@ -49,9 +49,11 @@ int do_getitimer(int which, struct itime
 
 	switch (which) {
 	case ITIMER_REAL:
+		spin_lock_irq(&tsk->sighand->siglock);
 		value->it_value = itimer_get_remtime(&tsk->signal->real_timer);
 		value->it_interval =
 			ktime_to_timeval(tsk->signal->it_real_incr);
+		spin_unlock_irq(&tsk->sighand->siglock);
 		break;
 	case ITIMER_VIRTUAL:
 		read_lock(&tasklist_lock);
@@ -150,18 +152,25 @@ int do_setitimer(int which, struct itime
 
 	switch (which) {
 	case ITIMER_REAL:
+again:
+		spin_lock_irq(&tsk->sighand->siglock);
 		timer = &tsk->signal->real_timer;
-		hrtimer_cancel(timer);
 		if (ovalue) {
 			ovalue->it_value = itimer_get_remtime(timer);
 			ovalue->it_interval
 				= ktime_to_timeval(tsk->signal->it_real_incr);
 		}
+		/* We are sharing ->siglock with it_real_fn() */
+		if (hrtimer_try_to_cancel(timer) < 0) {
+			spin_unlock_irq(&tsk->sighand->siglock);
+			goto again;
+		}
 		tsk->signal->it_real_incr =
 			timeval_to_ktime(value->it_interval);
 		expires = timeval_to_ktime(value->it_value);
 		if (expires.tv64 != 0)
 			hrtimer_start(timer, expires, HRTIMER_REL);
+		spin_unlock_irq(&tsk->sighand->siglock);
 		break;
 	case ITIMER_VIRTUAL:
 		nval = timeval_to_cputime(&value->it_value);
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index 197208b..216f574 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -194,9 +194,7 @@ static inline int common_clock_set(const
 
 static int common_timer_create(struct k_itimer *new_timer)
 {
-	hrtimer_init(&new_timer->it.real.timer, new_timer->it_clock);
-	new_timer->it.real.timer.data = new_timer;
-	new_timer->it.real.timer.function = posix_timer_fn;
+	hrtimer_init(&new_timer->it.real.timer, new_timer->it_clock, 0);
 	return 0;
 }
 
@@ -290,7 +288,8 @@ void do_schedule_next_timer(struct sigin
 		info->si_overrun = timr->it_overrun_last;
 	}
 
-	unlock_timer(timr, flags);
+	if (timr)
+		unlock_timer(timr, flags);
 }
 
 int posix_timer_event(struct k_itimer *timr,int si_private)
@@ -692,6 +691,7 @@ common_timer_set(struct k_itimer *timr, 
 		 struct itimerspec *new_setting, struct itimerspec *old_setting)
 {
 	struct hrtimer *timer = &timr->it.real.timer;
+	enum hrtimer_mode mode;
 
 	if (old_setting)
 		common_timer_get(timr, old_setting);
@@ -713,14 +713,10 @@ common_timer_set(struct k_itimer *timr, 
 	if (!new_setting->it_value.tv_sec && !new_setting->it_value.tv_nsec)
 		return 0;
 
-	/* Posix madness. Only absolute CLOCK_REALTIME timers
-	 * are affected by clock sets. So we must reiniatilize
-	 * the timer.
-	 */
-	if (timr->it_clock == CLOCK_REALTIME && (flags & TIMER_ABSTIME))
-		hrtimer_rebase(timer, CLOCK_REALTIME);
-	else
-		hrtimer_rebase(timer, CLOCK_MONOTONIC);
+	mode = flags & TIMER_ABSTIME ? HRTIMER_ABS : HRTIMER_REL;
+	hrtimer_init(&timr->it.real.timer, timr->it_clock, mode);
+	timr->it.real.timer.data = timr;
+	timr->it.real.timer.function = posix_timer_fn;
 
 	timer->expires = timespec_to_ktime(new_setting->it_value);
 
@@ -728,11 +724,15 @@ common_timer_set(struct k_itimer *timr, 
 	timr->it.real.interval = timespec_to_ktime(new_setting->it_interval);
 
 	/* SIGEV_NONE timers are not queued ! See common_timer_get */
-	if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE))
+	if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) {
+		/* Setup correct expiry time for relative timers */
+		if (mode == HRTIMER_REL)
+			timer->expires = ktime_add(timer->expires,
+						   timer->base->get_time());
 		return 0;
+	}
 
-	hrtimer_start(timer, timer->expires, (flags & TIMER_ABSTIME) ?
-		      HRTIMER_ABS : HRTIMER_REL);
+	hrtimer_start(timer, timer->expires, mode);
 	return 0;
 }
 
@@ -875,12 +875,6 @@ int do_posix_clock_nosettime(const clock
 }
 EXPORT_SYMBOL_GPL(do_posix_clock_nosettime);
 
-int do_posix_clock_notimer_create(struct k_itimer *timer)
-{
-	return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(do_posix_clock_notimer_create);
-
 int do_posix_clock_nonanosleep(const clockid_t clock, int flags,
 			       struct timespec *t, struct timespec __user *r)
 {
@@ -947,21 +941,8 @@ sys_clock_getres(const clockid_t which_c
 static int common_nsleep(const clockid_t which_clock, int flags,
 			 struct timespec *tsave, struct timespec __user *rmtp)
 {
-	int mode = flags & TIMER_ABSTIME ? HRTIMER_ABS : HRTIMER_REL;
-	int clockid = which_clock;
-
-	switch (which_clock) {
-	case CLOCK_REALTIME:
-		/* Posix madness. Only absolute timers on clock realtime
-		   are affected by clock set. */
-		if (mode != HRTIMER_ABS)
-			clockid = CLOCK_MONOTONIC;
-	case CLOCK_MONOTONIC:
-		break;
-	default:
-		return -EINVAL;
-	}
-	return hrtimer_nanosleep(tsave, rmtp, mode, clockid);
+	return hrtimer_nanosleep(tsave, rmtp, flags & TIMER_ABSTIME ?
+				 HRTIMER_ABS : HRTIMER_REL, which_clock);
 }
 
 asmlinkage long
diff --git a/kernel/power/console.c b/kernel/power/console.c
index 7ff375e..579d239 100644
--- a/kernel/power/console.c
+++ b/kernel/power/console.c
@@ -9,18 +9,11 @@
 #include <linux/console.h>
 #include "power.h"
 
-static int new_loglevel = 10;
-static int orig_loglevel;
 #ifdef SUSPEND_CONSOLE
 static int orig_fgconsole, orig_kmsg;
-#endif
 
 int pm_prepare_console(void)
 {
-	orig_loglevel = console_loglevel;
-	console_loglevel = new_loglevel;
-
-#ifdef SUSPEND_CONSOLE
 	acquire_console_sem();
 
 	orig_fgconsole = fg_console;
@@ -41,18 +34,15 @@ int pm_prepare_console(void)
 	}
 	orig_kmsg = kmsg_redirect;
 	kmsg_redirect = SUSPEND_CONSOLE;
-#endif
 	return 0;
 }
 
 void pm_restore_console(void)
 {
-	console_loglevel = orig_loglevel;
-#ifdef SUSPEND_CONSOLE
 	acquire_console_sem();
 	set_console(orig_fgconsole);
 	release_console_sem();
 	kmsg_redirect = orig_kmsg;
-#endif
 	return;
 }
+#endif
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index e24446f..0b43847 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -53,7 +53,7 @@ static void power_down(suspend_disk_meth
 
 	switch(mode) {
 	case PM_DISK_PLATFORM:
-		kernel_power_off_prepare();
+		kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
 		error = pm_ops->enter(PM_SUSPEND_DISK);
 		break;
 	case PM_DISK_SHUTDOWN:
@@ -95,13 +95,6 @@ static int prepare_processes(void)
 		goto thaw;
 	}
 
-	if (pm_disk_mode == PM_DISK_PLATFORM) {
-		if (pm_ops && pm_ops->prepare) {
-			if ((error = pm_ops->prepare(PM_SUSPEND_DISK)))
-				goto thaw;
-		}
-	}
-
 	/* Free memory before shutting down devices. */
 	if (!(error = swsusp_shrink_memory()))
 		return 0;
@@ -367,14 +360,14 @@ power_attr(resume);
 
 static ssize_t image_size_show(struct subsystem * subsys, char *buf)
 {
-	return sprintf(buf, "%u\n", image_size);
+	return sprintf(buf, "%lu\n", image_size);
 }
 
 static ssize_t image_size_store(struct subsystem * subsys, const char * buf, size_t n)
 {
-	unsigned int size;
+	unsigned long size;
 
-	if (sscanf(buf, "%u", &size) == 1) {
+	if (sscanf(buf, "%lu", &size) == 1) {
 		image_size = size;
 		return n;
 	}
diff --git a/kernel/power/main.c b/kernel/power/main.c
index d253f3a..9cb235c 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -133,10 +133,10 @@ static int suspend_enter(suspend_state_t
 static void suspend_finish(suspend_state_t state)
 {
 	device_resume();
-	if (pm_ops && pm_ops->finish)
-		pm_ops->finish(state);
 	thaw_processes();
 	enable_nonboot_cpus();
+	if (pm_ops && pm_ops->finish)
+		pm_ops->finish(state);
 	pm_restore_console();
 }
 
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 7e8492f..d8f0d1a 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -42,8 +42,13 @@ static struct subsys_attribute _name##_a
 
 extern struct subsystem power_subsys;
 
+#ifdef SUSPEND_CONSOLE
 extern int pm_prepare_console(void);
 extern void pm_restore_console(void);
+#else
+static int pm_prepare_console(void) { return 0; }
+static void pm_restore_console(void) {}
+#endif
 
 /* References to section boundaries */
 extern const void __nosave_begin, __nosave_end;
@@ -51,8 +56,8 @@ extern const void __nosave_begin, __nosa
 extern unsigned int nr_copy_pages;
 extern struct pbe *pagedir_nosave;
 
-/* Preferred image size in MB (default 500) */
-extern unsigned int image_size;
+/* Preferred image size in bytes (default 500 MB) */
+extern unsigned long image_size;
 
 extern asmlinkage int swsusp_arch_suspend(void);
 extern asmlinkage int swsusp_arch_resume(void);
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index 55a18d2..59c91c1 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -70,12 +70,12 @@
 #include "power.h"
 
 /*
- * Preferred image size in MB (tunable via /sys/power/image_size).
+ * Preferred image size in bytes (tunable via /sys/power/image_size).
  * When it is set to N, swsusp will do its best to ensure the image
- * size will not exceed N MB, but if that is impossible, it will
+ * size will not exceed N bytes, but if that is impossible, it will
  * try to create the smallest image possible.
  */
-unsigned int image_size = 500;
+unsigned long image_size = 500 * 1024 * 1024;
 
 #ifdef CONFIG_HIGHMEM
 unsigned int count_highmem_pages(void);
@@ -590,7 +590,7 @@ int swsusp_shrink_memory(void)
 			if (!tmp)
 				return -ENOMEM;
 			pages += tmp;
-		} else if (size > (image_size * 1024 * 1024) / PAGE_SIZE) {
+		} else if (size > image_size / PAGE_SIZE) {
 			tmp = shrink_all_memory(SHRINK_BITE);
 			pages += tmp;
 		}
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index 7732199..7712912 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -114,16 +114,16 @@ rcu_torture_alloc(void)
 {
 	struct list_head *p;
 
-	spin_lock(&rcu_torture_lock);
+	spin_lock_bh(&rcu_torture_lock);
 	if (list_empty(&rcu_torture_freelist)) {
 		atomic_inc(&n_rcu_torture_alloc_fail);
-		spin_unlock(&rcu_torture_lock);
+		spin_unlock_bh(&rcu_torture_lock);
 		return NULL;
 	}
 	atomic_inc(&n_rcu_torture_alloc);
 	p = rcu_torture_freelist.next;
 	list_del_init(p);
-	spin_unlock(&rcu_torture_lock);
+	spin_unlock_bh(&rcu_torture_lock);
 	return container_of(p, struct rcu_torture, rtort_free);
 }
 
@@ -134,9 +134,9 @@ static void
 rcu_torture_free(struct rcu_torture *p)
 {
 	atomic_inc(&n_rcu_torture_free);
-	spin_lock(&rcu_torture_lock);
+	spin_lock_bh(&rcu_torture_lock);
 	list_add_tail(&p->rtort_free, &rcu_torture_freelist);
-	spin_unlock(&rcu_torture_lock);
+	spin_unlock_bh(&rcu_torture_lock);
 }
 
 static void
diff --git a/kernel/sched.c b/kernel/sched.c
index 788ecce..f77f23f 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -3850,6 +3850,10 @@ do_sched_setscheduler(pid_t pid, int pol
 asmlinkage long sys_sched_setscheduler(pid_t pid, int policy,
 				       struct sched_param __user *param)
 {
+	/* negative values for policy are not valid */
+	if (policy < 0)
+		return -EINVAL;
+
 	return do_sched_setscheduler(pid, policy, param);
 }
 
@@ -4027,7 +4031,7 @@ long sched_getaffinity(pid_t pid, cpumas
 		goto out_unlock;
 
 	retval = 0;
-	cpus_and(*mask, p->cpus_allowed, cpu_possible_map);
+	cpus_and(*mask, p->cpus_allowed, cpu_online_map);
 
 out_unlock:
 	read_unlock(&tasklist_lock);
@@ -5137,7 +5141,7 @@ static void init_sched_build_groups(stru
 #define SEARCH_SCOPE		2
 #define MIN_CACHE_SIZE		(64*1024U)
 #define DEFAULT_CACHE_SIZE	(5*1024*1024U)
-#define ITERATIONS		2
+#define ITERATIONS		1
 #define SIZE_THRESH		130
 #define COST_THRESH		130
 
@@ -5476,9 +5480,9 @@ static unsigned long long measure_migrat
 				break;
 			}
 		/*
-		 * Increase the cachesize in 5% steps:
+		 * Increase the cachesize in 10% steps:
 		 */
-		size = size * 20 / 19;
+		size = size * 10 / 9;
 	}
 
 	if (migration_debug)
diff --git a/kernel/signal.c b/kernel/signal.c
index 5dafbd3..d3efafd 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2721,6 +2721,32 @@ sys_pause(void)
 
 #endif
 
+#ifdef __ARCH_WANT_SYS_RT_SIGSUSPEND
+asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
+{
+	sigset_t newset;
+
+	/* XXX: Don't preclude handling different sized sigset_t's.  */
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP));
+
+	spin_lock_irq(&current->sighand->siglock);
+	current->saved_sigmask = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	set_thread_flag(TIF_RESTORE_SIGMASK);
+	return -ERESTARTNOHAND;
+}
+#endif /* __ARCH_WANT_SYS_RT_SIGSUSPEND */
+
 void __init signals_init(void)
 {
 	sigqueue_cachep =
diff --git a/kernel/sys.c b/kernel/sys.c
index d09cac2..0929c69 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -440,23 +440,25 @@ void kernel_kexec(void)
 }
 EXPORT_SYMBOL_GPL(kernel_kexec);
 
+void kernel_shutdown_prepare(enum system_states state)
+{
+	notifier_call_chain(&reboot_notifier_list,
+		(state == SYSTEM_HALT)?SYS_HALT:SYS_POWER_OFF, NULL);
+	system_state = state;
+	device_shutdown();
+}
 /**
  *	kernel_halt - halt the system
  *
  *	Shutdown everything and perform a clean system halt.
  */
-void kernel_halt_prepare(void)
-{
-	notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
-	system_state = SYSTEM_HALT;
-	device_shutdown();
-}
 void kernel_halt(void)
 {
-	kernel_halt_prepare();
+	kernel_shutdown_prepare(SYSTEM_HALT);
 	printk(KERN_EMERG "System halted.\n");
 	machine_halt();
 }
+
 EXPORT_SYMBOL_GPL(kernel_halt);
 
 /**
@@ -464,20 +466,13 @@ EXPORT_SYMBOL_GPL(kernel_halt);
  *
  *	Shutdown everything and perform a clean system power_off.
  */
-void kernel_power_off_prepare(void)
-{
-	notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
-	system_state = SYSTEM_POWER_OFF;
-	device_shutdown();
-}
 void kernel_power_off(void)
 {
-	kernel_power_off_prepare();
+	kernel_shutdown_prepare(SYSTEM_POWER_OFF);
 	printk(KERN_EMERG "Power down.\n");
 	machine_power_off();
 }
 EXPORT_SYMBOL_GPL(kernel_power_off);
-
 /*
  * Reboot system call: for obvious reasons only root may call it,
  * and even root needs to set up some magic numbers in the registers
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index f5d69b6..71dd6f6 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -870,6 +870,27 @@ static ctl_table vm_table[] = {
 		.strategy	= &sysctl_jiffies,
 	},
 #endif
+#ifdef CONFIG_NUMA
+	{
+		.ctl_name	= VM_ZONE_RECLAIM_MODE,
+		.procname	= "zone_reclaim_mode",
+		.data		= &zone_reclaim_mode,
+		.maxlen		= sizeof(zone_reclaim_mode),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &zero,
+	},
+	{
+		.ctl_name	= VM_ZONE_RECLAIM_INTERVAL,
+		.procname	= "zone_reclaim_interval",
+		.data		= &zone_reclaim_interval,
+		.maxlen		= sizeof(zone_reclaim_interval),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_jiffies,
+		.strategy	= &sysctl_jiffies,
+	},
+#endif
 	{ .ctl_name = 0 }
 };
 
diff --git a/kernel/time.c b/kernel/time.c
index 7477b1d..1f23e68 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -155,7 +155,7 @@ int do_sys_settimeofday(struct timespec 
 	static int firsttime = 1;
 	int error = 0;
 
-	if (!timespec_valid(tv))
+	if (tv && !timespec_valid(tv))
 		return -EINVAL;
 
 	error = security_settime(tv, tz);
diff --git a/kernel/user.c b/kernel/user.c
index 89e562f..d9deae4 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/bitops.h>
 #include <linux/key.h>
+#include <linux/interrupt.h>
 
 /*
  * UID task count cache, to get fast user lookup in "alloc_uid"
@@ -27,6 +28,16 @@
 
 static kmem_cache_t *uid_cachep;
 static struct list_head uidhash_table[UIDHASH_SZ];
+
+/*
+ * The uidhash_lock is mostly taken from process context, but it is
+ * occasionally also taken from softirq/tasklet context, when
+ * task-structs get RCU-freed. Hence all locking must be softirq-safe.
+ * But free_uid() is also called with local interrupts disabled, and running
+ * local_bh_enable() with local interrupts disabled is an error - we'll run
+ * softirq callbacks, and they can unconditionally enable interrupts, and
+ * the caller of free_uid() didn't expect that..
+ */
 static DEFINE_SPINLOCK(uidhash_lock);
 
 struct user_struct root_user = {
@@ -82,15 +93,19 @@ static inline struct user_struct *uid_ha
 struct user_struct *find_user(uid_t uid)
 {
 	struct user_struct *ret;
+	unsigned long flags;
 
-	spin_lock(&uidhash_lock);
+	spin_lock_irqsave(&uidhash_lock, flags);
 	ret = uid_hash_find(uid, uidhashentry(uid));
-	spin_unlock(&uidhash_lock);
+	spin_unlock_irqrestore(&uidhash_lock, flags);
 	return ret;
 }
 
 void free_uid(struct user_struct *up)
 {
+	unsigned long flags;
+
+	local_irq_save(flags);
 	if (up && atomic_dec_and_lock(&up->__count, &uidhash_lock)) {
 		uid_hash_remove(up);
 		key_put(up->uid_keyring);
@@ -98,6 +113,7 @@ void free_uid(struct user_struct *up)
 		kmem_cache_free(uid_cachep, up);
 		spin_unlock(&uidhash_lock);
 	}
+	local_irq_restore(flags);
 }
 
 struct user_struct * alloc_uid(uid_t uid)
@@ -105,9 +121,9 @@ struct user_struct * alloc_uid(uid_t uid
 	struct list_head *hashent = uidhashentry(uid);
 	struct user_struct *up;
 
-	spin_lock(&uidhash_lock);
+	spin_lock_irq(&uidhash_lock);
 	up = uid_hash_find(uid, hashent);
-	spin_unlock(&uidhash_lock);
+	spin_unlock_irq(&uidhash_lock);
 
 	if (!up) {
 		struct user_struct *new;
@@ -137,7 +153,7 @@ struct user_struct * alloc_uid(uid_t uid
 		 * Before adding this, check whether we raced
 		 * on adding the same user already..
 		 */
-		spin_lock(&uidhash_lock);
+		spin_lock_irq(&uidhash_lock);
 		up = uid_hash_find(uid, hashent);
 		if (up) {
 			key_put(new->uid_keyring);
@@ -147,7 +163,7 @@ struct user_struct * alloc_uid(uid_t uid
 			uid_hash_insert(new, hashent);
 			up = new;
 		}
-		spin_unlock(&uidhash_lock);
+		spin_unlock_irq(&uidhash_lock);
 
 	}
 	return up;
@@ -183,9 +199,9 @@ static int __init uid_cache_init(void)
 		INIT_LIST_HEAD(uidhash_table + n);
 
 	/* Insert the root user immediately (init already runs as root) */
-	spin_lock(&uidhash_lock);
+	spin_lock_irq(&uidhash_lock);
 	uid_hash_insert(&root_user, uidhashentry(0));
-	spin_unlock(&uidhash_lock);
+	spin_unlock_irq(&uidhash_lock);
 
 	return 0;
 }
diff --git a/lib/Makefile b/lib/Makefile
index 8535f4d..648b2c1 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -9,7 +9,7 @@ lib-y := errno.o ctype.o string.o vsprin
 
 lib-y	+= kobject.o kref.o kobject_uevent.o klist.o
 
-obj-y += sort.o parser.o halfmd4.o
+obj-y += sort.o parser.o halfmd4.o iomap_copy.o
 
 ifeq ($(CONFIG_DEBUG_KOBJECT),y)
 CFLAGS_kobject.o += -DDEBUG
diff --git a/lib/iomap_copy.c b/lib/iomap_copy.c
new file mode 100644
index 0000000..a6b1e27
--- /dev/null
+++ b/lib/iomap_copy.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2006 PathScale, Inc.  All Rights Reserved.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+
+/**
+ * __iowrite32_copy - copy data to MMIO space, in 32-bit units
+ * @to: destination, in MMIO space (must be 32-bit aligned)
+ * @from: source (must be 32-bit aligned)
+ * @count: number of 32-bit quantities to copy
+ *
+ * Copy data from kernel space to MMIO space, in units of 32 bits at a
+ * time.  Order of access is not guaranteed, nor is a memory barrier
+ * performed afterwards.
+ */
+void __attribute__((weak)) __iowrite32_copy(void __iomem *to,
+					    const void *from,
+					    size_t count)
+{
+	u32 __iomem *dst = to;
+	const u32 *src = from;
+	const u32 *end = src + count;
+
+	while (src < end)
+		__raw_writel(*src++, dst++);
+}
+EXPORT_SYMBOL_GPL(__iowrite32_copy);
diff --git a/mm/filemap.c b/mm/filemap.c
index a965b6b..44da3d4 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -94,6 +94,7 @@ generic_file_direct_IO(int rw, struct ki
  *    ->private_lock		(try_to_unmap_one)
  *    ->tree_lock		(try_to_unmap_one)
  *    ->zone.lru_lock		(follow_page->mark_page_accessed)
+ *    ->zone.lru_lock		(check_pte_range->isolate_lru_page)
  *    ->private_lock		(page_remove_rmap->set_page_dirty)
  *    ->tree_lock		(page_remove_rmap->set_page_dirty)
  *    ->inode_lock		(page_remove_rmap->set_page_dirty)
diff --git a/mm/memory.c b/mm/memory.c
index 7a11ddd..2bee1f2 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1871,6 +1871,7 @@ static int do_swap_page(struct mm_struct
 		goto out;
 
 	entry = pte_to_swp_entry(orig_pte);
+again:
 	page = lookup_swap_cache(entry);
 	if (!page) {
  		swapin_readahead(entry, address, vma);
@@ -1894,6 +1895,12 @@ static int do_swap_page(struct mm_struct
 
 	mark_page_accessed(page);
 	lock_page(page);
+	if (!PageSwapCache(page)) {
+		/* Page migration has occured */
+		unlock_page(page);
+		page_cache_release(page);
+		goto again;
+	}
 
 	/*
 	 * Back out if somebody else already faulted in this pte.
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 3171f88..27da6d5 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -95,6 +95,9 @@
 #define MPOL_MF_INVERT (MPOL_MF_INTERNAL << 1)		/* Invert check for nodemask */
 #define MPOL_MF_STATS (MPOL_MF_INTERNAL << 2)		/* Gather statistics */
 
+/* The number of pages to migrate per call to migrate_pages() */
+#define MIGRATE_CHUNK_SIZE 256
+
 static kmem_cache_t *policy_cache;
 static kmem_cache_t *sn_cache;
 
@@ -185,8 +188,8 @@ static struct mempolicy *mpol_new(int mo
 }
 
 static void gather_stats(struct page *, void *);
-static void migrate_page_add(struct vm_area_struct *vma,
-	struct page *page, struct list_head *pagelist, unsigned long flags);
+static void migrate_page_add(struct page *page, struct list_head *pagelist,
+				unsigned long flags);
 
 /* Scan through pages checking if pages follow certain conditions. */
 static int check_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
@@ -208,6 +211,17 @@ static int check_pte_range(struct vm_are
 		page = vm_normal_page(vma, addr, *pte);
 		if (!page)
 			continue;
+		/*
+		 * The check for PageReserved here is important to avoid
+		 * handling zero pages and other pages that may have been
+		 * marked special by the system.
+		 *
+		 * If the PageReserved would not be checked here then f.e.
+		 * the location of the zero page could have an influence
+		 * on MPOL_MF_STRICT, zero pages would be counted for
+		 * the per node stats, and there would be useless attempts
+		 * to put zero pages on the migration list.
+		 */
 		if (PageReserved(page))
 			continue;
 		nid = page_to_nid(page);
@@ -216,11 +230,8 @@ static int check_pte_range(struct vm_are
 
 		if (flags & MPOL_MF_STATS)
 			gather_stats(page, private);
-		else if (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) {
-			spin_unlock(ptl);
-			migrate_page_add(vma, page, private, flags);
-			spin_lock(ptl);
-		}
+		else if (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL))
+			migrate_page_add(page, private, flags);
 		else
 			break;
 	} while (pte++, addr += PAGE_SIZE, addr != end);
@@ -309,6 +320,10 @@ check_range(struct mm_struct *mm, unsign
 	int err;
 	struct vm_area_struct *first, *vma, *prev;
 
+	/* Clear the LRU lists so pages can be isolated */
+	if (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL))
+		lru_add_drain_all();
+
 	first = find_vma(mm, start);
 	if (!first)
 		return ERR_PTR(-EFAULT);
@@ -519,72 +534,103 @@ long do_get_mempolicy(int *policy, nodem
  * page migration
  */
 
-/* Check if we are the only process mapping the page in question */
-static inline int single_mm_mapping(struct mm_struct *mm,
-			struct address_space *mapping)
+static void migrate_page_add(struct page *page, struct list_head *pagelist,
+				unsigned long flags)
 {
-	struct vm_area_struct *vma;
-	struct prio_tree_iter iter;
-	int rc = 1;
-
-	spin_lock(&mapping->i_mmap_lock);
-	vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, 0, ULONG_MAX)
-		if (mm != vma->vm_mm) {
-			rc = 0;
-			goto out;
-		}
-	list_for_each_entry(vma, &mapping->i_mmap_nonlinear, shared.vm_set.list)
-		if (mm != vma->vm_mm) {
-			rc = 0;
-			goto out;
-		}
-out:
-	spin_unlock(&mapping->i_mmap_lock);
-	return rc;
+	/*
+	 * Avoid migrating a page that is shared with others.
+	 */
+	if ((flags & MPOL_MF_MOVE_ALL) || page_mapcount(page) == 1) {
+		if (isolate_lru_page(page))
+			list_add(&page->lru, pagelist);
+	}
 }
 
 /*
- * Add a page to be migrated to the pagelist
+ * Migrate the list 'pagelist' of pages to a certain destination.
+ *
+ * Specify destination with either non-NULL vma or dest_node >= 0
+ * Return the number of pages not migrated or error code
  */
-static void migrate_page_add(struct vm_area_struct *vma,
-	struct page *page, struct list_head *pagelist, unsigned long flags)
+static int migrate_pages_to(struct list_head *pagelist,
+			struct vm_area_struct *vma, int dest)
 {
-	/*
-	 * Avoid migrating a page that is shared by others and not writable.
-	 */
-	if ((flags & MPOL_MF_MOVE_ALL) || !page->mapping || PageAnon(page) ||
-	    mapping_writably_mapped(page->mapping) ||
-	    single_mm_mapping(vma->vm_mm, page->mapping)) {
-		int rc = isolate_lru_page(page);
+	LIST_HEAD(newlist);
+	LIST_HEAD(moved);
+	LIST_HEAD(failed);
+	int err = 0;
+	int nr_pages;
+	struct page *page;
+	struct list_head *p;
 
-		if (rc == 1)
-			list_add(&page->lru, pagelist);
-		/*
-		 * If the isolate attempt was not successful then we just
-		 * encountered an unswappable page. Something must be wrong.
-	 	 */
-		WARN_ON(rc == 0);
+redo:
+	nr_pages = 0;
+	list_for_each(p, pagelist) {
+		if (vma)
+			page = alloc_page_vma(GFP_HIGHUSER, vma, vma->vm_start);
+		else
+			page = alloc_pages_node(dest, GFP_HIGHUSER, 0);
+
+		if (!page) {
+			err = -ENOMEM;
+			goto out;
+		}
+		list_add(&page->lru, &newlist);
+		nr_pages++;
+		if (nr_pages > MIGRATE_CHUNK_SIZE);
+			break;
+	}
+	err = migrate_pages(pagelist, &newlist, &moved, &failed);
+
+	putback_lru_pages(&moved);	/* Call release pages instead ?? */
+
+	if (err >= 0 && list_empty(&newlist) && !list_empty(pagelist))
+		goto redo;
+out:
+	/* Return leftover allocated pages */
+	while (!list_empty(&newlist)) {
+		page = list_entry(newlist.next, struct page, lru);
+		list_del(&page->lru);
+		__free_page(page);
 	}
+	list_splice(&failed, pagelist);
+	if (err < 0)
+		return err;
+
+	/* Calculate number of leftover pages */
+	nr_pages = 0;
+	list_for_each(p, pagelist)
+		nr_pages++;
+	return nr_pages;
 }
 
-static int swap_pages(struct list_head *pagelist)
+/*
+ * Migrate pages from one node to a target node.
+ * Returns error or the number of pages not migrated.
+ */
+int migrate_to_node(struct mm_struct *mm, int source, int dest, int flags)
 {
-	LIST_HEAD(moved);
-	LIST_HEAD(failed);
-	int n;
+	nodemask_t nmask;
+	LIST_HEAD(pagelist);
+	int err = 0;
 
-	n = migrate_pages(pagelist, NULL, &moved, &failed);
-	putback_lru_pages(&failed);
-	putback_lru_pages(&moved);
+	nodes_clear(nmask);
+	node_set(source, nmask);
 
-	return n;
+	check_range(mm, mm->mmap->vm_start, TASK_SIZE, &nmask,
+			flags | MPOL_MF_DISCONTIG_OK, &pagelist);
+
+	if (!list_empty(&pagelist)) {
+		err = migrate_pages_to(&pagelist, NULL, dest);
+		if (!list_empty(&pagelist))
+			putback_lru_pages(&pagelist);
+	}
+	return err;
 }
 
 /*
- * For now migrate_pages simply swaps out the pages from nodes that are in
- * the source set but not in the target set. In the future, we would
- * want a function that moves pages between the two nodesets in such
- * a way as to preserve the physical layout as much as possible.
+ * Move pages between the two nodesets so as to preserve the physical
+ * layout as much as possible.
  *
  * Returns the number of page that could not be moved.
  */
@@ -592,22 +638,76 @@ int do_migrate_pages(struct mm_struct *m
 	const nodemask_t *from_nodes, const nodemask_t *to_nodes, int flags)
 {
 	LIST_HEAD(pagelist);
-	int count = 0;
-	nodemask_t nodes;
+	int busy = 0;
+	int err = 0;
+	nodemask_t tmp;
 
-	nodes_andnot(nodes, *from_nodes, *to_nodes);
+  	down_read(&mm->mmap_sem);
 
-	down_read(&mm->mmap_sem);
-	check_range(mm, mm->mmap->vm_start, TASK_SIZE, &nodes,
-			flags | MPOL_MF_DISCONTIG_OK, &pagelist);
+/*
+ * Find a 'source' bit set in 'tmp' whose corresponding 'dest'
+ * bit in 'to' is not also set in 'tmp'.  Clear the found 'source'
+ * bit in 'tmp', and return that <source, dest> pair for migration.
+ * The pair of nodemasks 'to' and 'from' define the map.
+ *
+ * If no pair of bits is found that way, fallback to picking some
+ * pair of 'source' and 'dest' bits that are not the same.  If the
+ * 'source' and 'dest' bits are the same, this represents a node
+ * that will be migrating to itself, so no pages need move.
+ *
+ * If no bits are left in 'tmp', or if all remaining bits left
+ * in 'tmp' correspond to the same bit in 'to', return false
+ * (nothing left to migrate).
+ *
+ * This lets us pick a pair of nodes to migrate between, such that
+ * if possible the dest node is not already occupied by some other
+ * source node, minimizing the risk of overloading the memory on a
+ * node that would happen if we migrated incoming memory to a node
+ * before migrating outgoing memory source that same node.
+ *
+ * A single scan of tmp is sufficient.  As we go, we remember the
+ * most recent <s, d> pair that moved (s != d).  If we find a pair
+ * that not only moved, but what's better, moved to an empty slot
+ * (d is not set in tmp), then we break out then, with that pair.
+ * Otherwise when we finish scannng from_tmp, we at least have the
+ * most recent <s, d> pair that moved.  If we get all the way through
+ * the scan of tmp without finding any node that moved, much less
+ * moved to an empty node, then there is nothing left worth migrating.
+ */
 
-	if (!list_empty(&pagelist)) {
-		count = swap_pages(&pagelist);
-		putback_lru_pages(&pagelist);
+	tmp = *from_nodes;
+	while (!nodes_empty(tmp)) {
+		int s,d;
+		int source = -1;
+		int dest = 0;
+
+		for_each_node_mask(s, tmp) {
+			d = node_remap(s, *from_nodes, *to_nodes);
+			if (s == d)
+				continue;
+
+			source = s;	/* Node moved. Memorize */
+			dest = d;
+
+			/* dest not in remaining from nodes? */
+			if (!node_isset(dest, tmp))
+				break;
+		}
+		if (source == -1)
+			break;
+
+		node_clear(source, tmp);
+		err = migrate_to_node(mm, source, dest, flags);
+		if (err > 0)
+			busy += err;
+		if (err < 0)
+			break;
 	}
 
 	up_read(&mm->mmap_sem);
-	return count;
+	if (err < 0)
+		return err;
+	return busy;
 }
 
 long do_mbind(unsigned long start, unsigned long len,
@@ -667,8 +767,9 @@ long do_mbind(unsigned long start, unsig
 		int nr_failed = 0;
 
 		err = mbind_range(vma, start, end, new);
+
 		if (!list_empty(&pagelist))
-			nr_failed = swap_pages(&pagelist);
+			nr_failed = migrate_pages_to(&pagelist, vma, -1);
 
 		if (!err && nr_failed && (flags & MPOL_MF_STRICT))
 			err = -EIO;
@@ -1000,6 +1101,33 @@ static unsigned interleave_nodes(struct 
 	return nid;
 }
 
+/*
+ * Depending on the memory policy provide a node from which to allocate the
+ * next slab entry.
+ */
+unsigned slab_node(struct mempolicy *policy)
+{
+	switch (policy->policy) {
+	case MPOL_INTERLEAVE:
+		return interleave_nodes(policy);
+
+	case MPOL_BIND:
+		/*
+		 * Follow bind policy behavior and start allocation at the
+		 * first node.
+		 */
+		return policy->v.zonelist->zones[0]->zone_pgdat->node_id;
+
+	case MPOL_PREFERRED:
+		if (policy->v.preferred_node >= 0)
+			return policy->v.preferred_node;
+		/* Fall through */
+
+	default:
+		return numa_node_id();
+	}
+}
+
 /* Do static interleaving for a VMA with known offset. */
 static unsigned offset_il_node(struct mempolicy *pol,
 		struct vm_area_struct *vma, unsigned long off)
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 14bd4ec..b05ab8f 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -271,6 +271,7 @@ void out_of_memory(gfp_t gfp_mask, int o
 	if (printk_ratelimit()) {
 		printk("oom-killer: gfp_mask=0x%x, order=%d\n",
 			gfp_mask, order);
+		dump_stack();
 		show_mem();
 	}
 
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 5240e42..945559f 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -46,7 +46,7 @@
 static long ratelimit_pages = 32;
 
 static long total_pages;	/* The total number of pages in the machine. */
-static int dirty_exceeded;	/* Dirty mem may be over limit */
+static int dirty_exceeded __cacheline_aligned_in_smp;	/* Dirty mem may be over limit */
 
 /*
  * When balance_dirty_pages decides that the caller needs to perform some
@@ -212,7 +212,8 @@ static void balance_dirty_pages(struct a
 		if (nr_reclaimable + wbs.nr_writeback <= dirty_thresh)
 			break;
 
-		dirty_exceeded = 1;
+		if (!dirty_exceeded)
+			dirty_exceeded = 1;
 
 		/* Note: nr_reclaimable denotes nr_dirty + nr_unstable.
 		 * Unstable writes are a feature of certain networked
@@ -234,7 +235,7 @@ static void balance_dirty_pages(struct a
 		blk_congestion_wait(WRITE, HZ/10);
 	}
 
-	if (nr_reclaimable + wbs.nr_writeback <= dirty_thresh)
+	if (nr_reclaimable + wbs.nr_writeback <= dirty_thresh && dirty_exceeded)
 		dirty_exceeded = 0;
 
 	if (writeback_in_progress(bdi))
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index c2e2974..44b4eb4 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -878,7 +878,9 @@ get_page_from_freelist(gfp_t gfp_mask, u
 				mark = (*z)->pages_high;
 			if (!zone_watermark_ok(*z, order, mark,
 				    classzone_idx, alloc_flags))
-				continue;
+				if (!zone_reclaim_mode ||
+				    !zone_reclaim(*z, gfp_mask, order))
+					continue;
 		}
 
 		page = buffered_rmqueue(zonelist, *z, order, gfp_mask);
@@ -1595,13 +1597,22 @@ static void __init build_zonelists(pg_da
 	prev_node = local_node;
 	nodes_clear(used_mask);
 	while ((node = find_next_best_node(local_node, &used_mask)) >= 0) {
+		int distance = node_distance(local_node, node);
+
+		/*
+		 * If another node is sufficiently far away then it is better
+		 * to reclaim pages in a zone before going off node.
+		 */
+		if (distance > RECLAIM_DISTANCE)
+			zone_reclaim_mode = 1;
+
 		/*
 		 * We don't want to pressure a particular node.
 		 * So adding penalty to the first node in same
 		 * distance group to make it round-robin.
 		 */
-		if (node_distance(local_node, node) !=
-				node_distance(local_node, prev_node))
+
+		if (distance != node_distance(local_node, prev_node))
 			node_load[node] += load;
 		prev_node = node;
 		load--;
@@ -1788,7 +1799,7 @@ void zonetable_add(struct zone *zone, in
 	memmap_init_zone((size), (nid), (zone), (start_pfn))
 #endif
 
-static int __meminit zone_batchsize(struct zone *zone)
+static int __cpuinit zone_batchsize(struct zone *zone)
 {
 	int batch;
 
@@ -1882,7 +1893,7 @@ static struct per_cpu_pageset
  * Dynamically allocate memory for the
  * per cpu pageset array in struct zone.
  */
-static int __meminit process_zones(int cpu)
+static int __cpuinit process_zones(int cpu)
 {
 	struct zone *zone, *dzone;
 
@@ -1923,7 +1934,7 @@ static inline void free_zone_pagesets(in
 	}
 }
 
-static int __meminit pageset_cpuup_callback(struct notifier_block *nfb,
+static int __cpuinit pageset_cpuup_callback(struct notifier_block *nfb,
 		unsigned long action,
 		void *hcpu)
 {
diff --git a/mm/rmap.c b/mm/rmap.c
index dfbb89f..df2c41c 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -33,7 +33,7 @@
  *     mapping->i_mmap_lock
  *       anon_vma->lock
  *         mm->page_table_lock or pte_lock
- *           zone->lru_lock (in mark_page_accessed)
+ *           zone->lru_lock (in mark_page_accessed, isolate_lru_page)
  *           swap_lock (in swap_duplicate, swap_info_get)
  *             mmlist_lock (in mmput, drain_mmlist and others)
  *             mapping->private_lock (in __set_page_dirty_buffers)
@@ -52,6 +52,7 @@
 #include <linux/init.h>
 #include <linux/rmap.h>
 #include <linux/rcupdate.h>
+#include <linux/module.h>
 
 #include <asm/tlbflush.h>
 
@@ -205,6 +206,36 @@ out:
 	return anon_vma;
 }
 
+#ifdef CONFIG_MIGRATION
+/*
+ * Remove an anonymous page from swap replacing the swap pte's
+ * through real pte's pointing to valid pages and then releasing
+ * the page from the swap cache.
+ *
+ * Must hold page lock on page.
+ */
+void remove_from_swap(struct page *page)
+{
+	struct anon_vma *anon_vma;
+	struct vm_area_struct *vma;
+
+	if (!PageAnon(page) || !PageSwapCache(page))
+		return;
+
+	anon_vma = page_lock_anon_vma(page);
+	if (!anon_vma)
+		return;
+
+	list_for_each_entry(vma, &anon_vma->head, anon_vma_node)
+		remove_vma_swap(vma, page);
+
+	spin_unlock(&anon_vma->lock);
+
+	delete_from_swap_cache(page);
+}
+EXPORT_SYMBOL(remove_from_swap);
+#endif
+
 /*
  * At what user virtual address is page expected in vma?
  */
@@ -541,7 +572,8 @@ void page_remove_rmap(struct page *page)
  * Subfunctions of try_to_unmap: try_to_unmap_one called
  * repeatedly from either try_to_unmap_anon or try_to_unmap_file.
  */
-static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma)
+static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
+				int ignore_refs)
 {
 	struct mm_struct *mm = vma->vm_mm;
 	unsigned long address;
@@ -564,7 +596,8 @@ static int try_to_unmap_one(struct page 
 	 * skipped over this mm) then we should reactivate it.
 	 */
 	if ((vma->vm_flags & VM_LOCKED) ||
-			ptep_clear_flush_young(vma, address, pte)) {
+			(ptep_clear_flush_young(vma, address, pte)
+				&& !ignore_refs)) {
 		ret = SWAP_FAIL;
 		goto out_unmap;
 	}
@@ -698,7 +731,7 @@ static void try_to_unmap_cluster(unsigne
 	pte_unmap_unlock(pte - 1, ptl);
 }
 
-static int try_to_unmap_anon(struct page *page)
+static int try_to_unmap_anon(struct page *page, int ignore_refs)
 {
 	struct anon_vma *anon_vma;
 	struct vm_area_struct *vma;
@@ -709,7 +742,7 @@ static int try_to_unmap_anon(struct page
 		return ret;
 
 	list_for_each_entry(vma, &anon_vma->head, anon_vma_node) {
-		ret = try_to_unmap_one(page, vma);
+		ret = try_to_unmap_one(page, vma, ignore_refs);
 		if (ret == SWAP_FAIL || !page_mapped(page))
 			break;
 	}
@@ -726,7 +759,7 @@ static int try_to_unmap_anon(struct page
  *
  * This function is only called from try_to_unmap for object-based pages.
  */
-static int try_to_unmap_file(struct page *page)
+static int try_to_unmap_file(struct page *page, int ignore_refs)
 {
 	struct address_space *mapping = page->mapping;
 	pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
@@ -740,7 +773,7 @@ static int try_to_unmap_file(struct page
 
 	spin_lock(&mapping->i_mmap_lock);
 	vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
-		ret = try_to_unmap_one(page, vma);
+		ret = try_to_unmap_one(page, vma, ignore_refs);
 		if (ret == SWAP_FAIL || !page_mapped(page))
 			goto out;
 	}
@@ -825,16 +858,16 @@ out:
  * SWAP_AGAIN	- we missed a mapping, try again later
  * SWAP_FAIL	- the page is unswappable
  */
-int try_to_unmap(struct page *page)
+int try_to_unmap(struct page *page, int ignore_refs)
 {
 	int ret;
 
 	BUG_ON(!PageLocked(page));
 
 	if (PageAnon(page))
-		ret = try_to_unmap_anon(page);
+		ret = try_to_unmap_anon(page, ignore_refs);
 	else
-		ret = try_to_unmap_file(page);
+		ret = try_to_unmap_file(page, ignore_refs);
 
 	if (!page_mapped(page))
 		ret = SWAP_SUCCESS;
diff --git a/mm/shmem.c b/mm/shmem.c
index ce501bc..f7ac7b8 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1028,6 +1028,14 @@ repeat:
 			page_cache_release(swappage);
 			goto repeat;
 		}
+		if (!PageSwapCache(swappage)) {
+			/* Page migration has occured */
+			shmem_swp_unmap(entry);
+			spin_unlock(&info->lock);
+			unlock_page(swappage);
+			page_cache_release(swappage);
+			goto repeat;
+		}
 		if (PageWriteback(swappage)) {
 			shmem_swp_unmap(entry);
 			spin_unlock(&info->lock);
diff --git a/mm/slab.c b/mm/slab.c
index 9374293..7137025 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -55,7 +55,7 @@
  *
  * SMP synchronization:
  *  constructors and destructors are called without any locking.
- *  Several members in kmem_cache_t and struct slab never change, they
+ *  Several members in struct kmem_cache and struct slab never change, they
  *	are accessed without any locking.
  *  The per-cpu arrays are never accessed from the wrong cpu, no locking,
  *  	and local interrupts are disabled so slab code is preempt-safe.
@@ -68,7 +68,7 @@
  * Further notes from the original documentation:
  *
  * 11 April '97.  Started multi-threading - markhe
- *	The global cache-chain is protected by the semaphore 'cache_chain_sem'.
+ *	The global cache-chain is protected by the mutex 'cache_chain_mutex'.
  *	The sem is only needed when accessing/extending the cache-chain, which
  *	can never happen inside an interrupt (kmem_cache_create(),
  *	kmem_cache_shrink() and kmem_cache_reap()).
@@ -103,6 +103,8 @@
 #include	<linux/rcupdate.h>
 #include	<linux/string.h>
 #include	<linux/nodemask.h>
+#include	<linux/mempolicy.h>
+#include	<linux/mutex.h>
 
 #include	<asm/uaccess.h>
 #include	<asm/cacheflush.h>
@@ -242,7 +244,7 @@ struct slab {
  */
 struct slab_rcu {
 	struct rcu_head head;
-	kmem_cache_t *cachep;
+	struct kmem_cache *cachep;
 	void *addr;
 };
 
@@ -314,6 +316,8 @@ struct kmem_list3 __initdata initkmem_li
  */
 static __always_inline int index_of(const size_t size)
 {
+	extern void __bad_size(void);
+
 	if (__builtin_constant_p(size)) {
 		int i = 0;
 
@@ -324,19 +328,16 @@ static __always_inline int index_of(cons
 		i++;
 #include "linux/kmalloc_sizes.h"
 #undef CACHE
-		{
-			extern void __bad_size(void);
-			__bad_size();
-		}
+		__bad_size();
 	} else
-		BUG();
+		__bad_size();
 	return 0;
 }
 
 #define INDEX_AC index_of(sizeof(struct arraycache_init))
 #define INDEX_L3 index_of(sizeof(struct kmem_list3))
 
-static inline void kmem_list3_init(struct kmem_list3 *parent)
+static void kmem_list3_init(struct kmem_list3 *parent)
 {
 	INIT_LIST_HEAD(&parent->slabs_full);
 	INIT_LIST_HEAD(&parent->slabs_partial);
@@ -362,7 +363,7 @@ static inline void kmem_list3_init(struc
 	} while (0)
 
 /*
- * kmem_cache_t
+ * struct kmem_cache
  *
  * manages a cache.
  */
@@ -373,7 +374,7 @@ struct kmem_cache {
 	unsigned int batchcount;
 	unsigned int limit;
 	unsigned int shared;
-	unsigned int objsize;
+	unsigned int buffer_size;
 /* 2) touched by every alloc & free from the backend */
 	struct kmem_list3 *nodelists[MAX_NUMNODES];
 	unsigned int flags;	/* constant flags */
@@ -390,15 +391,15 @@ struct kmem_cache {
 	size_t colour;		/* cache colouring range */
 	unsigned int colour_off;	/* colour offset */
 	unsigned int colour_next;	/* cache colouring */
-	kmem_cache_t *slabp_cache;
+	struct kmem_cache *slabp_cache;
 	unsigned int slab_size;
 	unsigned int dflags;	/* dynamic flags */
 
 	/* constructor func */
-	void (*ctor) (void *, kmem_cache_t *, unsigned long);
+	void (*ctor) (void *, struct kmem_cache *, unsigned long);
 
 	/* de-constructor func */
-	void (*dtor) (void *, kmem_cache_t *, unsigned long);
+	void (*dtor) (void *, struct kmem_cache *, unsigned long);
 
 /* 4) cache creation/removal */
 	const char *name;
@@ -421,8 +422,14 @@ struct kmem_cache {
 	atomic_t freemiss;
 #endif
 #if DEBUG
-	int dbghead;
-	int reallen;
+	/*
+	 * If debugging is enabled, then the allocator can add additional
+	 * fields and/or padding to every object. buffer_size contains the total
+	 * object size including these internal fields, the following two
+	 * variables contain the offset to the user object and its size.
+	 */
+	int obj_offset;
+	int obj_size;
 #endif
 };
 
@@ -493,50 +500,50 @@ struct kmem_cache {
 
 /* memory layout of objects:
  * 0		: objp
- * 0 .. cachep->dbghead - BYTES_PER_WORD - 1: padding. This ensures that
+ * 0 .. cachep->obj_offset - BYTES_PER_WORD - 1: padding. This ensures that
  * 		the end of an object is aligned with the end of the real
  * 		allocation. Catches writes behind the end of the allocation.
- * cachep->dbghead - BYTES_PER_WORD .. cachep->dbghead - 1:
+ * cachep->obj_offset - BYTES_PER_WORD .. cachep->obj_offset - 1:
  * 		redzone word.
- * cachep->dbghead: The real object.
- * cachep->objsize - 2* BYTES_PER_WORD: redzone word [BYTES_PER_WORD long]
- * cachep->objsize - 1* BYTES_PER_WORD: last caller address [BYTES_PER_WORD long]
+ * cachep->obj_offset: The real object.
+ * cachep->buffer_size - 2* BYTES_PER_WORD: redzone word [BYTES_PER_WORD long]
+ * cachep->buffer_size - 1* BYTES_PER_WORD: last caller address [BYTES_PER_WORD long]
  */
-static int obj_dbghead(kmem_cache_t *cachep)
+static int obj_offset(struct kmem_cache *cachep)
 {
-	return cachep->dbghead;
+	return cachep->obj_offset;
 }
 
-static int obj_reallen(kmem_cache_t *cachep)
+static int obj_size(struct kmem_cache *cachep)
 {
-	return cachep->reallen;
+	return cachep->obj_size;
 }
 
-static unsigned long *dbg_redzone1(kmem_cache_t *cachep, void *objp)
+static unsigned long *dbg_redzone1(struct kmem_cache *cachep, void *objp)
 {
 	BUG_ON(!(cachep->flags & SLAB_RED_ZONE));
-	return (unsigned long*) (objp+obj_dbghead(cachep)-BYTES_PER_WORD);
+	return (unsigned long*) (objp+obj_offset(cachep)-BYTES_PER_WORD);
 }
 
-static unsigned long *dbg_redzone2(kmem_cache_t *cachep, void *objp)
+static unsigned long *dbg_redzone2(struct kmem_cache *cachep, void *objp)
 {
 	BUG_ON(!(cachep->flags & SLAB_RED_ZONE));
 	if (cachep->flags & SLAB_STORE_USER)
-		return (unsigned long *)(objp + cachep->objsize -
+		return (unsigned long *)(objp + cachep->buffer_size -
 					 2 * BYTES_PER_WORD);
-	return (unsigned long *)(objp + cachep->objsize - BYTES_PER_WORD);
+	return (unsigned long *)(objp + cachep->buffer_size - BYTES_PER_WORD);
 }
 
-static void **dbg_userword(kmem_cache_t *cachep, void *objp)
+static void **dbg_userword(struct kmem_cache *cachep, void *objp)
 {
 	BUG_ON(!(cachep->flags & SLAB_STORE_USER));
-	return (void **)(objp + cachep->objsize - BYTES_PER_WORD);
+	return (void **)(objp + cachep->buffer_size - BYTES_PER_WORD);
 }
 
 #else
 
-#define obj_dbghead(x)			0
-#define obj_reallen(cachep)		(cachep->objsize)
+#define obj_offset(x)			0
+#define obj_size(cachep)		(cachep->buffer_size)
 #define dbg_redzone1(cachep, objp)	({BUG(); (unsigned long *)NULL;})
 #define dbg_redzone2(cachep, objp)	({BUG(); (unsigned long *)NULL;})
 #define dbg_userword(cachep, objp)	({BUG(); (void **)NULL;})
@@ -589,6 +596,18 @@ static inline struct slab *page_get_slab
 	return (struct slab *)page->lru.prev;
 }
 
+static inline struct kmem_cache *virt_to_cache(const void *obj)
+{
+	struct page *page = virt_to_page(obj);
+	return page_get_cache(page);
+}
+
+static inline struct slab *virt_to_slab(const void *obj)
+{
+	struct page *page = virt_to_page(obj);
+	return page_get_slab(page);
+}
+
 /* These are the default caches for kmalloc. Custom caches can have other sizes. */
 struct cache_sizes malloc_sizes[] = {
 #define CACHE(x) { .cs_size = (x) },
@@ -617,21 +636,21 @@ static struct arraycache_init initarray_
     { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
 
 /* internal cache of cache description objs */
-static kmem_cache_t cache_cache = {
+static struct kmem_cache cache_cache = {
 	.batchcount = 1,
 	.limit = BOOT_CPUCACHE_ENTRIES,
 	.shared = 1,
-	.objsize = sizeof(kmem_cache_t),
+	.buffer_size = sizeof(struct kmem_cache),
 	.flags = SLAB_NO_REAP,
 	.spinlock = SPIN_LOCK_UNLOCKED,
 	.name = "kmem_cache",
 #if DEBUG
-	.reallen = sizeof(kmem_cache_t),
+	.obj_size = sizeof(struct kmem_cache),
 #endif
 };
 
 /* Guard access to the cache-chain. */
-static struct semaphore cache_chain_sem;
+static DEFINE_MUTEX(cache_chain_mutex);
 static struct list_head cache_chain;
 
 /*
@@ -655,17 +674,17 @@ static enum {
 
 static DEFINE_PER_CPU(struct work_struct, reap_work);
 
-static void free_block(kmem_cache_t *cachep, void **objpp, int len, int node);
-static void enable_cpucache(kmem_cache_t *cachep);
+static void free_block(struct kmem_cache *cachep, void **objpp, int len, int node);
+static void enable_cpucache(struct kmem_cache *cachep);
 static void cache_reap(void *unused);
-static int __node_shrink(kmem_cache_t *cachep, int node);
+static int __node_shrink(struct kmem_cache *cachep, int node);
 
-static inline struct array_cache *ac_data(kmem_cache_t *cachep)
+static inline struct array_cache *cpu_cache_get(struct kmem_cache *cachep)
 {
 	return cachep->array[smp_processor_id()];
 }
 
-static inline kmem_cache_t *__find_general_cachep(size_t size, gfp_t gfpflags)
+static inline struct kmem_cache *__find_general_cachep(size_t size, gfp_t gfpflags)
 {
 	struct cache_sizes *csizep = malloc_sizes;
 
@@ -689,43 +708,80 @@ static inline kmem_cache_t *__find_gener
 	return csizep->cs_cachep;
 }
 
-kmem_cache_t *kmem_find_general_cachep(size_t size, gfp_t gfpflags)
+struct kmem_cache *kmem_find_general_cachep(size_t size, gfp_t gfpflags)
 {
 	return __find_general_cachep(size, gfpflags);
 }
 EXPORT_SYMBOL(kmem_find_general_cachep);
 
-/* Cal the num objs, wastage, and bytes left over for a given slab size. */
-static void cache_estimate(unsigned long gfporder, size_t size, size_t align,
-			   int flags, size_t *left_over, unsigned int *num)
+static size_t slab_mgmt_size(size_t nr_objs, size_t align)
 {
-	int i;
-	size_t wastage = PAGE_SIZE << gfporder;
-	size_t extra = 0;
-	size_t base = 0;
-
-	if (!(flags & CFLGS_OFF_SLAB)) {
-		base = sizeof(struct slab);
-		extra = sizeof(kmem_bufctl_t);
-	}
-	i = 0;
-	while (i * size + ALIGN(base + i * extra, align) <= wastage)
-		i++;
-	if (i > 0)
-		i--;
+	return ALIGN(sizeof(struct slab)+nr_objs*sizeof(kmem_bufctl_t), align);
+}
+
+/* Calculate the number of objects and left-over bytes for a given
+   buffer size. */
+static void cache_estimate(unsigned long gfporder, size_t buffer_size,
+			   size_t align, int flags, size_t *left_over,
+			   unsigned int *num)
+{
+	int nr_objs;
+	size_t mgmt_size;
+	size_t slab_size = PAGE_SIZE << gfporder;
+
+	/*
+	 * The slab management structure can be either off the slab or
+	 * on it. For the latter case, the memory allocated for a
+	 * slab is used for:
+	 *
+	 * - The struct slab
+	 * - One kmem_bufctl_t for each object
+	 * - Padding to respect alignment of @align
+	 * - @buffer_size bytes for each object
+	 *
+	 * If the slab management structure is off the slab, then the
+	 * alignment will already be calculated into the size. Because
+	 * the slabs are all pages aligned, the objects will be at the
+	 * correct alignment when allocated.
+	 */
+	if (flags & CFLGS_OFF_SLAB) {
+		mgmt_size = 0;
+		nr_objs = slab_size / buffer_size;
+
+		if (nr_objs > SLAB_LIMIT)
+			nr_objs = SLAB_LIMIT;
+	} else {
+		/*
+		 * Ignore padding for the initial guess. The padding
+		 * is at most @align-1 bytes, and @buffer_size is at
+		 * least @align. In the worst case, this result will
+		 * be one greater than the number of objects that fit
+		 * into the memory allocation when taking the padding
+		 * into account.
+		 */
+		nr_objs = (slab_size - sizeof(struct slab)) /
+			  (buffer_size + sizeof(kmem_bufctl_t));
+
+		/*
+		 * This calculated number will be either the right
+		 * amount, or one greater than what we want.
+		 */
+		if (slab_mgmt_size(nr_objs, align) + nr_objs*buffer_size
+		       > slab_size)
+			nr_objs--;
 
-	if (i > SLAB_LIMIT)
-		i = SLAB_LIMIT;
+		if (nr_objs > SLAB_LIMIT)
+			nr_objs = SLAB_LIMIT;
 
-	*num = i;
-	wastage -= i * size;
-	wastage -= ALIGN(base + i * extra, align);
-	*left_over = wastage;
+		mgmt_size = slab_mgmt_size(nr_objs, align);
+	}
+	*num = nr_objs;
+	*left_over = slab_size - nr_objs*buffer_size - mgmt_size;
 }
 
 #define slab_error(cachep, msg) __slab_error(__FUNCTION__, cachep, msg)
 
-static void __slab_error(const char *function, kmem_cache_t *cachep, char *msg)
+static void __slab_error(const char *function, struct kmem_cache *cachep, char *msg)
 {
 	printk(KERN_ERR "slab error in %s(): cache `%s': %s\n",
 	       function, cachep->name, msg);
@@ -772,7 +828,9 @@ static struct array_cache *alloc_arrayca
 }
 
 #ifdef CONFIG_NUMA
-static inline struct array_cache **alloc_alien_cache(int node, int limit)
+static void *__cache_alloc_node(struct kmem_cache *, gfp_t, int);
+
+static struct array_cache **alloc_alien_cache(int node, int limit)
 {
 	struct array_cache **ac_ptr;
 	int memsize = sizeof(void *) * MAX_NUMNODES;
@@ -799,7 +857,7 @@ static inline struct array_cache **alloc
 	return ac_ptr;
 }
 
-static inline void free_alien_cache(struct array_cache **ac_ptr)
+static void free_alien_cache(struct array_cache **ac_ptr)
 {
 	int i;
 
@@ -812,8 +870,8 @@ static inline void free_alien_cache(stru
 	kfree(ac_ptr);
 }
 
-static inline void __drain_alien_cache(kmem_cache_t *cachep,
-				       struct array_cache *ac, int node)
+static void __drain_alien_cache(struct kmem_cache *cachep,
+				struct array_cache *ac, int node)
 {
 	struct kmem_list3 *rl3 = cachep->nodelists[node];
 
@@ -825,7 +883,7 @@ static inline void __drain_alien_cache(k
 	}
 }
 
-static void drain_alien_cache(kmem_cache_t *cachep, struct kmem_list3 *l3)
+static void drain_alien_cache(struct kmem_cache *cachep, struct kmem_list3 *l3)
 {
 	int i = 0;
 	struct array_cache *ac;
@@ -850,14 +908,14 @@ static int __devinit cpuup_callback(stru
 				    unsigned long action, void *hcpu)
 {
 	long cpu = (long)hcpu;
-	kmem_cache_t *cachep;
+	struct kmem_cache *cachep;
 	struct kmem_list3 *l3 = NULL;
 	int node = cpu_to_node(cpu);
 	int memsize = sizeof(struct kmem_list3);
 
 	switch (action) {
 	case CPU_UP_PREPARE:
-		down(&cache_chain_sem);
+		mutex_lock(&cache_chain_mutex);
 		/* we need to do this right in the beginning since
 		 * alloc_arraycache's are going to use this list.
 		 * kmalloc_node allows us to add the slab to the right
@@ -912,7 +970,7 @@ static int __devinit cpuup_callback(stru
 				l3->shared = nc;
 			}
 		}
-		up(&cache_chain_sem);
+		mutex_unlock(&cache_chain_mutex);
 		break;
 	case CPU_ONLINE:
 		start_cpu_timer(cpu);
@@ -921,7 +979,7 @@ static int __devinit cpuup_callback(stru
 	case CPU_DEAD:
 		/* fall thru */
 	case CPU_UP_CANCELED:
-		down(&cache_chain_sem);
+		mutex_lock(&cache_chain_mutex);
 
 		list_for_each_entry(cachep, &cache_chain, next) {
 			struct array_cache *nc;
@@ -973,13 +1031,13 @@ static int __devinit cpuup_callback(stru
 			spin_unlock_irq(&cachep->spinlock);
 			kfree(nc);
 		}
-		up(&cache_chain_sem);
+		mutex_unlock(&cache_chain_mutex);
 		break;
 #endif
 	}
 	return NOTIFY_OK;
       bad:
-	up(&cache_chain_sem);
+	mutex_unlock(&cache_chain_mutex);
 	return NOTIFY_BAD;
 }
 
@@ -988,7 +1046,7 @@ static struct notifier_block cpucache_no
 /*
  * swap the static kmem_list3 with kmalloced memory
  */
-static void init_list(kmem_cache_t *cachep, struct kmem_list3 *list, int nodeid)
+static void init_list(struct kmem_cache *cachep, struct kmem_list3 *list, int nodeid)
 {
 	struct kmem_list3 *ptr;
 
@@ -1028,14 +1086,14 @@ void __init kmem_cache_init(void)
 
 	/* Bootstrap is tricky, because several objects are allocated
 	 * from caches that do not exist yet:
-	 * 1) initialize the cache_cache cache: it contains the kmem_cache_t
+	 * 1) initialize the cache_cache cache: it contains the struct kmem_cache
 	 *    structures of all caches, except cache_cache itself: cache_cache
 	 *    is statically allocated.
 	 *    Initially an __init data area is used for the head array and the
 	 *    kmem_list3 structures, it's replaced with a kmalloc allocated
 	 *    array at the end of the bootstrap.
 	 * 2) Create the first kmalloc cache.
-	 *    The kmem_cache_t for the new cache is allocated normally.
+	 *    The struct kmem_cache for the new cache is allocated normally.
 	 *    An __init data area is used for the head array.
 	 * 3) Create the remaining kmalloc caches, with minimally sized
 	 *    head arrays.
@@ -1047,16 +1105,15 @@ void __init kmem_cache_init(void)
 	 */
 
 	/* 1) create the cache_cache */
-	init_MUTEX(&cache_chain_sem);
 	INIT_LIST_HEAD(&cache_chain);
 	list_add(&cache_cache.next, &cache_chain);
 	cache_cache.colour_off = cache_line_size();
 	cache_cache.array[smp_processor_id()] = &initarray_cache.cache;
 	cache_cache.nodelists[numa_node_id()] = &initkmem_list3[CACHE_CACHE];
 
-	cache_cache.objsize = ALIGN(cache_cache.objsize, cache_line_size());
+	cache_cache.buffer_size = ALIGN(cache_cache.buffer_size, cache_line_size());
 
-	cache_estimate(0, cache_cache.objsize, cache_line_size(), 0,
+	cache_estimate(0, cache_cache.buffer_size, cache_line_size(), 0,
 		       &left_over, &cache_cache.num);
 	if (!cache_cache.num)
 		BUG();
@@ -1129,8 +1186,8 @@ void __init kmem_cache_init(void)
 		ptr = kmalloc(sizeof(struct arraycache_init), GFP_KERNEL);
 
 		local_irq_disable();
-		BUG_ON(ac_data(&cache_cache) != &initarray_cache.cache);
-		memcpy(ptr, ac_data(&cache_cache),
+		BUG_ON(cpu_cache_get(&cache_cache) != &initarray_cache.cache);
+		memcpy(ptr, cpu_cache_get(&cache_cache),
 		       sizeof(struct arraycache_init));
 		cache_cache.array[smp_processor_id()] = ptr;
 		local_irq_enable();
@@ -1138,9 +1195,9 @@ void __init kmem_cache_init(void)
 		ptr = kmalloc(sizeof(struct arraycache_init), GFP_KERNEL);
 
 		local_irq_disable();
-		BUG_ON(ac_data(malloc_sizes[INDEX_AC].cs_cachep)
+		BUG_ON(cpu_cache_get(malloc_sizes[INDEX_AC].cs_cachep)
 		       != &initarray_generic.cache);
-		memcpy(ptr, ac_data(malloc_sizes[INDEX_AC].cs_cachep),
+		memcpy(ptr, cpu_cache_get(malloc_sizes[INDEX_AC].cs_cachep),
 		       sizeof(struct arraycache_init));
 		malloc_sizes[INDEX_AC].cs_cachep->array[smp_processor_id()] =
 		    ptr;
@@ -1167,18 +1224,18 @@ void __init kmem_cache_init(void)
 
 	/* 6) resize the head arrays to their final sizes */
 	{
-		kmem_cache_t *cachep;
-		down(&cache_chain_sem);
+		struct kmem_cache *cachep;
+		mutex_lock(&cache_chain_mutex);
 		list_for_each_entry(cachep, &cache_chain, next)
 		    enable_cpucache(cachep);
-		up(&cache_chain_sem);
+		mutex_unlock(&cache_chain_mutex);
 	}
 
 	/* Done! */
 	g_cpucache_up = FULL;
 
 	/* Register a cpu startup notifier callback
-	 * that initializes ac_data for all new cpus
+	 * that initializes cpu_cache_get for all new cpus
 	 */
 	register_cpu_notifier(&cpucache_notifier);
 
@@ -1210,7 +1267,7 @@ __initcall(cpucache_init);
  * did not request dmaable memory, we might get it, but that
  * would be relatively rare and ignorable.
  */
-static void *kmem_getpages(kmem_cache_t *cachep, gfp_t flags, int nodeid)
+static void *kmem_getpages(struct kmem_cache *cachep, gfp_t flags, int nodeid)
 {
 	struct page *page;
 	void *addr;
@@ -1236,7 +1293,7 @@ static void *kmem_getpages(kmem_cache_t 
 /*
  * Interface to system's page release.
  */
-static void kmem_freepages(kmem_cache_t *cachep, void *addr)
+static void kmem_freepages(struct kmem_cache *cachep, void *addr)
 {
 	unsigned long i = (1 << cachep->gfporder);
 	struct page *page = virt_to_page(addr);
@@ -1258,7 +1315,7 @@ static void kmem_freepages(kmem_cache_t 
 static void kmem_rcu_free(struct rcu_head *head)
 {
 	struct slab_rcu *slab_rcu = (struct slab_rcu *)head;
-	kmem_cache_t *cachep = slab_rcu->cachep;
+	struct kmem_cache *cachep = slab_rcu->cachep;
 
 	kmem_freepages(cachep, slab_rcu->addr);
 	if (OFF_SLAB(cachep))
@@ -1268,12 +1325,12 @@ static void kmem_rcu_free(struct rcu_hea
 #if DEBUG
 
 #ifdef CONFIG_DEBUG_PAGEALLOC
-static void store_stackinfo(kmem_cache_t *cachep, unsigned long *addr,
+static void store_stackinfo(struct kmem_cache *cachep, unsigned long *addr,
 			    unsigned long caller)
 {
-	int size = obj_reallen(cachep);
+	int size = obj_size(cachep);
 
-	addr = (unsigned long *)&((char *)addr)[obj_dbghead(cachep)];
+	addr = (unsigned long *)&((char *)addr)[obj_offset(cachep)];
 
 	if (size < 5 * sizeof(unsigned long))
 		return;
@@ -1301,10 +1358,10 @@ static void store_stackinfo(kmem_cache_t
 }
 #endif
 
-static void poison_obj(kmem_cache_t *cachep, void *addr, unsigned char val)
+static void poison_obj(struct kmem_cache *cachep, void *addr, unsigned char val)
 {
-	int size = obj_reallen(cachep);
-	addr = &((char *)addr)[obj_dbghead(cachep)];
+	int size = obj_size(cachep);
+	addr = &((char *)addr)[obj_offset(cachep)];
 
 	memset(addr, val, size);
 	*(unsigned char *)(addr + size - 1) = POISON_END;
@@ -1323,7 +1380,7 @@ static void dump_line(char *data, int of
 
 #if DEBUG
 
-static void print_objinfo(kmem_cache_t *cachep, void *objp, int lines)
+static void print_objinfo(struct kmem_cache *cachep, void *objp, int lines)
 {
 	int i, size;
 	char *realobj;
@@ -1341,8 +1398,8 @@ static void print_objinfo(kmem_cache_t *
 			     (unsigned long)*dbg_userword(cachep, objp));
 		printk("\n");
 	}
-	realobj = (char *)objp + obj_dbghead(cachep);
-	size = obj_reallen(cachep);
+	realobj = (char *)objp + obj_offset(cachep);
+	size = obj_size(cachep);
 	for (i = 0; i < size && lines; i += 16, lines--) {
 		int limit;
 		limit = 16;
@@ -1352,14 +1409,14 @@ static void print_objinfo(kmem_cache_t *
 	}
 }
 
-static void check_poison_obj(kmem_cache_t *cachep, void *objp)
+static void check_poison_obj(struct kmem_cache *cachep, void *objp)
 {
 	char *realobj;
 	int size, i;
 	int lines = 0;
 
-	realobj = (char *)objp + obj_dbghead(cachep);
-	size = obj_reallen(cachep);
+	realobj = (char *)objp + obj_offset(cachep);
+	size = obj_size(cachep);
 
 	for (i = 0; i < size; i++) {
 		char exp = POISON_FREE;
@@ -1392,20 +1449,20 @@ static void check_poison_obj(kmem_cache_
 		/* Print some data about the neighboring objects, if they
 		 * exist:
 		 */
-		struct slab *slabp = page_get_slab(virt_to_page(objp));
+		struct slab *slabp = virt_to_slab(objp);
 		int objnr;
 
-		objnr = (objp - slabp->s_mem) / cachep->objsize;
+		objnr = (unsigned)(objp - slabp->s_mem) / cachep->buffer_size;
 		if (objnr) {
-			objp = slabp->s_mem + (objnr - 1) * cachep->objsize;
-			realobj = (char *)objp + obj_dbghead(cachep);
+			objp = slabp->s_mem + (objnr - 1) * cachep->buffer_size;
+			realobj = (char *)objp + obj_offset(cachep);
 			printk(KERN_ERR "Prev obj: start=%p, len=%d\n",
 			       realobj, size);
 			print_objinfo(cachep, objp, 2);
 		}
 		if (objnr + 1 < cachep->num) {
-			objp = slabp->s_mem + (objnr + 1) * cachep->objsize;
-			realobj = (char *)objp + obj_dbghead(cachep);
+			objp = slabp->s_mem + (objnr + 1) * cachep->buffer_size;
+			realobj = (char *)objp + obj_offset(cachep);
 			printk(KERN_ERR "Next obj: start=%p, len=%d\n",
 			       realobj, size);
 			print_objinfo(cachep, objp, 2);
@@ -1414,25 +1471,23 @@ static void check_poison_obj(kmem_cache_
 }
 #endif
 
-/* Destroy all the objs in a slab, and release the mem back to the system.
- * Before calling the slab must have been unlinked from the cache.
- * The cache-lock is not held/needed.
+#if DEBUG
+/**
+ * slab_destroy_objs - call the registered destructor for each object in
+ *      a slab that is to be destroyed.
  */
-static void slab_destroy(kmem_cache_t *cachep, struct slab *slabp)
+static void slab_destroy_objs(struct kmem_cache *cachep, struct slab *slabp)
 {
-	void *addr = slabp->s_mem - slabp->colouroff;
-
-#if DEBUG
 	int i;
 	for (i = 0; i < cachep->num; i++) {
-		void *objp = slabp->s_mem + cachep->objsize * i;
+		void *objp = slabp->s_mem + cachep->buffer_size * i;
 
 		if (cachep->flags & SLAB_POISON) {
 #ifdef CONFIG_DEBUG_PAGEALLOC
-			if ((cachep->objsize % PAGE_SIZE) == 0
+			if ((cachep->buffer_size % PAGE_SIZE) == 0
 			    && OFF_SLAB(cachep))
 				kernel_map_pages(virt_to_page(objp),
-						 cachep->objsize / PAGE_SIZE,
+						 cachep->buffer_size / PAGE_SIZE,
 						 1);
 			else
 				check_poison_obj(cachep, objp);
@@ -1449,18 +1504,32 @@ static void slab_destroy(kmem_cache_t *c
 					   "was overwritten");
 		}
 		if (cachep->dtor && !(cachep->flags & SLAB_POISON))
-			(cachep->dtor) (objp + obj_dbghead(cachep), cachep, 0);
+			(cachep->dtor) (objp + obj_offset(cachep), cachep, 0);
 	}
+}
 #else
+static void slab_destroy_objs(struct kmem_cache *cachep, struct slab *slabp)
+{
 	if (cachep->dtor) {
 		int i;
 		for (i = 0; i < cachep->num; i++) {
-			void *objp = slabp->s_mem + cachep->objsize * i;
+			void *objp = slabp->s_mem + cachep->buffer_size * i;
 			(cachep->dtor) (objp, cachep, 0);
 		}
 	}
+}
 #endif
 
+/**
+ * Destroy all the objs in a slab, and release the mem back to the system.
+ * Before calling the slab must have been unlinked from the cache.
+ * The cache-lock is not held/needed.
+ */
+static void slab_destroy(struct kmem_cache *cachep, struct slab *slabp)
+{
+	void *addr = slabp->s_mem - slabp->colouroff;
+
+	slab_destroy_objs(cachep, slabp);
 	if (unlikely(cachep->flags & SLAB_DESTROY_BY_RCU)) {
 		struct slab_rcu *slab_rcu;
 
@@ -1475,9 +1544,9 @@ static void slab_destroy(kmem_cache_t *c
 	}
 }
 
-/* For setting up all the kmem_list3s for cache whose objsize is same
+/* For setting up all the kmem_list3s for cache whose buffer_size is same
    as size of kmem_list3. */
-static inline void set_up_list3s(kmem_cache_t *cachep, int index)
+static void set_up_list3s(struct kmem_cache *cachep, int index)
 {
 	int node;
 
@@ -1490,15 +1559,20 @@ static inline void set_up_list3s(kmem_ca
 }
 
 /**
- * calculate_slab_order - calculate size (page order) of slabs and the number
- *                        of objects per slab.
+ * calculate_slab_order - calculate size (page order) of slabs
+ * @cachep: pointer to the cache that is being created
+ * @size: size of objects to be created in this cache.
+ * @align: required alignment for the objects.
+ * @flags: slab allocation flags
+ *
+ * Also calculates the number of objects per slab.
  *
  * This could be made much more intelligent.  For now, try to avoid using
  * high order pages for slabs.  When the gfp() functions are more friendly
  * towards high-order requests, this should be changed.
  */
-static inline size_t calculate_slab_order(kmem_cache_t *cachep, size_t size,
-					  size_t align, gfp_t flags)
+static inline size_t calculate_slab_order(struct kmem_cache *cachep,
+			size_t size, size_t align, unsigned long flags)
 {
 	size_t left_over = 0;
 
@@ -1569,13 +1643,13 @@ static inline size_t calculate_slab_orde
  * cacheline.  This can be beneficial if you're counting cycles as closely
  * as davem.
  */
-kmem_cache_t *
+struct kmem_cache *
 kmem_cache_create (const char *name, size_t size, size_t align,
-	unsigned long flags, void (*ctor)(void*, kmem_cache_t *, unsigned long),
-	void (*dtor)(void*, kmem_cache_t *, unsigned long))
+	unsigned long flags, void (*ctor)(void*, struct kmem_cache *, unsigned long),
+	void (*dtor)(void*, struct kmem_cache *, unsigned long))
 {
 	size_t left_over, slab_size, ralign;
-	kmem_cache_t *cachep = NULL;
+	struct kmem_cache *cachep = NULL;
 	struct list_head *p;
 
 	/*
@@ -1590,10 +1664,10 @@ kmem_cache_create (const char *name, siz
 		BUG();
 	}
 
-	down(&cache_chain_sem);
+	mutex_lock(&cache_chain_mutex);
 
 	list_for_each(p, &cache_chain) {
-		kmem_cache_t *pc = list_entry(p, kmem_cache_t, next);
+		struct kmem_cache *pc = list_entry(p, struct kmem_cache, next);
 		mm_segment_t old_fs = get_fs();
 		char tmp;
 		int res;
@@ -1608,7 +1682,7 @@ kmem_cache_create (const char *name, siz
 		set_fs(old_fs);
 		if (res) {
 			printk("SLAB: cache with size %d has lost its name\n",
-			       pc->objsize);
+			       pc->buffer_size);
 			continue;
 		}
 
@@ -1693,20 +1767,20 @@ kmem_cache_create (const char *name, siz
 	align = ralign;
 
 	/* Get cache's description obj. */
-	cachep = (kmem_cache_t *) kmem_cache_alloc(&cache_cache, SLAB_KERNEL);
+	cachep = kmem_cache_alloc(&cache_cache, SLAB_KERNEL);
 	if (!cachep)
 		goto oops;
-	memset(cachep, 0, sizeof(kmem_cache_t));
+	memset(cachep, 0, sizeof(struct kmem_cache));
 
 #if DEBUG
-	cachep->reallen = size;
+	cachep->obj_size = size;
 
 	if (flags & SLAB_RED_ZONE) {
 		/* redzoning only works with word aligned caches */
 		align = BYTES_PER_WORD;
 
 		/* add space for red zone words */
-		cachep->dbghead += BYTES_PER_WORD;
+		cachep->obj_offset += BYTES_PER_WORD;
 		size += 2 * BYTES_PER_WORD;
 	}
 	if (flags & SLAB_STORE_USER) {
@@ -1719,8 +1793,8 @@ kmem_cache_create (const char *name, siz
 	}
 #if FORCED_DEBUG && defined(CONFIG_DEBUG_PAGEALLOC)
 	if (size >= malloc_sizes[INDEX_L3 + 1].cs_size
-	    && cachep->reallen > cache_line_size() && size < PAGE_SIZE) {
-		cachep->dbghead += PAGE_SIZE - size;
+	    && cachep->obj_size > cache_line_size() && size < PAGE_SIZE) {
+		cachep->obj_offset += PAGE_SIZE - size;
 		size = PAGE_SIZE;
 	}
 #endif
@@ -1783,7 +1857,7 @@ kmem_cache_create (const char *name, siz
 	if (flags & SLAB_CACHE_DMA)
 		cachep->gfpflags |= GFP_DMA;
 	spin_lock_init(&cachep->spinlock);
-	cachep->objsize = size;
+	cachep->buffer_size = size;
 
 	if (flags & CFLGS_OFF_SLAB)
 		cachep->slabp_cache = kmem_find_general_cachep(slab_size, 0u);
@@ -1840,11 +1914,11 @@ kmem_cache_create (const char *name, siz
 		    jiffies + REAPTIMEOUT_LIST3 +
 		    ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
 
-		BUG_ON(!ac_data(cachep));
-		ac_data(cachep)->avail = 0;
-		ac_data(cachep)->limit = BOOT_CPUCACHE_ENTRIES;
-		ac_data(cachep)->batchcount = 1;
-		ac_data(cachep)->touched = 0;
+		BUG_ON(!cpu_cache_get(cachep));
+		cpu_cache_get(cachep)->avail = 0;
+		cpu_cache_get(cachep)->limit = BOOT_CPUCACHE_ENTRIES;
+		cpu_cache_get(cachep)->batchcount = 1;
+		cpu_cache_get(cachep)->touched = 0;
 		cachep->batchcount = 1;
 		cachep->limit = BOOT_CPUCACHE_ENTRIES;
 	}
@@ -1856,7 +1930,7 @@ kmem_cache_create (const char *name, siz
 	if (!cachep && (flags & SLAB_PANIC))
 		panic("kmem_cache_create(): failed to create slab `%s'\n",
 		      name);
-	up(&cache_chain_sem);
+	mutex_unlock(&cache_chain_mutex);
 	return cachep;
 }
 EXPORT_SYMBOL(kmem_cache_create);
@@ -1872,7 +1946,7 @@ static void check_irq_on(void)
 	BUG_ON(irqs_disabled());
 }
 
-static void check_spinlock_acquired(kmem_cache_t *cachep)
+static void check_spinlock_acquired(struct kmem_cache *cachep)
 {
 #ifdef CONFIG_SMP
 	check_irq_off();
@@ -1880,7 +1954,7 @@ static void check_spinlock_acquired(kmem
 #endif
 }
 
-static inline void check_spinlock_acquired_node(kmem_cache_t *cachep, int node)
+static void check_spinlock_acquired_node(struct kmem_cache *cachep, int node)
 {
 #ifdef CONFIG_SMP
 	check_irq_off();
@@ -1913,24 +1987,24 @@ static void smp_call_function_all_cpus(v
 	preempt_enable();
 }
 
-static void drain_array_locked(kmem_cache_t *cachep, struct array_cache *ac,
+static void drain_array_locked(struct kmem_cache *cachep, struct array_cache *ac,
 				int force, int node);
 
 static void do_drain(void *arg)
 {
-	kmem_cache_t *cachep = (kmem_cache_t *) arg;
+	struct kmem_cache *cachep = (struct kmem_cache *) arg;
 	struct array_cache *ac;
 	int node = numa_node_id();
 
 	check_irq_off();
-	ac = ac_data(cachep);
+	ac = cpu_cache_get(cachep);
 	spin_lock(&cachep->nodelists[node]->list_lock);
 	free_block(cachep, ac->entry, ac->avail, node);
 	spin_unlock(&cachep->nodelists[node]->list_lock);
 	ac->avail = 0;
 }
 
-static void drain_cpu_caches(kmem_cache_t *cachep)
+static void drain_cpu_caches(struct kmem_cache *cachep)
 {
 	struct kmem_list3 *l3;
 	int node;
@@ -1951,7 +2025,7 @@ static void drain_cpu_caches(kmem_cache_
 	spin_unlock_irq(&cachep->spinlock);
 }
 
-static int __node_shrink(kmem_cache_t *cachep, int node)
+static int __node_shrink(struct kmem_cache *cachep, int node)
 {
 	struct slab *slabp;
 	struct kmem_list3 *l3 = cachep->nodelists[node];
@@ -1980,7 +2054,7 @@ static int __node_shrink(kmem_cache_t *c
 	return ret;
 }
 
-static int __cache_shrink(kmem_cache_t *cachep)
+static int __cache_shrink(struct kmem_cache *cachep)
 {
 	int ret = 0, i = 0;
 	struct kmem_list3 *l3;
@@ -2006,7 +2080,7 @@ static int __cache_shrink(kmem_cache_t *
  * Releases as many slabs as possible for a cache.
  * To help debugging, a zero exit status indicates all slabs were released.
  */
-int kmem_cache_shrink(kmem_cache_t *cachep)
+int kmem_cache_shrink(struct kmem_cache *cachep)
 {
 	if (!cachep || in_interrupt())
 		BUG();
@@ -2019,7 +2093,7 @@ EXPORT_SYMBOL(kmem_cache_shrink);
  * kmem_cache_destroy - delete a cache
  * @cachep: the cache to destroy
  *
- * Remove a kmem_cache_t object from the slab cache.
+ * Remove a struct kmem_cache object from the slab cache.
  * Returns 0 on success.
  *
  * It is expected this function will be called by a module when it is
@@ -2032,7 +2106,7 @@ EXPORT_SYMBOL(kmem_cache_shrink);
  * The caller must guarantee that noone will allocate memory from the cache
  * during the kmem_cache_destroy().
  */
-int kmem_cache_destroy(kmem_cache_t *cachep)
+int kmem_cache_destroy(struct kmem_cache *cachep)
 {
 	int i;
 	struct kmem_list3 *l3;
@@ -2044,18 +2118,18 @@ int kmem_cache_destroy(kmem_cache_t *cac
 	lock_cpu_hotplug();
 
 	/* Find the cache in the chain of caches. */
-	down(&cache_chain_sem);
+	mutex_lock(&cache_chain_mutex);
 	/*
 	 * the chain is never empty, cache_cache is never destroyed
 	 */
 	list_del(&cachep->next);
-	up(&cache_chain_sem);
+	mutex_unlock(&cache_chain_mutex);
 
 	if (__cache_shrink(cachep)) {
 		slab_error(cachep, "Can't free all objects");
-		down(&cache_chain_sem);
+		mutex_lock(&cache_chain_mutex);
 		list_add(&cachep->next, &cache_chain);
-		up(&cache_chain_sem);
+		mutex_unlock(&cache_chain_mutex);
 		unlock_cpu_hotplug();
 		return 1;
 	}
@@ -2083,7 +2157,7 @@ int kmem_cache_destroy(kmem_cache_t *cac
 EXPORT_SYMBOL(kmem_cache_destroy);
 
 /* Get the memory for a slab management obj. */
-static struct slab *alloc_slabmgmt(kmem_cache_t *cachep, void *objp,
+static struct slab *alloc_slabmgmt(struct kmem_cache *cachep, void *objp,
 				   int colour_off, gfp_t local_flags)
 {
 	struct slab *slabp;
@@ -2109,13 +2183,13 @@ static inline kmem_bufctl_t *slab_bufctl
 	return (kmem_bufctl_t *) (slabp + 1);
 }
 
-static void cache_init_objs(kmem_cache_t *cachep,
+static void cache_init_objs(struct kmem_cache *cachep,
 			    struct slab *slabp, unsigned long ctor_flags)
 {
 	int i;
 
 	for (i = 0; i < cachep->num; i++) {
-		void *objp = slabp->s_mem + cachep->objsize * i;
+		void *objp = slabp->s_mem + cachep->buffer_size * i;
 #if DEBUG
 		/* need to poison the objs? */
 		if (cachep->flags & SLAB_POISON)
@@ -2133,7 +2207,7 @@ static void cache_init_objs(kmem_cache_t
 		 * Otherwise, deadlock. They must also be threaded.
 		 */
 		if (cachep->ctor && !(cachep->flags & SLAB_POISON))
-			cachep->ctor(objp + obj_dbghead(cachep), cachep,
+			cachep->ctor(objp + obj_offset(cachep), cachep,
 				     ctor_flags);
 
 		if (cachep->flags & SLAB_RED_ZONE) {
@@ -2144,10 +2218,10 @@ static void cache_init_objs(kmem_cache_t
 				slab_error(cachep, "constructor overwrote the"
 					   " start of an object");
 		}
-		if ((cachep->objsize % PAGE_SIZE) == 0 && OFF_SLAB(cachep)
+		if ((cachep->buffer_size % PAGE_SIZE) == 0 && OFF_SLAB(cachep)
 		    && cachep->flags & SLAB_POISON)
 			kernel_map_pages(virt_to_page(objp),
-					 cachep->objsize / PAGE_SIZE, 0);
+					 cachep->buffer_size / PAGE_SIZE, 0);
 #else
 		if (cachep->ctor)
 			cachep->ctor(objp, cachep, ctor_flags);
@@ -2158,7 +2232,7 @@ static void cache_init_objs(kmem_cache_t
 	slabp->free = 0;
 }
 
-static void kmem_flagcheck(kmem_cache_t *cachep, gfp_t flags)
+static void kmem_flagcheck(struct kmem_cache *cachep, gfp_t flags)
 {
 	if (flags & SLAB_DMA) {
 		if (!(cachep->gfpflags & GFP_DMA))
@@ -2169,7 +2243,43 @@ static void kmem_flagcheck(kmem_cache_t 
 	}
 }
 
-static void set_slab_attr(kmem_cache_t *cachep, struct slab *slabp, void *objp)
+static void *slab_get_obj(struct kmem_cache *cachep, struct slab *slabp, int nodeid)
+{
+	void *objp = slabp->s_mem + (slabp->free * cachep->buffer_size);
+	kmem_bufctl_t next;
+
+	slabp->inuse++;
+	next = slab_bufctl(slabp)[slabp->free];
+#if DEBUG
+	slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE;
+	WARN_ON(slabp->nodeid != nodeid);
+#endif
+	slabp->free = next;
+
+	return objp;
+}
+
+static void slab_put_obj(struct kmem_cache *cachep, struct slab *slabp, void *objp,
+			  int nodeid)
+{
+	unsigned int objnr = (unsigned)(objp-slabp->s_mem) / cachep->buffer_size;
+
+#if DEBUG
+	/* Verify that the slab belongs to the intended node */
+	WARN_ON(slabp->nodeid != nodeid);
+
+	if (slab_bufctl(slabp)[objnr] != BUFCTL_FREE) {
+		printk(KERN_ERR "slab: double free detected in cache "
+		       "'%s', objp %p\n", cachep->name, objp);
+		BUG();
+	}
+#endif
+	slab_bufctl(slabp)[objnr] = slabp->free;
+	slabp->free = objnr;
+	slabp->inuse--;
+}
+
+static void set_slab_attr(struct kmem_cache *cachep, struct slab *slabp, void *objp)
 {
 	int i;
 	struct page *page;
@@ -2188,7 +2298,7 @@ static void set_slab_attr(kmem_cache_t *
  * Grow (by 1) the number of slabs within a cache.  This is called by
  * kmem_cache_alloc() when there are no active objs left in a cache.
  */
-static int cache_grow(kmem_cache_t *cachep, gfp_t flags, int nodeid)
+static int cache_grow(struct kmem_cache *cachep, gfp_t flags, int nodeid)
 {
 	struct slab *slabp;
 	void *objp;
@@ -2299,14 +2409,14 @@ static void kfree_debugcheck(const void 
 	}
 }
 
-static void *cache_free_debugcheck(kmem_cache_t *cachep, void *objp,
+static void *cache_free_debugcheck(struct kmem_cache *cachep, void *objp,
 				   void *caller)
 {
 	struct page *page;
 	unsigned int objnr;
 	struct slab *slabp;
 
-	objp -= obj_dbghead(cachep);
+	objp -= obj_offset(cachep);
 	kfree_debugcheck(objp);
 	page = virt_to_page(objp);
 
@@ -2338,31 +2448,31 @@ static void *cache_free_debugcheck(kmem_
 	if (cachep->flags & SLAB_STORE_USER)
 		*dbg_userword(cachep, objp) = caller;
 
-	objnr = (objp - slabp->s_mem) / cachep->objsize;
+	objnr = (unsigned)(objp - slabp->s_mem) / cachep->buffer_size;
 
 	BUG_ON(objnr >= cachep->num);
-	BUG_ON(objp != slabp->s_mem + objnr * cachep->objsize);
+	BUG_ON(objp != slabp->s_mem + objnr * cachep->buffer_size);
 
 	if (cachep->flags & SLAB_DEBUG_INITIAL) {
 		/* Need to call the slab's constructor so the
 		 * caller can perform a verify of its state (debugging).
 		 * Called without the cache-lock held.
 		 */
-		cachep->ctor(objp + obj_dbghead(cachep),
+		cachep->ctor(objp + obj_offset(cachep),
 			     cachep, SLAB_CTOR_CONSTRUCTOR | SLAB_CTOR_VERIFY);
 	}
 	if (cachep->flags & SLAB_POISON && cachep->dtor) {
 		/* we want to cache poison the object,
 		 * call the destruction callback
 		 */
-		cachep->dtor(objp + obj_dbghead(cachep), cachep, 0);
+		cachep->dtor(objp + obj_offset(cachep), cachep, 0);
 	}
 	if (cachep->flags & SLAB_POISON) {
 #ifdef CONFIG_DEBUG_PAGEALLOC
-		if ((cachep->objsize % PAGE_SIZE) == 0 && OFF_SLAB(cachep)) {
+		if ((cachep->buffer_size % PAGE_SIZE) == 0 && OFF_SLAB(cachep)) {
 			store_stackinfo(cachep, objp, (unsigned long)caller);
 			kernel_map_pages(virt_to_page(objp),
-					 cachep->objsize / PAGE_SIZE, 0);
+					 cachep->buffer_size / PAGE_SIZE, 0);
 		} else {
 			poison_obj(cachep, objp, POISON_FREE);
 		}
@@ -2373,7 +2483,7 @@ static void *cache_free_debugcheck(kmem_
 	return objp;
 }
 
-static void check_slabp(kmem_cache_t *cachep, struct slab *slabp)
+static void check_slabp(struct kmem_cache *cachep, struct slab *slabp)
 {
 	kmem_bufctl_t i;
 	int entries = 0;
@@ -2406,14 +2516,14 @@ static void check_slabp(kmem_cache_t *ca
 #define check_slabp(x,y) do { } while(0)
 #endif
 
-static void *cache_alloc_refill(kmem_cache_t *cachep, gfp_t flags)
+static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags)
 {
 	int batchcount;
 	struct kmem_list3 *l3;
 	struct array_cache *ac;
 
 	check_irq_off();
-	ac = ac_data(cachep);
+	ac = cpu_cache_get(cachep);
       retry:
 	batchcount = ac->batchcount;
 	if (!ac->touched && batchcount > BATCHREFILL_LIMIT) {
@@ -2458,22 +2568,12 @@ static void *cache_alloc_refill(kmem_cac
 		check_slabp(cachep, slabp);
 		check_spinlock_acquired(cachep);
 		while (slabp->inuse < cachep->num && batchcount--) {
-			kmem_bufctl_t next;
 			STATS_INC_ALLOCED(cachep);
 			STATS_INC_ACTIVE(cachep);
 			STATS_SET_HIGH(cachep);
 
-			/* get obj pointer */
-			ac->entry[ac->avail++] = slabp->s_mem +
-			    slabp->free * cachep->objsize;
-
-			slabp->inuse++;
-			next = slab_bufctl(slabp)[slabp->free];
-#if DEBUG
-			slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE;
-			WARN_ON(numa_node_id() != slabp->nodeid);
-#endif
-			slabp->free = next;
+			ac->entry[ac->avail++] = slab_get_obj(cachep, slabp,
+							    numa_node_id());
 		}
 		check_slabp(cachep, slabp);
 
@@ -2495,7 +2595,7 @@ static void *cache_alloc_refill(kmem_cac
 		x = cache_grow(cachep, flags, numa_node_id());
 
 		// cache_grow can reenable interrupts, then ac could change.
-		ac = ac_data(cachep);
+		ac = cpu_cache_get(cachep);
 		if (!x && ac->avail == 0)	// no objects in sight? abort
 			return NULL;
 
@@ -2507,7 +2607,7 @@ static void *cache_alloc_refill(kmem_cac
 }
 
 static inline void
-cache_alloc_debugcheck_before(kmem_cache_t *cachep, gfp_t flags)
+cache_alloc_debugcheck_before(struct kmem_cache *cachep, gfp_t flags)
 {
 	might_sleep_if(flags & __GFP_WAIT);
 #if DEBUG
@@ -2516,16 +2616,16 @@ cache_alloc_debugcheck_before(kmem_cache
 }
 
 #if DEBUG
-static void *cache_alloc_debugcheck_after(kmem_cache_t *cachep, gfp_t flags,
+static void *cache_alloc_debugcheck_after(struct kmem_cache *cachep, gfp_t flags,
 					void *objp, void *caller)
 {
 	if (!objp)
 		return objp;
 	if (cachep->flags & SLAB_POISON) {
 #ifdef CONFIG_DEBUG_PAGEALLOC
-		if ((cachep->objsize % PAGE_SIZE) == 0 && OFF_SLAB(cachep))
+		if ((cachep->buffer_size % PAGE_SIZE) == 0 && OFF_SLAB(cachep))
 			kernel_map_pages(virt_to_page(objp),
-					 cachep->objsize / PAGE_SIZE, 1);
+					 cachep->buffer_size / PAGE_SIZE, 1);
 		else
 			check_poison_obj(cachep, objp);
 #else
@@ -2550,7 +2650,7 @@ static void *cache_alloc_debugcheck_afte
 		*dbg_redzone1(cachep, objp) = RED_ACTIVE;
 		*dbg_redzone2(cachep, objp) = RED_ACTIVE;
 	}
-	objp += obj_dbghead(cachep);
+	objp += obj_offset(cachep);
 	if (cachep->ctor && cachep->flags & SLAB_POISON) {
 		unsigned long ctor_flags = SLAB_CTOR_CONSTRUCTOR;
 
@@ -2565,13 +2665,22 @@ static void *cache_alloc_debugcheck_afte
 #define cache_alloc_debugcheck_after(a,b,objp,d) (objp)
 #endif
 
-static inline void *____cache_alloc(kmem_cache_t *cachep, gfp_t flags)
+static inline void *____cache_alloc(struct kmem_cache *cachep, gfp_t flags)
 {
 	void *objp;
 	struct array_cache *ac;
 
+#ifdef CONFIG_NUMA
+	if (unlikely(current->mempolicy && !in_interrupt())) {
+		int nid = slab_node(current->mempolicy);
+
+		if (nid != numa_node_id())
+			return __cache_alloc_node(cachep, flags, nid);
+	}
+#endif
+
 	check_irq_off();
-	ac = ac_data(cachep);
+	ac = cpu_cache_get(cachep);
 	if (likely(ac->avail)) {
 		STATS_INC_ALLOCHIT(cachep);
 		ac->touched = 1;
@@ -2583,7 +2692,8 @@ static inline void *____cache_alloc(kmem
 	return objp;
 }
 
-static inline void *__cache_alloc(kmem_cache_t *cachep, gfp_t flags)
+static __always_inline void *
+__cache_alloc(struct kmem_cache *cachep, gfp_t flags, void *caller)
 {
 	unsigned long save_flags;
 	void *objp;
@@ -2594,7 +2704,7 @@ static inline void *__cache_alloc(kmem_c
 	objp = ____cache_alloc(cachep, flags);
 	local_irq_restore(save_flags);
 	objp = cache_alloc_debugcheck_after(cachep, flags, objp,
-					    __builtin_return_address(0));
+					    caller);
 	prefetchw(objp);
 	return objp;
 }
@@ -2603,13 +2713,12 @@ static inline void *__cache_alloc(kmem_c
 /*
  * A interface to enable slab creation on nodeid
  */
-static void *__cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int nodeid)
+static void *__cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid)
 {
 	struct list_head *entry;
 	struct slab *slabp;
 	struct kmem_list3 *l3;
 	void *obj;
-	kmem_bufctl_t next;
 	int x;
 
 	l3 = cachep->nodelists[nodeid];
@@ -2635,14 +2744,7 @@ static void *__cache_alloc_node(kmem_cac
 
 	BUG_ON(slabp->inuse == cachep->num);
 
-	/* get obj pointer */
-	obj = slabp->s_mem + slabp->free * cachep->objsize;
-	slabp->inuse++;
-	next = slab_bufctl(slabp)[slabp->free];
-#if DEBUG
-	slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE;
-#endif
-	slabp->free = next;
+	obj = slab_get_obj(cachep, slabp, nodeid);
 	check_slabp(cachep, slabp);
 	l3->free_objects--;
 	/* move slabp to correct slabp list: */
@@ -2673,7 +2775,7 @@ static void *__cache_alloc_node(kmem_cac
 /*
  * Caller needs to acquire correct kmem_list's list_lock
  */
-static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects,
+static void free_block(struct kmem_cache *cachep, void **objpp, int nr_objects,
 		       int node)
 {
 	int i;
@@ -2682,29 +2784,14 @@ static void free_block(kmem_cache_t *cac
 	for (i = 0; i < nr_objects; i++) {
 		void *objp = objpp[i];
 		struct slab *slabp;
-		unsigned int objnr;
 
-		slabp = page_get_slab(virt_to_page(objp));
+		slabp = virt_to_slab(objp);
 		l3 = cachep->nodelists[node];
 		list_del(&slabp->list);
-		objnr = (objp - slabp->s_mem) / cachep->objsize;
 		check_spinlock_acquired_node(cachep, node);
 		check_slabp(cachep, slabp);
-
-#if DEBUG
-		/* Verify that the slab belongs to the intended node */
-		WARN_ON(slabp->nodeid != node);
-
-		if (slab_bufctl(slabp)[objnr] != BUFCTL_FREE) {
-			printk(KERN_ERR "slab: double free detected in cache "
-			       "'%s', objp %p\n", cachep->name, objp);
-			BUG();
-		}
-#endif
-		slab_bufctl(slabp)[objnr] = slabp->free;
-		slabp->free = objnr;
+		slab_put_obj(cachep, slabp, objp, node);
 		STATS_DEC_ACTIVE(cachep);
-		slabp->inuse--;
 		l3->free_objects++;
 		check_slabp(cachep, slabp);
 
@@ -2726,7 +2813,7 @@ static void free_block(kmem_cache_t *cac
 	}
 }
 
-static void cache_flusharray(kmem_cache_t *cachep, struct array_cache *ac)
+static void cache_flusharray(struct kmem_cache *cachep, struct array_cache *ac)
 {
 	int batchcount;
 	struct kmem_list3 *l3;
@@ -2785,9 +2872,9 @@ static void cache_flusharray(kmem_cache_
  *
  * Called with disabled ints.
  */
-static inline void __cache_free(kmem_cache_t *cachep, void *objp)
+static inline void __cache_free(struct kmem_cache *cachep, void *objp)
 {
-	struct array_cache *ac = ac_data(cachep);
+	struct array_cache *ac = cpu_cache_get(cachep);
 
 	check_irq_off();
 	objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));
@@ -2798,7 +2885,7 @@ static inline void __cache_free(kmem_cac
 #ifdef CONFIG_NUMA
 	{
 		struct slab *slabp;
-		slabp = page_get_slab(virt_to_page(objp));
+		slabp = virt_to_slab(objp);
 		if (unlikely(slabp->nodeid != numa_node_id())) {
 			struct array_cache *alien = NULL;
 			int nodeid = slabp->nodeid;
@@ -2844,9 +2931,9 @@ static inline void __cache_free(kmem_cac
  * Allocate an object from this cache.  The flags are only relevant
  * if the cache has no available objects.
  */
-void *kmem_cache_alloc(kmem_cache_t *cachep, gfp_t flags)
+void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags)
 {
-	return __cache_alloc(cachep, flags);
+	return __cache_alloc(cachep, flags, __builtin_return_address(0));
 }
 EXPORT_SYMBOL(kmem_cache_alloc);
 
@@ -2864,12 +2951,12 @@ EXPORT_SYMBOL(kmem_cache_alloc);
  *
  * Currently only used for dentry validation.
  */
-int fastcall kmem_ptr_validate(kmem_cache_t *cachep, void *ptr)
+int fastcall kmem_ptr_validate(struct kmem_cache *cachep, void *ptr)
 {
 	unsigned long addr = (unsigned long)ptr;
 	unsigned long min_addr = PAGE_OFFSET;
 	unsigned long align_mask = BYTES_PER_WORD - 1;
-	unsigned long size = cachep->objsize;
+	unsigned long size = cachep->buffer_size;
 	struct page *page;
 
 	if (unlikely(addr < min_addr))
@@ -2905,32 +2992,23 @@ int fastcall kmem_ptr_validate(kmem_cach
  * New and improved: it will now make sure that the object gets
  * put on the correct node list so that there is no false sharing.
  */
-void *kmem_cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int nodeid)
+void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid)
 {
 	unsigned long save_flags;
 	void *ptr;
 
-	if (nodeid == -1)
-		return __cache_alloc(cachep, flags);
-
-	if (unlikely(!cachep->nodelists[nodeid])) {
-		/* Fall back to __cache_alloc if we run into trouble */
-		printk(KERN_WARNING
-		       "slab: not allocating in inactive node %d for cache %s\n",
-		       nodeid, cachep->name);
-		return __cache_alloc(cachep, flags);
-	}
-
 	cache_alloc_debugcheck_before(cachep, flags);
 	local_irq_save(save_flags);
-	if (nodeid == numa_node_id())
+
+	if (nodeid == -1 || nodeid == numa_node_id() ||
+	    !cachep->nodelists[nodeid])
 		ptr = ____cache_alloc(cachep, flags);
 	else
 		ptr = __cache_alloc_node(cachep, flags, nodeid);
 	local_irq_restore(save_flags);
-	ptr =
-	    cache_alloc_debugcheck_after(cachep, flags, ptr,
-					 __builtin_return_address(0));
+
+	ptr = cache_alloc_debugcheck_after(cachep, flags, ptr,
+					   __builtin_return_address(0));
 
 	return ptr;
 }
@@ -2938,7 +3016,7 @@ EXPORT_SYMBOL(kmem_cache_alloc_node);
 
 void *kmalloc_node(size_t size, gfp_t flags, int node)
 {
-	kmem_cache_t *cachep;
+	struct kmem_cache *cachep;
 
 	cachep = kmem_find_general_cachep(size, flags);
 	if (unlikely(cachep == NULL))
@@ -2969,9 +3047,10 @@ EXPORT_SYMBOL(kmalloc_node);
  * platforms.  For example, on i386, it means that the memory must come
  * from the first 16MB.
  */
-void *__kmalloc(size_t size, gfp_t flags)
+static __always_inline void *__do_kmalloc(size_t size, gfp_t flags,
+					  void *caller)
 {
-	kmem_cache_t *cachep;
+	struct kmem_cache *cachep;
 
 	/* If you want to save a few bytes .text space: replace
 	 * __ with kmem_.
@@ -2981,10 +3060,27 @@ void *__kmalloc(size_t size, gfp_t flags
 	cachep = __find_general_cachep(size, flags);
 	if (unlikely(cachep == NULL))
 		return NULL;
-	return __cache_alloc(cachep, flags);
+	return __cache_alloc(cachep, flags, caller);
+}
+
+#ifndef CONFIG_DEBUG_SLAB
+
+void *__kmalloc(size_t size, gfp_t flags)
+{
+	return __do_kmalloc(size, flags, NULL);
 }
 EXPORT_SYMBOL(__kmalloc);
 
+#else
+
+void *__kmalloc_track_caller(size_t size, gfp_t flags, void *caller)
+{
+	return __do_kmalloc(size, flags, caller);
+}
+EXPORT_SYMBOL(__kmalloc_track_caller);
+
+#endif
+
 #ifdef CONFIG_SMP
 /**
  * __alloc_percpu - allocate one copy of the object for every present
@@ -3042,7 +3138,7 @@ EXPORT_SYMBOL(__alloc_percpu);
  * Free an object which was previously allocated from this
  * cache.
  */
-void kmem_cache_free(kmem_cache_t *cachep, void *objp)
+void kmem_cache_free(struct kmem_cache *cachep, void *objp)
 {
 	unsigned long flags;
 
@@ -3063,15 +3159,15 @@ EXPORT_SYMBOL(kmem_cache_free);
  */
 void kfree(const void *objp)
 {
-	kmem_cache_t *c;
+	struct kmem_cache *c;
 	unsigned long flags;
 
 	if (unlikely(!objp))
 		return;
 	local_irq_save(flags);
 	kfree_debugcheck(objp);
-	c = page_get_cache(virt_to_page(objp));
-	mutex_debug_check_no_locks_freed(objp, obj_reallen(c));
+	c = virt_to_cache(objp);
+	mutex_debug_check_no_locks_freed(objp, obj_size(c));
 	__cache_free(c, (void *)objp);
 	local_irq_restore(flags);
 }
@@ -3100,13 +3196,13 @@ void free_percpu(const void *objp)
 EXPORT_SYMBOL(free_percpu);
 #endif
 
-unsigned int kmem_cache_size(kmem_cache_t *cachep)
+unsigned int kmem_cache_size(struct kmem_cache *cachep)
 {
-	return obj_reallen(cachep);
+	return obj_size(cachep);
 }
 EXPORT_SYMBOL(kmem_cache_size);
 
-const char *kmem_cache_name(kmem_cache_t *cachep)
+const char *kmem_cache_name(struct kmem_cache *cachep)
 {
 	return cachep->name;
 }
@@ -3115,7 +3211,7 @@ EXPORT_SYMBOL_GPL(kmem_cache_name);
 /*
  * This initializes kmem_list3 for all nodes.
  */
-static int alloc_kmemlist(kmem_cache_t *cachep)
+static int alloc_kmemlist(struct kmem_cache *cachep)
 {
 	int node;
 	struct kmem_list3 *l3;
@@ -3171,7 +3267,7 @@ static int alloc_kmemlist(kmem_cache_t *
 }
 
 struct ccupdate_struct {
-	kmem_cache_t *cachep;
+	struct kmem_cache *cachep;
 	struct array_cache *new[NR_CPUS];
 };
 
@@ -3181,13 +3277,13 @@ static void do_ccupdate_local(void *info
 	struct array_cache *old;
 
 	check_irq_off();
-	old = ac_data(new->cachep);
+	old = cpu_cache_get(new->cachep);
 
 	new->cachep->array[smp_processor_id()] = new->new[smp_processor_id()];
 	new->new[smp_processor_id()] = old;
 }
 
-static int do_tune_cpucache(kmem_cache_t *cachep, int limit, int batchcount,
+static int do_tune_cpucache(struct kmem_cache *cachep, int limit, int batchcount,
 			    int shared)
 {
 	struct ccupdate_struct new;
@@ -3233,7 +3329,7 @@ static int do_tune_cpucache(kmem_cache_t
 	return 0;
 }
 
-static void enable_cpucache(kmem_cache_t *cachep)
+static void enable_cpucache(struct kmem_cache *cachep)
 {
 	int err;
 	int limit, shared;
@@ -3246,13 +3342,13 @@ static void enable_cpucache(kmem_cache_t
 	 * The numbers are guessed, we should auto-tune as described by
 	 * Bonwick.
 	 */
-	if (cachep->objsize > 131072)
+	if (cachep->buffer_size > 131072)
 		limit = 1;
-	else if (cachep->objsize > PAGE_SIZE)
+	else if (cachep->buffer_size > PAGE_SIZE)
 		limit = 8;
-	else if (cachep->objsize > 1024)
+	else if (cachep->buffer_size > 1024)
 		limit = 24;
-	else if (cachep->objsize > 256)
+	else if (cachep->buffer_size > 256)
 		limit = 54;
 	else
 		limit = 120;
@@ -3267,7 +3363,7 @@ static void enable_cpucache(kmem_cache_t
 	 */
 	shared = 0;
 #ifdef CONFIG_SMP
-	if (cachep->objsize <= PAGE_SIZE)
+	if (cachep->buffer_size <= PAGE_SIZE)
 		shared = 8;
 #endif
 
@@ -3285,7 +3381,7 @@ static void enable_cpucache(kmem_cache_t
 		       cachep->name, -err);
 }
 
-static void drain_array_locked(kmem_cache_t *cachep, struct array_cache *ac,
+static void drain_array_locked(struct kmem_cache *cachep, struct array_cache *ac,
 				int force, int node)
 {
 	int tofree;
@@ -3314,7 +3410,7 @@ static void drain_array_locked(kmem_cach
  * - clear the per-cpu caches for this CPU.
  * - return freeable pages to the main free memory pool.
  *
- * If we cannot acquire the cache chain semaphore then just give up - we'll
+ * If we cannot acquire the cache chain mutex then just give up - we'll
  * try again on the next iteration.
  */
 static void cache_reap(void *unused)
@@ -3322,7 +3418,7 @@ static void cache_reap(void *unused)
 	struct list_head *walk;
 	struct kmem_list3 *l3;
 
-	if (down_trylock(&cache_chain_sem)) {
+	if (!mutex_trylock(&cache_chain_mutex)) {
 		/* Give up. Setup the next iteration. */
 		schedule_delayed_work(&__get_cpu_var(reap_work),
 				      REAPTIMEOUT_CPUC);
@@ -3330,12 +3426,12 @@ static void cache_reap(void *unused)
 	}
 
 	list_for_each(walk, &cache_chain) {
-		kmem_cache_t *searchp;
+		struct kmem_cache *searchp;
 		struct list_head *p;
 		int tofree;
 		struct slab *slabp;
 
-		searchp = list_entry(walk, kmem_cache_t, next);
+		searchp = list_entry(walk, struct kmem_cache, next);
 
 		if (searchp->flags & SLAB_NO_REAP)
 			goto next;
@@ -3347,7 +3443,7 @@ static void cache_reap(void *unused)
 			drain_alien_cache(searchp, l3);
 		spin_lock_irq(&l3->list_lock);
 
-		drain_array_locked(searchp, ac_data(searchp), 0,
+		drain_array_locked(searchp, cpu_cache_get(searchp), 0,
 				   numa_node_id());
 
 		if (time_after(l3->next_reap, jiffies))
@@ -3393,7 +3489,7 @@ static void cache_reap(void *unused)
 		cond_resched();
 	}
 	check_irq_on();
-	up(&cache_chain_sem);
+	mutex_unlock(&cache_chain_mutex);
 	drain_remote_pages();
 	/* Setup the next iteration */
 	schedule_delayed_work(&__get_cpu_var(reap_work), REAPTIMEOUT_CPUC);
@@ -3429,7 +3525,7 @@ static void *s_start(struct seq_file *m,
 	loff_t n = *pos;
 	struct list_head *p;
 
-	down(&cache_chain_sem);
+	mutex_lock(&cache_chain_mutex);
 	if (!n)
 		print_slabinfo_header(m);
 	p = cache_chain.next;
@@ -3438,25 +3534,25 @@ static void *s_start(struct seq_file *m,
 		if (p == &cache_chain)
 			return NULL;
 	}
-	return list_entry(p, kmem_cache_t, next);
+	return list_entry(p, struct kmem_cache, next);
 }
 
 static void *s_next(struct seq_file *m, void *p, loff_t *pos)
 {
-	kmem_cache_t *cachep = p;
+	struct kmem_cache *cachep = p;
 	++*pos;
 	return cachep->next.next == &cache_chain ? NULL
-	    : list_entry(cachep->next.next, kmem_cache_t, next);
+	    : list_entry(cachep->next.next, struct kmem_cache, next);
 }
 
 static void s_stop(struct seq_file *m, void *p)
 {
-	up(&cache_chain_sem);
+	mutex_unlock(&cache_chain_mutex);
 }
 
 static int s_show(struct seq_file *m, void *p)
 {
-	kmem_cache_t *cachep = p;
+	struct kmem_cache *cachep = p;
 	struct list_head *q;
 	struct slab *slabp;
 	unsigned long active_objs;
@@ -3516,7 +3612,7 @@ static int s_show(struct seq_file *m, vo
 		printk(KERN_ERR "slab: cache %s error: %s\n", name, error);
 
 	seq_printf(m, "%-17s %6lu %6lu %6u %4u %4d",
-		   name, active_objs, num_objs, cachep->objsize,
+		   name, active_objs, num_objs, cachep->buffer_size,
 		   cachep->num, (1 << cachep->gfporder));
 	seq_printf(m, " : tunables %4u %4u %4u",
 		   cachep->limit, cachep->batchcount, cachep->shared);
@@ -3603,10 +3699,11 @@ ssize_t slabinfo_write(struct file *file
 		return -EINVAL;
 
 	/* Find the cache in the chain of caches. */
-	down(&cache_chain_sem);
+	mutex_lock(&cache_chain_mutex);
 	res = -EINVAL;
 	list_for_each(p, &cache_chain) {
-		kmem_cache_t *cachep = list_entry(p, kmem_cache_t, next);
+		struct kmem_cache *cachep = list_entry(p, struct kmem_cache,
+						       next);
 
 		if (!strcmp(cachep->name, kbuf)) {
 			if (limit < 1 ||
@@ -3620,7 +3717,7 @@ ssize_t slabinfo_write(struct file *file
 			break;
 		}
 	}
-	up(&cache_chain_sem);
+	mutex_unlock(&cache_chain_mutex);
 	if (res >= 0)
 		res = count;
 	return res;
@@ -3644,5 +3741,5 @@ unsigned int ksize(const void *objp)
 	if (unlikely(objp == NULL))
 		return 0;
 
-	return obj_reallen(page_get_cache(virt_to_page(objp)));
+	return obj_size(virt_to_cache(objp));
 }
diff --git a/mm/swap.c b/mm/swap.c
index cbb48e7..bc2442a 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -174,6 +174,32 @@ void lru_add_drain(void)
 	put_cpu();
 }
 
+#ifdef CONFIG_NUMA
+static void lru_add_drain_per_cpu(void *dummy)
+{
+	lru_add_drain();
+}
+
+/*
+ * Returns 0 for success
+ */
+int lru_add_drain_all(void)
+{
+	return schedule_on_each_cpu(lru_add_drain_per_cpu, NULL);
+}
+
+#else
+
+/*
+ * Returns 0 for success
+ */
+int lru_add_drain_all(void)
+{
+	lru_add_drain();
+	return 0;
+}
+#endif
+
 /*
  * This path almost never happens for VM activity - pages are normally
  * freed via pagevecs.  But it gets used by networking.
diff --git a/mm/swap_state.c b/mm/swap_state.c
index 7b09ac5..db8a3d3 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -27,6 +27,7 @@ static struct address_space_operations s
 	.writepage	= swap_writepage,
 	.sync_page	= block_sync_page,
 	.set_page_dirty	= __set_page_dirty_nobuffers,
+	.migratepage	= migrate_page,
 };
 
 static struct backing_dev_info swap_backing_dev_info = {
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 957fef4..1f9cf0d 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -25,6 +25,7 @@
 #include <linux/rmap.h>
 #include <linux/security.h>
 #include <linux/backing-dev.h>
+#include <linux/mutex.h>
 #include <linux/capability.h>
 #include <linux/syscalls.h>
 
@@ -46,12 +47,12 @@ struct swap_list_t swap_list = {-1, -1};
 
 struct swap_info_struct swap_info[MAX_SWAPFILES];
 
-static DECLARE_MUTEX(swapon_sem);
+static DEFINE_MUTEX(swapon_mutex);
 
 /*
  * We need this because the bdev->unplug_fn can sleep and we cannot
  * hold swap_lock while calling the unplug_fn. And swap_lock
- * cannot be turned into a semaphore.
+ * cannot be turned into a mutex.
  */
 static DECLARE_RWSEM(swap_unplug_sem);
 
@@ -553,6 +554,15 @@ static int unuse_mm(struct mm_struct *mm
 	return 0;
 }
 
+#ifdef CONFIG_MIGRATION
+int remove_vma_swap(struct vm_area_struct *vma, struct page *page)
+{
+	swp_entry_t entry = { .val = page_private(page) };
+
+	return unuse_vma(vma, entry, page);
+}
+#endif
+
 /*
  * Scan swap_map from current position to next entry still in use.
  * Recycle to start on reaching the end, returning 0 when empty.
@@ -645,6 +655,7 @@ static int try_to_unuse(unsigned int typ
 		 */
 		swap_map = &si->swap_map[i];
 		entry = swp_entry(type, i);
+again:
 		page = read_swap_cache_async(entry, NULL, 0);
 		if (!page) {
 			/*
@@ -679,6 +690,12 @@ static int try_to_unuse(unsigned int typ
 		wait_on_page_locked(page);
 		wait_on_page_writeback(page);
 		lock_page(page);
+		if (!PageSwapCache(page)) {
+			/* Page migration has occured */
+			unlock_page(page);
+			page_cache_release(page);
+			goto again;
+		}
 		wait_on_page_writeback(page);
 
 		/*
@@ -1161,7 +1178,7 @@ asmlinkage long sys_swapoff(const char _
 	up_write(&swap_unplug_sem);
 
 	destroy_swap_extents(p);
-	down(&swapon_sem);
+	mutex_lock(&swapon_mutex);
 	spin_lock(&swap_lock);
 	drain_mmlist();
 
@@ -1180,7 +1197,7 @@ asmlinkage long sys_swapoff(const char _
 	p->swap_map = NULL;
 	p->flags = 0;
 	spin_unlock(&swap_lock);
-	up(&swapon_sem);
+	mutex_unlock(&swapon_mutex);
 	vfree(swap_map);
 	inode = mapping->host;
 	if (S_ISBLK(inode->i_mode)) {
@@ -1209,7 +1226,7 @@ static void *swap_start(struct seq_file 
 	int i;
 	loff_t l = *pos;
 
-	down(&swapon_sem);
+	mutex_lock(&swapon_mutex);
 
 	for (i = 0; i < nr_swapfiles; i++, ptr++) {
 		if (!(ptr->flags & SWP_USED) || !ptr->swap_map)
@@ -1238,7 +1255,7 @@ static void *swap_next(struct seq_file *
 
 static void swap_stop(struct seq_file *swap, void *v)
 {
-	up(&swapon_sem);
+	mutex_unlock(&swapon_mutex);
 }
 
 static int swap_show(struct seq_file *swap, void *v)
@@ -1540,7 +1557,7 @@ asmlinkage long sys_swapon(const char __
 		goto bad_swap;
 	}
 
-	down(&swapon_sem);
+	mutex_lock(&swapon_mutex);
 	spin_lock(&swap_lock);
 	p->flags = SWP_ACTIVE;
 	nr_swap_pages += nr_good_pages;
@@ -1566,7 +1583,7 @@ asmlinkage long sys_swapon(const char __
 		swap_info[prev].next = p - swap_info;
 	}
 	spin_unlock(&swap_lock);
-	up(&swapon_sem);
+	mutex_unlock(&swapon_mutex);
 	error = 0;
 	goto out;
 bad_swap:
diff --git a/mm/vmscan.c b/mm/vmscan.c
index bf903b2..5a61080 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -71,6 +71,9 @@ struct scan_control {
 
 	int may_writepage;
 
+	/* Can pages be swapped as part of reclaim? */
+	int may_swap;
+
 	/* This context's SWAP_CLUSTER_MAX. If freeing memory for
 	 * suspend, we effectively ignore SWAP_CLUSTER_MAX.
 	 * In this context, it doesn't matter that we scan the
@@ -458,6 +461,8 @@ static int shrink_list(struct list_head 
 		 * Try to allocate it some swap space here.
 		 */
 		if (PageAnon(page) && !PageSwapCache(page)) {
+			if (!sc->may_swap)
+				goto keep_locked;
 			if (!add_to_swap(page, GFP_ATOMIC))
 				goto activate_locked;
 		}
@@ -472,7 +477,13 @@ static int shrink_list(struct list_head 
 		 * processes. Try to unmap it here.
 		 */
 		if (page_mapped(page) && mapping) {
-			switch (try_to_unmap(page)) {
+			/*
+			 * No unmapping if we do not swap
+			 */
+			if (!sc->may_swap)
+				goto keep_locked;
+
+			switch (try_to_unmap(page, 0)) {
 			case SWAP_FAIL:
 				goto activate_locked;
 			case SWAP_AGAIN:
@@ -487,7 +498,7 @@ static int shrink_list(struct list_head 
 				goto keep_locked;
 			if (!may_enter_fs)
 				goto keep_locked;
-			if (laptop_mode && !sc->may_writepage)
+			if (!sc->may_writepage)
 				goto keep_locked;
 
 			/* Page is dirty, try to write it out here */
@@ -586,7 +597,7 @@ static inline void move_to_lru(struct pa
 }
 
 /*
- * Add isolated pages on the list back to the LRU
+ * Add isolated pages on the list back to the LRU.
  *
  * returns the number of pages put back.
  */
@@ -604,6 +615,15 @@ int putback_lru_pages(struct list_head *
 }
 
 /*
+ * Non migratable page
+ */
+int fail_migrate_page(struct page *newpage, struct page *page)
+{
+	return -EIO;
+}
+EXPORT_SYMBOL(fail_migrate_page);
+
+/*
  * swapout a single page
  * page is locked upon entry, unlocked on exit
  */
@@ -612,7 +632,7 @@ static int swap_page(struct page *page)
 	struct address_space *mapping = page_mapping(page);
 
 	if (page_mapped(page) && mapping)
-		if (try_to_unmap(page) != SWAP_SUCCESS)
+		if (try_to_unmap(page, 0) != SWAP_SUCCESS)
 			goto unlock_retry;
 
 	if (PageDirty(page)) {
@@ -648,6 +668,167 @@ unlock_retry:
 retry:
 	return -EAGAIN;
 }
+EXPORT_SYMBOL(swap_page);
+
+/*
+ * Page migration was first developed in the context of the memory hotplug
+ * project. The main authors of the migration code are:
+ *
+ * IWAMOTO Toshihiro <iwamoto@valinux.co.jp>
+ * Hirokazu Takahashi <taka@valinux.co.jp>
+ * Dave Hansen <haveblue@us.ibm.com>
+ * Christoph Lameter <clameter@sgi.com>
+ */
+
+/*
+ * Remove references for a page and establish the new page with the correct
+ * basic settings to be able to stop accesses to the page.
+ */
+int migrate_page_remove_references(struct page *newpage,
+				struct page *page, int nr_refs)
+{
+	struct address_space *mapping = page_mapping(page);
+	struct page **radix_pointer;
+
+	/*
+	 * Avoid doing any of the following work if the page count
+	 * indicates that the page is in use or truncate has removed
+	 * the page.
+	 */
+	if (!mapping || page_mapcount(page) + nr_refs != page_count(page))
+		return 1;
+
+	/*
+	 * Establish swap ptes for anonymous pages or destroy pte
+	 * maps for files.
+	 *
+	 * In order to reestablish file backed mappings the fault handlers
+	 * will take the radix tree_lock which may then be used to stop
+  	 * processses from accessing this page until the new page is ready.
+	 *
+	 * A process accessing via a swap pte (an anonymous page) will take a
+	 * page_lock on the old page which will block the process until the
+	 * migration attempt is complete. At that time the PageSwapCache bit
+	 * will be examined. If the page was migrated then the PageSwapCache
+	 * bit will be clear and the operation to retrieve the page will be
+	 * retried which will find the new page in the radix tree. Then a new
+	 * direct mapping may be generated based on the radix tree contents.
+	 *
+	 * If the page was not migrated then the PageSwapCache bit
+	 * is still set and the operation may continue.
+	 */
+	try_to_unmap(page, 1);
+
+	/*
+	 * Give up if we were unable to remove all mappings.
+	 */
+	if (page_mapcount(page))
+		return 1;
+
+	write_lock_irq(&mapping->tree_lock);
+
+	radix_pointer = (struct page **)radix_tree_lookup_slot(
+						&mapping->page_tree,
+						page_index(page));
+
+	if (!page_mapping(page) || page_count(page) != nr_refs ||
+			*radix_pointer != page) {
+		write_unlock_irq(&mapping->tree_lock);
+		return 1;
+	}
+
+	/*
+	 * Now we know that no one else is looking at the page.
+	 *
+	 * Certain minimal information about a page must be available
+	 * in order for other subsystems to properly handle the page if they
+	 * find it through the radix tree update before we are finished
+	 * copying the page.
+	 */
+	get_page(newpage);
+	newpage->index = page->index;
+	newpage->mapping = page->mapping;
+	if (PageSwapCache(page)) {
+		SetPageSwapCache(newpage);
+		set_page_private(newpage, page_private(page));
+	}
+
+	*radix_pointer = newpage;
+	__put_page(page);
+	write_unlock_irq(&mapping->tree_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(migrate_page_remove_references);
+
+/*
+ * Copy the page to its new location
+ */
+void migrate_page_copy(struct page *newpage, struct page *page)
+{
+	copy_highpage(newpage, page);
+
+	if (PageError(page))
+		SetPageError(newpage);
+	if (PageReferenced(page))
+		SetPageReferenced(newpage);
+	if (PageUptodate(page))
+		SetPageUptodate(newpage);
+	if (PageActive(page))
+		SetPageActive(newpage);
+	if (PageChecked(page))
+		SetPageChecked(newpage);
+	if (PageMappedToDisk(page))
+		SetPageMappedToDisk(newpage);
+
+	if (PageDirty(page)) {
+		clear_page_dirty_for_io(page);
+		set_page_dirty(newpage);
+ 	}
+
+	ClearPageSwapCache(page);
+	ClearPageActive(page);
+	ClearPagePrivate(page);
+	set_page_private(page, 0);
+	page->mapping = NULL;
+
+	/*
+	 * If any waiters have accumulated on the new page then
+	 * wake them up.
+	 */
+	if (PageWriteback(newpage))
+		end_page_writeback(newpage);
+}
+EXPORT_SYMBOL(migrate_page_copy);
+
+/*
+ * Common logic to directly migrate a single page suitable for
+ * pages that do not use PagePrivate.
+ *
+ * Pages are locked upon entry and exit.
+ */
+int migrate_page(struct page *newpage, struct page *page)
+{
+	BUG_ON(PageWriteback(page));	/* Writeback must be complete */
+
+	if (migrate_page_remove_references(newpage, page, 2))
+		return -EAGAIN;
+
+	migrate_page_copy(newpage, page);
+
+	/*
+	 * Remove auxiliary swap entries and replace
+	 * them with real ptes.
+	 *
+	 * Note that a real pte entry will allow processes that are not
+	 * waiting on the page lock to use the new page via the page tables
+	 * before the new page is unlocked.
+	 */
+	remove_from_swap(newpage);
+	return 0;
+}
+EXPORT_SYMBOL(migrate_page);
+
 /*
  * migrate_pages
  *
@@ -661,11 +842,6 @@ retry:
  * are movable anymore because t has become empty
  * or no retryable pages exist anymore.
  *
- * SIMPLIFIED VERSION: This implementation of migrate_pages
- * is only swapping out pages and never touches the second
- * list. The direct migration patchset
- * extends this function to avoid the use of swap.
- *
  * Return: Number of pages not migrated when "to" ran empty.
  */
 int migrate_pages(struct list_head *from, struct list_head *to,
@@ -686,6 +862,9 @@ redo:
 	retry = 0;
 
 	list_for_each_entry_safe(page, page2, from, lru) {
+		struct page *newpage = NULL;
+		struct address_space *mapping;
+
 		cond_resched();
 
 		rc = 0;
@@ -693,6 +872,9 @@ redo:
 			/* page was freed from under us. So we are done. */
 			goto next;
 
+		if (to && list_empty(to))
+			break;
+
 		/*
 		 * Skip locked pages during the first two passes to give the
 		 * functions holding the lock time to release the page. Later we
@@ -729,12 +911,69 @@ redo:
 			}
 		}
 
+		if (!to) {
+			rc = swap_page(page);
+			goto next;
+		}
+
+		newpage = lru_to_page(to);
+		lock_page(newpage);
+
 		/*
-		 * Page is properly locked and writeback is complete.
+		 * Pages are properly locked and writeback is complete.
 		 * Try to migrate the page.
 		 */
-		rc = swap_page(page);
-		goto next;
+		mapping = page_mapping(page);
+		if (!mapping)
+			goto unlock_both;
+
+		if (mapping->a_ops->migratepage) {
+			rc = mapping->a_ops->migratepage(newpage, page);
+			goto unlock_both;
+                }
+
+		/*
+		 * Trigger writeout if page is dirty
+		 */
+		if (PageDirty(page)) {
+			switch (pageout(page, mapping)) {
+			case PAGE_KEEP:
+			case PAGE_ACTIVATE:
+				goto unlock_both;
+
+			case PAGE_SUCCESS:
+				unlock_page(newpage);
+				goto next;
+
+			case PAGE_CLEAN:
+				; /* try to migrate the page below */
+			}
+                }
+		/*
+		 * If we have no buffer or can release the buffer
+		 * then do a simple migration.
+		 */
+		if (!page_has_buffers(page) ||
+		    try_to_release_page(page, GFP_KERNEL)) {
+			rc = migrate_page(newpage, page);
+			goto unlock_both;
+		}
+
+		/*
+		 * On early passes with mapped pages simply
+		 * retry. There may be a lock held for some
+		 * buffers that may go away. Later
+		 * swap them out.
+		 */
+		if (pass > 4) {
+			unlock_page(newpage);
+			newpage = NULL;
+			rc = swap_page(page);
+			goto next;
+		}
+
+unlock_both:
+		unlock_page(newpage);
 
 unlock_page:
 		unlock_page(page);
@@ -747,7 +986,10 @@ next:
 			list_move(&page->lru, failed);
 			nr_failed++;
 		} else {
-			/* Success */
+			if (newpage) {
+				/* Successful migration. Return page to LRU */
+				move_to_lru(newpage);
+			}
 			list_move(&page->lru, moved);
 		}
 	}
@@ -760,46 +1002,33 @@ next:
 	return nr_failed + retry;
 }
 
-static void lru_add_drain_per_cpu(void *dummy)
-{
-	lru_add_drain();
-}
-
 /*
  * Isolate one page from the LRU lists and put it on the
- * indicated list. Do necessary cache draining if the
- * page is not on the LRU lists yet.
+ * indicated list with elevated refcount.
  *
  * Result:
  *  0 = page not on LRU list
  *  1 = page removed from LRU list and added to the specified list.
- * -ENOENT = page is being freed elsewhere.
  */
 int isolate_lru_page(struct page *page)
 {
-	int rc = 0;
-	struct zone *zone = page_zone(page);
+	int ret = 0;
 
-redo:
-	spin_lock_irq(&zone->lru_lock);
-	rc = __isolate_lru_page(page);
-	if (rc == 1) {
-		if (PageActive(page))
-			del_page_from_active_list(zone, page);
-		else
-			del_page_from_inactive_list(zone, page);
-	}
-	spin_unlock_irq(&zone->lru_lock);
-	if (rc == 0) {
-		/*
-		 * Maybe this page is still waiting for a cpu to drain it
-		 * from one of the lru lists?
-		 */
-		rc = schedule_on_each_cpu(lru_add_drain_per_cpu, NULL);
-		if (rc == 0 && PageLRU(page))
-			goto redo;
+	if (PageLRU(page)) {
+		struct zone *zone = page_zone(page);
+		spin_lock_irq(&zone->lru_lock);
+		if (TestClearPageLRU(page)) {
+			ret = 1;
+			get_page(page);
+			if (PageActive(page))
+				del_page_from_active_list(zone, page);
+			else
+				del_page_from_inactive_list(zone, page);
+		}
+		spin_unlock_irq(&zone->lru_lock);
 	}
-	return rc;
+
+	return ret;
 }
 #endif
 
@@ -831,18 +1060,20 @@ static int isolate_lru_pages(int nr_to_s
 		page = lru_to_page(src);
 		prefetchw_prev_lru_page(page, src, flags);
 
-		switch (__isolate_lru_page(page)) {
-		case 1:
-			/* Succeeded to isolate page */
-			list_move(&page->lru, dst);
-			nr_taken++;
-			break;
-		case -ENOENT:
-			/* Not possible to isolate */
-			list_move(&page->lru, src);
-			break;
-		default:
+		if (!TestClearPageLRU(page))
 			BUG();
+		list_del(&page->lru);
+		if (get_page_testone(page)) {
+			/*
+			 * It is being freed elsewhere
+			 */
+			__put_page(page);
+			SetPageLRU(page);
+			list_add(&page->lru, src);
+			continue;
+		} else {
+			list_add(&page->lru, dst);
+			nr_taken++;
 		}
 	}
 
@@ -1176,7 +1407,8 @@ int try_to_free_pages(struct zone **zone
 	int i;
 
 	sc.gfp_mask = gfp_mask;
-	sc.may_writepage = 0;
+	sc.may_writepage = !laptop_mode;
+	sc.may_swap = 1;
 
 	inc_page_state(allocstall);
 
@@ -1278,7 +1510,8 @@ loop_again:
 	total_scanned = 0;
 	total_reclaimed = 0;
 	sc.gfp_mask = GFP_KERNEL;
-	sc.may_writepage = 0;
+	sc.may_writepage = !laptop_mode;
+	sc.may_swap = 1;
 	sc.nr_mapped = read_page_state(nr_mapped);
 
 	inc_page_state(pageoutrun);
@@ -1576,3 +1809,115 @@ static int __init kswapd_init(void)
 }
 
 module_init(kswapd_init)
+
+#ifdef CONFIG_NUMA
+/*
+ * Zone reclaim mode
+ *
+ * If non-zero call zone_reclaim when the number of free pages falls below
+ * the watermarks.
+ *
+ * In the future we may add flags to the mode. However, the page allocator
+ * should only have to check that zone_reclaim_mode != 0 before calling
+ * zone_reclaim().
+ */
+int zone_reclaim_mode __read_mostly;
+
+#define RECLAIM_OFF 0
+#define RECLAIM_ZONE (1<<0)	/* Run shrink_cache on the zone */
+#define RECLAIM_WRITE (1<<1)	/* Writeout pages during reclaim */
+#define RECLAIM_SWAP (1<<2)	/* Swap pages out during reclaim */
+#define RECLAIM_SLAB (1<<3)	/* Do a global slab shrink if the zone is out of memory */
+
+/*
+ * Mininum time between zone reclaim scans
+ */
+int zone_reclaim_interval __read_mostly = 30*HZ;
+
+/*
+ * Priority for ZONE_RECLAIM. This determines the fraction of pages
+ * of a node considered for each zone_reclaim. 4 scans 1/16th of
+ * a zone.
+ */
+#define ZONE_RECLAIM_PRIORITY 4
+
+/*
+ * Try to free up some pages from this zone through reclaim.
+ */
+int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
+{
+	int nr_pages;
+	struct task_struct *p = current;
+	struct reclaim_state reclaim_state;
+	struct scan_control sc;
+	cpumask_t mask;
+	int node_id;
+
+	if (time_before(jiffies,
+		zone->last_unsuccessful_zone_reclaim + zone_reclaim_interval))
+			return 0;
+
+	if (!(gfp_mask & __GFP_WAIT) ||
+		zone->all_unreclaimable ||
+		atomic_read(&zone->reclaim_in_progress) > 0)
+			return 0;
+
+	node_id = zone->zone_pgdat->node_id;
+	mask = node_to_cpumask(node_id);
+	if (!cpus_empty(mask) && node_id != numa_node_id())
+		return 0;
+
+	sc.may_writepage = !!(zone_reclaim_mode & RECLAIM_WRITE);
+	sc.may_swap = !!(zone_reclaim_mode & RECLAIM_SWAP);
+	sc.nr_scanned = 0;
+	sc.nr_reclaimed = 0;
+	sc.priority = ZONE_RECLAIM_PRIORITY + 1;
+	sc.nr_mapped = read_page_state(nr_mapped);
+	sc.gfp_mask = gfp_mask;
+
+	disable_swap_token();
+
+	nr_pages = 1 << order;
+	if (nr_pages > SWAP_CLUSTER_MAX)
+		sc.swap_cluster_max = nr_pages;
+	else
+		sc.swap_cluster_max = SWAP_CLUSTER_MAX;
+
+	cond_resched();
+	p->flags |= PF_MEMALLOC;
+	reclaim_state.reclaimed_slab = 0;
+	p->reclaim_state = &reclaim_state;
+
+	/*
+	 * Free memory by calling shrink zone with increasing priorities
+	 * until we have enough memory freed.
+	 */
+	do {
+		sc.priority--;
+		shrink_zone(zone, &sc);
+
+	} while (sc.nr_reclaimed < nr_pages && sc.priority > 0);
+
+	if (sc.nr_reclaimed < nr_pages && (zone_reclaim_mode & RECLAIM_SLAB)) {
+		/*
+		 * shrink_slab does not currently allow us to determine
+		 * how many pages were freed in the zone. So we just
+		 * shake the slab and then go offnode for a single allocation.
+		 *
+		 * shrink_slab will free memory on all zones and may take
+		 * a long time.
+		 */
+		shrink_slab(sc.nr_scanned, gfp_mask, order);
+		sc.nr_reclaimed = 1;    /* Avoid getting the off node timeout */
+	}
+
+	p->reclaim_state = NULL;
+	current->flags &= ~PF_MEMALLOC;
+
+	if (sc.nr_reclaimed == 0)
+		zone->last_unsuccessful_zone_reclaim = jiffies;
+
+	return sc.nr_reclaimed >= nr_pages;
+}
+#endif
+
diff --git a/net/Kconfig b/net/Kconfig
index 9296b26..bc603d9 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -150,6 +150,7 @@ endif
 
 source "net/dccp/Kconfig"
 source "net/sctp/Kconfig"
+source "net/tipc/Kconfig"
 source "net/atm/Kconfig"
 source "net/bridge/Kconfig"
 source "net/8021q/Kconfig"
@@ -159,7 +160,6 @@ source "net/ipx/Kconfig"
 source "drivers/net/appletalk/Kconfig"
 source "net/x25/Kconfig"
 source "net/lapb/Kconfig"
-source "net/tipc/Kconfig"
 
 config NET_DIVERT
 	bool "Frame Diverter (EXPERIMENTAL)"
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index ba44288..da687c8 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -104,6 +104,7 @@ static void destroy_nbp(struct net_bridg
 {
 	struct net_device *dev = p->dev;
 
+	dev->br_port = NULL;
 	p->br = NULL;
 	p->dev = NULL;
 	dev_put(dev);
@@ -118,13 +119,24 @@ static void destroy_nbp_rcu(struct rcu_h
 	destroy_nbp(p);
 }
 
-/* called with RTNL */
+/* Delete port(interface) from bridge is done in two steps.
+ * via RCU. First step, marks device as down. That deletes
+ * all the timers and stops new packets from flowing through.
+ *
+ * Final cleanup doesn't occur until after all CPU's finished
+ * processing packets.
+ *
+ * Protected from multiple admin operations by RTNL mutex
+ */
 static void del_nbp(struct net_bridge_port *p)
 {
 	struct net_bridge *br = p->br;
 	struct net_device *dev = p->dev;
 
-	dev->br_port = NULL;
+	/* Race between RTNL notify and RCU callback */
+	if (p->deleted)
+		return;
+
 	dev_set_promiscuity(dev, -1);
 
 	cancel_delayed_work(&p->carrier_check);
@@ -132,16 +144,13 @@ static void del_nbp(struct net_bridge_po
 
 	spin_lock_bh(&br->lock);
 	br_stp_disable_port(p);
+	p->deleted = 1;
 	spin_unlock_bh(&br->lock);
 
 	br_fdb_delete_by_port(br, p);
 
 	list_del_rcu(&p->list);
 
-	del_timer_sync(&p->message_age_timer);
-	del_timer_sync(&p->forward_delay_timer);
-	del_timer_sync(&p->hold_timer);
-	
 	call_rcu(&p->rcu, destroy_nbp_rcu);
 }
 
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index c5bd631..e330b17 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -68,6 +68,7 @@ struct net_bridge_port
 	/* STP */
 	u8				priority;
 	u8				state;
+	u8				deleted;
 	u16				port_no;
 	unsigned char			topology_change_ack;
 	unsigned char			config_pending;
diff --git a/net/bridge/netfilter/ebt_ip.c b/net/bridge/netfilter/ebt_ip.c
index f158fe6..dc5d0b2 100644
--- a/net/bridge/netfilter/ebt_ip.c
+++ b/net/bridge/netfilter/ebt_ip.c
@@ -92,7 +92,9 @@ static int ebt_ip_check(const char *tabl
 		if (info->invflags & EBT_IP_PROTO)
 			return -EINVAL;
 		if (info->protocol != IPPROTO_TCP &&
-		    info->protocol != IPPROTO_UDP)
+		    info->protocol != IPPROTO_UDP &&
+		    info->protocol != IPPROTO_SCTP &&
+		    info->protocol != IPPROTO_DCCP)
 			 return -EINVAL;
 	}
 	if (info->bitmask & EBT_IP_DPORT && info->dport[0] > info->dport[1])
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
index a29c123..0128fbb 100644
--- a/net/bridge/netfilter/ebt_log.c
+++ b/net/bridge/netfilter/ebt_log.c
@@ -95,7 +95,9 @@ ebt_log_packet(unsigned int pf, unsigned
 		       "tos=0x%02X, IP proto=%d", NIPQUAD(ih->saddr),
 		       NIPQUAD(ih->daddr), ih->tos, ih->protocol);
 		if (ih->protocol == IPPROTO_TCP ||
-		    ih->protocol == IPPROTO_UDP) {
+		    ih->protocol == IPPROTO_UDP ||
+		    ih->protocol == IPPROTO_SCTP ||
+		    ih->protocol == IPPROTO_DCCP) {
 			struct tcpudphdr _ports, *pptr;
 
 			pptr = skb_header_pointer(skb, ih->ihl*4,
diff --git a/net/core/dev.c b/net/core/dev.c
index fd070a0..ffb8207 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2543,13 +2543,14 @@ int dev_ioctl(unsigned int cmd, void __u
 		case SIOCBONDENSLAVE:
 		case SIOCBONDRELEASE:
 		case SIOCBONDSETHWADDR:
-		case SIOCBONDSLAVEINFOQUERY:
-		case SIOCBONDINFOQUERY:
 		case SIOCBONDCHANGEACTIVE:
 		case SIOCBRADDIF:
 		case SIOCBRDELIF:
 			if (!capable(CAP_NET_ADMIN))
 				return -EPERM;
+			/* fall through */
+		case SIOCBONDSLAVEINFOQUERY:
+		case SIOCBONDINFOQUERY:
 			dev_load(ifr.ifr_name);
 			rtnl_lock();
 			ret = dev_ifsioc(&ifr, cmd);
diff --git a/net/core/filter.c b/net/core/filter.c
index a52665f..93fbd01 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -64,7 +64,7 @@ static inline void *load_pointer(struct 
 }
 
 /**
- *	sk_run_filter	- 	run a filter on a socket
+ *	sk_run_filter - run a filter on a socket
  *	@skb: buffer to run the filter on
  *	@filter: filter to apply
  *	@flen: length of filter
@@ -74,13 +74,12 @@ static inline void *load_pointer(struct 
  * filtering, filter is the array of filter instructions, and
  * len is the number of filter blocks in the array.
  */
- 
 unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
 {
 	struct sock_filter *fentry;	/* We walk down these */
 	void *ptr;
-	u32 A = 0;	   		/* Accumulator */
-	u32 X = 0;   			/* Index Register */
+	u32 A = 0;			/* Accumulator */
+	u32 X = 0;			/* Index Register */
 	u32 mem[BPF_MEMWORDS];		/* Scratch Memory Store */
 	u32 tmp;
 	int k;
@@ -175,7 +174,7 @@ unsigned int sk_run_filter(struct sk_buf
 			continue;
 		case BPF_LD|BPF_W|BPF_ABS:
 			k = fentry->k;
- load_w:
+load_w:
 			ptr = load_pointer(skb, k, 4, &tmp);
 			if (ptr != NULL) {
 				A = ntohl(*(u32 *)ptr);
@@ -184,7 +183,7 @@ unsigned int sk_run_filter(struct sk_buf
 			break;
 		case BPF_LD|BPF_H|BPF_ABS:
 			k = fentry->k;
- load_h:
+load_h:
 			ptr = load_pointer(skb, k, 2, &tmp);
 			if (ptr != NULL) {
 				A = ntohs(*(u16 *)ptr);
@@ -374,7 +373,7 @@ int sk_chk_filter(struct sock_filter *fi
 		case BPF_JMP|BPF_JSET|BPF_K:
 		case BPF_JMP|BPF_JSET|BPF_X:
 			/* for conditionals both must be safe */
- 			if (pc + ftest->jt + 1 >= flen ||
+			if (pc + ftest->jt + 1 >= flen ||
 			    pc + ftest->jf + 1 >= flen)
 				return -EINVAL;
 			break;
@@ -384,7 +383,7 @@ int sk_chk_filter(struct sock_filter *fi
 		}
 	}
 
-        return (BPF_CLASS(filter[flen - 1].code) == BPF_RET) ? 0 : -EINVAL;
+	return (BPF_CLASS(filter[flen - 1].code) == BPF_RET) ? 0 : -EINVAL;
 }
 
 /**
@@ -404,8 +403,8 @@ int sk_attach_filter(struct sock_fprog *
 	int err;
 
 	/* Make sure new filter is there and in the right amounts. */
-        if (fprog->filter == NULL)
-                return -EINVAL;
+	if (fprog->filter == NULL)
+		return -EINVAL;
 
 	fp = sock_kmalloc(sk, fsize+sizeof(*fp), GFP_KERNEL);
 	if (!fp)
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 281a632..ea51f8d 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -703,7 +703,7 @@ int netpoll_setup(struct netpoll *np)
 		}
 	}
 
-	if (!memcmp(np->local_mac, "\0\0\0\0\0\0", 6) && ndev->dev_addr)
+	if (is_zero_ether_addr(np->local_mac) && ndev->dev_addr)
 		memcpy(np->local_mac, ndev->dev_addr, 6);
 
 	if (!np->local_ip) {
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 3906312..da16f8f 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -139,6 +139,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/wait.h>
+#include <linux/etherdevice.h>
 #include <net/checksum.h>
 #include <net/ipv6.h>
 #include <net/addrconf.h>
@@ -281,8 +282,8 @@ struct pktgen_dev {
         __u32 src_mac_count; /* How many MACs to iterate through */
         __u32 dst_mac_count; /* How many MACs to iterate through */
         
-        unsigned char dst_mac[6];
-        unsigned char src_mac[6];
+        unsigned char dst_mac[ETH_ALEN];
+        unsigned char src_mac[ETH_ALEN];
         
         __u32 cur_dst_mac_offset;
         __u32 cur_src_mac_offset;
@@ -594,16 +595,9 @@ static int pktgen_if_show(struct seq_fil
 
 	seq_puts(seq, "     src_mac: ");
 
-	if ((pkt_dev->src_mac[0] == 0) && 
-	    (pkt_dev->src_mac[1] == 0) && 
-	    (pkt_dev->src_mac[2] == 0) && 
-	    (pkt_dev->src_mac[3] == 0) && 
-	    (pkt_dev->src_mac[4] == 0) && 
-	    (pkt_dev->src_mac[5] == 0)) 
-
+	if (is_zero_ether_addr(pkt_dev->src_mac))
 		for (i = 0; i < 6; i++) 
 			seq_printf(seq,  "%02X%s", pkt_dev->odev->dev_addr[i], i == 5 ? "  " : ":");
-
 	else 
 		for (i = 0; i < 6; i++) 
 			seq_printf(seq,  "%02X%s", pkt_dev->src_mac[i], i == 5 ? "  " : ":");
@@ -1189,9 +1183,9 @@ static ssize_t pktgen_if_write(struct fi
 	}
 	if (!strcmp(name, "dst_mac")) {
 		char *v = valstr;
-                unsigned char old_dmac[6];
+		unsigned char old_dmac[ETH_ALEN];
 		unsigned char *m = pkt_dev->dst_mac;
-                memcpy(old_dmac, pkt_dev->dst_mac, 6);
+		memcpy(old_dmac, pkt_dev->dst_mac, ETH_ALEN);
                 
 		len = strn_len(&user_buffer[i], sizeof(valstr) - 1);
                 if (len < 0) { return len; }
@@ -1220,8 +1214,8 @@ static ssize_t pktgen_if_write(struct fi
 		}
 
 		/* Set up Dest MAC */
-                if (memcmp(old_dmac, pkt_dev->dst_mac, 6) != 0) 
-                        memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, 6);
+		if (compare_ether_addr(old_dmac, pkt_dev->dst_mac))
+			memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, ETH_ALEN);
                 
 		sprintf(pg_result, "OK: dstmac");
 		return count;
@@ -1560,17 +1554,11 @@ static void pktgen_setup_inject(struct p
         
         /* Default to the interface's mac if not explicitly set. */
 
-	if ((pkt_dev->src_mac[0] == 0) && 
-	    (pkt_dev->src_mac[1] == 0) && 
-	    (pkt_dev->src_mac[2] == 0) && 
-	    (pkt_dev->src_mac[3] == 0) && 
-	    (pkt_dev->src_mac[4] == 0) && 
-	    (pkt_dev->src_mac[5] == 0)) {
+	if (is_zero_ether_addr(pkt_dev->src_mac))
+	       memcpy(&(pkt_dev->hh[6]), pkt_dev->odev->dev_addr, ETH_ALEN);
 
-	       memcpy(&(pkt_dev->hh[6]), pkt_dev->odev->dev_addr, 6);
-       }
         /* Set up Dest MAC */
-        memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, 6);
+	memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, ETH_ALEN);
 
         /* Set up pkt size */
         pkt_dev->cur_pkt_size = pkt_dev->min_pkt_size;
@@ -1872,13 +1860,14 @@ static struct sk_buff *fill_packet_ipv4(
 	 */
 	mod_cur_headers(pkt_dev);
 
-	skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16, GFP_ATOMIC);
+	datalen = (odev->hard_header_len + 16) & ~0xf;
+	skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + datalen, GFP_ATOMIC);
 	if (!skb) {
 		sprintf(pkt_dev->result, "No memory");
 		return NULL;
 	}
 
-	skb_reserve(skb, 16);
+	skb_reserve(skb, datalen);
 
 	/*  Reserve for ethernet and IP header  */
 	eth = (__u8 *) skb_push(skb, 14);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index d0732e9..6766f11 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -135,13 +135,15 @@ void skb_under_panic(struct sk_buff *skb
 struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
 			    int fclone)
 {
+	kmem_cache_t *cache;
 	struct skb_shared_info *shinfo;
 	struct sk_buff *skb;
 	u8 *data;
 
+	cache = fclone ? skbuff_fclone_cache : skbuff_head_cache;
+
 	/* Get the HEAD */
-	skb = kmem_cache_alloc(fclone ? skbuff_fclone_cache : skbuff_head_cache,
-				gfp_mask & ~__GFP_DMA);
+	skb = kmem_cache_alloc(cache, gfp_mask & ~__GFP_DMA);
 	if (!skb)
 		goto out;
 
@@ -180,7 +182,7 @@ struct sk_buff *__alloc_skb(unsigned int
 out:
 	return skb;
 nodata:
-	kmem_cache_free(skbuff_head_cache, skb);
+	kmem_cache_free(cache, skb);
 	skb = NULL;
 	goto out;
 }
diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c
index ce9cb77..2c77daf 100644
--- a/net/dccp/ackvec.c
+++ b/net/dccp/ackvec.c
@@ -144,7 +144,7 @@ static inline int dccp_ackvec_set_buf_he
 						 const unsigned char state)
 {
 	unsigned int gap;
-	signed long new_head;
+	long new_head;
 
 	if (av->dccpav_vec_len + packets > av->dccpav_buf_len)
 		return -ENOBUFS;
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 00f9832..dc0487b 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -119,7 +119,8 @@ int dccp_v4_connect(struct sock *sk, str
 	if (err != 0)
 		goto failure;
 
-	err = ip_route_newports(&rt, inet->sport, inet->dport, sk);
+	err = ip_route_newports(&rt, IPPROTO_DCCP, inet->sport, inet->dport,
+	                        sk);
 	if (err != 0)
 		goto failure;
 
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index df07425..80c4d04 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -468,6 +468,7 @@ static int dccp_v6_send_response(struct 
 done:
         if (opt && opt != np->opt)
 		sock_kfree_s(sk, opt, opt->tot_len);
+	dst_release(dst);
 	return err;
 }
 
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 7a12180..960aa78 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -350,6 +350,7 @@ int ieee80211_rx(struct ieee80211_device
 	u8 src[ETH_ALEN];
 	struct ieee80211_crypt_data *crypt = NULL;
 	int keyidx = 0;
+	int can_be_decrypted = 0;
 
 	hdr = (struct ieee80211_hdr_4addr *)skb->data;
 	stats = &ieee->stats;
@@ -410,12 +411,23 @@ int ieee80211_rx(struct ieee80211_device
 		return 1;
 	}
 
-	if (is_multicast_ether_addr(hdr->addr1)
-	    ? ieee->host_mc_decrypt : ieee->host_decrypt) {
+	can_be_decrypted = (is_multicast_ether_addr(hdr->addr1) ||
+			    is_broadcast_ether_addr(hdr->addr2)) ?
+	    ieee->host_mc_decrypt : ieee->host_decrypt;
+
+	if (can_be_decrypted) {
 		int idx = 0;
-		if (skb->len >= hdrlen + 3)
+		if (skb->len >= hdrlen + 3) {
+			/* Top two-bits of byte 3 are the key index */
 			idx = skb->data[hdrlen + 3] >> 6;
+		}
+
+		/* ieee->crypt[] is WEP_KEY (4) in length.  Given that idx
+		 * is only allowed 2-bits of storage, no value of idx can
+		 * be provided via above code that would result in idx
+		 * being out of range */
 		crypt = ieee->crypt[idx];
+
 #ifdef NOT_YET
 		sta = NULL;
 
@@ -553,7 +565,7 @@ int ieee80211_rx(struct ieee80211_device
 
 	/* skb: hdr + (possibly fragmented, possibly encrypted) payload */
 
-	if (ieee->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
+	if ((fc & IEEE80211_FCTL_PROTECTED) && can_be_decrypted &&
 	    (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
 		goto rx_dropped;
 
@@ -617,7 +629,7 @@ int ieee80211_rx(struct ieee80211_device
 
 	/* skb: hdr + (possible reassembled) full MSDU payload; possibly still
 	 * encrypted/authenticated */
-	if (ieee->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
+	if ((fc & IEEE80211_FCTL_PROTECTED) && can_be_decrypted &&
 	    ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
 		goto rx_dropped;
 
@@ -1439,7 +1451,7 @@ void ieee80211_rx_mgt(struct ieee80211_d
 		break;
 
 	case IEEE80211_STYPE_PROBE_REQ:
-		IEEE80211_DEBUG_MGMT("recieved auth (%d)\n",
+		IEEE80211_DEBUG_MGMT("received auth (%d)\n",
 				     WLAN_FC_GET_STYPE(le16_to_cpu
 						       (header->frame_ctl)));
 
@@ -1473,7 +1485,7 @@ void ieee80211_rx_mgt(struct ieee80211_d
 		break;
 	case IEEE80211_STYPE_AUTH:
 
-		IEEE80211_DEBUG_MGMT("recieved auth (%d)\n",
+		IEEE80211_DEBUG_MGMT("received auth (%d)\n",
 				     WLAN_FC_GET_STYPE(le16_to_cpu
 						       (header->frame_ctl)));
 
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index 23e1630..f87c6b8 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -232,15 +232,18 @@ static char *ipw2100_translate_scan(stru
 	return start;
 }
 
+#define SCAN_ITEM_SIZE 128
+
 int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
 			  struct iw_request_info *info,
 			  union iwreq_data *wrqu, char *extra)
 {
 	struct ieee80211_network *network;
 	unsigned long flags;
+	int err = 0;
 
 	char *ev = extra;
-	char *stop = ev + IW_SCAN_MAX_DATA;
+	char *stop = ev + wrqu->data.length;
 	int i = 0;
 
 	IEEE80211_DEBUG_WX("Getting scan\n");
@@ -249,6 +252,11 @@ int ieee80211_wx_get_scan(struct ieee802
 
 	list_for_each_entry(network, &ieee->network_list, list) {
 		i++;
+		if (stop - ev < SCAN_ITEM_SIZE) {
+			err = -E2BIG;
+			break;
+		}
+
 		if (ieee->scan_age == 0 ||
 		    time_after(network->last_scanned + ieee->scan_age, jiffies))
 			ev = ipw2100_translate_scan(ieee, ev, stop, network);
@@ -270,7 +278,7 @@ int ieee80211_wx_get_scan(struct ieee802
 
 	IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
 
-	return 0;
+	return err;
 }
 
 int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 192092b..0b4e95f 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -233,7 +233,18 @@ static int is_in(struct ip_mc_list *pmc,
 	case IGMPV3_MODE_IS_EXCLUDE:
 		if (gdeleted || sdeleted)
 			return 0;
-		return !(pmc->gsquery && !psf->sf_gsresp);
+		if (!(pmc->gsquery && !psf->sf_gsresp)) {
+			if (pmc->sfmode == MCAST_INCLUDE)
+				return 1;
+			/* don't include if this source is excluded
+			 * in all filters
+			 */
+			if (psf->sf_count[MCAST_INCLUDE])
+				return type == IGMPV3_MODE_IS_INCLUDE;
+			return pmc->sfcount[MCAST_EXCLUDE] ==
+				psf->sf_count[MCAST_EXCLUDE];
+		}
+		return 0;
 	case IGMPV3_CHANGE_TO_INCLUDE:
 		if (gdeleted || sdeleted)
 			return 0;
@@ -385,7 +396,7 @@ static struct sk_buff *add_grec(struct s
 	struct igmpv3_report *pih;
 	struct igmpv3_grec *pgr = NULL;
 	struct ip_sf_list *psf, *psf_next, *psf_prev, **psf_list;
-	int scount, first, isquery, truncate;
+	int scount, stotal, first, isquery, truncate;
 
 	if (pmc->multiaddr == IGMP_ALL_HOSTS)
 		return skb;
@@ -395,25 +406,13 @@ static struct sk_buff *add_grec(struct s
 	truncate = type == IGMPV3_MODE_IS_EXCLUDE ||
 		    type == IGMPV3_CHANGE_TO_EXCLUDE;
 
+	stotal = scount = 0;
+
 	psf_list = sdeleted ? &pmc->tomb : &pmc->sources;
 
-	if (!*psf_list) {
-		if (type == IGMPV3_ALLOW_NEW_SOURCES ||
-		    type == IGMPV3_BLOCK_OLD_SOURCES)
-			return skb;
-		if (pmc->crcount || isquery) {
-			/* make sure we have room for group header and at
-			 * least one source.
-			 */
-			if (skb && AVAILABLE(skb) < sizeof(struct igmpv3_grec)+
-			    sizeof(__u32)) {
-				igmpv3_sendpack(skb);
-				skb = NULL; /* add_grhead will get a new one */
-			}
-			skb = add_grhead(skb, pmc, type, &pgr);
-		}
-		return skb;
-	}
+	if (!*psf_list)
+		goto empty_source;
+
 	pih = skb ? (struct igmpv3_report *)skb->h.igmph : NULL;
 
 	/* EX and TO_EX get a fresh packet, if needed */
@@ -426,7 +425,6 @@ static struct sk_buff *add_grec(struct s
 		}
 	}
 	first = 1;
-	scount = 0;
 	psf_prev = NULL;
 	for (psf=*psf_list; psf; psf=psf_next) {
 		u32 *psrc;
@@ -460,7 +458,7 @@ static struct sk_buff *add_grec(struct s
 		}
 		psrc = (u32 *)skb_put(skb, sizeof(u32));
 		*psrc = psf->sf_inaddr;
-		scount++;
+		scount++; stotal++;
 		if ((type == IGMPV3_ALLOW_NEW_SOURCES ||
 		     type == IGMPV3_BLOCK_OLD_SOURCES) && psf->sf_crcount) {
 			psf->sf_crcount--;
@@ -475,6 +473,21 @@ static struct sk_buff *add_grec(struct s
 		}
 		psf_prev = psf;
 	}
+
+empty_source:
+	if (!stotal) {
+		if (type == IGMPV3_ALLOW_NEW_SOURCES ||
+		    type == IGMPV3_BLOCK_OLD_SOURCES)
+			return skb;
+		if (pmc->crcount || isquery) {
+			/* make sure we have room for group header */
+			if (skb && AVAILABLE(skb)<sizeof(struct igmpv3_grec)) {
+				igmpv3_sendpack(skb);
+				skb = NULL; /* add_grhead will get a new one */
+			}
+			skb = add_grhead(skb, pmc, type, &pgr);
+		}
+	}
 	if (pgr)
 		pgr->grec_nsrcs = htons(scount);
 
@@ -557,11 +570,11 @@ static void igmpv3_send_cr(struct in_dev
 			skb = add_grec(skb, pmc, dtype, 1, 1);
 		}
 		if (pmc->crcount) {
-			pmc->crcount--;
 			if (pmc->sfmode == MCAST_EXCLUDE) {
 				type = IGMPV3_CHANGE_TO_INCLUDE;
 				skb = add_grec(skb, pmc, type, 1, 0);
 			}
+			pmc->crcount--;
 			if (pmc->crcount == 0) {
 				igmpv3_clear_zeros(&pmc->tomb);
 				igmpv3_clear_zeros(&pmc->sources);
@@ -594,12 +607,12 @@ static void igmpv3_send_cr(struct in_dev
 
 		/* filter mode changes */
 		if (pmc->crcount) {
-			pmc->crcount--;
 			if (pmc->sfmode == MCAST_EXCLUDE)
 				type = IGMPV3_CHANGE_TO_EXCLUDE;
 			else
 				type = IGMPV3_CHANGE_TO_INCLUDE;
 			skb = add_grec(skb, pmc, type, 0, 0);
+			pmc->crcount--;
 		}
 		spin_unlock_bh(&pmc->lock);
 	}
@@ -735,7 +748,8 @@ static void igmp_timer_expire(unsigned l
 	ip_ma_put(im);
 }
 
-static void igmp_marksources(struct ip_mc_list *pmc, int nsrcs, __u32 *srcs)
+/* mark EXCLUDE-mode sources */
+static int igmp_xmarksources(struct ip_mc_list *pmc, int nsrcs, __u32 *srcs)
 {
 	struct ip_sf_list *psf;
 	int i, scount;
@@ -744,6 +758,37 @@ static void igmp_marksources(struct ip_m
 	for (psf=pmc->sources; psf; psf=psf->sf_next) {
 		if (scount == nsrcs)
 			break;
+		for (i=0; i<nsrcs; i++) {
+			/* skip inactive filters */
+			if (pmc->sfcount[MCAST_INCLUDE] ||
+			    pmc->sfcount[MCAST_EXCLUDE] !=
+			    psf->sf_count[MCAST_EXCLUDE])
+				continue;
+			if (srcs[i] == psf->sf_inaddr) {
+				scount++;
+				break;
+			}
+		}
+	}
+	pmc->gsquery = 0;
+	if (scount == nsrcs)	/* all sources excluded */
+		return 0;
+	return 1;
+}
+
+static int igmp_marksources(struct ip_mc_list *pmc, int nsrcs, __u32 *srcs)
+{
+	struct ip_sf_list *psf;
+	int i, scount;
+
+	if (pmc->sfmode == MCAST_EXCLUDE)
+		return igmp_xmarksources(pmc, nsrcs, srcs);
+
+	/* mark INCLUDE-mode sources */
+	scount = 0;
+	for (psf=pmc->sources; psf; psf=psf->sf_next) {
+		if (scount == nsrcs)
+			break;
 		for (i=0; i<nsrcs; i++)
 			if (srcs[i] == psf->sf_inaddr) {
 				psf->sf_gsresp = 1;
@@ -751,6 +796,12 @@ static void igmp_marksources(struct ip_m
 				break;
 			}
 	}
+	if (!scount) {
+		pmc->gsquery = 0;
+		return 0;
+	}
+	pmc->gsquery = 1;
+	return 1;
 }
 
 static void igmp_heard_report(struct in_device *in_dev, u32 group)
@@ -845,6 +896,8 @@ static void igmp_heard_query(struct in_d
 	 */
 	read_lock(&in_dev->mc_list_lock);
 	for (im=in_dev->mc_list; im!=NULL; im=im->next) {
+		int changed;
+
 		if (group && group != im->multiaddr)
 			continue;
 		if (im->multiaddr == IGMP_ALL_HOSTS)
@@ -854,10 +907,11 @@ static void igmp_heard_query(struct in_d
 			im->gsquery = im->gsquery && mark;
 		else
 			im->gsquery = mark;
-		if (im->gsquery)
-			igmp_marksources(im, ntohs(ih3->nsrcs), ih3->srcs);
+		changed = !im->gsquery ||
+		    	igmp_marksources(im, ntohs(ih3->nsrcs), ih3->srcs);
 		spin_unlock_bh(&im->lock);
-		igmp_mod_timer(im, max_delay);
+		if (changed)
+			igmp_mod_timer(im, max_delay);
 	}
 	read_unlock(&in_dev->mc_list_lock);
 }
@@ -916,7 +970,7 @@ int igmp_rcv(struct sk_buff *skb)
 	case IGMP_MTRACE_RESP:
 		break;
 	default:
-		NETDEBUG(KERN_DEBUG "New IGMP type=%d, why we do not know about it?\n", ih->type);
+		break;
 	}
 
 drop:
@@ -1510,7 +1564,7 @@ static void sf_markstate(struct ip_mc_li
 
 static int sf_setstate(struct ip_mc_list *pmc)
 {
-	struct ip_sf_list *psf;
+	struct ip_sf_list *psf, *dpsf;
 	int mca_xcount = pmc->sfcount[MCAST_EXCLUDE];
 	int qrv = pmc->interface->mr_qrv;
 	int new_in, rv;
@@ -1522,8 +1576,46 @@ static int sf_setstate(struct ip_mc_list
 				!psf->sf_count[MCAST_INCLUDE];
 		} else
 			new_in = psf->sf_count[MCAST_INCLUDE] != 0;
-		if (new_in != psf->sf_oldin) {
-			psf->sf_crcount = qrv;
+		if (new_in) {
+			if (!psf->sf_oldin) {
+				struct ip_sf_list *prev = 0;
+
+				for (dpsf=pmc->tomb; dpsf; dpsf=dpsf->sf_next) {
+					if (dpsf->sf_inaddr == psf->sf_inaddr)
+						break;
+					prev = dpsf;
+				}
+				if (dpsf) {
+					if (prev)
+						prev->sf_next = dpsf->sf_next;
+					else
+						pmc->tomb = dpsf->sf_next;
+					kfree(dpsf);
+				}
+				psf->sf_crcount = qrv;
+				rv++;
+			}
+		} else if (psf->sf_oldin) {
+
+			psf->sf_crcount = 0;
+			/*
+			 * add or update "delete" records if an active filter
+			 * is now inactive
+			 */
+			for (dpsf=pmc->tomb; dpsf; dpsf=dpsf->sf_next)
+				if (dpsf->sf_inaddr == psf->sf_inaddr)
+					break;
+			if (!dpsf) {
+				dpsf = (struct ip_sf_list *)
+					kmalloc(sizeof(*dpsf), GFP_ATOMIC);
+				if (!dpsf)
+					continue;
+				*dpsf = *psf;
+				/* pmc->lock held by callers */
+				dpsf->sf_next = pmc->tomb;
+				pmc->tomb = dpsf;
+			}
+			dpsf->sf_crcount = qrv;
 			rv++;
 		}
 	}
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index bcefe64..e5c5b32 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -46,7 +46,6 @@ obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o
 obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
 
 # matches
-obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
 obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o
 obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
 obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_gre.c b/net/ipv4/netfilter/ip_conntrack_proto_gre.c
index c777abf..5679479 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_gre.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_gre.c
@@ -32,6 +32,7 @@
 #include <linux/in.h>
 #include <linux/list.h>
 #include <linux/seq_file.h>
+#include <linux/interrupt.h>
 
 static DEFINE_RWLOCK(ip_ct_gre_lock);
 #define ASSERT_READ_LOCK(x)
diff --git a/net/ipv4/netfilter/ipt_policy.c b/net/ipv4/netfilter/ipt_policy.c
index 709debc..18ca825 100644
--- a/net/ipv4/netfilter/ipt_policy.c
+++ b/net/ipv4/netfilter/ipt_policy.c
@@ -95,7 +95,10 @@ match_policy_out(const struct sk_buff *s
 static int match(const struct sk_buff *skb,
                  const struct net_device *in,
                  const struct net_device *out,
-                 const void *matchinfo, int offset, int *hotdrop)
+                 const void *matchinfo,
+                 int offset,
+                 unsigned int protoff,
+                 int *hotdrop)
 {
 	const struct ipt_policy_info *info = matchinfo;
 	int ret;
@@ -113,7 +116,7 @@ static int match(const struct sk_buff *s
 	return ret;
 }
 
-static int checkentry(const char *tablename, const struct ipt_ip *ip,
+static int checkentry(const char *tablename, const void *ip_void,
                       void *matchinfo, unsigned int matchsize,
                       unsigned int hook_mask)
 {
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 165a4d8..f29a12d 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -40,12 +40,12 @@
  */
  
 #include <linux/config.h> 
+#include <linux/types.h>
 #include <asm/atomic.h>
 #include <asm/byteorder.h>
 #include <asm/current.h>
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
-#include <linux/types.h>
 #include <linux/stddef.h>
 #include <linux/slab.h>
 #include <linux/errno.h>
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index f701a13..d82c242 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -240,9 +240,9 @@ static unsigned			rt_hash_mask;
 static int			rt_hash_log;
 static unsigned int		rt_hash_rnd;
 
-static struct rt_cache_stat *rt_cache_stat;
-#define RT_CACHE_STAT_INC(field)					  \
-		(per_cpu_ptr(rt_cache_stat, raw_smp_processor_id())->field++)
+static DEFINE_PER_CPU(struct rt_cache_stat, rt_cache_stat);
+#define RT_CACHE_STAT_INC(field) \
+	(per_cpu(rt_cache_stat, raw_smp_processor_id()).field++)
 
 static int rt_intern_hash(unsigned hash, struct rtable *rth,
 				struct rtable **res);
@@ -401,7 +401,7 @@ static void *rt_cpu_seq_start(struct seq
 		if (!cpu_possible(cpu))
 			continue;
 		*pos = cpu+1;
-		return per_cpu_ptr(rt_cache_stat, cpu);
+		return &per_cpu(rt_cache_stat, cpu);
 	}
 	return NULL;
 }
@@ -414,7 +414,7 @@ static void *rt_cpu_seq_next(struct seq_
 		if (!cpu_possible(cpu))
 			continue;
 		*pos = cpu+1;
-		return per_cpu_ptr(rt_cache_stat, cpu);
+		return &per_cpu(rt_cache_stat, cpu);
 	}
 	return NULL;
 	
@@ -3160,10 +3160,6 @@ int __init ip_rt_init(void)
 	ipv4_dst_ops.gc_thresh = (rt_hash_mask + 1);
 	ip_rt_max_size = (rt_hash_mask + 1) * 16;
 
-	rt_cache_stat = alloc_percpu(struct rt_cache_stat);
-	if (!rt_cache_stat)
-		return -ENOMEM;
-
 	devinet_init();
 	ip_fib_init();
 
@@ -3191,7 +3187,6 @@ int __init ip_rt_init(void)
 	if (!proc_net_fops_create("rt_cache", S_IRUGO, &rt_cache_seq_fops) ||
 	    !(rtstat_pde = create_proc_entry("rt_cache", S_IRUGO, 
 			    		     proc_net_stat))) {
-		free_percpu(rt_cache_stat);
 		return -ENOMEM;
 	}
 	rtstat_pde->proc_fops = &rt_cpu_seq_fops;
diff --git a/net/ipv4/tcp_htcp.c b/net/ipv4/tcp_htcp.c
index 3284cfb..128de4d 100644
--- a/net/ipv4/tcp_htcp.c
+++ b/net/ipv4/tcp_htcp.c
@@ -230,7 +230,6 @@ static void htcp_cong_avoid(struct sock 
 			if (tp->snd_cwnd < tp->snd_cwnd_clamp)
 				tp->snd_cwnd++;
 			tp->snd_cwnd_cnt = 0;
-			ca->ccount++;
 		}
 	}
 }
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 6ea3539..233bdf2 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -236,7 +236,7 @@ int tcp_v4_connect(struct sock *sk, stru
 	if (err)
 		goto failure;
 
-	err = ip_route_newports(&rt, inet->sport, inet->dport, sk);
+	err = ip_route_newports(&rt, IPPROTO_TCP, inet->sport, inet->dport, sk);
 	if (err)
 		goto failure;
 
@@ -1845,7 +1845,6 @@ void __init tcp_v4_init(struct net_proto
 }
 
 EXPORT_SYMBOL(ipv4_specific);
-EXPORT_SYMBOL(inet_bind_bucket_create);
 EXPORT_SYMBOL(tcp_hashinfo);
 EXPORT_SYMBOL(tcp_prot);
 EXPORT_SYMBOL(tcp_unhash);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index dfb4f14..d328d59 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2644,7 +2644,7 @@ static int if6_seq_show(struct seq_file 
 {
 	struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
 	seq_printf(seq,
-		   NIP6_FMT " %02x %02x %02x %02x %8s\n",
+		   NIP6_SEQFMT " %02x %02x %02x %02x %8s\n",
 		   NIP6(ifp->addr),
 		   ifp->idev->dev->ifindex,
 		   ifp->prefix_len,
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 72bd08a..840a33d 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -532,7 +532,7 @@ static int ac6_seq_show(struct seq_file 
 	struct ac6_iter_state *state = ac6_seq_private(seq);
 
 	seq_printf(seq,
-		   "%-4d %-15s " NIP6_FMT " %5d\n",
+		   "%-4d %-15s " NIP6_SEQFMT " %5d\n",
 		   state->dev->ifindex, state->dev->name,
 		   NIP6(im->aca_addr),
 		   im->aca_users);
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 4183c8d..69cbe8a 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -629,7 +629,7 @@ static void ip6fl_fl_seq_show(struct seq
 {
 	while(fl) {
 		seq_printf(seq,
-			   "%05X %-1d %-6d %-6d %-6ld %-8ld " NIP6_FMT " %-4d\n",
+			   "%05X %-1d %-6d %-6d %-6ld %-8ld " NIP6_SEQFMT " %-4d\n",
 			   (unsigned)ntohl(fl->label),
 			   fl->share,
 			   (unsigned)fl->owner,
@@ -645,7 +645,7 @@ static void ip6fl_fl_seq_show(struct seq
 static int ip6fl_seq_show(struct seq_file *seq, void *v)
 {
 	if (v == SEQ_START_TOKEN)
-		seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-39s %s\n",
+		seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n",
 			   "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt");
 	else
 		ip6fl_fl_seq_show(seq, v);
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 0e03eab..4420948 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1252,8 +1252,7 @@ int igmp6_event_query(struct sk_buff *sk
 		}
 	} else {
 		for (ma = idev->mc_list; ma; ma=ma->next) {
-			if (group_type != IPV6_ADDR_ANY &&
-			    !ipv6_addr_equal(group, &ma->mca_addr))
+			if (!ipv6_addr_equal(group, &ma->mca_addr))
 				continue;
 			spin_lock_bh(&ma->mca_lock);
 			if (ma->mca_flags & MAF_TIMER_RUNNING) {
@@ -1268,11 +1267,10 @@ int igmp6_event_query(struct sk_buff *sk
 					ma->mca_flags &= ~MAF_GSQUERY;
 			}
 			if (!(ma->mca_flags & MAF_GSQUERY) ||
-			   mld_marksources(ma, ntohs(mlh2->nsrcs), mlh2->srcs))
+			    mld_marksources(ma, ntohs(mlh2->nsrcs), mlh2->srcs))
 				igmp6_group_queried(ma, max_delay);
 			spin_unlock_bh(&ma->mca_lock);
-			if (group_type != IPV6_ADDR_ANY)
-				break;
+			break;
 		}
 	}
 	read_unlock_bh(&idev->lock);
@@ -1351,7 +1349,7 @@ static int is_in(struct ifmcaddr6 *pmc, 
 			 * in all filters
 			 */
 			if (psf->sf_count[MCAST_INCLUDE])
-				return 0;
+				return type == MLD2_MODE_IS_INCLUDE;
 			return pmc->mca_sfcount[MCAST_EXCLUDE] ==
 				psf->sf_count[MCAST_EXCLUDE];
 		}
@@ -1966,7 +1964,7 @@ static void sf_markstate(struct ifmcaddr
 
 static int sf_setstate(struct ifmcaddr6 *pmc)
 {
-	struct ip6_sf_list *psf;
+	struct ip6_sf_list *psf, *dpsf;
 	int mca_xcount = pmc->mca_sfcount[MCAST_EXCLUDE];
 	int qrv = pmc->idev->mc_qrv;
 	int new_in, rv;
@@ -1978,8 +1976,48 @@ static int sf_setstate(struct ifmcaddr6 
 				!psf->sf_count[MCAST_INCLUDE];
 		} else
 			new_in = psf->sf_count[MCAST_INCLUDE] != 0;
-		if (new_in != psf->sf_oldin) {
-			psf->sf_crcount = qrv;
+		if (new_in) {
+			if (!psf->sf_oldin) {
+				struct ip6_sf_list *prev = 0;
+
+				for (dpsf=pmc->mca_tomb; dpsf;
+				     dpsf=dpsf->sf_next) {
+					if (ipv6_addr_equal(&dpsf->sf_addr,
+					    &psf->sf_addr))
+						break;
+					prev = dpsf;
+				}
+				if (dpsf) {
+					if (prev)
+						prev->sf_next = dpsf->sf_next;
+					else
+						pmc->mca_tomb = dpsf->sf_next;
+					kfree(dpsf);
+				}
+				psf->sf_crcount = qrv;
+				rv++;
+			}
+		} else if (psf->sf_oldin) {
+			psf->sf_crcount = 0;
+			/*
+			 * add or update "delete" records if an active filter
+			 * is now inactive
+			 */
+			for (dpsf=pmc->mca_tomb; dpsf; dpsf=dpsf->sf_next)
+				if (ipv6_addr_equal(&dpsf->sf_addr,
+				    &psf->sf_addr))
+					break;
+			if (!dpsf) {
+				dpsf = (struct ip6_sf_list *)
+					kmalloc(sizeof(*dpsf), GFP_ATOMIC);
+				if (!dpsf)
+					continue;
+				*dpsf = *psf;
+				/* pmc->mca_lock held by callers */
+				dpsf->sf_next = pmc->mca_tomb;
+				pmc->mca_tomb = dpsf;
+			}
+			dpsf->sf_crcount = qrv;
 			rv++;
 		}
 	}
@@ -2373,7 +2411,7 @@ static int igmp6_mc_seq_show(struct seq_
 	struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
 
 	seq_printf(seq,
-		   "%-4d %-15s " NIP6_FMT " %5d %08X %ld\n", 
+		   "%-4d %-15s " NIP6_SEQFMT " %5d %08X %ld\n", 
 		   state->dev->ifindex, state->dev->name,
 		   NIP6(im->mca_addr),
 		   im->mca_users, im->mca_flags,
@@ -2542,12 +2580,12 @@ static int igmp6_mcf_seq_show(struct seq
 	if (v == SEQ_START_TOKEN) {
 		seq_printf(seq, 
 			   "%3s %6s "
-			   "%39s %39s %6s %6s\n", "Idx",
+			   "%32s %32s %6s %6s\n", "Idx",
 			   "Device", "Multicast Address",
 			   "Source Address", "INC", "EXC");
 	} else {
 		seq_printf(seq,
-			   "%3d %6.6s " NIP6_FMT " " NIP6_FMT " %6lu %6lu\n",
+			   "%3d %6.6s " NIP6_SEQFMT " " NIP6_SEQFMT " %6lu %6lu\n",
 			   state->dev->ifindex, state->dev->name,
 			   NIP6(state->im->mca_addr),
 			   NIP6(psf->sf_addr),
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index 663b474..db6073c 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -4,7 +4,6 @@
 
 # Link order matters here.
 obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o
-obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o
 obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
 obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o
 obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
diff --git a/net/ipv6/netfilter/ip6t_dst.c b/net/ipv6/netfilter/ip6t_dst.c
index 80fe826..b4c153a 100644
--- a/net/ipv6/netfilter/ip6t_dst.c
+++ b/net/ipv6/netfilter/ip6t_dst.c
@@ -36,19 +36,19 @@ MODULE_AUTHOR("Andras Kis-Szabo <kisza@s
 #endif
 
 /*
- * (Type & 0xC0) >> 6
- * 	0	-> ignorable
- * 	1	-> must drop the packet
- * 	2	-> send ICMP PARM PROB regardless and drop packet
- * 	3	-> Send ICMP if not a multicast address and drop packet
+ *  (Type & 0xC0) >> 6
+ *	0	-> ignorable
+ *	1	-> must drop the packet
+ *	2	-> send ICMP PARM PROB regardless and drop packet
+ *	3	-> Send ICMP if not a multicast address and drop packet
  *  (Type & 0x20) >> 5
- *  	0	-> invariant
- *  	1	-> can change the routing
+ *	0	-> invariant
+ *	1	-> can change the routing
  *  (Type & 0x1F) Type
- *      0	-> Pad1 (only 1 byte!)
- *      1	-> PadN LENGTH info (total length = length + 2)
- *      C0 | 2	-> JUMBO 4 x x x x ( xxxx > 64k )
- *      5	-> RTALERT 2 x x
+ *	0	-> Pad1 (only 1 byte!)
+ *	1	-> PadN LENGTH info (total length = length + 2)
+ *	C0 | 2	-> JUMBO 4 x x x x ( xxxx > 64k )
+ *	5	-> RTALERT 2 x x
  */
 
 static int
@@ -60,16 +60,16 @@ match(const struct sk_buff *skb,
       unsigned int protoff,
       int *hotdrop)
 {
-       struct ipv6_opt_hdr _optsh, *oh;
-       const struct ip6t_opts *optinfo = matchinfo;
-       unsigned int temp;
-       unsigned int ptr;
-       unsigned int hdrlen = 0;
-       unsigned int ret = 0;
-       u8 _opttype, *tp = NULL;
-       u8 _optlen, *lp = NULL;
-       unsigned int optlen;
-       
+	struct ipv6_opt_hdr _optsh, *oh;
+	const struct ip6t_opts *optinfo = matchinfo;
+	unsigned int temp;
+	unsigned int ptr;
+	unsigned int hdrlen = 0;
+	unsigned int ret = 0;
+	u8 _opttype, *tp = NULL;
+	u8 _optlen, *lp = NULL;
+	unsigned int optlen;
+
 #if HOPBYHOP
 	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP, NULL) < 0)
 #else
@@ -77,42 +77,41 @@ match(const struct sk_buff *skb,
 #endif
 		return 0;
 
-       oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
-       if (oh == NULL){
-	       *hotdrop = 1;
-       		return 0;
-       }
-
-       hdrlen = ipv6_optlen(oh);
-       if (skb->len - ptr < hdrlen){
-	       /* Packet smaller than it's length field */
-       		return 0;
-       }
-
-       DEBUGP("IPv6 OPTS LEN %u %u ", hdrlen, oh->hdrlen);
-
-       DEBUGP("len %02X %04X %02X ",
-       		optinfo->hdrlen, hdrlen,
-       		(!(optinfo->flags & IP6T_OPTS_LEN) ||
-                           ((optinfo->hdrlen == hdrlen) ^
-                           !!(optinfo->invflags & IP6T_OPTS_INV_LEN))));
-
-       ret = (oh != NULL)
-       		&&
-	      	(!(optinfo->flags & IP6T_OPTS_LEN) ||
-                           ((optinfo->hdrlen == hdrlen) ^
-                           !!(optinfo->invflags & IP6T_OPTS_INV_LEN)));
-
-       ptr += 2;
-       hdrlen -= 2;
-       if ( !(optinfo->flags & IP6T_OPTS_OPTS) ){
-	       return ret;
+	oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
+	if (oh == NULL) {
+		*hotdrop = 1;
+		return 0;
+	}
+
+	hdrlen = ipv6_optlen(oh);
+	if (skb->len - ptr < hdrlen) {
+		/* Packet smaller than it's length field */
+		return 0;
+	}
+
+	DEBUGP("IPv6 OPTS LEN %u %u ", hdrlen, oh->hdrlen);
+
+	DEBUGP("len %02X %04X %02X ",
+	       optinfo->hdrlen, hdrlen,
+	       (!(optinfo->flags & IP6T_OPTS_LEN) ||
+		((optinfo->hdrlen == hdrlen) ^
+		 !!(optinfo->invflags & IP6T_OPTS_INV_LEN))));
+
+	ret = (oh != NULL) &&
+	      (!(optinfo->flags & IP6T_OPTS_LEN) ||
+	       ((optinfo->hdrlen == hdrlen) ^
+		!!(optinfo->invflags & IP6T_OPTS_INV_LEN)));
+
+	ptr += 2;
+	hdrlen -= 2;
+	if (!(optinfo->flags & IP6T_OPTS_OPTS)) {
+		return ret;
 	} else if (optinfo->flags & IP6T_OPTS_NSTRICT) {
 		DEBUGP("Not strict - not implemented");
 	} else {
 		DEBUGP("Strict ");
-		DEBUGP("#%d ",optinfo->optsnr);
-		for(temp=0; temp<optinfo->optsnr; temp++){
+		DEBUGP("#%d ", optinfo->optsnr);
+		for (temp = 0; temp < optinfo->optsnr; temp++) {
 			/* type field exists ? */
 			if (hdrlen < 1)
 				break;
@@ -122,10 +121,10 @@ match(const struct sk_buff *skb,
 				break;
 
 			/* Type check */
-			if (*tp != (optinfo->opts[temp] & 0xFF00)>>8){
+			if (*tp != (optinfo->opts[temp] & 0xFF00) >> 8) {
 				DEBUGP("Tbad %02X %02X\n",
 				       *tp,
-				       (optinfo->opts[temp] & 0xFF00)>>8);
+				       (optinfo->opts[temp] & 0xFF00) >> 8);
 				return 0;
 			} else {
 				DEBUGP("Tok ");
@@ -169,7 +168,8 @@ match(const struct sk_buff *skb,
 		}
 		if (temp == optinfo->optsnr)
 			return ret;
-		else return 0;
+		else
+			return 0;
 	}
 
 	return 0;
@@ -178,25 +178,24 @@ match(const struct sk_buff *skb,
 /* Called when user tries to insert an entry of this type. */
 static int
 checkentry(const char *tablename,
-          const void *info,
-          void *matchinfo,
-          unsigned int matchinfosize,
-          unsigned int hook_mask)
+	   const void *info,
+	   void *matchinfo,
+	   unsigned int matchinfosize,
+	   unsigned int hook_mask)
 {
-       const struct ip6t_opts *optsinfo = matchinfo;
+	const struct ip6t_opts *optsinfo = matchinfo;
 
-       if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_opts))) {
-              DEBUGP("ip6t_opts: matchsize %u != %u\n",
-                      matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_opts)));
-              return 0;
-       }
-       if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
-              DEBUGP("ip6t_opts: unknown flags %X\n",
-                      optsinfo->invflags);
-              return 0;
-       }
+	if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_opts))) {
+		DEBUGP("ip6t_opts: matchsize %u != %u\n",
+		       matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_opts)));
+		return 0;
+	}
+	if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
+		DEBUGP("ip6t_opts: unknown flags %X\n", optsinfo->invflags);
+		return 0;
+	}
 
-       return 1;
+	return 1;
 }
 
 static struct ip6t_match opts_match = {
@@ -212,12 +211,12 @@ static struct ip6t_match opts_match = {
 
 static int __init init(void)
 {
-       return ip6t_register_match(&opts_match);
+	return ip6t_register_match(&opts_match);
 }
 
 static void __exit cleanup(void)
 {
-       ip6t_unregister_match(&opts_match);
+	ip6t_unregister_match(&opts_match);
 }
 
 module_init(init);
diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c
index ddf5f57..27396ac 100644
--- a/net/ipv6/netfilter/ip6t_eui64.c
+++ b/net/ipv6/netfilter/ip6t_eui64.c
@@ -27,45 +27,45 @@ match(const struct sk_buff *skb,
       unsigned int protoff,
       int *hotdrop)
 {
+	unsigned char eui64[8];
+	int i = 0;
 
-    unsigned char eui64[8];
-    int i=0;
+	if (!(skb->mac.raw >= skb->head &&
+	      (skb->mac.raw + ETH_HLEN) <= skb->data) &&
+	    offset != 0) {
+		*hotdrop = 1;
+		return 0;
+	}
 
-     if ( !(skb->mac.raw >= skb->head
-                && (skb->mac.raw + ETH_HLEN) <= skb->data)
-                && offset != 0) {
-                        *hotdrop = 1;
-                        return 0;
-                }
-    
-    memset(eui64, 0, sizeof(eui64));
-
-    if (eth_hdr(skb)->h_proto == ntohs(ETH_P_IPV6)) {
-      if (skb->nh.ipv6h->version == 0x6) { 
-         memcpy(eui64, eth_hdr(skb)->h_source, 3);
-         memcpy(eui64 + 5, eth_hdr(skb)->h_source + 3, 3);
-	 eui64[3]=0xff;
-	 eui64[4]=0xfe;
-	 eui64[0] |= 0x02;
-
-	 i=0;
-	 while ((skb->nh.ipv6h->saddr.s6_addr[8+i] ==
-			 eui64[i]) && (i<8)) i++;
-
-	 if ( i == 8 )
-	 	return 1;
-      }
-    }
+	memset(eui64, 0, sizeof(eui64));
+
+	if (eth_hdr(skb)->h_proto == ntohs(ETH_P_IPV6)) {
+		if (skb->nh.ipv6h->version == 0x6) {
+			memcpy(eui64, eth_hdr(skb)->h_source, 3);
+			memcpy(eui64 + 5, eth_hdr(skb)->h_source + 3, 3);
+			eui64[3] = 0xff;
+			eui64[4] = 0xfe;
+			eui64[0] |= 0x02;
+
+			i = 0;
+			while ((skb->nh.ipv6h->saddr.s6_addr[8+i] == eui64[i])
+			       && (i < 8))
+				i++;
+
+			if (i == 8)
+				return 1;
+		}
+	}
 
-    return 0;
+	return 0;
 }
 
 static int
 ip6t_eui64_checkentry(const char *tablename,
-		   const void  *ip,
-		   void *matchinfo,
-		   unsigned int matchsize,
-		   unsigned int hook_mask)
+		      const void *ip,
+		      void *matchinfo,
+		      unsigned int matchsize,
+		      unsigned int hook_mask)
 {
 	if (hook_mask
 	    & ~((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_IN) |
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c
index a9964b9..4c14125 100644
--- a/net/ipv6/netfilter/ip6t_frag.c
+++ b/net/ipv6/netfilter/ip6t_frag.c
@@ -31,12 +31,12 @@ MODULE_AUTHOR("Andras Kis-Szabo <kisza@s
 static inline int
 id_match(u_int32_t min, u_int32_t max, u_int32_t id, int invert)
 {
-       int r=0;
-       DEBUGP("frag id_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ',
-              min,id,max);
-       r=(id >= min && id <= max) ^ invert;
-       DEBUGP(" result %s\n",r? "PASS" : "FAILED");
-       return r;
+	int r = 0;
+	DEBUGP("frag id_match:%c 0x%x <= 0x%x <= 0x%x", invert ? '!' : ' ',
+	       min, id, max);
+	r = (id >= min && id <= max) ^ invert;
+	DEBUGP(" result %s\n", r ? "PASS" : "FAILED");
+	return r;
 }
 
 static int
@@ -48,92 +48,91 @@ match(const struct sk_buff *skb,
       unsigned int protoff,
       int *hotdrop)
 {
-       struct frag_hdr _frag, *fh;
-       const struct ip6t_frag *fraginfo = matchinfo;
-       unsigned int ptr;
+	struct frag_hdr _frag, *fh;
+	const struct ip6t_frag *fraginfo = matchinfo;
+	unsigned int ptr;
 
 	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL) < 0)
 		return 0;
 
 	fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag);
-	if (fh == NULL){
+	if (fh == NULL) {
 		*hotdrop = 1;
 		return 0;
 	}
 
-       DEBUGP("INFO %04X ", fh->frag_off);
-       DEBUGP("OFFSET %04X ", ntohs(fh->frag_off) & ~0x7);
-       DEBUGP("RES %02X %04X", fh->reserved, ntohs(fh->frag_off) & 0x6);
-       DEBUGP("MF %04X ", fh->frag_off & htons(IP6_MF));
-       DEBUGP("ID %u %08X\n", ntohl(fh->identification),
-	      ntohl(fh->identification));
-
-       DEBUGP("IPv6 FRAG id %02X ",
-       		(id_match(fraginfo->ids[0], fraginfo->ids[1],
-                           ntohl(fh->identification),
-                           !!(fraginfo->invflags & IP6T_FRAG_INV_IDS))));
-       DEBUGP("res %02X %02X%04X %02X ", 
-       		(fraginfo->flags & IP6T_FRAG_RES), fh->reserved,
-		ntohs(fh->frag_off) & 0x6,
-       		!((fraginfo->flags & IP6T_FRAG_RES)
-			&& (fh->reserved || (ntohs(fh->frag_off) & 0x06))));
-       DEBUGP("first %02X %02X %02X ", 
-       		(fraginfo->flags & IP6T_FRAG_FST),
-		ntohs(fh->frag_off) & ~0x7,
-       		!((fraginfo->flags & IP6T_FRAG_FST)
-			&& (ntohs(fh->frag_off) & ~0x7)));
-       DEBUGP("mf %02X %02X %02X ", 
-       		(fraginfo->flags & IP6T_FRAG_MF),
-		ntohs(fh->frag_off) & IP6_MF,
-       		!((fraginfo->flags & IP6T_FRAG_MF)
-			&& !((ntohs(fh->frag_off) & IP6_MF))));
-       DEBUGP("last %02X %02X %02X\n", 
-       		(fraginfo->flags & IP6T_FRAG_NMF),
-		ntohs(fh->frag_off) & IP6_MF,
-       		!((fraginfo->flags & IP6T_FRAG_NMF)
-			&& (ntohs(fh->frag_off) & IP6_MF)));
-
-       return (fh != NULL)
-       		&&
-       		(id_match(fraginfo->ids[0], fraginfo->ids[1],
-			  ntohl(fh->identification),
-                           !!(fraginfo->invflags & IP6T_FRAG_INV_IDS)))
-		&&
-		!((fraginfo->flags & IP6T_FRAG_RES)
-			&& (fh->reserved || (ntohs(fh->frag_off) & 0x6)))
-		&&
-		!((fraginfo->flags & IP6T_FRAG_FST)
-			&& (ntohs(fh->frag_off) & ~0x7))
-		&&
-		!((fraginfo->flags & IP6T_FRAG_MF)
-			&& !(ntohs(fh->frag_off) & IP6_MF))
-		&&
-		!((fraginfo->flags & IP6T_FRAG_NMF)
-			&& (ntohs(fh->frag_off) & IP6_MF));
+	DEBUGP("INFO %04X ", fh->frag_off);
+	DEBUGP("OFFSET %04X ", ntohs(fh->frag_off) & ~0x7);
+	DEBUGP("RES %02X %04X", fh->reserved, ntohs(fh->frag_off) & 0x6);
+	DEBUGP("MF %04X ", fh->frag_off & htons(IP6_MF));
+	DEBUGP("ID %u %08X\n", ntohl(fh->identification),
+	       ntohl(fh->identification));
+
+	DEBUGP("IPv6 FRAG id %02X ",
+	       (id_match(fraginfo->ids[0], fraginfo->ids[1],
+			 ntohl(fh->identification),
+			 !!(fraginfo->invflags & IP6T_FRAG_INV_IDS))));
+	DEBUGP("res %02X %02X%04X %02X ",
+	       (fraginfo->flags & IP6T_FRAG_RES), fh->reserved,
+	       ntohs(fh->frag_off) & 0x6,
+	       !((fraginfo->flags & IP6T_FRAG_RES)
+		 && (fh->reserved || (ntohs(fh->frag_off) & 0x06))));
+	DEBUGP("first %02X %02X %02X ",
+	       (fraginfo->flags & IP6T_FRAG_FST),
+	       ntohs(fh->frag_off) & ~0x7,
+	       !((fraginfo->flags & IP6T_FRAG_FST)
+		 && (ntohs(fh->frag_off) & ~0x7)));
+	DEBUGP("mf %02X %02X %02X ",
+	       (fraginfo->flags & IP6T_FRAG_MF),
+	       ntohs(fh->frag_off) & IP6_MF,
+	       !((fraginfo->flags & IP6T_FRAG_MF)
+		 && !((ntohs(fh->frag_off) & IP6_MF))));
+	DEBUGP("last %02X %02X %02X\n",
+	       (fraginfo->flags & IP6T_FRAG_NMF),
+	       ntohs(fh->frag_off) & IP6_MF,
+	       !((fraginfo->flags & IP6T_FRAG_NMF)
+		 && (ntohs(fh->frag_off) & IP6_MF)));
+
+	return (fh != NULL)
+	       &&
+	       (id_match(fraginfo->ids[0], fraginfo->ids[1],
+			 ntohl(fh->identification),
+			 !!(fraginfo->invflags & IP6T_FRAG_INV_IDS)))
+	       &&
+	       !((fraginfo->flags & IP6T_FRAG_RES)
+		 && (fh->reserved || (ntohs(fh->frag_off) & 0x6)))
+	       &&
+	       !((fraginfo->flags & IP6T_FRAG_FST)
+		 && (ntohs(fh->frag_off) & ~0x7))
+	       &&
+	       !((fraginfo->flags & IP6T_FRAG_MF)
+		 && !(ntohs(fh->frag_off) & IP6_MF))
+	       &&
+	       !((fraginfo->flags & IP6T_FRAG_NMF)
+		 && (ntohs(fh->frag_off) & IP6_MF));
 }
 
 /* Called when user tries to insert an entry of this type. */
 static int
 checkentry(const char *tablename,
-          const void *ip,
-          void *matchinfo,
-          unsigned int matchinfosize,
-          unsigned int hook_mask)
+	   const void *ip,
+	   void *matchinfo,
+	   unsigned int matchinfosize,
+	   unsigned int hook_mask)
 {
-       const struct ip6t_frag *fraginfo = matchinfo;
+	const struct ip6t_frag *fraginfo = matchinfo;
 
-       if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_frag))) {
-              DEBUGP("ip6t_frag: matchsize %u != %u\n",
-                      matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_frag)));
-              return 0;
-       }
-       if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) {
-              DEBUGP("ip6t_frag: unknown flags %X\n",
-                      fraginfo->invflags);
-              return 0;
-       }
+	if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_frag))) {
+		DEBUGP("ip6t_frag: matchsize %u != %u\n",
+		       matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_frag)));
+		return 0;
+	}
+	if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) {
+		DEBUGP("ip6t_frag: unknown flags %X\n", fraginfo->invflags);
+		return 0;
+	}
 
-       return 1;
+	return 1;
 }
 
 static struct ip6t_match frag_match = {
@@ -145,12 +144,12 @@ static struct ip6t_match frag_match = {
 
 static int __init init(void)
 {
-       return ip6t_register_match(&frag_match);
+	return ip6t_register_match(&frag_match);
 }
 
 static void __exit cleanup(void)
 {
-       ip6t_unregister_match(&frag_match);
+	ip6t_unregister_match(&frag_match);
 }
 
 module_init(init);
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c
index ed8ded1..37a8474 100644
--- a/net/ipv6/netfilter/ip6t_hbh.c
+++ b/net/ipv6/netfilter/ip6t_hbh.c
@@ -36,19 +36,19 @@ MODULE_AUTHOR("Andras Kis-Szabo <kisza@s
 #endif
 
 /*
- * (Type & 0xC0) >> 6
- * 	0	-> ignorable
- * 	1	-> must drop the packet
- * 	2	-> send ICMP PARM PROB regardless and drop packet
- * 	3	-> Send ICMP if not a multicast address and drop packet
+ *  (Type & 0xC0) >> 6
+ *	0	-> ignorable
+ *	1	-> must drop the packet
+ *	2	-> send ICMP PARM PROB regardless and drop packet
+ *	3	-> Send ICMP if not a multicast address and drop packet
  *  (Type & 0x20) >> 5
- *  	0	-> invariant
- *  	1	-> can change the routing
+ *	0	-> invariant
+ *	1	-> can change the routing
  *  (Type & 0x1F) Type
- *      0	-> Pad1 (only 1 byte!)
- *      1	-> PadN LENGTH info (total length = length + 2)
- *      C0 | 2	-> JUMBO 4 x x x x ( xxxx > 64k )
- *      5	-> RTALERT 2 x x
+ *	0	-> Pad1 (only 1 byte!)
+ *	1	-> PadN LENGTH info (total length = length + 2)
+ *	C0 | 2	-> JUMBO 4 x x x x ( xxxx > 64k )
+ *	5	-> RTALERT 2 x x
  */
 
 static int
@@ -60,16 +60,16 @@ match(const struct sk_buff *skb,
       unsigned int protoff,
       int *hotdrop)
 {
-       struct ipv6_opt_hdr _optsh, *oh;
-       const struct ip6t_opts *optinfo = matchinfo;
-       unsigned int temp;
-       unsigned int ptr;
-       unsigned int hdrlen = 0;
-       unsigned int ret = 0;
-       u8 _opttype, *tp = NULL;
-       u8 _optlen, *lp = NULL;
-       unsigned int optlen;
-       
+	struct ipv6_opt_hdr _optsh, *oh;
+	const struct ip6t_opts *optinfo = matchinfo;
+	unsigned int temp;
+	unsigned int ptr;
+	unsigned int hdrlen = 0;
+	unsigned int ret = 0;
+	u8 _opttype, *tp = NULL;
+	u8 _optlen, *lp = NULL;
+	unsigned int optlen;
+
 #if HOPBYHOP
 	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP, NULL) < 0)
 #else
@@ -77,42 +77,41 @@ match(const struct sk_buff *skb,
 #endif
 		return 0;
 
-       oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
-       if (oh == NULL){
-	       *hotdrop = 1;
-       		return 0;
-       }
-
-       hdrlen = ipv6_optlen(oh);
-       if (skb->len - ptr < hdrlen){
-	       /* Packet smaller than it's length field */
-       		return 0;
-       }
-
-       DEBUGP("IPv6 OPTS LEN %u %u ", hdrlen, oh->hdrlen);
-
-       DEBUGP("len %02X %04X %02X ",
-       		optinfo->hdrlen, hdrlen,
-       		(!(optinfo->flags & IP6T_OPTS_LEN) ||
-                           ((optinfo->hdrlen == hdrlen) ^
-                           !!(optinfo->invflags & IP6T_OPTS_INV_LEN))));
-
-       ret = (oh != NULL)
-       		&&
-	      	(!(optinfo->flags & IP6T_OPTS_LEN) ||
-                           ((optinfo->hdrlen == hdrlen) ^
-                           !!(optinfo->invflags & IP6T_OPTS_INV_LEN)));
-
-       ptr += 2;
-       hdrlen -= 2;
-       if ( !(optinfo->flags & IP6T_OPTS_OPTS) ){
-	       return ret;
+	oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
+	if (oh == NULL) {
+		*hotdrop = 1;
+		return 0;
+	}
+
+	hdrlen = ipv6_optlen(oh);
+	if (skb->len - ptr < hdrlen) {
+		/* Packet smaller than it's length field */
+		return 0;
+	}
+
+	DEBUGP("IPv6 OPTS LEN %u %u ", hdrlen, oh->hdrlen);
+
+	DEBUGP("len %02X %04X %02X ",
+	       optinfo->hdrlen, hdrlen,
+	       (!(optinfo->flags & IP6T_OPTS_LEN) ||
+		((optinfo->hdrlen == hdrlen) ^
+		 !!(optinfo->invflags & IP6T_OPTS_INV_LEN))));
+
+	ret = (oh != NULL) &&
+	      (!(optinfo->flags & IP6T_OPTS_LEN) ||
+	       ((optinfo->hdrlen == hdrlen) ^
+		!!(optinfo->invflags & IP6T_OPTS_INV_LEN)));
+
+	ptr += 2;
+	hdrlen -= 2;
+	if (!(optinfo->flags & IP6T_OPTS_OPTS)) {
+		return ret;
 	} else if (optinfo->flags & IP6T_OPTS_NSTRICT) {
 		DEBUGP("Not strict - not implemented");
 	} else {
 		DEBUGP("Strict ");
-		DEBUGP("#%d ",optinfo->optsnr);
-		for(temp=0; temp<optinfo->optsnr; temp++){
+		DEBUGP("#%d ", optinfo->optsnr);
+		for (temp = 0; temp < optinfo->optsnr; temp++) {
 			/* type field exists ? */
 			if (hdrlen < 1)
 				break;
@@ -122,10 +121,10 @@ match(const struct sk_buff *skb,
 				break;
 
 			/* Type check */
-			if (*tp != (optinfo->opts[temp] & 0xFF00)>>8){
+			if (*tp != (optinfo->opts[temp] & 0xFF00) >> 8) {
 				DEBUGP("Tbad %02X %02X\n",
 				       *tp,
-				       (optinfo->opts[temp] & 0xFF00)>>8);
+				       (optinfo->opts[temp] & 0xFF00) >> 8);
 				return 0;
 			} else {
 				DEBUGP("Tok ");
@@ -169,7 +168,8 @@ match(const struct sk_buff *skb,
 		}
 		if (temp == optinfo->optsnr)
 			return ret;
-		else return 0;
+		else
+			return 0;
 	}
 
 	return 0;
@@ -178,25 +178,24 @@ match(const struct sk_buff *skb,
 /* Called when user tries to insert an entry of this type. */
 static int
 checkentry(const char *tablename,
-          const void *entry,
-          void *matchinfo,
-          unsigned int matchinfosize,
-          unsigned int hook_mask)
+	   const void *entry,
+	   void *matchinfo,
+	   unsigned int matchinfosize,
+	   unsigned int hook_mask)
 {
-       const struct ip6t_opts *optsinfo = matchinfo;
+	const struct ip6t_opts *optsinfo = matchinfo;
 
-       if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_opts))) {
-              DEBUGP("ip6t_opts: matchsize %u != %u\n",
-                      matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_opts)));
-              return 0;
-       }
-       if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
-              DEBUGP("ip6t_opts: unknown flags %X\n",
-                      optsinfo->invflags);
-              return 0;
-       }
+	if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_opts))) {
+		DEBUGP("ip6t_opts: matchsize %u != %u\n",
+		       matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_opts)));
+		return 0;
+	}
+	if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
+		DEBUGP("ip6t_opts: unknown flags %X\n", optsinfo->invflags);
+		return 0;
+	}
 
-       return 1;
+	return 1;
 }
 
 static struct ip6t_match opts_match = {
@@ -212,12 +211,12 @@ static struct ip6t_match opts_match = {
 
 static int __init init(void)
 {
-       return ip6t_register_match(&opts_match);
+	return ip6t_register_match(&opts_match);
 }
 
 static void __exit cleanup(void)
 {
-       ip6t_unregister_match(&opts_match);
+	ip6t_unregister_match(&opts_match);
 }
 
 module_init(init);
diff --git a/net/ipv6/netfilter/ip6t_ipv6header.c b/net/ipv6/netfilter/ip6t_ipv6header.c
index fda1cea..83ad6b2 100644
--- a/net/ipv6/netfilter/ip6t_ipv6header.c
+++ b/net/ipv6/netfilter/ip6t_ipv6header.c
@@ -50,20 +50,20 @@ ipv6header_match(const struct sk_buff *s
 	len = skb->len - ptr;
 	temp = 0;
 
-        while (ip6t_ext_hdr(nexthdr)) {
+	while (ip6t_ext_hdr(nexthdr)) {
 		struct ipv6_opt_hdr _hdr, *hp;
-        	int hdrlen;
+		int hdrlen;
 
 		/* Is there enough space for the next ext header? */
-                if (len < (int)sizeof(struct ipv6_opt_hdr))
-                        return 0;
+		if (len < (int)sizeof(struct ipv6_opt_hdr))
+			return 0;
 		/* No more exthdr -> evaluate */
-                if (nexthdr == NEXTHDR_NONE) {
+		if (nexthdr == NEXTHDR_NONE) {
 			temp |= MASK_NONE;
 			break;
 		}
 		/* ESP -> evaluate */
-                if (nexthdr == NEXTHDR_ESP) {
+		if (nexthdr == NEXTHDR_ESP) {
 			temp |= MASK_ESP;
 			break;
 		}
@@ -72,43 +72,43 @@ ipv6header_match(const struct sk_buff *s
 		BUG_ON(hp == NULL);
 
 		/* Calculate the header length */
-                if (nexthdr == NEXTHDR_FRAGMENT) {
-                        hdrlen = 8;
-                } else if (nexthdr == NEXTHDR_AUTH)
-                        hdrlen = (hp->hdrlen+2)<<2;
-                else
-                        hdrlen = ipv6_optlen(hp);
+		if (nexthdr == NEXTHDR_FRAGMENT) {
+			hdrlen = 8;
+		} else if (nexthdr == NEXTHDR_AUTH)
+			hdrlen = (hp->hdrlen + 2) << 2;
+		else
+			hdrlen = ipv6_optlen(hp);
 
 		/* set the flag */
-		switch (nexthdr){
-			case NEXTHDR_HOP:
-				temp |= MASK_HOPOPTS;
-				break;
-			case NEXTHDR_ROUTING:
-				temp |= MASK_ROUTING;
-				break;
-			case NEXTHDR_FRAGMENT:
-				temp |= MASK_FRAGMENT;
-				break;
-			case NEXTHDR_AUTH:
-				temp |= MASK_AH;
-				break;
-			case NEXTHDR_DEST:
-				temp |= MASK_DSTOPTS;
-				break;
-			default:
-				return 0;
-				break;
+		switch (nexthdr) {
+		case NEXTHDR_HOP:
+			temp |= MASK_HOPOPTS;
+			break;
+		case NEXTHDR_ROUTING:
+			temp |= MASK_ROUTING;
+			break;
+		case NEXTHDR_FRAGMENT:
+			temp |= MASK_FRAGMENT;
+			break;
+		case NEXTHDR_AUTH:
+			temp |= MASK_AH;
+			break;
+		case NEXTHDR_DEST:
+			temp |= MASK_DSTOPTS;
+			break;
+		default:
+			return 0;
+			break;
 		}
 
-                nexthdr = hp->nexthdr;
-                len -= hdrlen;
-                ptr += hdrlen;
+		nexthdr = hp->nexthdr;
+		len -= hdrlen;
+		ptr += hdrlen;
 		if (ptr > skb->len)
 			break;
-        }
+	}
 
-	if ( (nexthdr != NEXTHDR_NONE ) && (nexthdr != NEXTHDR_ESP) )
+	if ((nexthdr != NEXTHDR_NONE) && (nexthdr != NEXTHDR_ESP))
 		temp |= MASK_PROTO;
 
 	if (info->modeflag)
@@ -137,8 +137,8 @@ ipv6header_checkentry(const char *tablen
 		return 0;
 
 	/* invflags is 0 or 0xff in hard mode */
-	if ((!info->modeflag) && info->invflags != 0x00
-			      && info->invflags != 0xFF)
+	if ((!info->modeflag) && info->invflags != 0x00 &&
+	    info->invflags != 0xFF)
 		return 0;
 
 	return 1;
@@ -152,7 +152,7 @@ static struct ip6t_match ip6t_ipv6header
 	.me		= THIS_MODULE,
 };
 
-static int  __init ipv6header_init(void)
+static int __init ipv6header_init(void)
 {
 	return ip6t_register_match(&ip6t_ipv6header_match);
 }
@@ -164,4 +164,3 @@ static void __exit ipv6header_exit(void)
 
 module_init(ipv6header_init);
 module_exit(ipv6header_exit);
-
diff --git a/net/ipv6/netfilter/ip6t_owner.c b/net/ipv6/netfilter/ip6t_owner.c
index 5409b37..8c8a4c7 100644
--- a/net/ipv6/netfilter/ip6t_owner.c
+++ b/net/ipv6/netfilter/ip6t_owner.c
@@ -36,14 +36,14 @@ match(const struct sk_buff *skb,
 	if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file)
 		return 0;
 
-	if(info->match & IP6T_OWNER_UID) {
-		if((skb->sk->sk_socket->file->f_uid != info->uid) ^
+	if (info->match & IP6T_OWNER_UID) {
+		if ((skb->sk->sk_socket->file->f_uid != info->uid) ^
 		    !!(info->invert & IP6T_OWNER_UID))
 			return 0;
 	}
 
-	if(info->match & IP6T_OWNER_GID) {
-		if((skb->sk->sk_socket->file->f_gid != info->gid) ^
+	if (info->match & IP6T_OWNER_GID) {
+		if ((skb->sk->sk_socket->file->f_gid != info->gid) ^
 		    !!(info->invert & IP6T_OWNER_GID))
 			return 0;
 	}
@@ -53,23 +53,23 @@ match(const struct sk_buff *skb,
 
 static int
 checkentry(const char *tablename,
-           const void  *ip,
-           void *matchinfo,
-           unsigned int matchsize,
-           unsigned int hook_mask)
+	   const void *ip,
+	   void *matchinfo,
+	   unsigned int matchsize,
+	   unsigned int hook_mask)
 {
 	const struct ip6t_owner_info *info = matchinfo;
 
-        if (hook_mask
-            & ~((1 << NF_IP6_LOCAL_OUT) | (1 << NF_IP6_POST_ROUTING))) {
-                printk("ip6t_owner: only valid for LOCAL_OUT or POST_ROUTING.\n");
-                return 0;
-        }
+	if (hook_mask
+	    & ~((1 << NF_IP6_LOCAL_OUT) | (1 << NF_IP6_POST_ROUTING))) {
+		printk("ip6t_owner: only valid for LOCAL_OUT or POST_ROUTING.\n");
+		return 0;
+	}
 
 	if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_owner_info)))
 		return 0;
 
-	if (info->match & (IP6T_OWNER_PID|IP6T_OWNER_SID)) {
+	if (info->match & (IP6T_OWNER_PID | IP6T_OWNER_SID)) {
 		printk("ipt_owner: pid and sid matching "
 		       "not supported anymore\n");
 		return 0;
diff --git a/net/ipv6/netfilter/ip6t_policy.c b/net/ipv6/netfilter/ip6t_policy.c
index 13fedad..afe1cc4 100644
--- a/net/ipv6/netfilter/ip6t_policy.c
+++ b/net/ipv6/netfilter/ip6t_policy.c
@@ -118,7 +118,7 @@ static int match(const struct sk_buff *s
 	return ret;
 }
 
-static int checkentry(const char *tablename, const struct ip6t_ip6 *ip,
+static int checkentry(const char *tablename, const void *ip_void,
                       void *matchinfo, unsigned int matchsize,
                       unsigned int hook_mask)
 {
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c
index 8465b43..8f82476 100644
--- a/net/ipv6/netfilter/ip6t_rt.c
+++ b/net/ipv6/netfilter/ip6t_rt.c
@@ -33,12 +33,12 @@ MODULE_AUTHOR("Andras Kis-Szabo <kisza@s
 static inline int
 segsleft_match(u_int32_t min, u_int32_t max, u_int32_t id, int invert)
 {
-       int r=0;
-       DEBUGP("rt segsleft_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ',
-              min,id,max);
-       r=(id >= min && id <= max) ^ invert;
-       DEBUGP(" result %s\n",r? "PASS" : "FAILED");
-       return r;
+	int r = 0;
+	DEBUGP("rt segsleft_match:%c 0x%x <= 0x%x <= 0x%x",
+	       invert ? '!' : ' ', min, id, max);
+	r = (id >= min && id <= max) ^ invert;
+	DEBUGP(" result %s\n", r ? "PASS" : "FAILED");
+	return r;
 }
 
 static int
@@ -50,87 +50,93 @@ match(const struct sk_buff *skb,
       unsigned int protoff,
       int *hotdrop)
 {
-       struct ipv6_rt_hdr _route, *rh;
-       const struct ip6t_rt *rtinfo = matchinfo;
-       unsigned int temp;
-       unsigned int ptr;
-       unsigned int hdrlen = 0;
-       unsigned int ret = 0;
-       struct in6_addr *ap, _addr;
+	struct ipv6_rt_hdr _route, *rh;
+	const struct ip6t_rt *rtinfo = matchinfo;
+	unsigned int temp;
+	unsigned int ptr;
+	unsigned int hdrlen = 0;
+	unsigned int ret = 0;
+	struct in6_addr *ap, _addr;
 
 	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL) < 0)
 		return 0;
 
-       rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route);
-       if (rh == NULL){
-	       *hotdrop = 1;
-       		return 0;
-       }
-
-       hdrlen = ipv6_optlen(rh);
-       if (skb->len - ptr < hdrlen){
-	       /* Pcket smaller than its length field */
-       		return 0;
-       }
-
-       DEBUGP("IPv6 RT LEN %u %u ", hdrlen, rh->hdrlen);
-       DEBUGP("TYPE %04X ", rh->type);
-       DEBUGP("SGS_LEFT %u %02X\n", rh->segments_left, rh->segments_left);
-
-       DEBUGP("IPv6 RT segsleft %02X ",
-       		(segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1],
-                           rh->segments_left,
-                           !!(rtinfo->invflags & IP6T_RT_INV_SGS))));
-       DEBUGP("type %02X %02X %02X ",
-       		rtinfo->rt_type, rh->type, 
-       		(!(rtinfo->flags & IP6T_RT_TYP) ||
-                           ((rtinfo->rt_type == rh->type) ^
-                           !!(rtinfo->invflags & IP6T_RT_INV_TYP))));
-       DEBUGP("len %02X %04X %02X ",
-       		rtinfo->hdrlen, hdrlen,
-       		(!(rtinfo->flags & IP6T_RT_LEN) ||
-                           ((rtinfo->hdrlen == hdrlen) ^
-                           !!(rtinfo->invflags & IP6T_RT_INV_LEN))));
-       DEBUGP("res %02X %02X %02X ", 
-       		(rtinfo->flags & IP6T_RT_RES), ((struct rt0_hdr *)rh)->reserved,
-       		!((rtinfo->flags & IP6T_RT_RES) && (((struct rt0_hdr *)rh)->reserved)));
-
-       ret = (rh != NULL)
-       		&&
-       		(segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1],
-                           rh->segments_left,
-                           !!(rtinfo->invflags & IP6T_RT_INV_SGS)))
-		&&
-	      	(!(rtinfo->flags & IP6T_RT_LEN) ||
-                           ((rtinfo->hdrlen == hdrlen) ^
-                           !!(rtinfo->invflags & IP6T_RT_INV_LEN)))
-		&&
-       		(!(rtinfo->flags & IP6T_RT_TYP) ||
-                           ((rtinfo->rt_type == rh->type) ^
-                           !!(rtinfo->invflags & IP6T_RT_INV_TYP)));
+	rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route);
+	if (rh == NULL) {
+		*hotdrop = 1;
+		return 0;
+	}
+
+	hdrlen = ipv6_optlen(rh);
+	if (skb->len - ptr < hdrlen) {
+		/* Pcket smaller than its length field */
+		return 0;
+	}
+
+	DEBUGP("IPv6 RT LEN %u %u ", hdrlen, rh->hdrlen);
+	DEBUGP("TYPE %04X ", rh->type);
+	DEBUGP("SGS_LEFT %u %02X\n", rh->segments_left, rh->segments_left);
+
+	DEBUGP("IPv6 RT segsleft %02X ",
+	       (segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1],
+			       rh->segments_left,
+			       !!(rtinfo->invflags & IP6T_RT_INV_SGS))));
+	DEBUGP("type %02X %02X %02X ",
+	       rtinfo->rt_type, rh->type,
+	       (!(rtinfo->flags & IP6T_RT_TYP) ||
+		((rtinfo->rt_type == rh->type) ^
+		 !!(rtinfo->invflags & IP6T_RT_INV_TYP))));
+	DEBUGP("len %02X %04X %02X ",
+	       rtinfo->hdrlen, hdrlen,
+	       (!(rtinfo->flags & IP6T_RT_LEN) ||
+		((rtinfo->hdrlen == hdrlen) ^
+		 !!(rtinfo->invflags & IP6T_RT_INV_LEN))));
+	DEBUGP("res %02X %02X %02X ",
+	       (rtinfo->flags & IP6T_RT_RES),
+	       ((struct rt0_hdr *)rh)->reserved,
+	       !((rtinfo->flags & IP6T_RT_RES) &&
+		 (((struct rt0_hdr *)rh)->reserved)));
+
+	ret = (rh != NULL)
+	      &&
+	      (segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1],
+			      rh->segments_left,
+			      !!(rtinfo->invflags & IP6T_RT_INV_SGS)))
+	      &&
+	      (!(rtinfo->flags & IP6T_RT_LEN) ||
+	       ((rtinfo->hdrlen == hdrlen) ^
+		!!(rtinfo->invflags & IP6T_RT_INV_LEN)))
+	      &&
+	      (!(rtinfo->flags & IP6T_RT_TYP) ||
+	       ((rtinfo->rt_type == rh->type) ^
+		!!(rtinfo->invflags & IP6T_RT_INV_TYP)));
 
 	if (ret && (rtinfo->flags & IP6T_RT_RES)) {
 		u_int32_t *rp, _reserved;
 		rp = skb_header_pointer(skb,
-					ptr + offsetof(struct rt0_hdr, reserved),
-					sizeof(_reserved), &_reserved);
+					ptr + offsetof(struct rt0_hdr,
+						       reserved),
+					sizeof(_reserved),
+					&_reserved);
 
 		ret = (*rp == 0);
 	}
 
-	DEBUGP("#%d ",rtinfo->addrnr);
-       if ( !(rtinfo->flags & IP6T_RT_FST) ){
-	       return ret;
+	DEBUGP("#%d ", rtinfo->addrnr);
+	if (!(rtinfo->flags & IP6T_RT_FST)) {
+		return ret;
 	} else if (rtinfo->flags & IP6T_RT_FST_NSTRICT) {
 		DEBUGP("Not strict ");
-		if ( rtinfo->addrnr > (unsigned int)((hdrlen-8)/16) ){
+		if (rtinfo->addrnr > (unsigned int)((hdrlen - 8) / 16)) {
 			DEBUGP("There isn't enough space\n");
 			return 0;
 		} else {
 			unsigned int i = 0;
 
-			DEBUGP("#%d ",rtinfo->addrnr);
-			for(temp=0; temp<(unsigned int)((hdrlen-8)/16); temp++){
+			DEBUGP("#%d ", rtinfo->addrnr);
+			for (temp = 0;
+			     temp < (unsigned int)((hdrlen - 8) / 16);
+			     temp++) {
 				ap = skb_header_pointer(skb,
 							ptr
 							+ sizeof(struct rt0_hdr)
@@ -141,24 +147,26 @@ match(const struct sk_buff *skb,
 				BUG_ON(ap == NULL);
 
 				if (ipv6_addr_equal(ap, &rtinfo->addrs[i])) {
-					DEBUGP("i=%d temp=%d;\n",i,temp);
+					DEBUGP("i=%d temp=%d;\n", i, temp);
 					i++;
 				}
-				if (i==rtinfo->addrnr) break;
+				if (i == rtinfo->addrnr)
+					break;
 			}
 			DEBUGP("i=%d #%d\n", i, rtinfo->addrnr);
 			if (i == rtinfo->addrnr)
 				return ret;
-			else return 0;
+			else
+				return 0;
 		}
 	} else {
 		DEBUGP("Strict ");
-		if ( rtinfo->addrnr > (unsigned int)((hdrlen-8)/16) ){
+		if (rtinfo->addrnr > (unsigned int)((hdrlen - 8) / 16)) {
 			DEBUGP("There isn't enough space\n");
 			return 0;
 		} else {
-			DEBUGP("#%d ",rtinfo->addrnr);
-			for(temp=0; temp<rtinfo->addrnr; temp++){
+			DEBUGP("#%d ", rtinfo->addrnr);
+			for (temp = 0; temp < rtinfo->addrnr; temp++) {
 				ap = skb_header_pointer(skb,
 							ptr
 							+ sizeof(struct rt0_hdr)
@@ -171,9 +179,11 @@ match(const struct sk_buff *skb,
 					break;
 			}
 			DEBUGP("temp=%d #%d\n", temp, rtinfo->addrnr);
-			if ((temp == rtinfo->addrnr) && (temp == (unsigned int)((hdrlen-8)/16)))
+			if ((temp == rtinfo->addrnr) &&
+			    (temp == (unsigned int)((hdrlen - 8) / 16)))
 				return ret;
-			else return 0;
+			else
+				return 0;
 		}
 	}
 
@@ -183,32 +193,31 @@ match(const struct sk_buff *skb,
 /* Called when user tries to insert an entry of this type. */
 static int
 checkentry(const char *tablename,
-          const void *entry,
-          void *matchinfo,
-          unsigned int matchinfosize,
-          unsigned int hook_mask)
+	   const void *entry,
+	   void *matchinfo,
+	   unsigned int matchinfosize,
+	   unsigned int hook_mask)
 {
-       const struct ip6t_rt *rtinfo = matchinfo;
+	const struct ip6t_rt *rtinfo = matchinfo;
 
-       if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_rt))) {
-              DEBUGP("ip6t_rt: matchsize %u != %u\n",
-                      matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_rt)));
-              return 0;
-       }
-       if (rtinfo->invflags & ~IP6T_RT_INV_MASK) {
-              DEBUGP("ip6t_rt: unknown flags %X\n",
-                      rtinfo->invflags);
-              return 0;
-       }
-       if ( (rtinfo->flags & (IP6T_RT_RES|IP6T_RT_FST_MASK)) && 
-		       (!(rtinfo->flags & IP6T_RT_TYP) || 
-		       (rtinfo->rt_type != 0) || 
-		       (rtinfo->invflags & IP6T_RT_INV_TYP)) ) {
-	      DEBUGP("`--rt-type 0' required before `--rt-0-*'");
-              return 0;
-       }
+	if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_rt))) {
+		DEBUGP("ip6t_rt: matchsize %u != %u\n",
+		       matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_rt)));
+		return 0;
+	}
+	if (rtinfo->invflags & ~IP6T_RT_INV_MASK) {
+		DEBUGP("ip6t_rt: unknown flags %X\n", rtinfo->invflags);
+		return 0;
+	}
+	if ((rtinfo->flags & (IP6T_RT_RES | IP6T_RT_FST_MASK)) &&
+	    (!(rtinfo->flags & IP6T_RT_TYP) ||
+	     (rtinfo->rt_type != 0) ||
+	     (rtinfo->invflags & IP6T_RT_INV_TYP))) {
+		DEBUGP("`--rt-type 0' required before `--rt-0-*'");
+		return 0;
+	}
 
-       return 1;
+	return 1;
 }
 
 static struct ip6t_match rt_match = {
@@ -220,12 +229,12 @@ static struct ip6t_match rt_match = {
 
 static int __init init(void)
 {
-       return ip6t_register_match(&rt_match);
+	return ip6t_register_match(&rt_match);
 }
 
 static void __exit cleanup(void)
 {
-       ip6t_unregister_match(&rt_match);
+	ip6t_unregister_match(&rt_match);
 }
 
 module_init(init);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 66d0400..ca9cf68 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -515,6 +515,7 @@ static int tcp_v6_send_synack(struct soc
 done:
         if (opt && opt != np->opt)
 		sock_kfree_s(sk, opt, opt->tot_len);
+	dst_release(dst);
 	return err;
 }
 
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 43f1ce7..ae86d23 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1620,6 +1620,7 @@ static int key_notify_sa_flush(struct km
 		return -ENOBUFS;
 	hdr = (struct sadb_msg *) skb_put(skb, sizeof(struct sadb_msg));
 	hdr->sadb_msg_satype = pfkey_proto2satype(c->data.proto);
+	hdr->sadb_msg_type = SADB_FLUSH;
 	hdr->sadb_msg_seq = c->seq;
 	hdr->sadb_msg_pid = c->pid;
 	hdr->sadb_msg_version = PF_KEY_V2;
@@ -2385,6 +2386,7 @@ static int key_notify_policy_flush(struc
 	if (!skb_out)
 		return -ENOBUFS;
 	hdr = (struct sadb_msg *) skb_put(skb_out, sizeof(struct sadb_msg));
+	hdr->sadb_msg_type = SADB_X_SPDFLUSH;
 	hdr->sadb_msg_seq = c->seq;
 	hdr->sadb_msg_pid = c->pid;
 	hdr->sadb_msg_version = PF_KEY_V2;
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index ee93abc..9db7dbd 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -365,7 +365,7 @@ static int packet_sendmsg_spkt(struct ki
 	 */
 	 
 	err = -EMSGSIZE;
- 	if(len>dev->mtu+dev->hard_header_len)
+	if (len > dev->mtu + dev->hard_header_len)
 		goto out_unlock;
 
 	err = -ENOBUFS;
@@ -935,7 +935,7 @@ static int packet_bind_spkt(struct socke
 	 *	Check legality
 	 */
 	 
-	if(addr_len!=sizeof(struct sockaddr))
+	if (addr_len != sizeof(struct sockaddr))
 		return -EINVAL;
 	strlcpy(name,uaddr->sa_data,sizeof(name));
 
@@ -1092,7 +1092,7 @@ static int packet_recvmsg(struct kiocb *
 	 *	retries.
 	 */
 
-	if(skb==NULL)
+	if (skb == NULL)
 		goto out;
 
 	/*
@@ -1392,8 +1392,8 @@ static int packet_getsockopt(struct sock
 	if (level != SOL_PACKET)
 		return -ENOPROTOOPT;
 
-  	if (get_user(len,optlen))
-  		return -EFAULT;
+	if (get_user(len, optlen))
+		return -EFAULT;
 
 	if (len < 0)
 		return -EINVAL;
@@ -1419,9 +1419,9 @@ static int packet_getsockopt(struct sock
 		return -ENOPROTOOPT;
 	}
 
-  	if (put_user(len, optlen))
-  		return -EFAULT;
-  	return 0;
+	if (put_user(len, optlen))
+		return -EFAULT;
+	return 0;
 }
 
 
diff --git a/net/rxrpc/krxtimod.c b/net/rxrpc/krxtimod.c
index 3ac81cd..3e74669 100644
--- a/net/rxrpc/krxtimod.c
+++ b/net/rxrpc/krxtimod.c
@@ -81,7 +81,7 @@ static int krxtimod(void *arg)
 
 	for (;;) {
 		unsigned long jif;
-		signed long timeout;
+		long timeout;
 
 		/* deal with the server being asked to die */
 		if (krxtimod_die) {
diff --git a/net/rxrpc/proc.c b/net/rxrpc/proc.c
index 3b5ecd8..29975d9 100644
--- a/net/rxrpc/proc.c
+++ b/net/rxrpc/proc.c
@@ -361,7 +361,7 @@ static void rxrpc_proc_peers_stop(struct
 static int rxrpc_proc_peers_show(struct seq_file *m, void *v)
 {
 	struct rxrpc_peer *peer = list_entry(v, struct rxrpc_peer, proc_link);
-	signed long timeout;
+	long timeout;
 
 	/* display header on line 1 */
 	if (v == SEQ_START_TOKEN) {
@@ -373,8 +373,8 @@ static int rxrpc_proc_peers_show(struct 
 	/* display one peer per line on subsequent lines */
 	timeout = 0;
 	if (!list_empty(&peer->timeout.link))
-		timeout = (signed long) peer->timeout.timo_jif -
-			(signed long) jiffies;
+		timeout = (long) peer->timeout.timo_jif -
+			(long) jiffies;
 
 	seq_printf(m, "%5hu %08x %5d %5d %8ld %5Zu %7lu\n",
 		   peer->trans->port,
@@ -468,7 +468,7 @@ static void rxrpc_proc_conns_stop(struct
 static int rxrpc_proc_conns_show(struct seq_file *m, void *v)
 {
 	struct rxrpc_connection *conn;
-	signed long timeout;
+	long timeout;
 
 	conn = list_entry(v, struct rxrpc_connection, proc_link);
 
@@ -484,8 +484,8 @@ static int rxrpc_proc_conns_show(struct 
 	/* display one conn per line on subsequent lines */
 	timeout = 0;
 	if (!list_empty(&conn->timeout.link))
-		timeout = (signed long) conn->timeout.timo_jif -
-			(signed long) jiffies;
+		timeout = (long) conn->timeout.timo_jif -
+			(long) jiffies;
 
 	seq_printf(m,
 		   "%5hu %08x %5hu %04hx %08x %-3.3s %08x %08x %5Zu %8ld\n",
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index 5b3a3e4..1641db3 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -228,14 +228,13 @@ static int prio_tune(struct Qdisc *sch, 
 	}
 	sch_tree_unlock(sch);
 
-	for (i=0; i<=TC_PRIO_MAX; i++) {
-		int band = q->prio2band[i];
-		if (q->queues[band] == &noop_qdisc) {
+	for (i=0; i<q->bands; i++) {
+		if (q->queues[i] == &noop_qdisc) {
 			struct Qdisc *child;
 			child = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
 			if (child) {
 				sch_tree_lock(sch);
-				child = xchg(&q->queues[band], child);
+				child = xchg(&q->queues[i], child);
 
 				if (child != &noop_qdisc)
 					qdisc_destroy(child);
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 8734bb7..86d8da0 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -144,6 +144,8 @@ static unsigned sfq_hash(struct sfq_sche
 		if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
 		    (iph->protocol == IPPROTO_TCP ||
 		     iph->protocol == IPPROTO_UDP ||
+		     iph->protocol == IPPROTO_SCTP ||
+		     iph->protocol == IPPROTO_DCCP ||
 		     iph->protocol == IPPROTO_ESP))
 			h2 ^= *(((u32*)iph) + iph->ihl);
 		break;
@@ -155,6 +157,8 @@ static unsigned sfq_hash(struct sfq_sche
 		h2 = iph->saddr.s6_addr32[3]^iph->nexthdr;
 		if (iph->nexthdr == IPPROTO_TCP ||
 		    iph->nexthdr == IPPROTO_UDP ||
+		    iph->nexthdr == IPPROTO_SCTP ||
+		    iph->nexthdr == IPPROTO_DCCP ||
 		    iph->nexthdr == IPPROTO_ESP)
 			h2 ^= *(u32*)&iph[1];
 		break;
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 4aa6fc6..cb78b50 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -257,20 +257,26 @@ int sctp_rcv(struct sk_buff *skb)
 	 */
 	sctp_bh_lock_sock(sk);
 
+	/* It is possible that the association could have moved to a different
+	 * socket if it is peeled off. If so, update the sk.
+	 */ 
+	if (sk != rcvr->sk) {
+		sctp_bh_lock_sock(rcvr->sk);
+		sctp_bh_unlock_sock(sk);
+		sk = rcvr->sk;
+	}
+
 	if (sock_owned_by_user(sk))
 		sk_add_backlog(sk, skb);
 	else
 		sctp_backlog_rcv(sk, skb);
 
-	/* Release the sock and any reference counts we took in the
-	 * lookup calls.
+	/* Release the sock and the sock ref we took in the lookup calls.
+	 * The asoc/ep ref will be released in sctp_backlog_rcv.
 	 */
 	sctp_bh_unlock_sock(sk);
-	if (asoc)
-		sctp_association_put(asoc);
-	else
-		sctp_endpoint_put(ep);
 	sock_put(sk);
+
 	return ret;
 
 discard_it:
@@ -296,12 +302,50 @@ discard_release:
 int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb)
 {
 	struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk;
-	struct sctp_inq *inqueue = &chunk->rcvr->inqueue;
+ 	struct sctp_inq *inqueue = NULL;
+ 	struct sctp_ep_common *rcvr = NULL;
+
+ 	rcvr = chunk->rcvr;
 
-	sctp_inq_push(inqueue, chunk);
+	BUG_TRAP(rcvr->sk == sk);
+
+ 	if (rcvr->dead) {
+ 		sctp_chunk_free(chunk);
+ 	} else {
+ 		inqueue = &chunk->rcvr->inqueue;
+ 		sctp_inq_push(inqueue, chunk);
+ 	}
+
+	/* Release the asoc/ep ref we took in the lookup calls in sctp_rcv. */ 
+ 	if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type)
+ 		sctp_association_put(sctp_assoc(rcvr));
+ 	else
+ 		sctp_endpoint_put(sctp_ep(rcvr));
+  
         return 0;
 }
 
+void sctp_backlog_migrate(struct sctp_association *assoc, 
+			  struct sock *oldsk, struct sock *newsk)
+{
+	struct sk_buff *skb;
+	struct sctp_chunk *chunk;
+
+	skb = oldsk->sk_backlog.head;
+	oldsk->sk_backlog.head = oldsk->sk_backlog.tail = NULL;
+	while (skb != NULL) {
+		struct sk_buff *next = skb->next;
+
+		chunk = SCTP_INPUT_CB(skb)->chunk;
+		skb->next = NULL;
+		if (&assoc->base == chunk->rcvr)
+			sk_add_backlog(newsk, skb);
+		else
+			sk_add_backlog(oldsk, skb);
+		skb = next;
+	}
+}
+
 /* Handle icmp frag needed error. */
 void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
 			   struct sctp_transport *t, __u32 pmtu)
@@ -544,10 +588,16 @@ int sctp_rcv_ootb(struct sk_buff *skb)
 	sctp_errhdr_t *err;
 
 	ch = (sctp_chunkhdr_t *) skb->data;
-	ch_end = ((__u8 *) ch) + WORD_ROUND(ntohs(ch->length));
 
 	/* Scan through all the chunks in the packet.  */
-	while (ch_end > (__u8 *)ch && ch_end < skb->tail) {
+	do {
+		/* Break out if chunk length is less then minimal. */
+		if (ntohs(ch->length) < sizeof(sctp_chunkhdr_t))
+			break;
+
+		ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
+		if (ch_end > skb->tail)
+			break;
 
 		/* RFC 8.4, 2) If the OOTB packet contains an ABORT chunk, the
 		 * receiver MUST silently discard the OOTB packet and take no
@@ -578,8 +628,7 @@ int sctp_rcv_ootb(struct sk_buff *skb)
 		}
 
 		ch = (sctp_chunkhdr_t *) ch_end;
-	        ch_end = ((__u8 *) ch) + WORD_ROUND(ntohs(ch->length));
-	}
+	} while (ch_end < skb->tail);
 
 	return 0;
 
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c
index 2d33922..297b895 100644
--- a/net/sctp/inqueue.c
+++ b/net/sctp/inqueue.c
@@ -73,8 +73,10 @@ void sctp_inq_free(struct sctp_inq *queu
 	/* If there is a packet which is currently being worked on,
 	 * free it as well.
 	 */
-	if (queue->in_progress)
+	if (queue->in_progress) {
 		sctp_chunk_free(queue->in_progress);
+		queue->in_progress = NULL;
+	}
 
 	if (queue->malloced) {
 		/* Dump the master memory segment.  */
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index 6e4dc28..d47a52c 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -176,7 +176,7 @@ static void sctp_seq_dump_remote_addrs(s
 
 static void * sctp_eps_seq_start(struct seq_file *seq, loff_t *pos)
 {
-	if (*pos > sctp_ep_hashsize)
+	if (*pos >= sctp_ep_hashsize)
 		return NULL;
 
 	if (*pos < 0)
@@ -185,8 +185,6 @@ static void * sctp_eps_seq_start(struct 
 	if (*pos == 0)
 		seq_printf(seq, " ENDPT     SOCK   STY SST HBKT LPORT   UID INODE LADDRS\n");
 
-	++*pos;
-
 	return (void *)pos;
 }
 
@@ -198,11 +196,9 @@ static void sctp_eps_seq_stop(struct seq
 
 static void * sctp_eps_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-	if (*pos > sctp_ep_hashsize)
+	if (++*pos >= sctp_ep_hashsize)
 		return NULL;
 
-	++*pos;
-
 	return pos;
 }
 
@@ -214,19 +210,19 @@ static int sctp_eps_seq_show(struct seq_
 	struct sctp_ep_common *epb;
 	struct sctp_endpoint *ep;
 	struct sock *sk;
-	int    hash = *(int *)v;
+	int    hash = *(loff_t *)v;
 
-	if (hash > sctp_ep_hashsize)
+	if (hash >= sctp_ep_hashsize)
 		return -ENOMEM;
 
-	head = &sctp_ep_hashtable[hash-1];
+	head = &sctp_ep_hashtable[hash];
 	sctp_local_bh_disable();
 	read_lock(&head->lock);
 	for (epb = head->chain; epb; epb = epb->next) {
 		ep = sctp_ep(epb);
 		sk = epb->sk;
 		seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk,
-			   sctp_sk(sk)->type, sk->sk_state, hash-1,
+			   sctp_sk(sk)->type, sk->sk_state, hash,
 			   epb->bind_addr.port,
 			   sock_i_uid(sk), sock_i_ino(sk));
 
@@ -283,7 +279,7 @@ void sctp_eps_proc_exit(void)
 
 static void * sctp_assocs_seq_start(struct seq_file *seq, loff_t *pos)
 {
-	if (*pos > sctp_assoc_hashsize)
+	if (*pos >= sctp_assoc_hashsize)
 		return NULL;
 
 	if (*pos < 0)
@@ -293,8 +289,6 @@ static void * sctp_assocs_seq_start(stru
 		seq_printf(seq, " ASSOC     SOCK   STY SST ST HBKT ASSOC-ID TX_QUEUE RX_QUEUE UID INODE LPORT "
 				"RPORT LADDRS <-> RADDRS\n");
 
-	++*pos;
-
 	return (void *)pos;
 }
 
@@ -306,11 +300,9 @@ static void sctp_assocs_seq_stop(struct 
 
 static void * sctp_assocs_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-	if (*pos > sctp_assoc_hashsize)
+	if (++*pos >= sctp_assoc_hashsize)
 		return NULL;
 
-	++*pos;
-
 	return pos;
 }
 
@@ -321,12 +313,12 @@ static int sctp_assocs_seq_show(struct s
 	struct sctp_ep_common *epb;
 	struct sctp_association *assoc;
 	struct sock *sk;
-	int    hash = *(int *)v;
+	int    hash = *(loff_t *)v;
 
-	if (hash > sctp_assoc_hashsize)
+	if (hash >= sctp_assoc_hashsize)
 		return -ENOMEM;
 
-	head = &sctp_assoc_hashtable[hash-1];
+	head = &sctp_assoc_hashtable[hash];
 	sctp_local_bh_disable();
 	read_lock(&head->lock);
 	for (epb = head->chain; epb; epb = epb->next) {
@@ -335,7 +327,7 @@ static int sctp_assocs_seq_show(struct s
 		seq_printf(seq,
 			   "%8p %8p %-3d %-3d %-2d %-4d %4d %8d %8d %7d %5lu %-5d %5d ",
 			   assoc, sk, sctp_sk(sk)->type, sk->sk_state,
-			   assoc->state, hash-1, assoc->assoc_id,
+			   assoc->state, hash, assoc->assoc_id,
 			   (sk->sk_rcvbuf - assoc->rwnd),
 			   assoc->sndbuf_used,
 			   sock_i_uid(sk), sock_i_ino(sk),
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 556c495..5e0de3c 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1275,7 +1275,12 @@ static sctp_cookie_param_t *sctp_pack_co
 	unsigned int keylen;
 	char *key;
 
-	headersize = sizeof(sctp_paramhdr_t) + SCTP_SECRET_SIZE;
+	/* Header size is static data prior to the actual cookie, including
+	 * any padding.
+	 */
+	headersize = sizeof(sctp_paramhdr_t) + 
+		     (sizeof(struct sctp_signed_cookie) - 
+		      sizeof(struct sctp_cookie));
 	bodysize = sizeof(struct sctp_cookie)
 		+ ntohs(init_chunk->chunk_hdr->length) + addrs_len;
 
@@ -1354,7 +1359,7 @@ struct sctp_association *sctp_unpack_coo
 	struct sctp_signed_cookie *cookie;
 	struct sctp_cookie *bear_cookie;
 	int headersize, bodysize, fixed_size;
-	__u8 digest[SCTP_SIGNATURE_SIZE];
+	__u8 *digest = ep->digest;
 	struct scatterlist sg;
 	unsigned int keylen, len;
 	char *key;
@@ -1362,7 +1367,12 @@ struct sctp_association *sctp_unpack_coo
 	struct sk_buff *skb = chunk->skb;
 	struct timeval tv;
 
-	headersize = sizeof(sctp_chunkhdr_t) + SCTP_SECRET_SIZE;
+	/* Header size is static data prior to the actual cookie, including
+	 * any padding.
+	 */
+	headersize = sizeof(sctp_chunkhdr_t) +
+		     (sizeof(struct sctp_signed_cookie) - 
+		      sizeof(struct sctp_cookie));
 	bodysize = ntohs(chunk->chunk_hdr->length) - headersize;
 	fixed_size = headersize + sizeof(struct sctp_cookie);
 
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index b8b38ab..8d1dc24 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1300,7 +1300,7 @@ static int sctp_cmd_interpreter(sctp_eve
 					"T1 INIT Timeout adjustment"
 					" init_err_counter: %d"
 					" cycle: %d"
-					" timeout: %d\n",
+					" timeout: %ld\n",
 					asoc->init_err_counter,
 					asoc->init_cycle,
 					asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT]);
@@ -1328,7 +1328,7 @@ static int sctp_cmd_interpreter(sctp_eve
 			SCTP_DEBUG_PRINTK(
 				"T1 COOKIE Timeout adjustment"
 				" init_err_counter: %d"
-				" timeout: %d\n",
+				" timeout: %ld\n",
 				asoc->init_err_counter,
 				asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE]);
 
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 477d7f8..2b9a832 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -884,7 +884,7 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(
 {
 	struct sctp_transport *transport = (struct sctp_transport *) arg;
 
-	if (asoc->overall_error_count > asoc->max_retrans) {
+	if (asoc->overall_error_count >= asoc->max_retrans) {
 		/* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
 		sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
 				SCTP_U32(SCTP_ERROR_NO_ERROR));
@@ -2122,7 +2122,7 @@ static sctp_disposition_t sctp_sf_do_5_2
 	struct sctp_bind_addr *bp;
 	int attempts = asoc->init_err_counter + 1;
 
-	if (attempts >= asoc->max_init_attempts) {
+	if (attempts > asoc->max_init_attempts) {
 		sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
 				SCTP_U32(SCTP_ERROR_STALE_COOKIE));
 		return SCTP_DISPOSITION_DELETE_TCB;
@@ -3090,6 +3090,8 @@ sctp_disposition_t sctp_sf_ootb(const st
 			break;
 
 		ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
+		if (ch_end > skb->tail)
+			break;
 
 		if (SCTP_CID_SHUTDOWN_ACK == ch->type)
 			ootb_shut_ack = 1;
@@ -4638,7 +4640,7 @@ sctp_disposition_t sctp_sf_t1_init_timer
 
 	SCTP_DEBUG_PRINTK("Timer T1 expired (INIT).\n");
 
-	if (attempts < asoc->max_init_attempts) {
+	if (attempts <= asoc->max_init_attempts) {
 		bp = (struct sctp_bind_addr *) &asoc->base.bind_addr;
 		repl = sctp_make_init(asoc, bp, GFP_ATOMIC, 0);
 		if (!repl)
@@ -4695,7 +4697,7 @@ sctp_disposition_t sctp_sf_t1_cookie_tim
 
 	SCTP_DEBUG_PRINTK("Timer T1 expired (COOKIE-ECHO).\n");
 
-	if (attempts < asoc->max_init_attempts) {
+	if (attempts <= asoc->max_init_attempts) {
 		repl = sctp_make_cookie_echo(asoc, NULL);
 		if (!repl)
 			return SCTP_DISPOSITION_NOMEM;
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index c98ee37..0ea947e 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2995,7 +2995,7 @@ SCTP_STATIC int sctp_init_sock(struct so
 	sp->hbinterval  = jiffies_to_msecs(sctp_hb_interval);
 	sp->pathmaxrxt  = sctp_max_retrans_path;
 	sp->pathmtu     = 0; // allow default discovery
-	sp->sackdelay   = sctp_sack_timeout;
+	sp->sackdelay   = jiffies_to_msecs(sctp_sack_timeout);
 	sp->param_flags = SPP_HB_ENABLE |
 	                  SPP_PMTUD_ENABLE |
 	                  SPP_SACKDELAY_ENABLE;
@@ -5426,7 +5426,7 @@ out:
 	return err;
 
 do_error:
-	if (asoc->init_err_counter + 1 >= asoc->max_init_attempts)
+	if (asoc->init_err_counter + 1 > asoc->max_init_attempts)
 		err = -ETIMEDOUT;
 	else
 		err = -ECONNREFUSED;
@@ -5602,8 +5602,12 @@ static void sctp_sock_migrate(struct soc
 	 */
 	newsp->type = type;
 
+	spin_lock_bh(&oldsk->sk_lock.slock);
+	/* Migrate the backlog from oldsk to newsk. */
+	sctp_backlog_migrate(assoc, oldsk, newsk);
 	/* Migrate the association to the new socket. */
 	sctp_assoc_migrate(assoc, newsk);
+	spin_unlock_bh(&oldsk->sk_lock.slock);
 
 	/* If the association on the newsk is already closed before accept()
 	 * is called, set RCV_SHUTDOWN flag.
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index fcd7096..dc6f3ff 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -159,12 +159,9 @@ static ctl_table sctp_table[] = {
 		.ctl_name	= NET_SCTP_PRESERVE_ENABLE,
 		.procname	= "cookie_preserve_enable",
 		.data		= &sctp_cookie_preserve_enable,
-		.maxlen		= sizeof(long),
+		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &proc_doulongvec_ms_jiffies_minmax,
-		.strategy	= &sctp_sysctl_jiffies_ms,
-		.extra1         = &rto_timer_min,
-		.extra2         = &rto_timer_max
+		.proc_handler	= &proc_dointvec
 	},
 	{
 		.ctl_name	= NET_SCTP_RTO_ALPHA,
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 68d73e2..160f62a 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -350,7 +350,7 @@ void sctp_transport_update_rto(struct sc
 	tp->rto_pending = 0;
 
 	SCTP_DEBUG_PRINTK("%s: transport: %p, rtt: %d, srtt: %d "
-			  "rttvar: %d, rto: %d\n", __FUNCTION__,
+			  "rttvar: %d, rto: %ld\n", __FUNCTION__,
 			  tp, rtt, tp->srtt, tp->rttvar, tp->rto);
 }
 
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index e4ada15..23632d8 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -420,7 +420,8 @@ static int rsc_parse(struct cache_detail
 			gss_mech_put(gm);
 			goto out;
 		}
-		if (gss_import_sec_context(buf, len, gm, &rsci.mechctx)) {
+		status = gss_import_sec_context(buf, len, gm, &rsci.mechctx);
+		if (status) {
 			gss_mech_put(gm);
 			goto out;
 		}
@@ -586,6 +587,20 @@ gss_verify_header(struct svc_rqst *rqstp
 }
 
 static int
+gss_write_null_verf(struct svc_rqst *rqstp)
+{
+	u32     *p;
+
+	svc_putu32(rqstp->rq_res.head, htonl(RPC_AUTH_NULL));
+	p = rqstp->rq_res.head->iov_base + rqstp->rq_res.head->iov_len;
+	/* don't really need to check if head->iov_len > PAGE_SIZE ... */
+	*p++ = 0;
+	if (!xdr_ressize_check(rqstp, p))
+		return -1;
+	return 0;
+}
+
+static int
 gss_write_verf(struct svc_rqst *rqstp, struct gss_ctx *ctx_id, u32 seq)
 {
 	u32			xdr_seq;
@@ -741,6 +756,21 @@ svcauth_gss_set_client(struct svc_rqst *
 	return SVC_OK;
 }
 
+static inline int
+gss_write_init_verf(struct svc_rqst *rqstp, struct rsi *rsip)
+{
+	struct rsc *rsci;
+
+	if (rsip->major_status != GSS_S_COMPLETE)
+		return gss_write_null_verf(rqstp);
+	rsci = gss_svc_searchbyctx(&rsip->out_handle);
+	if (rsci == NULL) {
+		rsip->major_status = GSS_S_NO_CONTEXT;
+		return gss_write_null_verf(rqstp);
+	}
+	return gss_write_verf(rqstp, rsci->mechctx, GSS_SEQ_WIN);
+}
+
 /*
  * Accept an rpcsec packet.
  * If context establishment, punt to user space
@@ -876,11 +906,7 @@ svcauth_gss_accept(struct svc_rqst *rqst
 		case -ENOENT:
 			goto drop;
 		case 0:
-			rsci = gss_svc_searchbyctx(&rsip->out_handle);
-			if (!rsci) {
-				goto drop;
-			}
-			if (gss_write_verf(rqstp, rsci->mechctx, GSS_SEQ_WIN))
+			if (gss_write_init_verf(rqstp, rsip))
 				goto drop;
 			if (resv->iov_len + 4 > PAGE_SIZE)
 				goto drop;
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 7415406..802d4fe 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -908,10 +908,10 @@ void rpc_release_task(struct rpc_task *t
 
 /**
  * rpc_run_task - Allocate a new RPC task, then run rpc_execute against it
- * @clnt - pointer to RPC client
- * @flags - RPC flags
- * @ops - RPC call ops
- * @data - user call data
+ * @clnt: pointer to RPC client
+ * @flags: RPC flags
+ * @ops: RPC call ops
+ * @data: user call data
  */
 struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags,
 					const struct rpc_call_ops *ops,
@@ -930,6 +930,7 @@ EXPORT_SYMBOL(rpc_run_task);
 /**
  * rpc_find_parent - find the parent of a child task.
  * @child: child task
+ * @parent: parent task
  *
  * Checks that the parent task is still sleeping on the
  * queue 'childq'. If so returns a pointer to the parent.
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index e67613e..5058062 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -1527,6 +1527,7 @@ svc_defer(struct cache_req *req)
 		dr->handle.owner = rqstp->rq_server;
 		dr->prot = rqstp->rq_prot;
 		dr->addr = rqstp->rq_addr;
+		dr->daddr = rqstp->rq_daddr;
 		dr->argslen = rqstp->rq_arg.len >> 2;
 		memcpy(dr->args, rqstp->rq_arg.head[0].iov_base-skip, dr->argslen<<2);
 	}
@@ -1552,6 +1553,7 @@ static int svc_deferred_recv(struct svc_
 	rqstp->rq_arg.len = dr->argslen<<2;
 	rqstp->rq_prot        = dr->prot;
 	rqstp->rq_addr        = dr->addr;
+	rqstp->rq_daddr       = dr->daddr;
 	return dr->argslen<<2;
 }
 
diff --git a/net/tipc/Kconfig b/net/tipc/Kconfig
index 05ab18e..3891cc0 100644
--- a/net/tipc/Kconfig
+++ b/net/tipc/Kconfig
@@ -8,7 +8,12 @@ menu "TIPC Configuration (EXPERIMENTAL)"
 config TIPC
 	tristate "The TIPC Protocol (EXPERIMENTAL)"
 	---help---
-	  TBD.
+	  The Transparent Inter Process Communication (TIPC) protocol is
+	  specially designed for intra cluster communication. This protocol
+	  originates from Ericsson where it has been used in carrier grade
+	  cluster applications for many years.
+	
+	  For more information about TIPC, see http://tipc.sourceforge.net.
 
 	  This protocol support is also available as a module ( = code which
 	  can be inserted in and removed from the running kernel whenever you
diff --git a/net/tipc/addr.c b/net/tipc/addr.c
index eca2226..0be25e1 100644
--- a/net/tipc/addr.c
+++ b/net/tipc/addr.c
@@ -47,7 +47,7 @@ u32 tipc_get_addr(void)
 }
 
 /**
- * addr_domain_valid - validates a network domain address
+ * tipc_addr_domain_valid - validates a network domain address
  * 
  * Accepts <Z.C.N>, <Z.C.0>, <Z.0.0>, and <0.0.0>, 
  * where Z, C, and N are non-zero and do not exceed the configured limits.
@@ -55,7 +55,7 @@ u32 tipc_get_addr(void)
  * Returns 1 if domain address is valid, otherwise 0
  */
 
-int addr_domain_valid(u32 addr)
+int tipc_addr_domain_valid(u32 addr)
 {
 	u32 n = tipc_node(addr);
 	u32 c = tipc_cluster(addr);
@@ -79,7 +79,7 @@ int addr_domain_valid(u32 addr)
 }
 
 /**
- * addr_node_valid - validates a proposed network address for this node
+ * tipc_addr_node_valid - validates a proposed network address for this node
  * 
  * Accepts <Z.C.N>, where Z, C, and N are non-zero and do not exceed 
  * the configured limits.
@@ -87,8 +87,8 @@ int addr_domain_valid(u32 addr)
  * Returns 1 if address can be used, otherwise 0
  */
 
-int addr_node_valid(u32 addr)
+int tipc_addr_node_valid(u32 addr)
 {
-	return (addr_domain_valid(addr) && tipc_node(addr));
+	return (tipc_addr_domain_valid(addr) && tipc_node(addr));
 }
 
diff --git a/net/tipc/addr.h b/net/tipc/addr.h
index 02ca717..bcfebb3 100644
--- a/net/tipc/addr.h
+++ b/net/tipc/addr.h
@@ -122,7 +122,7 @@ static inline char *addr_string_fill(cha
 	return string;
 }
 
-int addr_domain_valid(u32);
-int addr_node_valid(u32 addr);
+int tipc_addr_domain_valid(u32);
+int tipc_addr_node_valid(u32 addr);
 
 #endif
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 9713d62..a7b04f3 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -82,7 +82,7 @@ struct bcbearer {
 	struct bearer bearer;
 	struct media media;
 	struct bcbearer_pair bpairs[MAX_BEARERS];
-	struct bcbearer_pair bpairs_temp[TIPC_NUM_LINK_PRI];
+	struct bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1];
 };
 
 /**
@@ -104,7 +104,7 @@ static struct bclink *bclink = NULL;
 static struct link *bcl = NULL;
 static spinlock_t bc_lock = SPIN_LOCK_UNLOCKED;
 
-char bc_link_name[] = "multicast-link";
+char tipc_bclink_name[] = "multicast-link";
 
 
 static inline u32 buf_seqno(struct sk_buff *buf)
@@ -178,19 +178,19 @@ static void bclink_retransmit_pkt(u32 af
 		buf = buf->next;                
 	}
 	if (buf != NULL)
-		link_retransmit(bcl, buf, mod(to - after));
+		tipc_link_retransmit(bcl, buf, mod(to - after));
 	spin_unlock_bh(&bc_lock);              
 }
 
 /** 
- * bclink_acknowledge - handle acknowledgement of broadcast packets
+ * tipc_bclink_acknowledge - handle acknowledgement of broadcast packets
  * @n_ptr: node that sent acknowledgement info
  * @acked: broadcast sequence # that has been acknowledged
  * 
  * Node is locked, bc_lock unlocked.
  */
 
-void bclink_acknowledge(struct node *n_ptr, u32 acked)
+void tipc_bclink_acknowledge(struct node *n_ptr, u32 acked)
 {
 	struct sk_buff *crs;
 	struct sk_buff *next;
@@ -226,16 +226,16 @@ void bclink_acknowledge(struct node *n_p
 	/* Try resolving broadcast link congestion, if necessary */
 
 	if (unlikely(bcl->next_out))
-		link_push_queue(bcl);
+		tipc_link_push_queue(bcl);
 	if (unlikely(released && !list_empty(&bcl->waiting_ports)))
-		link_wakeup_ports(bcl, 0);
+		tipc_link_wakeup_ports(bcl, 0);
 	spin_unlock_bh(&bc_lock);
 }
 
 /** 
  * bclink_send_ack - unicast an ACK msg
  * 
- * net_lock and node lock set
+ * tipc_net_lock and node lock set
  */
 
 static void bclink_send_ack(struct node *n_ptr)
@@ -243,13 +243,13 @@ static void bclink_send_ack(struct node 
 	struct link *l_ptr = n_ptr->active_links[n_ptr->addr & 1];
 
 	if (l_ptr != NULL)
-		link_send_proto_msg(l_ptr, STATE_MSG, 0, 0, 0, 0, 0);
+		tipc_link_send_proto_msg(l_ptr, STATE_MSG, 0, 0, 0, 0, 0);
 }
 
 /** 
  * bclink_send_nack- broadcast a NACK msg
  * 
- * net_lock and node lock set
+ * tipc_net_lock and node lock set
  */
 
 static void bclink_send_nack(struct node *n_ptr)
@@ -271,11 +271,11 @@ static void bclink_send_nack(struct node
 		msg_set_bcgap_to(msg, n_ptr->bclink.gap_to);
 		msg_set_bcast_tag(msg, tipc_own_tag);
 
-		if (bearer_send(&bcbearer->bearer, buf, 0)) {
+		if (tipc_bearer_send(&bcbearer->bearer, buf, 0)) {
 			bcl->stats.sent_nacks++;
 			buf_discard(buf);
 		} else {
-			bearer_schedule(bcl->b_ptr, bcl);
+			tipc_bearer_schedule(bcl->b_ptr, bcl);
 			bcl->proto_msg_queue = buf;
 			bcl->stats.bearer_congs++;
 		}
@@ -291,12 +291,12 @@ static void bclink_send_nack(struct node
 }
 
 /** 
- * bclink_check_gap - send a NACK if a sequence gap exists
+ * tipc_bclink_check_gap - send a NACK if a sequence gap exists
  *
- * net_lock and node lock set
+ * tipc_net_lock and node lock set
  */
 
-void bclink_check_gap(struct node *n_ptr, u32 last_sent)
+void tipc_bclink_check_gap(struct node *n_ptr, u32 last_sent)
 {
 	if (!n_ptr->bclink.supported ||
 	    less_eq(last_sent, mod(n_ptr->bclink.last_in)))
@@ -309,19 +309,19 @@ void bclink_check_gap(struct node *n_ptr
 }
 
 /** 
- * bclink_peek_nack - process a NACK msg meant for another node
+ * tipc_bclink_peek_nack - process a NACK msg meant for another node
  * 
- * Only net_lock set.
+ * Only tipc_net_lock set.
  */
 
-void bclink_peek_nack(u32 dest, u32 sender_tag, u32 gap_after, u32 gap_to)
+void tipc_bclink_peek_nack(u32 dest, u32 sender_tag, u32 gap_after, u32 gap_to)
 {
-	struct node *n_ptr = node_find(dest);
+	struct node *n_ptr = tipc_node_find(dest);
 	u32 my_after, my_to;
 
-	if (unlikely(!n_ptr || !node_is_up(n_ptr)))
+	if (unlikely(!n_ptr || !tipc_node_is_up(n_ptr)))
 		return;
-	node_lock(n_ptr);
+	tipc_node_lock(n_ptr);
 	/*
 	 * Modify gap to suppress unnecessary NACKs from this node
 	 */
@@ -364,20 +364,20 @@ void bclink_peek_nack(u32 dest, u32 send
 			bclink_set_gap(n_ptr);
 		}
 	}
-	node_unlock(n_ptr);
+	tipc_node_unlock(n_ptr);
 }
 
 /**
- * bclink_send_msg - broadcast a packet to all nodes in cluster
+ * tipc_bclink_send_msg - broadcast a packet to all nodes in cluster
  */
 
-int bclink_send_msg(struct sk_buff *buf)
+int tipc_bclink_send_msg(struct sk_buff *buf)
 {
 	int res;
 
 	spin_lock_bh(&bc_lock);
 
-	res = link_send_buf(bcl, buf);
+	res = tipc_link_send_buf(bcl, buf);
 	if (unlikely(res == -ELINKCONG))
 		buf_discard(buf);
 	else
@@ -393,22 +393,22 @@ int bclink_send_msg(struct sk_buff *buf)
 }
 
 /**
- * bclink_recv_pkt - receive a broadcast packet, and deliver upwards
+ * tipc_bclink_recv_pkt - receive a broadcast packet, and deliver upwards
  * 
- * net_lock is read_locked, no other locks set
+ * tipc_net_lock is read_locked, no other locks set
  */
 
-void bclink_recv_pkt(struct sk_buff *buf)
+void tipc_bclink_recv_pkt(struct sk_buff *buf)
 {        
 	struct tipc_msg *msg = buf_msg(buf);
-	struct node* node = node_find(msg_prevnode(msg));
+	struct node* node = tipc_node_find(msg_prevnode(msg));
 	u32 next_in;
 	u32 seqno;
 	struct sk_buff *deferred;
 
 	msg_dbg(msg, "<BC<<<");
 
-	if (unlikely(!node || !node_is_up(node) || !node->bclink.supported || 
+	if (unlikely(!node || !tipc_node_is_up(node) || !node->bclink.supported || 
 		     (msg_mc_netid(msg) != tipc_net_id))) {
 		buf_discard(buf);
 		return;
@@ -417,14 +417,14 @@ void bclink_recv_pkt(struct sk_buff *buf
 	if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) {
 		msg_dbg(msg, "<BCNACK<<<");
 		if (msg_destnode(msg) == tipc_own_addr) {
-			node_lock(node);
-			bclink_acknowledge(node, msg_bcast_ack(msg));
-			node_unlock(node);
+			tipc_node_lock(node);
+			tipc_bclink_acknowledge(node, msg_bcast_ack(msg));
+			tipc_node_unlock(node);
 			bcl->stats.recv_nacks++;
 			bclink_retransmit_pkt(msg_bcgap_after(msg),
 					      msg_bcgap_to(msg));
 		} else {
-			bclink_peek_nack(msg_destnode(msg),
+			tipc_bclink_peek_nack(msg_destnode(msg),
 					 msg_bcast_tag(msg),
 					 msg_bcgap_after(msg),
 					 msg_bcgap_to(msg));
@@ -433,7 +433,7 @@ void bclink_recv_pkt(struct sk_buff *buf
 		return;
 	}
 
-	node_lock(node);
+	tipc_node_lock(node);
 receive:
 	deferred = node->bclink.deferred_head;
 	next_in = mod(node->bclink.last_in + 1);
@@ -448,26 +448,26 @@ receive:
 			bcl->stats.sent_acks++;
 		}
 		if (likely(msg_isdata(msg))) {
-			node_unlock(node);
-			port_recv_mcast(buf, NULL);
+			tipc_node_unlock(node);
+			tipc_port_recv_mcast(buf, NULL);
 		} else if (msg_user(msg) == MSG_BUNDLER) {
 			bcl->stats.recv_bundles++;
 			bcl->stats.recv_bundled += msg_msgcnt(msg);
-			node_unlock(node);
-			link_recv_bundle(buf);
+			tipc_node_unlock(node);
+			tipc_link_recv_bundle(buf);
 		} else if (msg_user(msg) == MSG_FRAGMENTER) {
 			bcl->stats.recv_fragments++;
-			if (link_recv_fragment(&node->bclink.defragm,
-					       &buf, &msg))
+			if (tipc_link_recv_fragment(&node->bclink.defragm,
+						    &buf, &msg))
 				bcl->stats.recv_fragmented++;
-			node_unlock(node);
-			net_route_msg(buf);
+			tipc_node_unlock(node);
+			tipc_net_route_msg(buf);
 		} else {
-			node_unlock(node);
-			net_route_msg(buf);
+			tipc_node_unlock(node);
+			tipc_net_route_msg(buf);
 		}
 		if (deferred && (buf_seqno(deferred) == mod(next_in + 1))) {
-			node_lock(node);
+			tipc_node_lock(node);
 			buf = deferred;
 			msg = buf_msg(buf);
 			node->bclink.deferred_head = deferred->next;
@@ -478,9 +478,9 @@ receive:
 		u32 gap_after = node->bclink.gap_after;
 		u32 gap_to = node->bclink.gap_to;
 
-		if (link_defer_pkt(&node->bclink.deferred_head,
-				   &node->bclink.deferred_tail,
-				   buf)) {
+		if (tipc_link_defer_pkt(&node->bclink.deferred_head,
+					&node->bclink.deferred_tail,
+					buf)) {
 			node->bclink.nack_sync++;
 			bcl->stats.deferred_recv++;
 			if (seqno == mod(gap_after + 1))
@@ -497,10 +497,10 @@ receive:
 		bcl->stats.duplicates++;
 		buf_discard(buf);
 	}
-	node_unlock(node);
+	tipc_node_unlock(node);
 }
 
-u32 bclink_get_last_sent(void)
+u32 tipc_bclink_get_last_sent(void)
 {
 	u32 last_sent = mod(bcl->next_out_no - 1);
 
@@ -509,15 +509,15 @@ u32 bclink_get_last_sent(void)
 	return last_sent;
 }
 
-u32 bclink_acks_missing(struct node *n_ptr)
+u32 tipc_bclink_acks_missing(struct node *n_ptr)
 {
 	return (n_ptr->bclink.supported &&
-		(bclink_get_last_sent() != n_ptr->bclink.acked));
+		(tipc_bclink_get_last_sent() != n_ptr->bclink.acked));
 }
 
 
 /**
- * bcbearer_send - send a packet through the broadcast pseudo-bearer
+ * tipc_bcbearer_send - send a packet through the broadcast pseudo-bearer
  * 
  * Send through as many bearers as necessary to reach all nodes
  * that support TIPC multicasting.
@@ -525,9 +525,9 @@ u32 bclink_acks_missing(struct node *n_p
  * Returns 0 if packet sent successfully, non-zero if not
  */
 
-int bcbearer_send(struct sk_buff *buf,
-		  struct tipc_bearer *unused1,
-		  struct tipc_media_addr *unused2)
+int tipc_bcbearer_send(struct sk_buff *buf,
+		       struct tipc_bearer *unused1,
+		       struct tipc_media_addr *unused2)
 {
 	static int send_count = 0;
 
@@ -541,8 +541,8 @@ int bcbearer_send(struct sk_buff *buf,
 	if (likely(!msg_non_seq(buf_msg(buf)))) {
 		struct tipc_msg *msg;
 
-		assert(cluster_bcast_nodes.count != 0);
-		bcbuf_set_acks(buf, cluster_bcast_nodes.count);
+		assert(tipc_cltr_bcast_nodes.count != 0);
+		bcbuf_set_acks(buf, tipc_cltr_bcast_nodes.count);
 		msg = buf_msg(buf);
 		msg_set_non_seq(msg);
 		msg_set_mc_netid(msg, tipc_net_id);
@@ -555,7 +555,7 @@ int bcbearer_send(struct sk_buff *buf,
 
 	/* Send buffer over bearers until all targets reached */
 	
-	remains = cluster_bcast_nodes;
+	remains = tipc_cltr_bcast_nodes;
 
 	for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) {
 		struct bearer *p = bcbearer->bpairs[bp_index].primary;
@@ -564,7 +564,7 @@ int bcbearer_send(struct sk_buff *buf,
 		if (!p)
 			break;	/* no more bearers to try */
 
-		nmap_diff(&remains, &p->nodes, &remains_new);
+		tipc_nmap_diff(&remains, &p->nodes, &remains_new);
 		if (remains_new.count == remains.count)
 			continue;	/* bearer pair doesn't add anything */
 
@@ -597,10 +597,10 @@ update:
 }
 
 /**
- * bcbearer_sort - create sets of bearer pairs used by broadcast bearer
+ * tipc_bcbearer_sort - create sets of bearer pairs used by broadcast bearer
  */
 
-void bcbearer_sort(void)
+void tipc_bcbearer_sort(void)
 {
 	struct bcbearer_pair *bp_temp = bcbearer->bpairs_temp;
 	struct bcbearer_pair *bp_curr;
@@ -614,7 +614,7 @@ void bcbearer_sort(void)
 	memset(bp_temp, 0, sizeof(bcbearer->bpairs_temp));
 
 	for (b_index = 0; b_index < MAX_BEARERS; b_index++) {
-		struct bearer *b = &bearers[b_index];
+		struct bearer *b = &tipc_bearers[b_index];
 
 		if (!b->active || !b->nodes.count)
 			continue;
@@ -630,7 +630,7 @@ void bcbearer_sort(void)
 	bp_curr = bcbearer->bpairs;
 	memset(bcbearer->bpairs, 0, sizeof(bcbearer->bpairs));
 
-	for (pri = (TIPC_NUM_LINK_PRI - 1); pri >= 0; pri--) {
+	for (pri = TIPC_MAX_LINK_PRI; pri >= 0; pri--) {
 
 		if (!bp_temp[pri].primary)
 			continue;
@@ -638,8 +638,8 @@ void bcbearer_sort(void)
 		bp_curr->primary = bp_temp[pri].primary;
 
 		if (bp_temp[pri].secondary) {
-			if (nmap_equal(&bp_temp[pri].primary->nodes,
-				       &bp_temp[pri].secondary->nodes)) {
+			if (tipc_nmap_equal(&bp_temp[pri].primary->nodes,
+					    &bp_temp[pri].secondary->nodes)) {
 				bp_curr->secondary = bp_temp[pri].secondary;
 			} else {
 				bp_curr++;
@@ -654,14 +654,14 @@ void bcbearer_sort(void)
 }
 
 /**
- * bcbearer_push - resolve bearer congestion
+ * tipc_bcbearer_push - resolve bearer congestion
  * 
  * Forces bclink to push out any unsent packets, until all packets are gone
  * or congestion reoccurs.
  * No locks set when function called
  */
 
-void bcbearer_push(void)
+void tipc_bcbearer_push(void)
 {
 	struct bearer *b_ptr;
 
@@ -669,20 +669,20 @@ void bcbearer_push(void)
 	b_ptr = &bcbearer->bearer;
 	if (b_ptr->publ.blocked) {
 		b_ptr->publ.blocked = 0;
-		bearer_lock_push(b_ptr);
+		tipc_bearer_lock_push(b_ptr);
 	}
 	spin_unlock_bh(&bc_lock);
 }
 
 
-int bclink_stats(char *buf, const u32 buf_size)
+int tipc_bclink_stats(char *buf, const u32 buf_size)
 {
 	struct print_buf pb;
 
 	if (!bcl)
 		return 0;
 
-	printbuf_init(&pb, buf, buf_size);
+	tipc_printbuf_init(&pb, buf, buf_size);
 
 	spin_lock_bh(&bc_lock);
 
@@ -718,10 +718,10 @@ int bclink_stats(char *buf, const u32 bu
 		    : 0);
 
 	spin_unlock_bh(&bc_lock);
-	return printbuf_validate(&pb);
+	return tipc_printbuf_validate(&pb);
 }
 
-int bclink_reset_stats(void)
+int tipc_bclink_reset_stats(void)
 {
 	if (!bcl)
 		return -ENOPROTOOPT;
@@ -732,7 +732,7 @@ int bclink_reset_stats(void)
 	return TIPC_OK;
 }
 
-int bclink_set_queue_limits(u32 limit)
+int tipc_bclink_set_queue_limits(u32 limit)
 {
 	if (!bcl)
 		return -ENOPROTOOPT;
@@ -740,12 +740,12 @@ int bclink_set_queue_limits(u32 limit)
 		return -EINVAL;
 
 	spin_lock_bh(&bc_lock);
-	link_set_queue_limits(bcl, limit);
+	tipc_link_set_queue_limits(bcl, limit);
 	spin_unlock_bh(&bc_lock);
 	return TIPC_OK;
 }
 
-int bclink_init(void)
+int tipc_bclink_init(void)
 {
 	bcbearer = kmalloc(sizeof(*bcbearer), GFP_ATOMIC);
 	bclink = kmalloc(sizeof(*bclink), GFP_ATOMIC);
@@ -762,7 +762,7 @@ int bclink_init(void)
 	memset(bcbearer, 0, sizeof(struct bcbearer));
 	INIT_LIST_HEAD(&bcbearer->bearer.cong_links);
 	bcbearer->bearer.media = &bcbearer->media;
-	bcbearer->media.send_msg = bcbearer_send;
+	bcbearer->media.send_msg = tipc_bcbearer_send;
 	sprintf(bcbearer->media.name, "tipc-multicast");
 
 	bcl = &bclink->link;
@@ -772,27 +772,27 @@ int bclink_init(void)
 	bclink->node.lock =  SPIN_LOCK_UNLOCKED;        
 	bcl->owner = &bclink->node;
         bcl->max_pkt = MAX_PKT_DEFAULT_MCAST;
-	link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT);
+	tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT);
 	bcl->b_ptr = &bcbearer->bearer;
 	bcl->state = WORKING_WORKING;
-	sprintf(bcl->name, bc_link_name);
+	sprintf(bcl->name, tipc_bclink_name);
 
 	if (BCLINK_LOG_BUF_SIZE) {
 		char *pb = kmalloc(BCLINK_LOG_BUF_SIZE, GFP_ATOMIC);
 
 		if (!pb)
 			goto nomem;
-		printbuf_init(&bcl->print_buf, pb, BCLINK_LOG_BUF_SIZE);
+		tipc_printbuf_init(&bcl->print_buf, pb, BCLINK_LOG_BUF_SIZE);
 	}
 
 	return TIPC_OK;
 }
 
-void bclink_stop(void)
+void tipc_bclink_stop(void)
 {
 	spin_lock_bh(&bc_lock);
 	if (bcbearer) {
-		link_stop(bcl);
+		tipc_link_stop(bcl);
 		if (BCLINK_LOG_BUF_SIZE)
 			kfree(bcl->print_buf.buf);
 		bcl = NULL;
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index 5430e52..0e3be2a 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -70,14 +70,14 @@ struct port_list {
 
 struct node;
 
-extern char bc_link_name[];
+extern char tipc_bclink_name[];
 
 
 /**
  * nmap_get - determine if node exists in a node map
  */
 
-static inline int nmap_get(struct node_map *nm_ptr, u32 node)
+static inline int tipc_nmap_get(struct node_map *nm_ptr, u32 node)
 {
 	int n = tipc_node(node);
 	int w = n / WSIZE;
@@ -90,7 +90,7 @@ static inline int nmap_get(struct node_m
  * nmap_add - add a node to a node map
  */
 
-static inline void nmap_add(struct node_map *nm_ptr, u32 node)
+static inline void tipc_nmap_add(struct node_map *nm_ptr, u32 node)
 {
 	int n = tipc_node(node);
 	int w = n / WSIZE;
@@ -106,7 +106,7 @@ static inline void nmap_add(struct node_
  * nmap_remove - remove a node from a node map
  */
 
-static inline void nmap_remove(struct node_map *nm_ptr, u32 node)
+static inline void tipc_nmap_remove(struct node_map *nm_ptr, u32 node)
 {
 	int n = tipc_node(node);
 	int w = n / WSIZE;
@@ -122,7 +122,7 @@ static inline void nmap_remove(struct no
  * nmap_equal - test for equality of node maps
  */
 
-static inline int nmap_equal(struct node_map *nm_a, struct node_map *nm_b)
+static inline int tipc_nmap_equal(struct node_map *nm_a, struct node_map *nm_b)
 {
 	return !memcmp(nm_a, nm_b, sizeof(*nm_a));
 }
@@ -134,8 +134,8 @@ static inline int nmap_equal(struct node
  * @nm_diff: output node map A-B (i.e. nodes of A that are not in B)
  */
 
-static inline void nmap_diff(struct node_map *nm_a, struct node_map *nm_b,
-			     struct node_map *nm_diff)
+static inline void tipc_nmap_diff(struct node_map *nm_a, struct node_map *nm_b,
+				  struct node_map *nm_diff)
 {
 	int stop = sizeof(nm_a->map) / sizeof(u32);
 	int w;
@@ -159,7 +159,7 @@ static inline void nmap_diff(struct node
  * port_list_add - add a port to a port list, ensuring no duplicates
  */
 
-static inline void port_list_add(struct port_list *pl_ptr, u32 port)
+static inline void tipc_port_list_add(struct port_list *pl_ptr, u32 port)
 {
 	struct port_list *item = pl_ptr;
 	int i;
@@ -194,7 +194,7 @@ static inline void port_list_add(struct 
  * Note: First item is on stack, so it doesn't need to be released
  */
 
-static inline void port_list_free(struct port_list *pl_ptr)
+static inline void tipc_port_list_free(struct port_list *pl_ptr)
 {
 	struct port_list *item;
 	struct port_list *next;
@@ -206,18 +206,18 @@ static inline void port_list_free(struct
 }
 
 
-int  bclink_init(void);
-void bclink_stop(void);
-void bclink_acknowledge(struct node *n_ptr, u32 acked);
-int  bclink_send_msg(struct sk_buff *buf);
-void bclink_recv_pkt(struct sk_buff *buf);
-u32  bclink_get_last_sent(void);
-u32  bclink_acks_missing(struct node *n_ptr);
-void bclink_check_gap(struct node *n_ptr, u32 seqno);
-int  bclink_stats(char *stats_buf, const u32 buf_size);
-int  bclink_reset_stats(void);
-int  bclink_set_queue_limits(u32 limit);
-void bcbearer_sort(void);
-void bcbearer_push(void);
+int  tipc_bclink_init(void);
+void tipc_bclink_stop(void);
+void tipc_bclink_acknowledge(struct node *n_ptr, u32 acked);
+int  tipc_bclink_send_msg(struct sk_buff *buf);
+void tipc_bclink_recv_pkt(struct sk_buff *buf);
+u32  tipc_bclink_get_last_sent(void);
+u32  tipc_bclink_acks_missing(struct node *n_ptr);
+void tipc_bclink_check_gap(struct node *n_ptr, u32 seqno);
+int  tipc_bclink_stats(char *stats_buf, const u32 buf_size);
+int  tipc_bclink_reset_stats(void);
+int  tipc_bclink_set_queue_limits(u32 limit);
+void tipc_bcbearer_sort(void);
+void tipc_bcbearer_push(void);
 
 #endif
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 3dd19fd..64dcb0f 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -48,7 +48,7 @@
 static struct media *media_list = 0;
 static u32 media_count = 0;
 
-struct bearer *bearers = 0;
+struct bearer *tipc_bearers = 0;
 
 /**
  * media_name_valid - validate media name
@@ -107,7 +107,7 @@ int  tipc_register_media(u32 media_type,
 	u32 i;
 	int res = -EINVAL;
 
-	write_lock_bh(&net_lock);
+	write_lock_bh(&tipc_net_lock);
 	if (!media_list)
 		goto exit;
 
@@ -119,7 +119,8 @@ int  tipc_register_media(u32 media_type,
 		warn("Media registration error: no broadcast address supplied\n");
 		goto exit;
 	}
-	if (bearer_priority >= TIPC_NUM_LINK_PRI) {
+	if ((bearer_priority < TIPC_MIN_LINK_PRI) &&
+	    (bearer_priority > TIPC_MAX_LINK_PRI)) {
 		warn("Media registration error: priority %u\n", bearer_priority);
 		goto exit;
 	}
@@ -164,15 +165,15 @@ int  tipc_register_media(u32 media_type,
 	dbg("Media <%s> registered\n", name);
 	res = 0;
 exit:
-	write_unlock_bh(&net_lock);
+	write_unlock_bh(&tipc_net_lock);
 	return res;
 }
 
 /**
- * media_addr_printf - record media address in print buffer
+ * tipc_media_addr_printf - record media address in print buffer
  */
 
-void media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a)
+void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a)
 {
 	struct media *m_ptr;
 	u32 media_type;
@@ -200,25 +201,25 @@ void media_addr_printf(struct print_buf 
 }
 
 /**
- * media_get_names - record names of registered media in buffer
+ * tipc_media_get_names - record names of registered media in buffer
  */
 
-struct sk_buff *media_get_names(void)
+struct sk_buff *tipc_media_get_names(void)
 {
 	struct sk_buff *buf;
 	struct media *m_ptr;
 	int i;
 
-	buf = cfg_reply_alloc(MAX_MEDIA * TLV_SPACE(TIPC_MAX_MEDIA_NAME));
+	buf = tipc_cfg_reply_alloc(MAX_MEDIA * TLV_SPACE(TIPC_MAX_MEDIA_NAME));
 	if (!buf)
 		return NULL;
 
-	read_lock_bh(&net_lock);
+	read_lock_bh(&tipc_net_lock);
 	for (i = 0, m_ptr = media_list; i < media_count; i++, m_ptr++) {
-		cfg_append_tlv(buf, TIPC_TLV_MEDIA_NAME, m_ptr->name, 
-			       strlen(m_ptr->name) + 1);
+		tipc_cfg_append_tlv(buf, TIPC_TLV_MEDIA_NAME, m_ptr->name, 
+				    strlen(m_ptr->name) + 1);
 	}
-	read_unlock_bh(&net_lock);
+	read_unlock_bh(&tipc_net_lock);
 	return buf;
 }
 
@@ -282,7 +283,7 @@ static struct bearer *bearer_find(const 
 	struct bearer *b_ptr;
 	u32 i;
 
-	for (i = 0, b_ptr = bearers; i < MAX_BEARERS; i++, b_ptr++) {
+	for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) {
 		if (b_ptr->active && (!strcmp(b_ptr->publ.name, name)))
 			return b_ptr;
 	}
@@ -290,16 +291,16 @@ static struct bearer *bearer_find(const 
 }
 
 /**
- * bearer_find - locates bearer object with matching interface name
+ * tipc_bearer_find_interface - locates bearer object with matching interface name
  */
 
-struct bearer *bearer_find_interface(const char *if_name)
+struct bearer *tipc_bearer_find_interface(const char *if_name)
 {
 	struct bearer *b_ptr;
 	char *b_if_name;
 	u32 i;
 
-	for (i = 0, b_ptr = bearers; i < MAX_BEARERS; i++, b_ptr++) {
+	for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) {
 		if (!b_ptr->active)
 			continue;
 		b_if_name = strchr(b_ptr->publ.name, ':') + 1;
@@ -310,54 +311,54 @@ struct bearer *bearer_find_interface(con
 }
 
 /**
- * bearer_get_names - record names of bearers in buffer
+ * tipc_bearer_get_names - record names of bearers in buffer
  */
 
-struct sk_buff *bearer_get_names(void)
+struct sk_buff *tipc_bearer_get_names(void)
 {
 	struct sk_buff *buf;
 	struct media *m_ptr;
 	struct bearer *b_ptr;
 	int i, j;
 
-	buf = cfg_reply_alloc(MAX_BEARERS * TLV_SPACE(TIPC_MAX_BEARER_NAME));
+	buf = tipc_cfg_reply_alloc(MAX_BEARERS * TLV_SPACE(TIPC_MAX_BEARER_NAME));
 	if (!buf)
 		return NULL;
 
-	read_lock_bh(&net_lock);
+	read_lock_bh(&tipc_net_lock);
 	for (i = 0, m_ptr = media_list; i < media_count; i++, m_ptr++) {
 		for (j = 0; j < MAX_BEARERS; j++) {
-			b_ptr = &bearers[j];
+			b_ptr = &tipc_bearers[j];
 			if (b_ptr->active && (b_ptr->media == m_ptr)) {
-				cfg_append_tlv(buf, TIPC_TLV_BEARER_NAME, 
-					       b_ptr->publ.name, 
-					       strlen(b_ptr->publ.name) + 1);
+				tipc_cfg_append_tlv(buf, TIPC_TLV_BEARER_NAME, 
+						    b_ptr->publ.name, 
+						    strlen(b_ptr->publ.name) + 1);
 			}
 		}
 	}
-	read_unlock_bh(&net_lock);
+	read_unlock_bh(&tipc_net_lock);
 	return buf;
 }
 
-void bearer_add_dest(struct bearer *b_ptr, u32 dest)
+void tipc_bearer_add_dest(struct bearer *b_ptr, u32 dest)
 {
-	nmap_add(&b_ptr->nodes, dest);
-	disc_update_link_req(b_ptr->link_req);
-	bcbearer_sort();
+	tipc_nmap_add(&b_ptr->nodes, dest);
+	tipc_disc_update_link_req(b_ptr->link_req);
+	tipc_bcbearer_sort();
 }
 
-void bearer_remove_dest(struct bearer *b_ptr, u32 dest)
+void tipc_bearer_remove_dest(struct bearer *b_ptr, u32 dest)
 {
-	nmap_remove(&b_ptr->nodes, dest);
-	disc_update_link_req(b_ptr->link_req);
-	bcbearer_sort();
+	tipc_nmap_remove(&b_ptr->nodes, dest);
+	tipc_disc_update_link_req(b_ptr->link_req);
+	tipc_bcbearer_sort();
 }
 
 /*
  * bearer_push(): Resolve bearer congestion. Force the waiting
  * links to push out their unsent packets, one packet per link
  * per iteration, until all packets are gone or congestion reoccurs.
- * 'net_lock' is read_locked when this function is called
+ * 'tipc_net_lock' is read_locked when this function is called
  * bearer.lock must be taken before calling
  * Returns binary true(1) ore false(0)
  */
@@ -371,7 +372,7 @@ static int bearer_push(struct bearer *b_
 
 	while (!list_empty(&b_ptr->cong_links) && (res != PUSH_FAILED)) {
 		list_for_each_entry_safe(ln, tln, &b_ptr->cong_links, link_list) {
-			res = link_push_packet(ln);
+			res = tipc_link_push_packet(ln);
 			if (res == PUSH_FAILED)
 				break;
 			if (res == PUSH_FINISHED)
@@ -381,7 +382,7 @@ static int bearer_push(struct bearer *b_
 	return list_empty(&b_ptr->cong_links);
 }
 
-void bearer_lock_push(struct bearer *b_ptr)
+void tipc_bearer_lock_push(struct bearer *b_ptr)
 {
 	int res;
 
@@ -389,7 +390,7 @@ void bearer_lock_push(struct bearer *b_p
 	res = bearer_push(b_ptr);
 	spin_unlock_bh(&b_ptr->publ.lock);
 	if (res)
-		bcbearer_push();
+		tipc_bcbearer_push();
 }
 
 
@@ -404,7 +405,7 @@ void tipc_continue(struct tipc_bearer *t
 	spin_lock_bh(&b_ptr->publ.lock);
 	b_ptr->continue_count++;
 	if (!list_empty(&b_ptr->cong_links))
-		k_signal((Handler)bearer_lock_push, (unsigned long)b_ptr);
+		tipc_k_signal((Handler)tipc_bearer_lock_push, (unsigned long)b_ptr);
 	b_ptr->publ.blocked = 0;
 	spin_unlock_bh(&b_ptr->publ.lock);
 }
@@ -413,11 +414,11 @@ void tipc_continue(struct tipc_bearer *t
  * Schedule link for sending of messages after the bearer 
  * has been deblocked by 'continue()'. This method is called 
  * when somebody tries to send a message via this link while 
- * the bearer is congested. 'net_lock' is in read_lock here
+ * the bearer is congested. 'tipc_net_lock' is in read_lock here
  * bearer.lock is busy
  */
 
-static void bearer_schedule_unlocked(struct bearer *b_ptr, struct link *l_ptr)
+static void tipc_bearer_schedule_unlocked(struct bearer *b_ptr, struct link *l_ptr)
 {
 	list_move_tail(&l_ptr->link_list, &b_ptr->cong_links);
 }
@@ -426,24 +427,24 @@ static void bearer_schedule_unlocked(str
  * Schedule link for sending of messages after the bearer 
  * has been deblocked by 'continue()'. This method is called 
  * when somebody tries to send a message via this link while 
- * the bearer is congested. 'net_lock' is in read_lock here,
+ * the bearer is congested. 'tipc_net_lock' is in read_lock here,
  * bearer.lock is free
  */
 
-void bearer_schedule(struct bearer *b_ptr, struct link *l_ptr)
+void tipc_bearer_schedule(struct bearer *b_ptr, struct link *l_ptr)
 {
 	spin_lock_bh(&b_ptr->publ.lock);
-	bearer_schedule_unlocked(b_ptr, l_ptr);
+	tipc_bearer_schedule_unlocked(b_ptr, l_ptr);
 	spin_unlock_bh(&b_ptr->publ.lock);
 }
 
 
 /*
- * bearer_resolve_congestion(): Check if there is bearer congestion,
+ * tipc_bearer_resolve_congestion(): Check if there is bearer congestion,
  * and if there is, try to resolve it before returning.
- * 'net_lock' is read_locked when this function is called
+ * 'tipc_net_lock' is read_locked when this function is called
  */
-int bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr)
+int tipc_bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr)
 {
 	int res = 1;
 
@@ -451,7 +452,7 @@ int bearer_resolve_congestion(struct bea
 		return 1;
 	spin_lock_bh(&b_ptr->publ.lock);
 	if (!bearer_push(b_ptr)) {
-		bearer_schedule_unlocked(b_ptr, l_ptr);
+		tipc_bearer_schedule_unlocked(b_ptr, l_ptr);
 		res = 0;
 	}
 	spin_unlock_bh(&b_ptr->publ.lock);
@@ -476,14 +477,19 @@ int tipc_enable_bearer(const char *name,
 
 	if (tipc_mode != TIPC_NET_MODE)
 		return -ENOPROTOOPT;
+
 	if (!bearer_name_validate(name, &b_name) ||
-	    !addr_domain_valid(bcast_scope) ||
-	    !in_scope(bcast_scope, tipc_own_addr) ||
-	    (priority > TIPC_NUM_LINK_PRI))
+	    !tipc_addr_domain_valid(bcast_scope) ||
+	    !in_scope(bcast_scope, tipc_own_addr))
+		return -EINVAL;
+
+	if ((priority < TIPC_MIN_LINK_PRI ||
+	     priority > TIPC_MAX_LINK_PRI) &&
+	    (priority != TIPC_MEDIA_LINK_PRI))
 		return -EINVAL;
 
-	write_lock_bh(&net_lock);
-	if (!bearers)
+	write_lock_bh(&tipc_net_lock);
+	if (!tipc_bearers)
 		goto failed;
 
 	m_ptr = media_find(b_name.media_name);
@@ -491,22 +497,23 @@ int tipc_enable_bearer(const char *name,
 		warn("No media <%s>\n", b_name.media_name);
 		goto failed;
 	}
-	if (priority == TIPC_NUM_LINK_PRI)
+
+	if (priority == TIPC_MEDIA_LINK_PRI)
 		priority = m_ptr->priority;
 
 restart:
 	bearer_id = MAX_BEARERS;
 	with_this_prio = 1;
 	for (i = MAX_BEARERS; i-- != 0; ) {
-		if (!bearers[i].active) {
+		if (!tipc_bearers[i].active) {
 			bearer_id = i;
 			continue;
 		}
-		if (!strcmp(name, bearers[i].publ.name)) {
+		if (!strcmp(name, tipc_bearers[i].publ.name)) {
 			warn("Bearer <%s> already enabled\n", name);
 			goto failed;
 		}
-		if ((bearers[i].priority == priority) &&
+		if ((tipc_bearers[i].priority == priority) &&
 		    (++with_this_prio > 2)) {
 			if (priority-- == 0) {
 				warn("Third bearer <%s> with priority %u, unable to lower to %u\n",
@@ -523,7 +530,7 @@ restart:
 		goto failed;
 	}
 
-	b_ptr = &bearers[bearer_id];
+	b_ptr = &tipc_bearers[bearer_id];
 	memset(b_ptr, 0, sizeof(struct bearer));
 
 	strcpy(b_ptr->publ.name, name);
@@ -542,16 +549,16 @@ restart:
 	INIT_LIST_HEAD(&b_ptr->cong_links);
 	INIT_LIST_HEAD(&b_ptr->links);
 	if (m_ptr->bcast) {
-		b_ptr->link_req = disc_init_link_req(b_ptr, &m_ptr->bcast_addr,
-						     bcast_scope, 2);
+		b_ptr->link_req = tipc_disc_init_link_req(b_ptr, &m_ptr->bcast_addr,
+							  bcast_scope, 2);
 	}
 	b_ptr->publ.lock = SPIN_LOCK_UNLOCKED;
-	write_unlock_bh(&net_lock);
-	info("Enabled bearer <%s>, discovery domain %s\n",
-	     name, addr_string_fill(addr_string, bcast_scope));
+	write_unlock_bh(&tipc_net_lock);
+	info("Enabled bearer <%s>, discovery domain %s, priority %u\n",
+	     name, addr_string_fill(addr_string, bcast_scope), priority);
 	return 0;
 failed:
-	write_unlock_bh(&net_lock);
+	write_unlock_bh(&tipc_net_lock);
 	return res;
 }
 
@@ -569,11 +576,11 @@ int tipc_block_bearer(const char *name)
 	if (tipc_mode != TIPC_NET_MODE)
 		return -ENOPROTOOPT;
 
-	read_lock_bh(&net_lock);
+	read_lock_bh(&tipc_net_lock);
 	b_ptr = bearer_find(name);
 	if (!b_ptr) {
 		warn("Attempt to block unknown bearer <%s>\n", name);
-		read_unlock_bh(&net_lock);
+		read_unlock_bh(&tipc_net_lock);
 		return -EINVAL;
 	}
 
@@ -583,11 +590,11 @@ int tipc_block_bearer(const char *name)
 		struct node *n_ptr = l_ptr->owner;
 
 		spin_lock_bh(&n_ptr->lock);
-		link_reset(l_ptr);
+		tipc_link_reset(l_ptr);
 		spin_unlock_bh(&n_ptr->lock);
 	}
 	spin_unlock_bh(&b_ptr->publ.lock);
-	read_unlock_bh(&net_lock);
+	read_unlock_bh(&tipc_net_lock);
 	info("Blocked bearer <%s>\n", name);
 	return TIPC_OK;
 }
@@ -595,7 +602,7 @@ int tipc_block_bearer(const char *name)
 /**
  * bearer_disable -
  * 
- * Note: This routine assumes caller holds net_lock.
+ * Note: This routine assumes caller holds tipc_net_lock.
  */
 
 static int bearer_disable(const char *name)
@@ -613,19 +620,19 @@ static int bearer_disable(const char *na
 		return -EINVAL;
 	}
 
-	disc_stop_link_req(b_ptr->link_req);
+	tipc_disc_stop_link_req(b_ptr->link_req);
 	spin_lock_bh(&b_ptr->publ.lock);
 	b_ptr->link_req = NULL;
 	b_ptr->publ.blocked = 1;
 	if (b_ptr->media->disable_bearer) {
 		spin_unlock_bh(&b_ptr->publ.lock);
-		write_unlock_bh(&net_lock);
+		write_unlock_bh(&tipc_net_lock);
 		b_ptr->media->disable_bearer(&b_ptr->publ);
-		write_lock_bh(&net_lock);
+		write_lock_bh(&tipc_net_lock);
 		spin_lock_bh(&b_ptr->publ.lock);
 	}
 	list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
-		link_delete(l_ptr);
+		tipc_link_delete(l_ptr);
 	}
 	spin_unlock_bh(&b_ptr->publ.lock);
 	info("Disabled bearer <%s>\n", name);
@@ -637,54 +644,54 @@ int tipc_disable_bearer(const char *name
 {
 	int res;
 
-	write_lock_bh(&net_lock);
+	write_lock_bh(&tipc_net_lock);
 	res = bearer_disable(name);
-	write_unlock_bh(&net_lock);
+	write_unlock_bh(&tipc_net_lock);
 	return res;
 }
 
 
 
-int bearer_init(void)
+int tipc_bearer_init(void)
 {
 	int res;
 
-	write_lock_bh(&net_lock);
-	bearers = kmalloc(MAX_BEARERS * sizeof(struct bearer), GFP_ATOMIC);
+	write_lock_bh(&tipc_net_lock);
+	tipc_bearers = kmalloc(MAX_BEARERS * sizeof(struct bearer), GFP_ATOMIC);
 	media_list = kmalloc(MAX_MEDIA * sizeof(struct media), GFP_ATOMIC);
-	if (bearers && media_list) {
-		memset(bearers, 0, MAX_BEARERS * sizeof(struct bearer));
+	if (tipc_bearers && media_list) {
+		memset(tipc_bearers, 0, MAX_BEARERS * sizeof(struct bearer));
 		memset(media_list, 0, MAX_MEDIA * sizeof(struct media));
 		res = TIPC_OK;
 	} else {
-		kfree(bearers);
+		kfree(tipc_bearers);
 		kfree(media_list);
-		bearers = 0;
+		tipc_bearers = 0;
 		media_list = 0;
 		res = -ENOMEM;
 	}
-	write_unlock_bh(&net_lock);
+	write_unlock_bh(&tipc_net_lock);
 	return res;
 }
 
-void bearer_stop(void)
+void tipc_bearer_stop(void)
 {
 	u32 i;
 
-	if (!bearers)
+	if (!tipc_bearers)
 		return;
 
 	for (i = 0; i < MAX_BEARERS; i++) {
-		if (bearers[i].active)
-			bearers[i].publ.blocked = 1;
+		if (tipc_bearers[i].active)
+			tipc_bearers[i].publ.blocked = 1;
 	}
 	for (i = 0; i < MAX_BEARERS; i++) {
-		if (bearers[i].active)
-			bearer_disable(bearers[i].publ.name);
+		if (tipc_bearers[i].active)
+			bearer_disable(tipc_bearers[i].publ.name);
 	}
-	kfree(bearers);
+	kfree(tipc_bearers);
 	kfree(media_list);
-	bearers = 0;
+	tipc_bearers = 0;
 	media_list = 0;
 	media_count = 0;
 }
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index 21e63d3..c4e7c1c 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -37,7 +37,7 @@
 #ifndef _TIPC_BEARER_H
 #define _TIPC_BEARER_H
 
-#include <net/tipc/tipc_bearer.h>
+#include "core.h"
 #include "bcast.h"
 
 #define MAX_BEARERS 8
@@ -114,26 +114,24 @@ struct bearer_name {
 
 struct link;
 
-extern struct bearer *bearers;
+extern struct bearer *tipc_bearers;
 
-void media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a);
-struct sk_buff *media_get_names(void);
+void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a);
+struct sk_buff *tipc_media_get_names(void);
 
-struct sk_buff *bearer_get_names(void);
-void bearer_add_dest(struct bearer *b_ptr, u32 dest);
-void bearer_remove_dest(struct bearer *b_ptr, u32 dest);
-void bearer_schedule(struct bearer *b_ptr, struct link *l_ptr);
-struct bearer *bearer_find_interface(const char *if_name);
-int bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr);
-int bearer_init(void);
-void bearer_stop(void);
-int bearer_broadcast(struct sk_buff *buf, struct tipc_bearer *b_ptr,
-		     struct tipc_media_addr *dest);
-void bearer_lock_push(struct bearer *b_ptr);
+struct sk_buff *tipc_bearer_get_names(void);
+void tipc_bearer_add_dest(struct bearer *b_ptr, u32 dest);
+void tipc_bearer_remove_dest(struct bearer *b_ptr, u32 dest);
+void tipc_bearer_schedule(struct bearer *b_ptr, struct link *l_ptr);
+struct bearer *tipc_bearer_find_interface(const char *if_name);
+int tipc_bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr);
+int tipc_bearer_init(void);
+void tipc_bearer_stop(void);
+void tipc_bearer_lock_push(struct bearer *b_ptr);
 
 
 /**
- * bearer_send- sends buffer to destination over bearer 
+ * tipc_bearer_send- sends buffer to destination over bearer 
  * 
  * Returns true (1) if successful, or false (0) if unable to send
  * 
@@ -150,23 +148,23 @@ void bearer_lock_push(struct bearer *b_p
  * and let TIPC's link code deal with the undelivered message. 
  */
 
-static inline int bearer_send(struct bearer *b_ptr, struct sk_buff *buf,
-			      struct tipc_media_addr *dest)
+static inline int tipc_bearer_send(struct bearer *b_ptr, struct sk_buff *buf,
+				   struct tipc_media_addr *dest)
 {
 	return !b_ptr->media->send_msg(buf, &b_ptr->publ, dest);
 }
 
 /**
- * bearer_congested - determines if bearer is currently congested
+ * tipc_bearer_congested - determines if bearer is currently congested
  */
 
-static inline int bearer_congested(struct bearer *b_ptr, struct link *l_ptr)
+static inline int tipc_bearer_congested(struct bearer *b_ptr, struct link *l_ptr)
 {
 	if (unlikely(b_ptr->publ.blocked))
 		return 1;
 	if (likely(list_empty(&b_ptr->cong_links)))
 		return 0;
-	return !bearer_resolve_congestion(b_ptr, l_ptr);
+	return !tipc_bearer_resolve_congestion(b_ptr, l_ptr);
 }
 
 #endif
diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c
index f0f7bac..ab974ca 100644
--- a/net/tipc/cluster.c
+++ b/net/tipc/cluster.c
@@ -44,15 +44,15 @@
 #include "msg.h"
 #include "bearer.h"
 
-void cluster_multicast(struct cluster *c_ptr, struct sk_buff *buf, 
-		       u32 lower, u32 upper);
-struct sk_buff *cluster_prepare_routing_msg(u32 data_size, u32 dest);
-
-struct node **local_nodes = 0;
-struct node_map cluster_bcast_nodes = {0,{0,}};
-u32 highest_allowed_slave = 0;
+void tipc_cltr_multicast(struct cluster *c_ptr, struct sk_buff *buf, 
+			 u32 lower, u32 upper);
+struct sk_buff *tipc_cltr_prepare_routing_msg(u32 data_size, u32 dest);
+
+struct node **tipc_local_nodes = 0;
+struct node_map tipc_cltr_bcast_nodes = {0,{0,}};
+u32 tipc_highest_allowed_slave = 0;
 
-struct cluster *cluster_create(u32 addr)
+struct cluster *tipc_cltr_create(u32 addr)
 {
 	struct _zone *z_ptr;
 	struct cluster *c_ptr;
@@ -77,16 +77,16 @@ struct cluster *cluster_create(u32 addr)
 	}
 	memset(c_ptr->nodes, 0, alloc);  
 	if (in_own_cluster(addr))
-		local_nodes = c_ptr->nodes;
+		tipc_local_nodes = c_ptr->nodes;
 	c_ptr->highest_slave = LOWEST_SLAVE - 1;
 	c_ptr->highest_node = 0;
 	
-	z_ptr = zone_find(tipc_zone(addr));
+	z_ptr = tipc_zone_find(tipc_zone(addr));
 	if (z_ptr == NULL) {
-		z_ptr = zone_create(addr);
+		z_ptr = tipc_zone_create(addr);
 	}
 	if (z_ptr != NULL) {
-		zone_attach_cluster(z_ptr, c_ptr);
+		tipc_zone_attach_cluster(z_ptr, c_ptr);
 		c_ptr->owner = z_ptr;
 	}
 	else {
@@ -97,23 +97,23 @@ struct cluster *cluster_create(u32 addr)
 	return c_ptr;
 }
 
-void cluster_delete(struct cluster *c_ptr)
+void tipc_cltr_delete(struct cluster *c_ptr)
 {
 	u32 n_num;
 
 	if (!c_ptr)
 		return;
 	for (n_num = 1; n_num <= c_ptr->highest_node; n_num++) {
-		node_delete(c_ptr->nodes[n_num]);
+		tipc_node_delete(c_ptr->nodes[n_num]);
 	}
 	for (n_num = LOWEST_SLAVE; n_num <= c_ptr->highest_slave; n_num++) {
-		node_delete(c_ptr->nodes[n_num]);
+		tipc_node_delete(c_ptr->nodes[n_num]);
 	}
 	kfree(c_ptr->nodes);
 	kfree(c_ptr);
 }
 
-u32 cluster_next_node(struct cluster *c_ptr, u32 addr)
+u32 tipc_cltr_next_node(struct cluster *c_ptr, u32 addr)
 {
 	struct node *n_ptr;
 	u32 n_num = tipc_node(addr) + 1;
@@ -122,24 +122,24 @@ u32 cluster_next_node(struct cluster *c_
 		return addr;
 	for (; n_num <= c_ptr->highest_node; n_num++) {
 		n_ptr = c_ptr->nodes[n_num];
-		if (n_ptr && node_has_active_links(n_ptr))
+		if (n_ptr && tipc_node_has_active_links(n_ptr))
 			return n_ptr->addr;
 	}
 	for (n_num = 1; n_num < tipc_node(addr); n_num++) {
 		n_ptr = c_ptr->nodes[n_num];
-		if (n_ptr && node_has_active_links(n_ptr))
+		if (n_ptr && tipc_node_has_active_links(n_ptr))
 			return n_ptr->addr;
 	}
 	return 0;
 }
 
-void cluster_attach_node(struct cluster *c_ptr, struct node *n_ptr)
+void tipc_cltr_attach_node(struct cluster *c_ptr, struct node *n_ptr)
 {
 	u32 n_num = tipc_node(n_ptr->addr);
 	u32 max_n_num = tipc_max_nodes;
 
 	if (in_own_cluster(n_ptr->addr))
-		max_n_num = highest_allowed_slave;
+		max_n_num = tipc_highest_allowed_slave;
 	assert(n_num > 0);
 	assert(n_num <= max_n_num);
 	assert(c_ptr->nodes[n_num] == 0);
@@ -149,12 +149,12 @@ void cluster_attach_node(struct cluster 
 }
 
 /**
- * cluster_select_router - select router to a cluster
+ * tipc_cltr_select_router - select router to a cluster
  * 
  * Uses deterministic and fair algorithm.
  */
 
-u32 cluster_select_router(struct cluster *c_ptr, u32 ref)
+u32 tipc_cltr_select_router(struct cluster *c_ptr, u32 ref)
 {
 	u32 n_num;
 	u32 ulim = c_ptr->highest_node;
@@ -174,29 +174,29 @@ u32 cluster_select_router(struct cluster
 
 	/* Lookup upwards with wrap-around */
 	do {
-		if (node_is_up(c_ptr->nodes[n_num]))
+		if (tipc_node_is_up(c_ptr->nodes[n_num]))
 			break;
 	} while (++n_num <= ulim);
 	if (n_num > ulim) {
 		n_num = 1;
 		do {
-			if (node_is_up(c_ptr->nodes[n_num]))
+			if (tipc_node_is_up(c_ptr->nodes[n_num]))
 				break;
 		} while (++n_num < tstart);
 		if (n_num == tstart)
 			return 0;
 	}
 	assert(n_num <= ulim);
-	return node_select_router(c_ptr->nodes[n_num], ref);
+	return tipc_node_select_router(c_ptr->nodes[n_num], ref);
 }
 
 /**
- * cluster_select_node - select destination node within a remote cluster
+ * tipc_cltr_select_node - select destination node within a remote cluster
  * 
  * Uses deterministic and fair algorithm.
  */
 
-struct node *cluster_select_node(struct cluster *c_ptr, u32 selector)
+struct node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector)
 {
 	u32 n_num;
 	u32 mask = tipc_max_nodes;
@@ -215,11 +215,11 @@ struct node *cluster_select_node(struct 
 
 	/* Lookup upwards with wrap-around */
 	for (n_num = start_entry; n_num <= c_ptr->highest_node; n_num++) {
-		if (node_has_active_links(c_ptr->nodes[n_num]))
+		if (tipc_node_has_active_links(c_ptr->nodes[n_num]))
 			return c_ptr->nodes[n_num];
 	}
 	for (n_num = 1; n_num < start_entry; n_num++) {
-		if (node_has_active_links(c_ptr->nodes[n_num]))
+		if (tipc_node_has_active_links(c_ptr->nodes[n_num]))
 			return c_ptr->nodes[n_num];
 	}
 	return 0;
@@ -229,7 +229,7 @@ struct node *cluster_select_node(struct 
  *    Routing table management: See description in node.c
  */
 
-struct sk_buff *cluster_prepare_routing_msg(u32 data_size, u32 dest)
+struct sk_buff *tipc_cltr_prepare_routing_msg(u32 data_size, u32 dest)
 {
 	u32 size = INT_H_SIZE + data_size;
 	struct sk_buff *buf = buf_acquire(size);
@@ -243,39 +243,39 @@ struct sk_buff *cluster_prepare_routing_
 	return buf;
 }
 
-void cluster_bcast_new_route(struct cluster *c_ptr, u32 dest,
+void tipc_cltr_bcast_new_route(struct cluster *c_ptr, u32 dest,
 			     u32 lower, u32 upper)
 {
-	struct sk_buff *buf = cluster_prepare_routing_msg(0, c_ptr->addr);
+	struct sk_buff *buf = tipc_cltr_prepare_routing_msg(0, c_ptr->addr);
 	struct tipc_msg *msg;
 
 	if (buf) {
 		msg = buf_msg(buf);
 		msg_set_remote_node(msg, dest);
 		msg_set_type(msg, ROUTE_ADDITION);
-		cluster_multicast(c_ptr, buf, lower, upper);
+		tipc_cltr_multicast(c_ptr, buf, lower, upper);
 	} else {
 		warn("Memory squeeze: broadcast of new route failed\n");
 	}
 }
 
-void cluster_bcast_lost_route(struct cluster *c_ptr, u32 dest,
-			      u32 lower, u32 upper)
+void tipc_cltr_bcast_lost_route(struct cluster *c_ptr, u32 dest,
+				u32 lower, u32 upper)
 {
-	struct sk_buff *buf = cluster_prepare_routing_msg(0, c_ptr->addr);
+	struct sk_buff *buf = tipc_cltr_prepare_routing_msg(0, c_ptr->addr);
 	struct tipc_msg *msg;
 
 	if (buf) {
 		msg = buf_msg(buf);
 		msg_set_remote_node(msg, dest);
 		msg_set_type(msg, ROUTE_REMOVAL);
-		cluster_multicast(c_ptr, buf, lower, upper);
+		tipc_cltr_multicast(c_ptr, buf, lower, upper);
 	} else {
 		warn("Memory squeeze: broadcast of lost route failed\n");
 	}
 }
 
-void cluster_send_slave_routes(struct cluster *c_ptr, u32 dest)
+void tipc_cltr_send_slave_routes(struct cluster *c_ptr, u32 dest)
 {
 	struct sk_buff *buf;
 	struct tipc_msg *msg;
@@ -288,21 +288,21 @@ void cluster_send_slave_routes(struct cl
 	assert(in_own_cluster(c_ptr->addr));
 	if (highest <= LOWEST_SLAVE)
 		return;
-	buf = cluster_prepare_routing_msg(highest - LOWEST_SLAVE + 1,
-					  c_ptr->addr);
+	buf = tipc_cltr_prepare_routing_msg(highest - LOWEST_SLAVE + 1,
+					    c_ptr->addr);
 	if (buf) {
 		msg = buf_msg(buf);
 		msg_set_remote_node(msg, c_ptr->addr);
 		msg_set_type(msg, SLAVE_ROUTING_TABLE);
 		for (n_num = LOWEST_SLAVE; n_num <= highest; n_num++) {
 			if (c_ptr->nodes[n_num] && 
-			    node_has_active_links(c_ptr->nodes[n_num])) {
+			    tipc_node_has_active_links(c_ptr->nodes[n_num])) {
 				send = 1;
 				msg_set_dataoctet(msg, n_num);
 			}
 		}
 		if (send)
-			link_send(buf, dest, dest);
+			tipc_link_send(buf, dest, dest);
 		else
 			buf_discard(buf);
 	} else {
@@ -310,7 +310,7 @@ void cluster_send_slave_routes(struct cl
 	}
 }
 
-void cluster_send_ext_routes(struct cluster *c_ptr, u32 dest)
+void tipc_cltr_send_ext_routes(struct cluster *c_ptr, u32 dest)
 {
 	struct sk_buff *buf;
 	struct tipc_msg *msg;
@@ -323,20 +323,20 @@ void cluster_send_ext_routes(struct clus
 	assert(!is_slave(dest));
 	assert(in_own_cluster(dest));
 	highest = c_ptr->highest_node;
-	buf = cluster_prepare_routing_msg(highest + 1, c_ptr->addr);
+	buf = tipc_cltr_prepare_routing_msg(highest + 1, c_ptr->addr);
 	if (buf) {
 		msg = buf_msg(buf);
 		msg_set_remote_node(msg, c_ptr->addr);
 		msg_set_type(msg, EXT_ROUTING_TABLE);
 		for (n_num = 1; n_num <= highest; n_num++) {
 			if (c_ptr->nodes[n_num] && 
-			    node_has_active_links(c_ptr->nodes[n_num])) {
+			    tipc_node_has_active_links(c_ptr->nodes[n_num])) {
 				send = 1;
 				msg_set_dataoctet(msg, n_num);
 			}
 		}
 		if (send)
-			link_send(buf, dest, dest);
+			tipc_link_send(buf, dest, dest);
 		else
 			buf_discard(buf);
 	} else {
@@ -344,7 +344,7 @@ void cluster_send_ext_routes(struct clus
 	}
 }
 
-void cluster_send_local_routes(struct cluster *c_ptr, u32 dest)
+void tipc_cltr_send_local_routes(struct cluster *c_ptr, u32 dest)
 {
 	struct sk_buff *buf;
 	struct tipc_msg *msg;
@@ -354,20 +354,20 @@ void cluster_send_local_routes(struct cl
 
 	assert(is_slave(dest));
 	assert(in_own_cluster(c_ptr->addr));
-	buf = cluster_prepare_routing_msg(highest, c_ptr->addr);
+	buf = tipc_cltr_prepare_routing_msg(highest, c_ptr->addr);
 	if (buf) {
 		msg = buf_msg(buf);
 		msg_set_remote_node(msg, c_ptr->addr);
 		msg_set_type(msg, LOCAL_ROUTING_TABLE);
 		for (n_num = 1; n_num <= highest; n_num++) {
 			if (c_ptr->nodes[n_num] && 
-			    node_has_active_links(c_ptr->nodes[n_num])) {
+			    tipc_node_has_active_links(c_ptr->nodes[n_num])) {
 				send = 1;
 				msg_set_dataoctet(msg, n_num);
 			}
 		}
 		if (send)
-			link_send(buf, dest, dest);
+			tipc_link_send(buf, dest, dest);
 		else
 			buf_discard(buf);
 	} else {
@@ -375,7 +375,7 @@ void cluster_send_local_routes(struct cl
 	}
 }
 
-void cluster_recv_routing_table(struct sk_buff *buf)
+void tipc_cltr_recv_routing_table(struct sk_buff *buf)
 {
 	struct tipc_msg *msg = buf_msg(buf);
 	struct cluster *c_ptr;
@@ -388,9 +388,9 @@ void cluster_recv_routing_table(struct s
 	u32 c_num;
 	u32 n_num;
 
-	c_ptr = cluster_find(rem_node);
+	c_ptr = tipc_cltr_find(rem_node);
 	if (!c_ptr) {
-		c_ptr = cluster_create(rem_node);
+		c_ptr = tipc_cltr_create(rem_node);
 		if (!c_ptr) {
 			buf_discard(buf);
 			return;
@@ -412,10 +412,10 @@ void cluster_recv_routing_table(struct s
 				u32 addr = tipc_addr(z_num, c_num, n_num);
 				n_ptr = c_ptr->nodes[n_num];
 				if (!n_ptr) {
-					n_ptr = node_create(addr);
+					n_ptr = tipc_node_create(addr);
 				}
 				if (n_ptr)
-					node_add_router(n_ptr, router);
+					tipc_node_add_router(n_ptr, router);
 			}
 		}
 		break;
@@ -428,10 +428,10 @@ void cluster_recv_routing_table(struct s
 				u32 addr = tipc_addr(z_num, c_num, slave_num);
 				n_ptr = c_ptr->nodes[slave_num];
 				if (!n_ptr) {
-					n_ptr = node_create(addr);
+					n_ptr = tipc_node_create(addr);
 				}
 				if (n_ptr)
-					node_add_router(n_ptr, router);
+					tipc_node_add_router(n_ptr, router);
 			}
 		}
 		break;
@@ -445,9 +445,9 @@ void cluster_recv_routing_table(struct s
 		}
 		n_ptr = c_ptr->nodes[tipc_node(rem_node)];
 		if (!n_ptr)
-			n_ptr = node_create(rem_node);
+			n_ptr = tipc_node_create(rem_node);
 		if (n_ptr)
-			node_add_router(n_ptr, router);
+			tipc_node_add_router(n_ptr, router);
 		break;
 	case ROUTE_REMOVAL:
 		if (!is_slave(tipc_own_addr)) {
@@ -459,7 +459,7 @@ void cluster_recv_routing_table(struct s
 		}
 		n_ptr = c_ptr->nodes[tipc_node(rem_node)];
 		if (n_ptr)
-			node_remove_router(n_ptr, router);
+			tipc_node_remove_router(n_ptr, router);
 		break;
 	default:
 		assert(!"Illegal routing manager message received\n");
@@ -467,7 +467,7 @@ void cluster_recv_routing_table(struct s
 	buf_discard(buf);
 }
 
-void cluster_remove_as_router(struct cluster *c_ptr, u32 router)
+void tipc_cltr_remove_as_router(struct cluster *c_ptr, u32 router)
 {
 	u32 start_entry;
 	u32 tstop;
@@ -486,17 +486,17 @@ void cluster_remove_as_router(struct clu
 
 	for (n_num = start_entry; n_num <= tstop; n_num++) {
 		if (c_ptr->nodes[n_num]) {
-			node_remove_router(c_ptr->nodes[n_num], router);
+			tipc_node_remove_router(c_ptr->nodes[n_num], router);
 		}
 	}
 }
 
 /**
- * cluster_multicast - multicast message to local nodes 
+ * tipc_cltr_multicast - multicast message to local nodes 
  */
 
-void cluster_multicast(struct cluster *c_ptr, struct sk_buff *buf, 
-		       u32 lower, u32 upper)
+void tipc_cltr_multicast(struct cluster *c_ptr, struct sk_buff *buf, 
+			 u32 lower, u32 upper)
 {
 	struct sk_buff *buf_copy;
 	struct node *n_ptr;
@@ -505,9 +505,9 @@ void cluster_multicast(struct cluster *c
 
 	assert(lower <= upper);
 	assert(((lower >= 1) && (lower <= tipc_max_nodes)) ||
-	       ((lower >= LOWEST_SLAVE) && (lower <= highest_allowed_slave)));
+	       ((lower >= LOWEST_SLAVE) && (lower <= tipc_highest_allowed_slave)));
 	assert(((upper >= 1) && (upper <= tipc_max_nodes)) ||
-	       ((upper >= LOWEST_SLAVE) && (upper <= highest_allowed_slave)));
+	       ((upper >= LOWEST_SLAVE) && (upper <= tipc_highest_allowed_slave)));
 	assert(in_own_cluster(c_ptr->addr));
 
 	tstop = is_slave(upper) ? c_ptr->highest_slave : c_ptr->highest_node;
@@ -515,22 +515,22 @@ void cluster_multicast(struct cluster *c
 		tstop = upper;
 	for (n_num = lower; n_num <= tstop; n_num++) {
 		n_ptr = c_ptr->nodes[n_num];
-		if (n_ptr && node_has_active_links(n_ptr)) {
+		if (n_ptr && tipc_node_has_active_links(n_ptr)) {
 			buf_copy = skb_copy(buf, GFP_ATOMIC);
 			if (buf_copy == NULL)
 				break;
 			msg_set_destnode(buf_msg(buf_copy), n_ptr->addr);
-			link_send(buf_copy, n_ptr->addr, n_ptr->addr);
+			tipc_link_send(buf_copy, n_ptr->addr, n_ptr->addr);
 		}
 	}
 	buf_discard(buf);
 }
 
 /**
- * cluster_broadcast - broadcast message to all nodes within cluster
+ * tipc_cltr_broadcast - broadcast message to all nodes within cluster
  */
 
-void cluster_broadcast(struct sk_buff *buf)
+void tipc_cltr_broadcast(struct sk_buff *buf)
 {
 	struct sk_buff *buf_copy;
 	struct cluster *c_ptr;
@@ -541,7 +541,7 @@ void cluster_broadcast(struct sk_buff *b
 	u32 node_type;
 
 	if (tipc_mode == TIPC_NET_MODE) {
-		c_ptr = cluster_find(tipc_own_addr);
+		c_ptr = tipc_cltr_find(tipc_own_addr);
 		assert(in_own_cluster(c_ptr->addr));	/* For now */
 
 		/* Send to standard nodes, then repeat loop sending to slaves */
@@ -550,14 +550,14 @@ void cluster_broadcast(struct sk_buff *b
 		for (node_type = 1; node_type <= 2; node_type++) {
 			for (n_num = tstart; n_num <= tstop; n_num++) {
 				n_ptr = c_ptr->nodes[n_num];
-				if (n_ptr && node_has_active_links(n_ptr)) {
+				if (n_ptr && tipc_node_has_active_links(n_ptr)) {
 					buf_copy = skb_copy(buf, GFP_ATOMIC);
 					if (buf_copy == NULL)
 						goto exit;
 					msg_set_destnode(buf_msg(buf_copy), 
 							 n_ptr->addr);
-					link_send(buf_copy, n_ptr->addr, 
-						  n_ptr->addr);
+					tipc_link_send(buf_copy, n_ptr->addr, 
+						       n_ptr->addr);
 				}
 			}
 			tstart = LOWEST_SLAVE;
@@ -568,9 +568,9 @@ exit:
 	buf_discard(buf);
 }
 
-int cluster_init(void)
+int tipc_cltr_init(void)
 {
-	highest_allowed_slave = LOWEST_SLAVE + tipc_max_slaves;
-	return cluster_create(tipc_own_addr) ? TIPC_OK : -ENOMEM;
+	tipc_highest_allowed_slave = LOWEST_SLAVE + tipc_max_slaves;
+	return tipc_cltr_create(tipc_own_addr) ? TIPC_OK : -ENOMEM;
 }
 
diff --git a/net/tipc/cluster.h b/net/tipc/cluster.h
index 1ffb095..9963642 100644
--- a/net/tipc/cluster.h
+++ b/net/tipc/cluster.h
@@ -60,29 +60,29 @@ struct cluster {
 };
 
 
-extern struct node **local_nodes;
-extern u32 highest_allowed_slave;
-extern struct node_map cluster_bcast_nodes;
-
-void cluster_remove_as_router(struct cluster *c_ptr, u32 router);
-void cluster_send_ext_routes(struct cluster *c_ptr, u32 dest);
-struct node *cluster_select_node(struct cluster *c_ptr, u32 selector);
-u32 cluster_select_router(struct cluster *c_ptr, u32 ref);
-void cluster_recv_routing_table(struct sk_buff *buf);
-struct cluster *cluster_create(u32 addr);
-void cluster_delete(struct cluster *c_ptr);
-void cluster_attach_node(struct cluster *c_ptr, struct node *n_ptr);
-void cluster_send_slave_routes(struct cluster *c_ptr, u32 dest);
-void cluster_broadcast(struct sk_buff *buf);
-int cluster_init(void);
-u32 cluster_next_node(struct cluster *c_ptr, u32 addr);
-void cluster_bcast_new_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi);
-void cluster_send_local_routes(struct cluster *c_ptr, u32 dest);
-void cluster_bcast_lost_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi);
+extern struct node **tipc_local_nodes;
+extern u32 tipc_highest_allowed_slave;
+extern struct node_map tipc_cltr_bcast_nodes;
+
+void tipc_cltr_remove_as_router(struct cluster *c_ptr, u32 router);
+void tipc_cltr_send_ext_routes(struct cluster *c_ptr, u32 dest);
+struct node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector);
+u32 tipc_cltr_select_router(struct cluster *c_ptr, u32 ref);
+void tipc_cltr_recv_routing_table(struct sk_buff *buf);
+struct cluster *tipc_cltr_create(u32 addr);
+void tipc_cltr_delete(struct cluster *c_ptr);
+void tipc_cltr_attach_node(struct cluster *c_ptr, struct node *n_ptr);
+void tipc_cltr_send_slave_routes(struct cluster *c_ptr, u32 dest);
+void tipc_cltr_broadcast(struct sk_buff *buf);
+int tipc_cltr_init(void);
+u32 tipc_cltr_next_node(struct cluster *c_ptr, u32 addr);
+void tipc_cltr_bcast_new_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi);
+void tipc_cltr_send_local_routes(struct cluster *c_ptr, u32 dest);
+void tipc_cltr_bcast_lost_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi);
 
-static inline struct cluster *cluster_find(u32 addr)
+static inline struct cluster *tipc_cltr_find(u32 addr)
 {
-	struct _zone *z_ptr = zone_find(addr);
+	struct _zone *z_ptr = tipc_zone_find(addr);
 
 	if (z_ptr)
 		return z_ptr->clusters[1];
diff --git a/net/tipc/config.c b/net/tipc/config.c
index 8ddef4f..3c8e674 100644
--- a/net/tipc/config.c
+++ b/net/tipc/config.c
@@ -70,13 +70,13 @@ static int req_tlv_space;		/* request me
 static int rep_headroom;		/* reply message headroom to use */
 
 
-void cfg_link_event(u32 addr, char *name, int up)
+void tipc_cfg_link_event(u32 addr, char *name, int up)
 {
 	/* TIPC DOESN'T HANDLE LINK EVENT SUBSCRIPTIONS AT THE MOMENT */
 }
 
 
-struct sk_buff *cfg_reply_alloc(int payload_size)
+struct sk_buff *tipc_cfg_reply_alloc(int payload_size)
 {
 	struct sk_buff *buf;
 
@@ -86,14 +86,14 @@ struct sk_buff *cfg_reply_alloc(int payl
 	return buf;
 }
 
-int cfg_append_tlv(struct sk_buff *buf, int tlv_type, 
-		   void *tlv_data, int tlv_data_size)
+int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type, 
+			void *tlv_data, int tlv_data_size)
 {
 	struct tlv_desc *tlv = (struct tlv_desc *)buf->tail;
 	int new_tlv_space = TLV_SPACE(tlv_data_size);
 
 	if (skb_tailroom(buf) < new_tlv_space) {
-		dbg("cfg_append_tlv unable to append TLV\n");
+		dbg("tipc_cfg_append_tlv unable to append TLV\n");
 		return 0;
 	}
 	skb_put(buf, new_tlv_space);
@@ -104,28 +104,28 @@ int cfg_append_tlv(struct sk_buff *buf, 
 	return 1;
 }
 
-struct sk_buff *cfg_reply_unsigned_type(u16 tlv_type, u32 value)
+struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value)
 {
 	struct sk_buff *buf;
 	u32 value_net;
 
-	buf = cfg_reply_alloc(TLV_SPACE(sizeof(value)));
+	buf = tipc_cfg_reply_alloc(TLV_SPACE(sizeof(value)));
 	if (buf) {
 		value_net = htonl(value);
-		cfg_append_tlv(buf, tlv_type, &value_net, 
-			       sizeof(value_net));
+		tipc_cfg_append_tlv(buf, tlv_type, &value_net, 
+				    sizeof(value_net));
 	}
 	return buf;
 }
 
-struct sk_buff *cfg_reply_string_type(u16 tlv_type, char *string)
+struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string)
 {
 	struct sk_buff *buf;
 	int string_len = strlen(string) + 1;
 
-	buf = cfg_reply_alloc(TLV_SPACE(string_len));
+	buf = tipc_cfg_reply_alloc(TLV_SPACE(string_len));
 	if (buf)
-		cfg_append_tlv(buf, tlv_type, string, string_len);
+		tipc_cfg_append_tlv(buf, tlv_type, string, string_len);
 	return buf;
 }
 
@@ -246,7 +246,7 @@ static void cfg_cmd_event(struct tipc_cm
 	exit:
 	rmsg.result_len = htonl(msg_sect[1].iov_len);
 	rmsg.retval = htonl(rv);
-	cfg_respond(msg_sect, 2u, orig);
+	tipc_cfg_respond(msg_sect, 2u, orig);
 }
 #endif
 
@@ -255,26 +255,26 @@ static struct sk_buff *cfg_enable_bearer
 	struct tipc_bearer_config *args;
 
 	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_BEARER_CONFIG))
-		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
+		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
 
 	args = (struct tipc_bearer_config *)TLV_DATA(req_tlv_area);
 	if (tipc_enable_bearer(args->name,
 			       ntohl(args->detect_scope),
 			       ntohl(args->priority)))
-		return cfg_reply_error_string("unable to enable bearer");
+		return tipc_cfg_reply_error_string("unable to enable bearer");
 
-	return cfg_reply_none();
+	return tipc_cfg_reply_none();
 }
 
 static struct sk_buff *cfg_disable_bearer(void)
 {
 	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_BEARER_NAME))
-		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
+		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
 
 	if (tipc_disable_bearer((char *)TLV_DATA(req_tlv_area)))
-		return cfg_reply_error_string("unable to disable bearer");
+		return tipc_cfg_reply_error_string("unable to disable bearer");
 
-	return cfg_reply_none();
+	return tipc_cfg_reply_none();
 }
 
 static struct sk_buff *cfg_set_own_addr(void)
@@ -282,25 +282,25 @@ static struct sk_buff *cfg_set_own_addr(
 	u32 addr;
 
 	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
-		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
+		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
 
 	addr = *(u32 *)TLV_DATA(req_tlv_area);
 	addr = ntohl(addr);
 	if (addr == tipc_own_addr)
-		return cfg_reply_none();
-	if (!addr_node_valid(addr))
-		return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
-					      " (node address)");
+		return tipc_cfg_reply_none();
+	if (!tipc_addr_node_valid(addr))
+		return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
+						   " (node address)");
 	if (tipc_own_addr)
-		return cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
-					      " (cannot change node address once assigned)");
+		return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
+						   " (cannot change node address once assigned)");
 
 	spin_unlock_bh(&config_lock);
-	stop_net();
+	tipc_core_stop_net();
 	tipc_own_addr = addr;
-	start_net();
+	tipc_core_start_net();
 	spin_lock_bh(&config_lock);
-	return cfg_reply_none();
+	return tipc_cfg_reply_none();
 }
 
 static struct sk_buff *cfg_set_remote_mng(void)
@@ -308,12 +308,12 @@ static struct sk_buff *cfg_set_remote_mn
 	u32 value;
 
 	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
-		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
+		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
 
 	value = *(u32 *)TLV_DATA(req_tlv_area);
 	value = ntohl(value);
 	tipc_remote_management = (value != 0);
-	return cfg_reply_none();
+	return tipc_cfg_reply_none();
 }
 
 static struct sk_buff *cfg_set_max_publications(void)
@@ -321,15 +321,15 @@ static struct sk_buff *cfg_set_max_publi
 	u32 value;
 
 	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
-		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
+		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
 
 	value = *(u32 *)TLV_DATA(req_tlv_area);
 	value = ntohl(value);
 	if (value != delimit(value, 1, 65535))
-		return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
-					      " (max publications must be 1-65535)");
+		return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
+						   " (max publications must be 1-65535)");
 	tipc_max_publications = value;
-	return cfg_reply_none();
+	return tipc_cfg_reply_none();
 }
 
 static struct sk_buff *cfg_set_max_subscriptions(void)
@@ -337,15 +337,15 @@ static struct sk_buff *cfg_set_max_subsc
 	u32 value;
 
 	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
-		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
+		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
 
 	value = *(u32 *)TLV_DATA(req_tlv_area);
 	value = ntohl(value);
 	if (value != delimit(value, 1, 65535))
-		return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
-					      " (max subscriptions must be 1-65535");
+		return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
+						   " (max subscriptions must be 1-65535");
 	tipc_max_subscriptions = value;
-	return cfg_reply_none();
+	return tipc_cfg_reply_none();
 }
 
 static struct sk_buff *cfg_set_max_ports(void)
@@ -354,31 +354,31 @@ static struct sk_buff *cfg_set_max_ports
 	u32 value;
 
 	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
-		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
+		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
 	value = *(u32 *)TLV_DATA(req_tlv_area);
 	value = ntohl(value);
 	if (value != delimit(value, 127, 65535))
-		return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
-					      " (max ports must be 127-65535)");
+		return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
+						   " (max ports must be 127-65535)");
 
 	if (value == tipc_max_ports)
-		return cfg_reply_none();
+		return tipc_cfg_reply_none();
 
 	if (atomic_read(&tipc_user_count) > 2)
-		return cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
-					      " (cannot change max ports while TIPC users exist)");
+		return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
+						   " (cannot change max ports while TIPC users exist)");
 
 	spin_unlock_bh(&config_lock);
 	orig_mode = tipc_get_mode();
 	if (orig_mode == TIPC_NET_MODE)
-		stop_net();
-	stop_core();
+		tipc_core_stop_net();
+	tipc_core_stop();
 	tipc_max_ports = value;
-	start_core();
+	tipc_core_start();
 	if (orig_mode == TIPC_NET_MODE)
-		start_net();
+		tipc_core_start_net();
 	spin_lock_bh(&config_lock);
-	return cfg_reply_none();
+	return tipc_cfg_reply_none();
 }
 
 static struct sk_buff *set_net_max(int value, int *parameter)
@@ -388,13 +388,13 @@ static struct sk_buff *set_net_max(int v
 	if (value != *parameter) {
 		orig_mode = tipc_get_mode();
 		if (orig_mode == TIPC_NET_MODE)
-			stop_net();
+			tipc_core_stop_net();
 		*parameter = value;
 		if (orig_mode == TIPC_NET_MODE)
-			start_net();
+			tipc_core_start_net();
 	}
 
-	return cfg_reply_none();
+	return tipc_cfg_reply_none();
 }
 
 static struct sk_buff *cfg_set_max_zones(void)
@@ -402,12 +402,12 @@ static struct sk_buff *cfg_set_max_zones
 	u32 value;
 
 	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
-		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
+		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
 	value = *(u32 *)TLV_DATA(req_tlv_area);
 	value = ntohl(value);
 	if (value != delimit(value, 1, 255))
-		return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
-					      " (max zones must be 1-255)");
+		return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
+						   " (max zones must be 1-255)");
 	return set_net_max(value, &tipc_max_zones);
 }
 
@@ -416,13 +416,13 @@ static struct sk_buff *cfg_set_max_clust
 	u32 value;
 
 	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
-		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
+		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
 	value = *(u32 *)TLV_DATA(req_tlv_area);
 	value = ntohl(value);
 	if (value != 1)
-		return cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
-					      " (max clusters fixed at 1)");
-	return cfg_reply_none();
+		return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
+						   " (max clusters fixed at 1)");
+	return tipc_cfg_reply_none();
 }
 
 static struct sk_buff *cfg_set_max_nodes(void)
@@ -430,12 +430,12 @@ static struct sk_buff *cfg_set_max_nodes
 	u32 value;
 
 	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
-		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
+		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
 	value = *(u32 *)TLV_DATA(req_tlv_area);
 	value = ntohl(value);
 	if (value != delimit(value, 8, 2047))
-		return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
-					      " (max nodes must be 8-2047)");
+		return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
+						   " (max nodes must be 8-2047)");
 	return set_net_max(value, &tipc_max_nodes);
 }
 
@@ -444,13 +444,13 @@ static struct sk_buff *cfg_set_max_slave
 	u32 value;
 
 	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
-		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
+		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
 	value = *(u32 *)TLV_DATA(req_tlv_area);
 	value = ntohl(value);
 	if (value != 0)
-		return cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
-					      " (max secondary nodes fixed at 0)");
-	return cfg_reply_none();
+		return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
+						   " (max secondary nodes fixed at 0)");
+	return tipc_cfg_reply_none();
 }
 
 static struct sk_buff *cfg_set_netid(void)
@@ -458,22 +458,22 @@ static struct sk_buff *cfg_set_netid(voi
 	u32 value;
 
 	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
-		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
+		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
 	value = *(u32 *)TLV_DATA(req_tlv_area);
 	value = ntohl(value);
 	if (value != delimit(value, 1, 9999))
-		return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
-					      " (network id must be 1-9999)");
+		return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
+						   " (network id must be 1-9999)");
 
 	if (tipc_own_addr)
-		return cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
-					      " (cannot change network id once part of network)");
+		return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
+						   " (cannot change network id once part of network)");
 	
 	return set_net_max(value, &tipc_net_id);
 }
 
-struct sk_buff *cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area,
-			   int request_space, int reply_headroom)
+struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area,
+				int request_space, int reply_headroom)
 {
 	struct sk_buff *rep_tlv_buf;
 
@@ -490,19 +490,19 @@ struct sk_buff *cfg_do_cmd(u32 orig_node
 	if (likely(orig_node == tipc_own_addr)) {
 		/* command is permitted */
 	} else if (cmd >= 0x8000) {
-		rep_tlv_buf = cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
-						     " (cannot be done remotely)");
+		rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
+							  " (cannot be done remotely)");
 		goto exit;
 	} else if (!tipc_remote_management) {
-		rep_tlv_buf = cfg_reply_error_string(TIPC_CFG_NO_REMOTE);
+		rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NO_REMOTE);
 		goto exit;
 	}
 	else if (cmd >= 0x4000) {
 		u32 domain = 0;
 
-		if ((nametbl_translate(TIPC_ZM_SRV, 0, &domain) == 0) ||
+		if ((tipc_nametbl_translate(TIPC_ZM_SRV, 0, &domain) == 0) ||
 		    (domain != orig_node)) {
-			rep_tlv_buf = cfg_reply_error_string(TIPC_CFG_NOT_ZONE_MSTR);
+			rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_ZONE_MSTR);
 			goto exit;
 		}
 	}
@@ -511,50 +511,50 @@ struct sk_buff *cfg_do_cmd(u32 orig_node
 
 	switch (cmd) {
 	case TIPC_CMD_NOOP:
-		rep_tlv_buf = cfg_reply_none();
+		rep_tlv_buf = tipc_cfg_reply_none();
 		break;
 	case TIPC_CMD_GET_NODES:
-		rep_tlv_buf = node_get_nodes(req_tlv_area, req_tlv_space);
+		rep_tlv_buf = tipc_node_get_nodes(req_tlv_area, req_tlv_space);
 		break;
 	case TIPC_CMD_GET_LINKS:
-		rep_tlv_buf = node_get_links(req_tlv_area, req_tlv_space);
+		rep_tlv_buf = tipc_node_get_links(req_tlv_area, req_tlv_space);
 		break;
 	case TIPC_CMD_SHOW_LINK_STATS:
-		rep_tlv_buf = link_cmd_show_stats(req_tlv_area, req_tlv_space);
+		rep_tlv_buf = tipc_link_cmd_show_stats(req_tlv_area, req_tlv_space);
 		break;
 	case TIPC_CMD_RESET_LINK_STATS:
-		rep_tlv_buf = link_cmd_reset_stats(req_tlv_area, req_tlv_space);
+		rep_tlv_buf = tipc_link_cmd_reset_stats(req_tlv_area, req_tlv_space);
 		break;
 	case TIPC_CMD_SHOW_NAME_TABLE:
-		rep_tlv_buf = nametbl_get(req_tlv_area, req_tlv_space);
+		rep_tlv_buf = tipc_nametbl_get(req_tlv_area, req_tlv_space);
 		break;
 	case TIPC_CMD_GET_BEARER_NAMES:
-		rep_tlv_buf = bearer_get_names();
+		rep_tlv_buf = tipc_bearer_get_names();
 		break;
 	case TIPC_CMD_GET_MEDIA_NAMES:
-		rep_tlv_buf = media_get_names();
+		rep_tlv_buf = tipc_media_get_names();
 		break;
 	case TIPC_CMD_SHOW_PORTS:
-		rep_tlv_buf = port_get_ports();
+		rep_tlv_buf = tipc_port_get_ports();
 		break;
 #if 0
 	case TIPC_CMD_SHOW_PORT_STATS:
 		rep_tlv_buf = port_show_stats(req_tlv_area, req_tlv_space);
 		break;
 	case TIPC_CMD_RESET_PORT_STATS:
-		rep_tlv_buf = cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED);
+		rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED);
 		break;
 #endif
 	case TIPC_CMD_SET_LOG_SIZE:
-		rep_tlv_buf = log_resize(req_tlv_area, req_tlv_space);
+		rep_tlv_buf = tipc_log_resize(req_tlv_area, req_tlv_space);
 		break;
 	case TIPC_CMD_DUMP_LOG:
-		rep_tlv_buf = log_dump();
+		rep_tlv_buf = tipc_log_dump();
 		break;
 	case TIPC_CMD_SET_LINK_TOL:
 	case TIPC_CMD_SET_LINK_PRI:
 	case TIPC_CMD_SET_LINK_WINDOW:
-		rep_tlv_buf = link_cmd_config(req_tlv_area, req_tlv_space, cmd);
+		rep_tlv_buf = tipc_link_cmd_config(req_tlv_area, req_tlv_space, cmd);
 		break;
 	case TIPC_CMD_ENABLE_BEARER:
 		rep_tlv_buf = cfg_enable_bearer();
@@ -593,31 +593,31 @@ struct sk_buff *cfg_do_cmd(u32 orig_node
 		rep_tlv_buf = cfg_set_netid();
 		break;
 	case TIPC_CMD_GET_REMOTE_MNG:
-		rep_tlv_buf = cfg_reply_unsigned(tipc_remote_management);
+		rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_remote_management);
 		break;
 	case TIPC_CMD_GET_MAX_PORTS:
-		rep_tlv_buf = cfg_reply_unsigned(tipc_max_ports);
+		rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_ports);
 		break;
 	case TIPC_CMD_GET_MAX_PUBL:
-		rep_tlv_buf = cfg_reply_unsigned(tipc_max_publications);
+		rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_publications);
 		break;
 	case TIPC_CMD_GET_MAX_SUBSCR:
-		rep_tlv_buf = cfg_reply_unsigned(tipc_max_subscriptions);
+		rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_subscriptions);
 		break;
 	case TIPC_CMD_GET_MAX_ZONES:
-		rep_tlv_buf = cfg_reply_unsigned(tipc_max_zones);
+		rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_zones);
 		break;
 	case TIPC_CMD_GET_MAX_CLUSTERS:
-		rep_tlv_buf = cfg_reply_unsigned(tipc_max_clusters);
+		rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_clusters);
 		break;
 	case TIPC_CMD_GET_MAX_NODES:
-		rep_tlv_buf = cfg_reply_unsigned(tipc_max_nodes);
+		rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_nodes);
 		break;
 	case TIPC_CMD_GET_MAX_SLAVES:
-		rep_tlv_buf = cfg_reply_unsigned(tipc_max_slaves);
+		rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_slaves);
 		break;
 	case TIPC_CMD_GET_NETID:
-		rep_tlv_buf = cfg_reply_unsigned(tipc_net_id);
+		rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id);
 		break;
 	default:
 		rep_tlv_buf = NULL;
@@ -655,11 +655,11 @@ static void cfg_named_msg_event(void *us
 
 	/* Generate reply for request (if can't, return request) */
 
-	rep_buf = cfg_do_cmd(orig->node,
-			     ntohs(req_hdr->tcm_type), 
-			     msg + sizeof(*req_hdr),
-			     size - sizeof(*req_hdr),
-			     BUF_HEADROOM + MAX_H_SIZE + sizeof(*rep_hdr));
+	rep_buf = tipc_cfg_do_cmd(orig->node,
+				  ntohs(req_hdr->tcm_type), 
+				  msg + sizeof(*req_hdr),
+				  size - sizeof(*req_hdr),
+				  BUF_HEADROOM + MAX_H_SIZE + sizeof(*rep_hdr));
 	if (rep_buf) {
 		skb_push(rep_buf, sizeof(*rep_hdr));
 		rep_hdr = (struct tipc_cfg_msg_hdr *)rep_buf->data;
@@ -675,7 +675,7 @@ static void cfg_named_msg_event(void *us
 	tipc_send_buf2port(port_ref, orig, rep_buf, rep_buf->len);
 }
 
-int cfg_init(void)
+int tipc_cfg_init(void)
 {
 	struct tipc_name_seq seq;
 	int res;
@@ -696,7 +696,7 @@ int cfg_init(void)
 
 	seq.type = TIPC_CFG_SRV;
 	seq.lower = seq.upper = tipc_own_addr;
-	res = nametbl_publish_rsv(mng.port_ref, TIPC_ZONE_SCOPE, &seq);
+	res = tipc_nametbl_publish_rsv(mng.port_ref, TIPC_ZONE_SCOPE, &seq);
 	if (res)
 		goto failed;
 
@@ -709,7 +709,7 @@ failed:
 	return res;
 }
 
-void cfg_stop(void)
+void tipc_cfg_stop(void)
 {
 	if (mng.user_ref) {
 		tipc_detach(mng.user_ref);
diff --git a/net/tipc/config.h b/net/tipc/config.h
index 646377d..7a728f9 100644
--- a/net/tipc/config.h
+++ b/net/tipc/config.h
@@ -39,42 +39,41 @@
 
 /* ---------------------------------------------------------------------- */
 
-#include <linux/tipc.h>
-#include <linux/tipc_config.h>
+#include "core.h"
 #include "link.h"
 
-struct sk_buff *cfg_reply_alloc(int payload_size);
-int cfg_append_tlv(struct sk_buff *buf, int tlv_type, 
-		   void *tlv_data, int tlv_data_size);
-struct sk_buff *cfg_reply_unsigned_type(u16 tlv_type, u32 value);
-struct sk_buff *cfg_reply_string_type(u16 tlv_type, char *string);
+struct sk_buff *tipc_cfg_reply_alloc(int payload_size);
+int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type, 
+			void *tlv_data, int tlv_data_size);
+struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value);
+struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string);
 
-static inline struct sk_buff *cfg_reply_none(void)
+static inline struct sk_buff *tipc_cfg_reply_none(void)
 {
-	return cfg_reply_alloc(0);
+	return tipc_cfg_reply_alloc(0);
 }
 
-static inline struct sk_buff *cfg_reply_unsigned(u32 value)
+static inline struct sk_buff *tipc_cfg_reply_unsigned(u32 value)
 {
-	return cfg_reply_unsigned_type(TIPC_TLV_UNSIGNED, value);
+	return tipc_cfg_reply_unsigned_type(TIPC_TLV_UNSIGNED, value);
 }
 
-static inline struct sk_buff *cfg_reply_error_string(char *string)
+static inline struct sk_buff *tipc_cfg_reply_error_string(char *string)
 {
-	return cfg_reply_string_type(TIPC_TLV_ERROR_STRING, string);
+	return tipc_cfg_reply_string_type(TIPC_TLV_ERROR_STRING, string);
 }
 
-static inline struct sk_buff *cfg_reply_ultra_string(char *string)
+static inline struct sk_buff *tipc_cfg_reply_ultra_string(char *string)
 {
-	return cfg_reply_string_type(TIPC_TLV_ULTRA_STRING, string);
+	return tipc_cfg_reply_string_type(TIPC_TLV_ULTRA_STRING, string);
 }
 
-struct sk_buff *cfg_do_cmd(u32 orig_node, u16 cmd, 
-			   const void *req_tlv_area, int req_tlv_space, 
-			   int headroom);
-
-void cfg_link_event(u32 addr, char *name, int up);
-int  cfg_init(void);
-void cfg_stop(void);
+struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, 
+				const void *req_tlv_area, int req_tlv_space, 
+				int headroom);
+
+void tipc_cfg_link_event(u32 addr, char *name, int up);
+int  tipc_cfg_init(void);
+void tipc_cfg_stop(void);
 
 #endif
diff --git a/net/tipc/core.c b/net/tipc/core.c
index e83ac06..3d0a8ee 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -37,7 +37,6 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/random.h>
 
 #include "core.h"
@@ -49,14 +48,14 @@
 #include "subscr.h"
 #include "config.h"
 
-int  eth_media_start(void);
-void eth_media_stop(void);
-int  handler_start(void);
-void handler_stop(void);
-int  socket_init(void);
-void socket_stop(void);
-int  netlink_start(void);
-void netlink_stop(void);
+int  tipc_eth_media_start(void);
+void tipc_eth_media_stop(void);
+int  tipc_handler_start(void);
+void tipc_handler_stop(void);
+int  tipc_socket_init(void);
+void tipc_socket_stop(void);
+int  tipc_netlink_start(void);
+void tipc_netlink_stop(void);
 
 #define MOD_NAME "tipc_start: "
 
@@ -113,56 +112,56 @@ int tipc_get_mode(void)
 }
 
 /**
- * stop_net - shut down TIPC networking sub-systems
+ * tipc_core_stop_net - shut down TIPC networking sub-systems
  */
 
-void stop_net(void)
+void tipc_core_stop_net(void)
 {
-	eth_media_stop();
-	tipc_stop_net();
+	tipc_eth_media_stop();
+	tipc_net_stop();
 }
 
 /**
  * start_net - start TIPC networking sub-systems
  */
 
-int start_net(void)
+int tipc_core_start_net(void)
 {
 	int res;
 
-	if ((res = tipc_start_net()) ||
-	    (res = eth_media_start())) {
-		stop_net();
+	if ((res = tipc_net_start()) ||
+	    (res = tipc_eth_media_start())) {
+		tipc_core_stop_net();
 	}
 	return res;
 }
 
 /**
- * stop_core - switch TIPC from SINGLE NODE to NOT RUNNING mode
+ * tipc_core_stop - switch TIPC from SINGLE NODE to NOT RUNNING mode
  */
 
-void stop_core(void)
+void tipc_core_stop(void)
 {
 	if (tipc_mode != TIPC_NODE_MODE)
 		return;
 
 	tipc_mode = TIPC_NOT_RUNNING;
 
-	netlink_stop();
-	handler_stop();
-	cfg_stop();
-	subscr_stop();
-	reg_stop();
-	nametbl_stop();
-	ref_table_stop();
-	socket_stop();
+	tipc_netlink_stop();
+	tipc_handler_stop();
+	tipc_cfg_stop();
+	tipc_subscr_stop();
+	tipc_reg_stop();
+	tipc_nametbl_stop();
+	tipc_ref_table_stop();
+	tipc_socket_stop();
 }
 
 /**
- * start_core - switch TIPC from NOT RUNNING to SINGLE NODE mode
+ * tipc_core_start - switch TIPC from NOT RUNNING to SINGLE NODE mode
  */
 
-int start_core(void)
+int tipc_core_start(void)
 {
 	int res;
 
@@ -172,16 +171,16 @@ int start_core(void)
 	get_random_bytes(&tipc_random, sizeof(tipc_random));
 	tipc_mode = TIPC_NODE_MODE;
 
-	if ((res = handler_start()) || 
-	    (res = ref_table_init(tipc_max_ports + tipc_max_subscriptions,
-				  tipc_random)) ||
-	    (res = reg_start()) ||
-	    (res = nametbl_init()) ||
-            (res = k_signal((Handler)subscr_start, 0)) ||
-	    (res = k_signal((Handler)cfg_init, 0)) || 
-	    (res = netlink_start()) ||
-	    (res = socket_init())) {
-		stop_core();
+	if ((res = tipc_handler_start()) || 
+	    (res = tipc_ref_table_init(tipc_max_ports + tipc_max_subscriptions,
+				       tipc_random)) ||
+	    (res = tipc_reg_start()) ||
+	    (res = tipc_nametbl_init()) ||
+            (res = tipc_k_signal((Handler)tipc_subscr_start, 0)) ||
+	    (res = tipc_k_signal((Handler)tipc_cfg_init, 0)) || 
+	    (res = tipc_netlink_start()) ||
+	    (res = tipc_socket_init())) {
+		tipc_core_stop();
 	}
 	return res;
 }
@@ -191,7 +190,7 @@ static int __init tipc_init(void)
 {
 	int res;
 
-	log_reinit(CONFIG_TIPC_LOG);
+	tipc_log_reinit(CONFIG_TIPC_LOG);
 	info("Activated (compiled " __DATE__ " " __TIME__ ")\n");
 
 	tipc_own_addr = 0;
@@ -205,7 +204,7 @@ static int __init tipc_init(void)
 	tipc_max_slaves = delimit(CONFIG_TIPC_SLAVE_NODES, 0, 2047);
 	tipc_net_id = 4711;
 
-	if ((res = start_core()))
+	if ((res = tipc_core_start()))
 		err("Unable to start in single node mode\n");
 	else	
 		info("Started in single node mode\n");
@@ -214,10 +213,10 @@ static int __init tipc_init(void)
 
 static void __exit tipc_exit(void)
 {
-	stop_net();
-	stop_core();
+	tipc_core_stop_net();
+	tipc_core_stop();
 	info("Deactivated\n");
-	log_stop();
+	tipc_log_stop();
 }
 
 module_init(tipc_init);
diff --git a/net/tipc/core.h b/net/tipc/core.h
index b69b60b..1f2e8b2 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -37,6 +37,11 @@
 #ifndef _TIPC_CORE_H
 #define _TIPC_CORE_H
 
+#include <linux/tipc.h>
+#include <linux/tipc_config.h>
+#include <net/tipc/tipc_msg.h>
+#include <net/tipc/tipc_port.h>
+#include <net/tipc/tipc_bearer.h>
 #include <net/tipc/tipc.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -60,9 +65,9 @@
 #define assert(i)  BUG_ON(!(i))
 
 struct tipc_msg;
-extern struct print_buf *CONS, *LOG;
-extern struct print_buf *TEE(struct print_buf *, struct print_buf *);
-void msg_print(struct print_buf*,struct tipc_msg *,const char*);
+extern struct print_buf *TIPC_CONS, *TIPC_LOG;
+extern struct print_buf *TIPC_TEE(struct print_buf *, struct print_buf *);
+void tipc_msg_print(struct print_buf*,struct tipc_msg *,const char*);
 void tipc_printf(struct print_buf *, const char *fmt, ...);
 void tipc_dump(struct print_buf*,const char *fmt, ...);
 
@@ -79,7 +84,7 @@ void tipc_dump(struct print_buf*,const c
 #define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_NOTICE "TIPC: " fmt, ## arg)
 
 #define dbg(fmt, arg...)  do {if (DBG_OUTPUT) tipc_printf(DBG_OUTPUT, fmt, ## arg);} while(0)
-#define msg_dbg(msg, txt) do {if (DBG_OUTPUT) msg_print(DBG_OUTPUT, msg, txt);} while(0)
+#define msg_dbg(msg, txt) do {if (DBG_OUTPUT) tipc_msg_print(DBG_OUTPUT, msg, txt);} while(0)
 #define dump(fmt, arg...) do {if (DBG_OUTPUT) tipc_dump(DBG_OUTPUT, fmt, ##arg);} while(0)
 
 
@@ -89,15 +94,15 @@ void tipc_dump(struct print_buf*,const c
  * here, or on a per .c file basis, by redefining these symbols.  The following
  * print buffer options are available:
  *
- * NULL			: Output to null print buffer (i.e. print nowhere)
- * CONS			: Output to system console
- * LOG			: Output to TIPC log buffer 
- * &buf 		: Output to user-defined buffer (struct print_buf *)
- * TEE(&buf_a,&buf_b)	: Output to two print buffers (eg. TEE(CONS,LOG) )
+ * NULL				: Output to null print buffer (i.e. print nowhere)
+ * TIPC_CONS			: Output to system console
+ * TIPC_LOG			: Output to TIPC log buffer 
+ * &buf				: Output to user-defined buffer (struct print_buf *)
+ * TIPC_TEE(&buf_a,&buf_b)	: Output to two print buffers (eg. TIPC_TEE(TIPC_CONS,TIPC_LOG) )
  */
 
 #ifndef TIPC_OUTPUT
-#define TIPC_OUTPUT TEE(CONS,LOG)
+#define TIPC_OUTPUT TIPC_TEE(TIPC_CONS,TIPC_LOG)
 #endif
 
 #ifndef DBG_OUTPUT
@@ -162,10 +167,10 @@ extern atomic_t tipc_user_count;
  * Routines available to privileged subsystems
  */
 
-extern int  start_core(void);
-extern void stop_core(void);
-extern int  start_net(void);
-extern void stop_net(void);
+extern int  tipc_core_start(void);
+extern void tipc_core_stop(void);
+extern int  tipc_core_start_net(void);
+extern void tipc_core_stop_net(void);
 
 static inline int delimit(int val, int min, int max)
 {
@@ -183,7 +188,7 @@ static inline int delimit(int val, int m
 
 typedef void (*Handler) (unsigned long);
 
-u32 k_signal(Handler routine, unsigned long argument);
+u32 tipc_k_signal(Handler routine, unsigned long argument);
 
 /**
  * k_init_timer - initialize a timer
diff --git a/net/tipc/dbg.c b/net/tipc/dbg.c
index 7ed60a1..4f4beef 100644
--- a/net/tipc/dbg.c
+++ b/net/tipc/dbg.c
@@ -44,10 +44,10 @@ static char print_string[MAX_STRING];
 static spinlock_t print_lock = SPIN_LOCK_UNLOCKED;
 
 static struct print_buf cons_buf = { NULL, 0, NULL, NULL };
-struct print_buf *CONS = &cons_buf;
+struct print_buf *TIPC_CONS = &cons_buf;
 
 static struct print_buf log_buf = { NULL, 0, NULL, NULL };
-struct print_buf *LOG = &log_buf;
+struct print_buf *TIPC_LOG = &log_buf;
 
 
 #define FORMAT(PTR,LEN,FMT) \
@@ -66,15 +66,15 @@ struct print_buf *LOG = &log_buf;
  *    simultaneous use of the print buffer(s) being manipulated.
  * 2) tipc_printf() uses 'print_lock' to prevent simultaneous use of
  *    'print_string' and to protect its print buffer(s).
- * 3) TEE() uses 'print_lock' to protect its print buffer(s).
- * 4) Routines of the form log_XXX() uses 'print_lock' to protect LOG.
+ * 3) TIPC_TEE() uses 'print_lock' to protect its print buffer(s).
+ * 4) Routines of the form log_XXX() uses 'print_lock' to protect TIPC_LOG.
  */
 
 /**
- * printbuf_init - initialize print buffer to empty
+ * tipc_printbuf_init - initialize print buffer to empty
  */
 
-void printbuf_init(struct print_buf *pb, char *raw, u32 sz)
+void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 sz)
 {
 	if (!pb || !raw || (sz < (MAX_STRING + 1)))
 		return;
@@ -87,26 +87,26 @@ void printbuf_init(struct print_buf *pb,
 }
 
 /**
- * printbuf_reset - reinitialize print buffer to empty state
+ * tipc_printbuf_reset - reinitialize print buffer to empty state
  */
 
-void printbuf_reset(struct print_buf *pb)
+void tipc_printbuf_reset(struct print_buf *pb)
 {
 	if (pb && pb->buf)
-		printbuf_init(pb, pb->buf, pb->size);
+		tipc_printbuf_init(pb, pb->buf, pb->size);
 }
 
 /**
- * printbuf_empty - test if print buffer is in empty state
+ * tipc_printbuf_empty - test if print buffer is in empty state
  */
 
-int printbuf_empty(struct print_buf *pb)
+int tipc_printbuf_empty(struct print_buf *pb)
 {
 	return (!pb || !pb->buf || (pb->crs == pb->buf));
 }
 
 /**
- * printbuf_validate - check for print buffer overflow
+ * tipc_printbuf_validate - check for print buffer overflow
  * 
  * Verifies that a print buffer has captured all data written to it. 
  * If data has been lost, linearize buffer and prepend an error message
@@ -114,7 +114,7 @@ int printbuf_empty(struct print_buf *pb)
  * Returns length of print buffer data string (including trailing NULL)
  */
 
-int printbuf_validate(struct print_buf *pb)
+int tipc_printbuf_validate(struct print_buf *pb)
 {
         char *err = "             *** PRINT BUFFER WRAPPED AROUND ***\n";
         char *cp_buf;
@@ -126,13 +126,13 @@ int printbuf_validate(struct print_buf *
 	if (pb->buf[pb->size - 1] == '\0') {
                 cp_buf = kmalloc(pb->size, GFP_ATOMIC);
                 if (cp_buf != NULL){
-                        printbuf_init(&cb, cp_buf, pb->size);
-                        printbuf_move(&cb, pb);
-                        printbuf_move(pb, &cb);
+                        tipc_printbuf_init(&cb, cp_buf, pb->size);
+                        tipc_printbuf_move(&cb, pb);
+                        tipc_printbuf_move(pb, &cb);
                         kfree(cp_buf);
                         memcpy(pb->buf, err, strlen(err));
                 } else {
-                        printbuf_reset(pb);
+                        tipc_printbuf_reset(pb);
                         tipc_printf(pb, err);
                 }
 	}
@@ -140,13 +140,13 @@ int printbuf_validate(struct print_buf *
 }
 
 /**
- * printbuf_move - move print buffer contents to another print buffer
+ * tipc_printbuf_move - move print buffer contents to another print buffer
  * 
  * Current contents of destination print buffer (if any) are discarded.
  * Source print buffer becomes empty if a successful move occurs.
  */
 
-void printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from)
+void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from)
 {
 	int len;
 
@@ -156,12 +156,12 @@ void printbuf_move(struct print_buf *pb_
 		return;
 
 	if (!pb_from || !pb_from->buf) {
-		printbuf_reset(pb_to);
+		tipc_printbuf_reset(pb_to);
 		return;
 	}
 
 	if (pb_to->size < pb_from->size) {
-		printbuf_reset(pb_to);
+		tipc_printbuf_reset(pb_to);
 		tipc_printf(pb_to, "*** PRINT BUFFER OVERFLOW ***");
 		return;
 	}
@@ -179,7 +179,7 @@ void printbuf_move(struct print_buf *pb_
 	strcpy(pb_to->crs, pb_from->buf);
 	pb_to->crs += len;
 
-	printbuf_reset(pb_from);
+	tipc_printbuf_reset(pb_from);
 }
 
 /**
@@ -199,7 +199,7 @@ void tipc_printf(struct print_buf *pb, c
 		strcpy(print_string, "*** STRING TOO LONG ***");
 
 	while (pb) {
-		if (pb == CONS)
+		if (pb == TIPC_CONS)
 			printk(print_string);
 		else if (pb->buf) {
 			chars_left = pb->buf + pb->size - pb->crs - 1;
@@ -223,10 +223,10 @@ void tipc_printf(struct print_buf *pb, c
 }
 
 /**
- * TEE - perform next output operation on both print buffers  
+ * TIPC_TEE - perform next output operation on both print buffers  
  */
 
-struct print_buf *TEE(struct print_buf *b0, struct print_buf *b1)
+struct print_buf *TIPC_TEE(struct print_buf *b0, struct print_buf *b1)
 {
 	struct print_buf *pb = b0;
 
@@ -294,96 +294,96 @@ void tipc_dump(struct print_buf *pb, con
 	int len;
 
 	spin_lock_bh(&print_lock);
-	FORMAT(CONS->buf, len, fmt);
-	printk(CONS->buf);
+	FORMAT(TIPC_CONS->buf, len, fmt);
+	printk(TIPC_CONS->buf);
 
 	for (; pb; pb = pb->next) {
-		if (pb == CONS)
+		if (pb == TIPC_CONS)
 			continue;
 		printk("\n---- Start of dump,%s log ----\n\n", 
-		       (pb == LOG) ? "global" : "local");
+		       (pb == TIPC_LOG) ? "global" : "local");
 		printbuf_dump(pb);
-		printbuf_reset(pb);
+		tipc_printbuf_reset(pb);
 		printk("\n-------- End of dump --------\n");
 	}
 	spin_unlock_bh(&print_lock);
 }
 
 /**
- * log_stop - free up TIPC log print buffer 
+ * tipc_log_stop - free up TIPC log print buffer 
  */
 
-void log_stop(void)
+void tipc_log_stop(void)
 {
 	spin_lock_bh(&print_lock);
-	if (LOG->buf) {
-		kfree(LOG->buf);
-		LOG->buf = NULL;
+	if (TIPC_LOG->buf) {
+		kfree(TIPC_LOG->buf);
+		TIPC_LOG->buf = NULL;
 	}
 	spin_unlock_bh(&print_lock);
 }
 
 /**
- * log_reinit - set TIPC log print buffer to specified size
+ * tipc_log_reinit - set TIPC log print buffer to specified size
  */
 
-void log_reinit(int log_size)
+void tipc_log_reinit(int log_size)
 {
-	log_stop();
+	tipc_log_stop();
 
 	if (log_size) {
 		if (log_size <= MAX_STRING)
 			log_size = MAX_STRING + 1;
 		spin_lock_bh(&print_lock);
-		printbuf_init(LOG, kmalloc(log_size, GFP_ATOMIC), log_size);
+		tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC), log_size);
 		spin_unlock_bh(&print_lock);
 	}
 }
 
 /**
- * log_resize - reconfigure size of TIPC log buffer
+ * tipc_log_resize - reconfigure size of TIPC log buffer
  */
 
-struct sk_buff *log_resize(const void *req_tlv_area, int req_tlv_space)
+struct sk_buff *tipc_log_resize(const void *req_tlv_area, int req_tlv_space)
 {
 	u32 value;
 
 	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
-		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
+		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
 
 	value = *(u32 *)TLV_DATA(req_tlv_area);
 	value = ntohl(value);
 	if (value != delimit(value, 0, 32768))
-		return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
-					      " (log size must be 0-32768)");
-	log_reinit(value);
-	return cfg_reply_none();
+		return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
+						   " (log size must be 0-32768)");
+	tipc_log_reinit(value);
+	return tipc_cfg_reply_none();
 }
 
 /**
- * log_dump - capture TIPC log buffer contents in configuration message
+ * tipc_log_dump - capture TIPC log buffer contents in configuration message
  */
 
-struct sk_buff *log_dump(void)
+struct sk_buff *tipc_log_dump(void)
 {
 	struct sk_buff *reply;
 
 	spin_lock_bh(&print_lock);
-	if (!LOG->buf)
-		reply = cfg_reply_ultra_string("log not activated\n");
-	else if (printbuf_empty(LOG))
-		reply = cfg_reply_ultra_string("log is empty\n");
+	if (!TIPC_LOG->buf)
+		reply = tipc_cfg_reply_ultra_string("log not activated\n");
+	else if (tipc_printbuf_empty(TIPC_LOG))
+		reply = tipc_cfg_reply_ultra_string("log is empty\n");
 	else {
 		struct tlv_desc *rep_tlv;
 		struct print_buf pb;
 		int str_len;
 
-		str_len = min(LOG->size, 32768u);
-		reply = cfg_reply_alloc(TLV_SPACE(str_len));
+		str_len = min(TIPC_LOG->size, 32768u);
+		reply = tipc_cfg_reply_alloc(TLV_SPACE(str_len));
 		if (reply) {
 			rep_tlv = (struct tlv_desc *)reply->data;
-			printbuf_init(&pb, TLV_DATA(rep_tlv), str_len);
-			printbuf_move(&pb, LOG);
+			tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), str_len);
+			tipc_printbuf_move(&pb, TIPC_LOG);
 			str_len = strlen(TLV_DATA(rep_tlv)) + 1;
 			skb_put(reply, TLV_SPACE(str_len));
 			TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
diff --git a/net/tipc/dbg.h b/net/tipc/dbg.h
index c6b2a64..227f050 100644
--- a/net/tipc/dbg.h
+++ b/net/tipc/dbg.h
@@ -44,16 +44,16 @@ struct print_buf {
 	struct print_buf *next;
 };
 
-void printbuf_init(struct print_buf *pb, char *buf, u32 sz);
-void printbuf_reset(struct print_buf *pb);
-int  printbuf_empty(struct print_buf *pb);
-int  printbuf_validate(struct print_buf *pb);
-void printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from);
+void tipc_printbuf_init(struct print_buf *pb, char *buf, u32 sz);
+void tipc_printbuf_reset(struct print_buf *pb);
+int  tipc_printbuf_empty(struct print_buf *pb);
+int  tipc_printbuf_validate(struct print_buf *pb);
+void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from);
 
-void log_reinit(int log_size);
-void log_stop(void);
+void tipc_log_reinit(int log_size);
+void tipc_log_stop(void);
 
-struct sk_buff *log_resize(const void *req_tlv_area, int req_tlv_space);
-struct sk_buff *log_dump(void);
+struct sk_buff *tipc_log_resize(const void *req_tlv_area, int req_tlv_space);
+struct sk_buff *tipc_log_dump(void);
 
 #endif
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index b106ef1..53ba463 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -93,7 +93,7 @@ int disc_create_link(const struct tipc_l
  * disc_lost_link(): A link has lost contact
  */
 
-void disc_link_event(u32 addr, char *name, int up) 
+void tipc_disc_link_event(u32 addr, char *name, int up) 
 {
 	if (in_own_cluster(addr))
 		return;
@@ -103,17 +103,17 @@ void disc_link_event(u32 addr, char *nam
 }
 
 /** 
- * disc_init_msg - initialize a link setup message
+ * tipc_disc_init_msg - initialize a link setup message
  * @type: message type (request or response)
  * @req_links: number of links associated with message
  * @dest_domain: network domain of node(s) which should respond to message
  * @b_ptr: ptr to bearer issuing message
  */
 
-struct sk_buff *disc_init_msg(u32 type,
-			      u32 req_links,
-			      u32 dest_domain,
-			      struct bearer *b_ptr)
+struct sk_buff *tipc_disc_init_msg(u32 type,
+				   u32 req_links,
+				   u32 dest_domain,
+				   struct bearer *b_ptr)
 {
 	struct sk_buff *buf = buf_acquire(DSC_H_SIZE);
 	struct tipc_msg *msg;
@@ -132,11 +132,11 @@ struct sk_buff *disc_init_msg(u32 type,
 }
 
 /**
- * disc_recv_msg - handle incoming link setup message (request or response)
+ * tipc_disc_recv_msg - handle incoming link setup message (request or response)
  * @buf: buffer containing message
  */
 
-void disc_recv_msg(struct sk_buff *buf)
+void tipc_disc_recv_msg(struct sk_buff *buf)
 {
 	struct bearer *b_ptr = (struct bearer *)TIPC_SKB_CB(buf)->handle;
 	struct link *link;
@@ -153,9 +153,9 @@ void disc_recv_msg(struct sk_buff *buf)
 
 	if (net_id != tipc_net_id)
 		return;
-	if (!addr_domain_valid(dest))
+	if (!tipc_addr_domain_valid(dest))
 		return;
-	if (!addr_node_valid(orig))
+	if (!tipc_addr_node_valid(orig))
 		return;
 	if (orig == tipc_own_addr)
 		return;
@@ -169,11 +169,11 @@ void disc_recv_msg(struct sk_buff *buf)
 		/* Always accept link here */
 		struct sk_buff *rbuf;
 		struct tipc_media_addr *addr;
-		struct node *n_ptr = node_find(orig);
+		struct node *n_ptr = tipc_node_find(orig);
 		int link_up;
 		dbg(" in own cluster\n");
 		if (n_ptr == NULL) {
-			n_ptr = node_create(orig);
+			n_ptr = tipc_node_create(orig);
 		}
 		if (n_ptr == NULL) {
 			warn("Memory squeeze; Failed to create node\n");
@@ -183,7 +183,7 @@ void disc_recv_msg(struct sk_buff *buf)
 		link = n_ptr->links[b_ptr->identity];
 		if (!link) {
 			dbg("creating link\n");
-			link = link_create(b_ptr, orig, &media_addr);
+			link = tipc_link_create(b_ptr, orig, &media_addr);
 			if (!link) {
 				spin_unlock_bh(&n_ptr->lock);                
 				return;
@@ -196,13 +196,13 @@ void disc_recv_msg(struct sk_buff *buf)
 			warn("New bearer address for %s\n", 
 			     addr_string_fill(addr_string, orig));
 			memcpy(addr, &media_addr, sizeof(*addr));
-			link_reset(link);     
+			tipc_link_reset(link);     
 		}
-		link_up = link_is_up(link);
+		link_up = tipc_link_is_up(link);
 		spin_unlock_bh(&n_ptr->lock);                
 		if ((type == DSC_RESP_MSG) || link_up)
 			return;
-		rbuf = disc_init_msg(DSC_RESP_MSG, 1, orig, b_ptr);
+		rbuf = tipc_disc_init_msg(DSC_RESP_MSG, 1, orig, b_ptr);
 		if (rbuf != NULL) {
 			msg_dbg(buf_msg(rbuf),"SEND:");
 			b_ptr->media->send_msg(rbuf, &b_ptr->publ, &media_addr);
@@ -212,11 +212,11 @@ void disc_recv_msg(struct sk_buff *buf)
 }
 
 /**
- * disc_stop_link_req - stop sending periodic link setup requests
+ * tipc_disc_stop_link_req - stop sending periodic link setup requests
  * @req: ptr to link request structure
  */
 
-void disc_stop_link_req(struct link_req *req) 
+void tipc_disc_stop_link_req(struct link_req *req) 
 {
 	if (!req)
 		return;
@@ -228,11 +228,11 @@ void disc_stop_link_req(struct link_req 
 } 
 
 /**
- * disc_update_link_req - update frequency of periodic link setup requests
+ * tipc_disc_update_link_req - update frequency of periodic link setup requests
  * @req: ptr to link request structure
  */
 
-void disc_update_link_req(struct link_req *req) 
+void tipc_disc_update_link_req(struct link_req *req) 
 {
 	if (!req)
 		return;
@@ -282,7 +282,7 @@ static void disc_timeout(struct link_req
 }
 
 /**
- * disc_init_link_req - start sending periodic link setup requests
+ * tipc_disc_init_link_req - start sending periodic link setup requests
  * @b_ptr: ptr to bearer issuing requests
  * @dest: destination address for request messages
  * @dest_domain: network domain of node(s) which should respond to message
@@ -291,10 +291,10 @@ static void disc_timeout(struct link_req
  * Returns pointer to link request structure, or NULL if unable to create.
  */
 
-struct link_req *disc_init_link_req(struct bearer *b_ptr, 
-				    const struct tipc_media_addr *dest,
-				    u32 dest_domain,
-				    u32 req_links) 
+struct link_req *tipc_disc_init_link_req(struct bearer *b_ptr, 
+					 const struct tipc_media_addr *dest,
+					 u32 dest_domain,
+					 u32 req_links) 
 {
 	struct link_req *req;
 
@@ -302,7 +302,7 @@ struct link_req *disc_init_link_req(stru
 	if (!req)
 		return NULL;
 
-	req->buf = disc_init_msg(DSC_REQ_MSG, req_links, dest_domain, b_ptr);
+	req->buf = tipc_disc_init_msg(DSC_REQ_MSG, req_links, dest_domain, b_ptr);
 	if (!req->buf) {
 		kfree(req);
 		return NULL;
diff --git a/net/tipc/discover.h b/net/tipc/discover.h
index 2a6114d..0454fd1 100644
--- a/net/tipc/discover.h
+++ b/net/tipc/discover.h
@@ -37,20 +37,20 @@
 #ifndef _TIPC_DISCOVER_H
 #define _TIPC_DISCOVER_H
 
-#include <linux/tipc.h>
+#include "core.h"
 
 struct link_req;
 
-struct link_req *disc_init_link_req(struct bearer *b_ptr, 
-			            const struct tipc_media_addr *dest,
-			            u32 dest_domain,
-			            u32 req_links);
-void disc_update_link_req(struct link_req *req);
-void disc_stop_link_req(struct link_req *req);
+struct link_req *tipc_disc_init_link_req(struct bearer *b_ptr, 
+					 const struct tipc_media_addr *dest,
+					 u32 dest_domain,
+					 u32 req_links);
+void tipc_disc_update_link_req(struct link_req *req);
+void tipc_disc_stop_link_req(struct link_req *req);
 
-void disc_recv_msg(struct sk_buff *buf);
+void tipc_disc_recv_msg(struct sk_buff *buf);
 
-void disc_link_event(u32 addr, char *name, int up);
+void tipc_disc_link_event(u32 addr, char *name, int up);
 #if 0
 int  disc_create_link(const struct tipc_link_create *argv);
 #endif
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c
index 34d0462..1f8d83b 100644
--- a/net/tipc/eth_media.c
+++ b/net/tipc/eth_media.c
@@ -38,13 +38,11 @@
 #include <net/tipc/tipc_bearer.h>
 #include <net/tipc/tipc_msg.h>
 #include <linux/netdevice.h>
-#include <linux/version.h>
 
 #define MAX_ETH_BEARERS		2
-#define TIPC_PROTOCOL		0x88ca
-#define ETH_LINK_PRIORITY	10
+#define ETH_LINK_PRIORITY	TIPC_DEF_LINK_PRI
 #define ETH_LINK_TOLERANCE	TIPC_DEF_LINK_TOL
-
+#define ETH_LINK_WINDOW		TIPC_DEF_LINK_WIN
 
 /**
  * struct eth_bearer - Ethernet bearer data structure
@@ -78,7 +76,7 @@ static int send_msg(struct sk_buff *buf,
 		clone->nh.raw = clone->data;
 		dev = ((struct eth_bearer *)(tb_ptr->usr_handle))->dev;
 		clone->dev = dev;
-		dev->hard_header(clone, dev, TIPC_PROTOCOL, 
+		dev->hard_header(clone, dev, ETH_P_TIPC, 
 				 &dest->dev_addr.eth_addr,
 				 dev->dev_addr, clone->len);
 		dev_queue_xmit(clone);
@@ -141,7 +139,7 @@ static int enable_bearer(struct tipc_bea
 		return -EDQUOT;
 	if (!eb_ptr->dev) {
 		eb_ptr->dev = dev;
-		eb_ptr->tipc_packet_type.type = __constant_htons(TIPC_PROTOCOL);
+		eb_ptr->tipc_packet_type.type = __constant_htons(ETH_P_TIPC);
 		eb_ptr->tipc_packet_type.dev = dev;
 		eb_ptr->tipc_packet_type.func = recv_msg;
 		eb_ptr->tipc_packet_type.af_packet_priv = eb_ptr;
@@ -240,13 +238,13 @@ static char *eth_addr2str(struct tipc_me
 }
 
 /**
- * eth_media_start - activate Ethernet bearer support
+ * tipc_eth_media_start - activate Ethernet bearer support
  *
  * Register Ethernet media type with TIPC bearer code.  Also register
  * with OS for notifications about device state changes.
  */
 
-int eth_media_start(void)
+int tipc_eth_media_start(void)
 {                       
 	struct tipc_media_addr bcast_addr;
 	int res;
@@ -260,7 +258,7 @@ int eth_media_start(void)
 	res = tipc_register_media(TIPC_MEDIA_TYPE_ETH, "eth",
 				  enable_bearer, disable_bearer, send_msg, 
 				  eth_addr2str, &bcast_addr, ETH_LINK_PRIORITY, 
-				  ETH_LINK_TOLERANCE, TIPC_DEF_LINK_WIN);
+				  ETH_LINK_TOLERANCE, ETH_LINK_WINDOW);
 	if (res)
 		return res;
 
@@ -273,10 +271,10 @@ int eth_media_start(void)
 }
 
 /**
- * eth_media_stop - deactivate Ethernet bearer support
+ * tipc_eth_media_stop - deactivate Ethernet bearer support
  */
 
-void eth_media_stop(void)
+void tipc_eth_media_stop(void)
 {
 	int i;
 
diff --git a/net/tipc/handler.c b/net/tipc/handler.c
index f320010..966f70a 100644
--- a/net/tipc/handler.c
+++ b/net/tipc/handler.c
@@ -52,7 +52,7 @@ static void process_signal_queue(unsigne
 static DECLARE_TASKLET_DISABLED(tipc_tasklet, process_signal_queue, 0);
 
 
-unsigned int k_signal(Handler routine, unsigned long argument)
+unsigned int tipc_k_signal(Handler routine, unsigned long argument)
 {
 	struct queue_item *item;
 
@@ -93,7 +93,7 @@ static void process_signal_queue(unsigne
 	spin_unlock_bh(&qitem_lock);
 }
 
-int handler_start(void)
+int tipc_handler_start(void)
 {
 	tipc_queue_item_cache = 
 		kmem_cache_create("tipc_queue_items", sizeof(struct queue_item),
@@ -107,7 +107,7 @@ int handler_start(void)
 	return 0;
 }
 
-void handler_stop(void)
+void tipc_handler_stop(void)
 {
 	struct list_head *l, *n;
 	struct queue_item *item; 
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 7265f4b..511872a 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -148,12 +148,12 @@ static void link_print(struct link *l_pt
 #define LINK_LOG_BUF_SIZE 0
 
 #define dbg_link(fmt, arg...)  do {if (LINK_LOG_BUF_SIZE) tipc_printf(&l_ptr->print_buf, fmt, ## arg); } while(0)
-#define dbg_link_msg(msg, txt) do {if (LINK_LOG_BUF_SIZE) msg_print(&l_ptr->print_buf, msg, txt); } while(0)
+#define dbg_link_msg(msg, txt) do {if (LINK_LOG_BUF_SIZE) tipc_msg_print(&l_ptr->print_buf, msg, txt); } while(0)
 #define dbg_link_state(txt) do {if (LINK_LOG_BUF_SIZE) link_print(l_ptr, &l_ptr->print_buf, txt); } while(0)
 #define dbg_link_dump() do { \
 	if (LINK_LOG_BUF_SIZE) { \
 		tipc_printf(LOG, "\n\nDumping link <%s>:\n", l_ptr->name); \
-		printbuf_move(LOG, &l_ptr->print_buf); \
+		tipc_printbuf_move(LOG, &l_ptr->print_buf); \
 	} \
 } while (0)
 
@@ -252,14 +252,14 @@ static inline u32 link_last_sent(struct 
  *  Simple non-inlined link routines (i.e. referenced outside this file)
  */
 
-int link_is_up(struct link *l_ptr)
+int tipc_link_is_up(struct link *l_ptr)
 {
 	if (!l_ptr)
 		return 0;
 	return (link_working_working(l_ptr) || link_working_unknown(l_ptr));
 }
 
-int link_is_active(struct link *l_ptr)
+int tipc_link_is_active(struct link *l_ptr)
 {
 	return ((l_ptr->owner->active_links[0] == l_ptr) ||
 		(l_ptr->owner->active_links[1] == l_ptr));
@@ -338,15 +338,15 @@ static int link_name_validate(const char
  * link_timeout - handle expiration of link timer
  * @l_ptr: pointer to link
  * 
- * This routine must not grab "net_lock" to avoid a potential deadlock conflict
- * with link_delete().  (There is no risk that the node will be deleted by
- * another thread because link_delete() always cancels the link timer before
- * node_delete() is called.)
+ * This routine must not grab "tipc_net_lock" to avoid a potential deadlock conflict
+ * with tipc_link_delete().  (There is no risk that the node will be deleted by
+ * another thread because tipc_link_delete() always cancels the link timer before
+ * tipc_node_delete() is called.)
  */
 
 static void link_timeout(struct link *l_ptr)
 {
-	node_lock(l_ptr->owner);
+	tipc_node_lock(l_ptr->owner);
 
 	/* update counters used in statistical profiling of send traffic */
 
@@ -391,9 +391,9 @@ static void link_timeout(struct link *l_
 	link_state_event(l_ptr, TIMEOUT_EVT);
 
 	if (l_ptr->next_out)
-		link_push_queue(l_ptr);
+		tipc_link_push_queue(l_ptr);
 
-	node_unlock(l_ptr->owner);
+	tipc_node_unlock(l_ptr->owner);
 }
 
 static inline void link_set_timer(struct link *l_ptr, u32 time)
@@ -402,7 +402,7 @@ static inline void link_set_timer(struct
 }
 
 /**
- * link_create - create a new link
+ * tipc_link_create - create a new link
  * @b_ptr: pointer to associated bearer
  * @peer: network address of node at other end of link
  * @media_addr: media address to use when sending messages over link
@@ -410,8 +410,8 @@ static inline void link_set_timer(struct
  * Returns pointer to link.
  */
 
-struct link *link_create(struct bearer *b_ptr, const u32 peer,
-			 const struct tipc_media_addr *media_addr)
+struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
+			      const struct tipc_media_addr *media_addr)
 {
 	struct link *l_ptr;
 	struct tipc_msg *msg;
@@ -449,7 +449,7 @@ struct link *link_create(struct bearer *
 	strcpy((char *)msg_data(msg), if_name);
 
 	l_ptr->priority = b_ptr->priority;
-	link_set_queue_limits(l_ptr, b_ptr->media->window);
+	tipc_link_set_queue_limits(l_ptr, b_ptr->media->window);
 
 	link_init_max_pkt(l_ptr);
 
@@ -458,7 +458,7 @@ struct link *link_create(struct bearer *
 
 	link_reset_statistics(l_ptr);
 
-	l_ptr->owner = node_attach_link(l_ptr);
+	l_ptr->owner = tipc_node_attach_link(l_ptr);
 	if (!l_ptr->owner) {
 		kfree(l_ptr);
 		return NULL;
@@ -472,52 +472,52 @@ struct link *link_create(struct bearer *
 			warn("Memory squeeze; Failed to create link\n");
 			return NULL;
 		}
-		printbuf_init(&l_ptr->print_buf, pb, LINK_LOG_BUF_SIZE);
+		tipc_printbuf_init(&l_ptr->print_buf, pb, LINK_LOG_BUF_SIZE);
 	}
 
-	k_signal((Handler)link_start, (unsigned long)l_ptr);
+	tipc_k_signal((Handler)tipc_link_start, (unsigned long)l_ptr);
 
-	dbg("link_create(): tolerance = %u,cont intv = %u, abort_limit = %u\n",
+	dbg("tipc_link_create(): tolerance = %u,cont intv = %u, abort_limit = %u\n",
 	    l_ptr->tolerance, l_ptr->continuity_interval, l_ptr->abort_limit);
 	
 	return l_ptr;
 }
 
 /** 
- * link_delete - delete a link
+ * tipc_link_delete - delete a link
  * @l_ptr: pointer to link
  * 
- * Note: 'net_lock' is write_locked, bearer is locked.
+ * Note: 'tipc_net_lock' is write_locked, bearer is locked.
  * This routine must not grab the node lock until after link timer cancellation
  * to avoid a potential deadlock situation.  
  */
 
-void link_delete(struct link *l_ptr)
+void tipc_link_delete(struct link *l_ptr)
 {
 	if (!l_ptr) {
 		err("Attempt to delete non-existent link\n");
 		return;
 	}
 
-	dbg("link_delete()\n");
+	dbg("tipc_link_delete()\n");
 
 	k_cancel_timer(&l_ptr->timer);
 	
-	node_lock(l_ptr->owner);
-	link_reset(l_ptr);
-	node_detach_link(l_ptr->owner, l_ptr);
-	link_stop(l_ptr);
+	tipc_node_lock(l_ptr->owner);
+	tipc_link_reset(l_ptr);
+	tipc_node_detach_link(l_ptr->owner, l_ptr);
+	tipc_link_stop(l_ptr);
 	list_del_init(&l_ptr->link_list);
 	if (LINK_LOG_BUF_SIZE)
 		kfree(l_ptr->print_buf.buf);
-	node_unlock(l_ptr->owner);
+	tipc_node_unlock(l_ptr->owner);
 	k_term_timer(&l_ptr->timer);
 	kfree(l_ptr);
 }
 
-void link_start(struct link *l_ptr)
+void tipc_link_start(struct link *l_ptr)
 {
-	dbg("link_start %x\n", l_ptr);
+	dbg("tipc_link_start %x\n", l_ptr);
 	link_state_event(l_ptr, STARTING_EVT);
 }
 
@@ -535,8 +535,8 @@ static int link_schedule_port(struct lin
 {
 	struct port *p_ptr;
 
-	spin_lock_bh(&port_list_lock);
-	p_ptr = port_lock(origport);
+	spin_lock_bh(&tipc_port_list_lock);
+	p_ptr = tipc_port_lock(origport);
 	if (p_ptr) {
 		if (!p_ptr->wakeup)
 			goto exit;
@@ -548,13 +548,13 @@ static int link_schedule_port(struct lin
 		list_add_tail(&p_ptr->wait_list, &l_ptr->waiting_ports);
 		l_ptr->stats.link_congs++;
 exit:
-		port_unlock(p_ptr);
+		tipc_port_unlock(p_ptr);
 	}
-	spin_unlock_bh(&port_list_lock);
+	spin_unlock_bh(&tipc_port_list_lock);
 	return -ELINKCONG;
 }
 
-void link_wakeup_ports(struct link *l_ptr, int all)
+void tipc_link_wakeup_ports(struct link *l_ptr, int all)
 {
 	struct port *p_ptr;
 	struct port *temp_p_ptr;
@@ -564,7 +564,7 @@ void link_wakeup_ports(struct link *l_pt
 		win = 100000;
 	if (win <= 0)
 		return;
-	if (!spin_trylock_bh(&port_list_lock))
+	if (!spin_trylock_bh(&tipc_port_list_lock))
 		return;
 	if (link_congested(l_ptr))
 		goto exit;
@@ -583,7 +583,7 @@ void link_wakeup_ports(struct link *l_pt
 	}
 
 exit:
-	spin_unlock_bh(&port_list_lock);
+	spin_unlock_bh(&tipc_port_list_lock);
 }
 
 /** 
@@ -606,11 +606,11 @@ static void link_release_outqueue(struct
 }
 
 /**
- * link_reset_fragments - purge link's inbound message fragments queue
+ * tipc_link_reset_fragments - purge link's inbound message fragments queue
  * @l_ptr: pointer to link
  */
 
-void link_reset_fragments(struct link *l_ptr)
+void tipc_link_reset_fragments(struct link *l_ptr)
 {
 	struct sk_buff *buf = l_ptr->defragm_buf;
 	struct sk_buff *next;
@@ -624,11 +624,11 @@ void link_reset_fragments(struct link *l
 }
 
 /** 
- * link_stop - purge all inbound and outbound messages associated with link
+ * tipc_link_stop - purge all inbound and outbound messages associated with link
  * @l_ptr: pointer to link
  */
 
-void link_stop(struct link *l_ptr)
+void tipc_link_stop(struct link *l_ptr)
 {
 	struct sk_buff *buf;
 	struct sk_buff *next;
@@ -647,7 +647,7 @@ void link_stop(struct link *l_ptr)
 		buf = next;
 	}
 
-	link_reset_fragments(l_ptr);
+	tipc_link_reset_fragments(l_ptr);
 
 	buf_discard(l_ptr->proto_msg_queue);
 	l_ptr->proto_msg_queue = NULL;
@@ -677,7 +677,7 @@ static void link_send_event(void (*fcn)(
 	ev->up = up;
 	ev->fcn = fcn;
 	memcpy(ev->name, l_ptr->name, TIPC_MAX_LINK_NAME);
-	k_signal((Handler)link_recv_event, (unsigned long)ev);
+	tipc_k_signal((Handler)link_recv_event, (unsigned long)ev);
 }
 
 #else
@@ -686,7 +686,7 @@ static void link_send_event(void (*fcn)(
 
 #endif
 
-void link_reset(struct link *l_ptr)
+void tipc_link_reset(struct link *l_ptr)
 {
 	struct sk_buff *buf;
 	u32 prev_state = l_ptr->state;
@@ -706,13 +706,13 @@ void link_reset(struct link *l_ptr)
 	if ((prev_state == RESET_UNKNOWN) || (prev_state == RESET_RESET))
 		return;
 
-	node_link_down(l_ptr->owner, l_ptr);
-	bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr);
+	tipc_node_link_down(l_ptr->owner, l_ptr);
+	tipc_bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr);
 #if 0
-	tipc_printf(CONS, "\nReset link <%s>\n", l_ptr->name);
+	tipc_printf(TIPC_CONS, "\nReset link <%s>\n", l_ptr->name);
 	dbg_link_dump();
 #endif
-	if (node_has_active_links(l_ptr->owner) &&
+	if (tipc_node_has_active_links(l_ptr->owner) &&
 	    l_ptr->owner->permit_changeover) {
 		l_ptr->reset_checkpoint = checkpoint;
 		l_ptr->exp_msg_count = START_CHANGEOVER;
@@ -730,7 +730,7 @@ void link_reset(struct link *l_ptr)
 		buf = next;
 	}
 	if (!list_empty(&l_ptr->waiting_ports))
-		link_wakeup_ports(l_ptr, 1);
+		tipc_link_wakeup_ports(l_ptr, 1);
 
 	l_ptr->retransm_queue_head = 0;
 	l_ptr->retransm_queue_size = 0;
@@ -747,20 +747,20 @@ void link_reset(struct link *l_ptr)
 	l_ptr->stale_count = 0;
 	link_reset_statistics(l_ptr);
 
-	link_send_event(cfg_link_event, l_ptr, 0);
+	link_send_event(tipc_cfg_link_event, l_ptr, 0);
 	if (!in_own_cluster(l_ptr->addr))
-		link_send_event(disc_link_event, l_ptr, 0);
+		link_send_event(tipc_disc_link_event, l_ptr, 0);
 }
 
 
 static void link_activate(struct link *l_ptr)
 {
 	l_ptr->next_in_no = 1;
-	node_link_up(l_ptr->owner, l_ptr);
-	bearer_add_dest(l_ptr->b_ptr, l_ptr->addr);
-	link_send_event(cfg_link_event, l_ptr, 1);
+	tipc_node_link_up(l_ptr->owner, l_ptr);
+	tipc_bearer_add_dest(l_ptr->b_ptr, l_ptr->addr);
+	link_send_event(tipc_cfg_link_event, l_ptr, 1);
 	if (!in_own_cluster(l_ptr->addr))
-		link_send_event(disc_link_event, l_ptr, 1);
+		link_send_event(tipc_disc_link_event, l_ptr, 1);
 }
 
 /**
@@ -799,13 +799,13 @@ static void link_state_event(struct link
 			dbg_link("TIM ");
 			if (l_ptr->next_in_no != l_ptr->checkpoint) {
 				l_ptr->checkpoint = l_ptr->next_in_no;
-				if (bclink_acks_missing(l_ptr->owner)) {
-					link_send_proto_msg(l_ptr, STATE_MSG, 
-							    0, 0, 0, 0, 0);
+				if (tipc_bclink_acks_missing(l_ptr->owner)) {
+					tipc_link_send_proto_msg(l_ptr, STATE_MSG, 
+								 0, 0, 0, 0, 0);
 					l_ptr->fsm_msg_cnt++;
 				} else if (l_ptr->max_pkt < l_ptr->max_pkt_target) {
-					link_send_proto_msg(l_ptr, STATE_MSG, 
-							    1, 0, 0, 0, 0);
+					tipc_link_send_proto_msg(l_ptr, STATE_MSG, 
+								 1, 0, 0, 0, 0);
 					l_ptr->fsm_msg_cnt++;
 				}
 				link_set_timer(l_ptr, cont_intv);
@@ -814,16 +814,16 @@ static void link_state_event(struct link
 			dbg_link(" -> WU\n");
 			l_ptr->state = WORKING_UNKNOWN;
 			l_ptr->fsm_msg_cnt = 0;
-			link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0);
+			tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0);
 			l_ptr->fsm_msg_cnt++;
 			link_set_timer(l_ptr, cont_intv / 4);
 			break;
 		case RESET_MSG:
 			dbg_link("RES -> RR\n");
-			link_reset(l_ptr);
+			tipc_link_reset(l_ptr);
 			l_ptr->state = RESET_RESET;
 			l_ptr->fsm_msg_cnt = 0;
-			link_send_proto_msg(l_ptr, ACTIVATE_MSG, 0, 0, 0, 0, 0);
+			tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 0, 0, 0, 0, 0);
 			l_ptr->fsm_msg_cnt++;
 			link_set_timer(l_ptr, cont_intv);
 			break;
@@ -844,10 +844,10 @@ static void link_state_event(struct link
 			break;
 		case RESET_MSG:
 			dbg_link("RES -> RR\n");
-			link_reset(l_ptr);
+			tipc_link_reset(l_ptr);
 			l_ptr->state = RESET_RESET;
 			l_ptr->fsm_msg_cnt = 0;
-			link_send_proto_msg(l_ptr, ACTIVATE_MSG, 0, 0, 0, 0, 0);
+			tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 0, 0, 0, 0, 0);
 			l_ptr->fsm_msg_cnt++;
 			link_set_timer(l_ptr, cont_intv);
 			break;
@@ -858,9 +858,9 @@ static void link_state_event(struct link
 				l_ptr->state = WORKING_WORKING;
 				l_ptr->fsm_msg_cnt = 0;
 				l_ptr->checkpoint = l_ptr->next_in_no;
-				if (bclink_acks_missing(l_ptr->owner)) {
-					link_send_proto_msg(l_ptr, STATE_MSG,
-							    0, 0, 0, 0, 0);
+				if (tipc_bclink_acks_missing(l_ptr->owner)) {
+					tipc_link_send_proto_msg(l_ptr, STATE_MSG,
+								 0, 0, 0, 0, 0);
 					l_ptr->fsm_msg_cnt++;
 				}
 				link_set_timer(l_ptr, cont_intv);
@@ -868,18 +868,18 @@ static void link_state_event(struct link
 				dbg_link("Probing %u/%u,timer = %u ms)\n",
 					 l_ptr->fsm_msg_cnt, l_ptr->abort_limit,
 					 cont_intv / 4);
-				link_send_proto_msg(l_ptr, STATE_MSG, 
-						    1, 0, 0, 0, 0);
+				tipc_link_send_proto_msg(l_ptr, STATE_MSG, 
+							 1, 0, 0, 0, 0);
 				l_ptr->fsm_msg_cnt++;
 				link_set_timer(l_ptr, cont_intv / 4);
 			} else {	/* Link has failed */
 				dbg_link("-> RU (%u probes unanswered)\n",
 					 l_ptr->fsm_msg_cnt);
-				link_reset(l_ptr);
+				tipc_link_reset(l_ptr);
 				l_ptr->state = RESET_UNKNOWN;
 				l_ptr->fsm_msg_cnt = 0;
-				link_send_proto_msg(l_ptr, RESET_MSG,
-						    0, 0, 0, 0, 0);
+				tipc_link_send_proto_msg(l_ptr, RESET_MSG,
+							 0, 0, 0, 0, 0);
 				l_ptr->fsm_msg_cnt++;
 				link_set_timer(l_ptr, cont_intv);
 			}
@@ -904,7 +904,7 @@ static void link_state_event(struct link
 			l_ptr->state = WORKING_WORKING;
 			l_ptr->fsm_msg_cnt = 0;
 			link_activate(l_ptr);
-			link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0);
+			tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0);
 			l_ptr->fsm_msg_cnt++;
 			link_set_timer(l_ptr, cont_intv);
 			break;
@@ -913,7 +913,7 @@ static void link_state_event(struct link
 			dbg_link(" -> RR\n");
 			l_ptr->state = RESET_RESET;
 			l_ptr->fsm_msg_cnt = 0;
-			link_send_proto_msg(l_ptr, ACTIVATE_MSG, 1, 0, 0, 0, 0);
+			tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 1, 0, 0, 0, 0);
 			l_ptr->fsm_msg_cnt++;
 			link_set_timer(l_ptr, cont_intv);
 			break;
@@ -923,7 +923,7 @@ static void link_state_event(struct link
 			/* fall through */
 		case TIMEOUT_EVT:
 			dbg_link("TIM \n");
-			link_send_proto_msg(l_ptr, RESET_MSG, 0, 0, 0, 0, 0);
+			tipc_link_send_proto_msg(l_ptr, RESET_MSG, 0, 0, 0, 0, 0);
 			l_ptr->fsm_msg_cnt++;
 			link_set_timer(l_ptr, cont_intv);
 			break;
@@ -947,7 +947,7 @@ static void link_state_event(struct link
 			l_ptr->state = WORKING_WORKING;
 			l_ptr->fsm_msg_cnt = 0;
 			link_activate(l_ptr);
-			link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0);
+			tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0);
 			l_ptr->fsm_msg_cnt++;
 			link_set_timer(l_ptr, cont_intv);
 			break;
@@ -956,7 +956,7 @@ static void link_state_event(struct link
 			break;
 		case TIMEOUT_EVT:
 			dbg_link("TIM\n");
-			link_send_proto_msg(l_ptr, ACTIVATE_MSG, 0, 0, 0, 0, 0);
+			tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 0, 0, 0, 0, 0);
 			l_ptr->fsm_msg_cnt++;
 			link_set_timer(l_ptr, cont_intv);
 			dbg_link("fsm_msg_cnt %u\n", l_ptr->fsm_msg_cnt);
@@ -1023,12 +1023,12 @@ static inline void link_add_to_outqueue(
 }
 
 /* 
- * link_send_buf() is the 'full path' for messages, called from 
+ * tipc_link_send_buf() is the 'full path' for messages, called from 
  * inside TIPC when the 'fast path' in tipc_send_buf
  * has failed, and from link_send()
  */
 
-int link_send_buf(struct link *l_ptr, struct sk_buff *buf)
+int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
 {
 	struct tipc_msg *msg = buf_msg(buf);
 	u32 size = msg_size(msg);
@@ -1051,7 +1051,7 @@ int link_send_buf(struct link *l_ptr, st
 		buf_discard(buf);
 		if (imp > CONN_MANAGER) {
 			warn("Resetting <%s>, send queue full", l_ptr->name);
-			link_reset(l_ptr);
+			tipc_link_reset(l_ptr);
 		}
 		return dsz;
 	}
@@ -1059,21 +1059,21 @@ int link_send_buf(struct link *l_ptr, st
 	/* Fragmentation needed ? */
 
 	if (size > max_packet)
-		return link_send_long_buf(l_ptr, buf);
+		return tipc_link_send_long_buf(l_ptr, buf);
 
 	/* Packet can be queued or sent: */
 
 	if (queue_size > l_ptr->stats.max_queue_sz)
 		l_ptr->stats.max_queue_sz = queue_size;
 
-	if (likely(!bearer_congested(l_ptr->b_ptr, l_ptr) && 
+	if (likely(!tipc_bearer_congested(l_ptr->b_ptr, l_ptr) && 
 		   !link_congested(l_ptr))) {
 		link_add_to_outqueue(l_ptr, buf, msg);
 
-		if (likely(bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr))) {
+		if (likely(tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr))) {
 			l_ptr->unacked_window = 0;
 		} else {
-			bearer_schedule(l_ptr->b_ptr, l_ptr);
+			tipc_bearer_schedule(l_ptr->b_ptr, l_ptr);
 			l_ptr->stats.bearer_congs++;
 			l_ptr->next_out = buf;
 		}
@@ -1088,7 +1088,7 @@ int link_send_buf(struct link *l_ptr, st
 
 		if (l_ptr->next_out && 
 		    link_bundle_buf(l_ptr, l_ptr->last_out, buf)) {
-			bearer_resolve_congestion(l_ptr->b_ptr, l_ptr);
+			tipc_bearer_resolve_congestion(l_ptr->b_ptr, l_ptr);
 			return dsz;
 		}
 
@@ -1114,38 +1114,38 @@ int link_send_buf(struct link *l_ptr, st
 	if (!l_ptr->next_out)
 		l_ptr->next_out = buf;
 	link_add_to_outqueue(l_ptr, buf, msg);
-	bearer_resolve_congestion(l_ptr->b_ptr, l_ptr);
+	tipc_bearer_resolve_congestion(l_ptr->b_ptr, l_ptr);
 	return dsz;
 }
 
 /* 
- * link_send(): same as link_send_buf(), but the link to use has 
+ * tipc_link_send(): same as tipc_link_send_buf(), but the link to use has 
  * not been selected yet, and the the owner node is not locked
  * Called by TIPC internal users, e.g. the name distributor
  */
 
-int link_send(struct sk_buff *buf, u32 dest, u32 selector)
+int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector)
 {
 	struct link *l_ptr;
 	struct node *n_ptr;
 	int res = -ELINKCONG;
 
-	read_lock_bh(&net_lock);
-	n_ptr = node_select(dest, selector);
+	read_lock_bh(&tipc_net_lock);
+	n_ptr = tipc_node_select(dest, selector);
 	if (n_ptr) {
-		node_lock(n_ptr);
+		tipc_node_lock(n_ptr);
 		l_ptr = n_ptr->active_links[selector & 1];
-		dbg("link_send: found link %x for dest %x\n", l_ptr, dest);
+		dbg("tipc_link_send: found link %x for dest %x\n", l_ptr, dest);
 		if (l_ptr) {
-			res = link_send_buf(l_ptr, buf);
+			res = tipc_link_send_buf(l_ptr, buf);
 		}
-		node_unlock(n_ptr);
+		tipc_node_unlock(n_ptr);
 	} else {
 		dbg("Attempt to send msg to unknown node:\n");
 		msg_dbg(buf_msg(buf),">>>");
 		buf_discard(buf);
 	}
-	read_unlock_bh(&net_lock);
+	read_unlock_bh(&tipc_net_lock);
 	return res;
 }
 
@@ -1166,14 +1166,14 @@ static inline int link_send_buf_fast(str
 		if (likely(msg_size(msg) <= link_max_pkt(l_ptr))) {
 			if (likely(list_empty(&l_ptr->b_ptr->cong_links))) {
 				link_add_to_outqueue(l_ptr, buf, msg);
-				if (likely(bearer_send(l_ptr->b_ptr, buf,
-						       &l_ptr->media_addr))) {
+				if (likely(tipc_bearer_send(l_ptr->b_ptr, buf,
+							    &l_ptr->media_addr))) {
 					l_ptr->unacked_window = 0;
 					msg_dbg(msg,"SENT_FAST:");
 					return res;
 				}
 				dbg("failed sent fast...\n");
-				bearer_schedule(l_ptr->b_ptr, l_ptr);
+				tipc_bearer_schedule(l_ptr->b_ptr, l_ptr);
 				l_ptr->stats.bearer_congs++;
 				l_ptr->next_out = buf;
 				return res;
@@ -1182,7 +1182,7 @@ static inline int link_send_buf_fast(str
 		else
 			*used_max_pkt = link_max_pkt(l_ptr);
 	}
-	return link_send_buf(l_ptr, buf);  /* All other cases */
+	return tipc_link_send_buf(l_ptr, buf);  /* All other cases */
 }
 
 /* 
@@ -1200,24 +1200,24 @@ int tipc_send_buf_fast(struct sk_buff *b
 	u32 dummy;
 
 	if (destnode == tipc_own_addr)
-		return port_recv_msg(buf);
+		return tipc_port_recv_msg(buf);
 
-	read_lock_bh(&net_lock);
-	n_ptr = node_select(destnode, selector);
+	read_lock_bh(&tipc_net_lock);
+	n_ptr = tipc_node_select(destnode, selector);
 	if (likely(n_ptr)) {
-		node_lock(n_ptr);
+		tipc_node_lock(n_ptr);
 		l_ptr = n_ptr->active_links[selector];
 		dbg("send_fast: buf %x selected %x, destnode = %x\n",
 		    buf, l_ptr, destnode);
 		if (likely(l_ptr)) {
 			res = link_send_buf_fast(l_ptr, buf, &dummy);
-			node_unlock(n_ptr);
-			read_unlock_bh(&net_lock);
+			tipc_node_unlock(n_ptr);
+			read_unlock_bh(&tipc_net_lock);
 			return res;
 		}
-		node_unlock(n_ptr);
+		tipc_node_unlock(n_ptr);
 	}
-	read_unlock_bh(&net_lock);
+	read_unlock_bh(&tipc_net_lock);
 	res = msg_data_sz(buf_msg(buf));
 	tipc_reject_msg(buf, TIPC_ERR_NO_NODE);
 	return res;
@@ -1225,15 +1225,15 @@ int tipc_send_buf_fast(struct sk_buff *b
 
 
 /* 
- * link_send_sections_fast: Entry for messages where the 
+ * tipc_link_send_sections_fast: Entry for messages where the 
  * destination processor is known and the header is complete,
  * except for total message length. 
  * Returns user data length or errno.
  */
-int link_send_sections_fast(struct port *sender, 
-			    struct iovec const *msg_sect,
-			    const u32 num_sect, 
-			    u32 destaddr)
+int tipc_link_send_sections_fast(struct port *sender, 
+				 struct iovec const *msg_sect,
+				 const u32 num_sect, 
+				 u32 destaddr)
 {
 	struct tipc_msg *hdr = &sender->publ.phdr;
 	struct link *l_ptr;
@@ -1253,10 +1253,10 @@ again:
 	res = msg_build(hdr, msg_sect, num_sect, sender->max_pkt,
 			!sender->user_port, &buf);
 
-	read_lock_bh(&net_lock);
-	node = node_select(destaddr, selector);
+	read_lock_bh(&tipc_net_lock);
+	node = tipc_node_select(destaddr, selector);
 	if (likely(node)) {
-		node_lock(node);
+		tipc_node_lock(node);
 		l_ptr = node->active_links[selector];
 		if (likely(l_ptr)) {
 			if (likely(buf)) {
@@ -1265,8 +1265,8 @@ again:
 				if (unlikely(res < 0))
 					buf_discard(buf);
 exit:
-				node_unlock(node);
-				read_unlock_bh(&net_lock);
+				tipc_node_unlock(node);
+				read_unlock_bh(&tipc_net_lock);
 				return res;
 			}
 
@@ -1290,8 +1290,8 @@ exit:
 			 */
 
 			sender->max_pkt = link_max_pkt(l_ptr);
-			node_unlock(node);
-			read_unlock_bh(&net_lock);
+			tipc_node_unlock(node);
+			read_unlock_bh(&tipc_net_lock);
 
 
 			if ((msg_hdr_sz(hdr) + res) <= sender->max_pkt)
@@ -1300,17 +1300,17 @@ exit:
 			return link_send_sections_long(sender, msg_sect,
 						       num_sect, destaddr);
 		}
-		node_unlock(node);
+		tipc_node_unlock(node);
 	}
-	read_unlock_bh(&net_lock);
+	read_unlock_bh(&tipc_net_lock);
 
 	/* Couldn't find a link to the destination node */
 
 	if (buf)
 		return tipc_reject_msg(buf, TIPC_ERR_NO_NODE);
 	if (res >= 0)
-		return port_reject_sections(sender, hdr, msg_sect, num_sect,
-					    TIPC_ERR_NO_NODE);
+		return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect,
+						 TIPC_ERR_NO_NODE);
 	return res;
 }
 
@@ -1444,17 +1444,17 @@ error:
 	 * Now we have a buffer chain. Select a link and check
 	 * that packet size is still OK
 	 */
-	node = node_select(destaddr, sender->publ.ref & 1);
+	node = tipc_node_select(destaddr, sender->publ.ref & 1);
 	if (likely(node)) {
-		node_lock(node);
+		tipc_node_lock(node);
 		l_ptr = node->active_links[sender->publ.ref & 1];
 		if (!l_ptr) {
-			node_unlock(node);
+			tipc_node_unlock(node);
 			goto reject;
 		}
 		if (link_max_pkt(l_ptr) < max_pkt) {
 			sender->max_pkt = link_max_pkt(l_ptr);
-			node_unlock(node);
+			tipc_node_unlock(node);
 			for (; buf_chain; buf_chain = buf) {
 				buf = buf_chain->next;
 				buf_discard(buf_chain);
@@ -1467,8 +1467,8 @@ reject:
 			buf = buf_chain->next;
 			buf_discard(buf_chain);
 		}
-		return port_reject_sections(sender, hdr, msg_sect, num_sect,
-					    TIPC_ERR_NO_NODE);
+		return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect,
+						 TIPC_ERR_NO_NODE);
 	}
 
 	/* Append whole chain to send queue: */
@@ -1491,15 +1491,15 @@ reject:
 
 	/* Send it, if possible: */
 
-	link_push_queue(l_ptr);
-	node_unlock(node);
+	tipc_link_push_queue(l_ptr);
+	tipc_node_unlock(node);
 	return dsz;
 }
 
 /* 
- * link_push_packet: Push one unsent packet to the media
+ * tipc_link_push_packet: Push one unsent packet to the media
  */
-u32 link_push_packet(struct link *l_ptr)
+u32 tipc_link_push_packet(struct link *l_ptr)
 {
 	struct sk_buff *buf = l_ptr->first_out;
 	u32 r_q_size = l_ptr->retransm_queue_size;
@@ -1526,7 +1526,7 @@ u32 link_push_packet(struct link *l_ptr)
 	if (r_q_size && buf && !skb_cloned(buf)) {
 		msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1));
 		msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); 
-		if (bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
+		if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
 			msg_dbg(buf_msg(buf), ">DEF-RETR>");
 			l_ptr->retransm_queue_head = mod(++r_q_head);
 			l_ptr->retransm_queue_size = --r_q_size;
@@ -1545,7 +1545,7 @@ u32 link_push_packet(struct link *l_ptr)
 	if (buf) {
 		msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1));
 		msg_set_bcast_ack(buf_msg(buf),l_ptr->owner->bclink.last_in); 
-		if (bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
+		if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
 			msg_dbg(buf_msg(buf), ">DEF-PROT>");
 			l_ptr->unacked_window = 0;
 			buf_discard(buf);
@@ -1569,7 +1569,7 @@ u32 link_push_packet(struct link *l_ptr)
 		if (mod(next - first) < l_ptr->queue_limit[0]) {
 			msg_set_ack(msg, mod(l_ptr->next_in_no - 1));
 			msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); 
-			if (bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
+			if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
 				if (msg_user(msg) == MSG_BUNDLER)
 					msg_set_type(msg, CLOSED_MSG);
 				msg_dbg(msg, ">PUSH-DATA>");
@@ -1589,29 +1589,29 @@ u32 link_push_packet(struct link *l_ptr)
  * push_queue(): push out the unsent messages of a link where
  *               congestion has abated. Node is locked
  */
-void link_push_queue(struct link *l_ptr)
+void tipc_link_push_queue(struct link *l_ptr)
 {
 	u32 res;
 
-	if (bearer_congested(l_ptr->b_ptr, l_ptr))
+	if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr))
 		return;
 
 	do {
-		res = link_push_packet(l_ptr);
+		res = tipc_link_push_packet(l_ptr);
 	}
 	while (res == TIPC_OK);
 	if (res == PUSH_FAILED)
-		bearer_schedule(l_ptr->b_ptr, l_ptr);
+		tipc_bearer_schedule(l_ptr->b_ptr, l_ptr);
 }
 
-void link_retransmit(struct link *l_ptr, struct sk_buff *buf, 
-		     u32 retransmits)
+void tipc_link_retransmit(struct link *l_ptr, struct sk_buff *buf, 
+			  u32 retransmits)
 {
 	struct tipc_msg *msg;
 
 	dbg("Retransmitting %u in link %x\n", retransmits, l_ptr);
 
-	if (bearer_congested(l_ptr->b_ptr, l_ptr) && buf && !skb_cloned(buf)) {
+	if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr) && buf && !skb_cloned(buf)) {
 		msg_dbg(buf_msg(buf), ">NO_RETR->BCONG>");
 		dbg_print_link(l_ptr, "   ");
 		l_ptr->retransm_queue_head = msg_seqno(buf_msg(buf));
@@ -1622,15 +1622,15 @@ void link_retransmit(struct link *l_ptr,
 		msg = buf_msg(buf);
 		msg_set_ack(msg, mod(l_ptr->next_in_no - 1));
 		msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); 
-		if (bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
+		if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
                         /* Catch if retransmissions fail repeatedly: */
                         if (l_ptr->last_retransmitted == msg_seqno(msg)) {
                                 if (++l_ptr->stale_count > 100) {
-                                        msg_print(CONS, buf_msg(buf), ">RETR>");
+                                        tipc_msg_print(TIPC_CONS, buf_msg(buf), ">RETR>");
                                         info("...Retransmitted %u times\n",
 					     l_ptr->stale_count);
-                                        link_print(l_ptr, CONS, "Resetting Link\n");;
-                                        link_reset(l_ptr);
+                                        link_print(l_ptr, TIPC_CONS, "Resetting Link\n");;
+                                        tipc_link_reset(l_ptr);
                                         break;
                                 }
                         } else {
@@ -1643,7 +1643,7 @@ void link_retransmit(struct link *l_ptr,
 			retransmits--;
 			l_ptr->stats.retransmitted++;
 		} else {
-			bearer_schedule(l_ptr->b_ptr, l_ptr);
+			tipc_bearer_schedule(l_ptr->b_ptr, l_ptr);
 			l_ptr->stats.bearer_congs++;
 			l_ptr->retransm_queue_head = msg_seqno(buf_msg(buf));
 			l_ptr->retransm_queue_size = retransmits;
@@ -1663,9 +1663,9 @@ static void link_recv_non_seq(struct sk_
 	struct tipc_msg *msg = buf_msg(buf);
 
 	if (msg_user(msg) ==  LINK_CONFIG)
-		disc_recv_msg(buf);
+		tipc_disc_recv_msg(buf);
 	else
-		bclink_recv_pkt(buf);
+		tipc_bclink_recv_pkt(buf);
 }
 
 /** 
@@ -1692,7 +1692,7 @@ static struct sk_buff *link_insert_defer
 
 void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
 {
-	read_lock_bh(&net_lock);
+	read_lock_bh(&tipc_net_lock);
 	while (head) {
 		struct bearer *b_ptr;
 		struct node *n_ptr;
@@ -1720,22 +1720,22 @@ void tipc_recv_msg(struct sk_buff *head,
 			link_recv_non_seq(buf);
 			continue;
 		}
-		n_ptr = node_find(msg_prevnode(msg));
+		n_ptr = tipc_node_find(msg_prevnode(msg));
 		if (unlikely(!n_ptr))
 			goto cont;
 
-		node_lock(n_ptr);
+		tipc_node_lock(n_ptr);
 		l_ptr = n_ptr->links[b_ptr->identity];
 		if (unlikely(!l_ptr)) {
-			node_unlock(n_ptr);
+			tipc_node_unlock(n_ptr);
 			goto cont;
 		}
 		/* 
 		 * Release acked messages 
 		 */
 		if (less(n_ptr->bclink.acked, msg_bcast_ack(msg))) {
-			if (node_is_up(n_ptr) && n_ptr->bclink.supported)
-				bclink_acknowledge(n_ptr, msg_bcast_ack(msg));
+			if (tipc_node_is_up(n_ptr) && n_ptr->bclink.supported)
+				tipc_bclink_acknowledge(n_ptr, msg_bcast_ack(msg));
 		}
 
 		crs = l_ptr->first_out;
@@ -1752,12 +1752,12 @@ void tipc_recv_msg(struct sk_buff *head,
 			l_ptr->out_queue_size -= released;
 		}
 		if (unlikely(l_ptr->next_out))
-			link_push_queue(l_ptr);
+			tipc_link_push_queue(l_ptr);
 		if (unlikely(!list_empty(&l_ptr->waiting_ports)))
-			link_wakeup_ports(l_ptr, 0);
+			tipc_link_wakeup_ports(l_ptr, 0);
 		if (unlikely(++l_ptr->unacked_window >= TIPC_MIN_LINK_WIN)) {
 			l_ptr->stats.sent_acks++;
-			link_send_proto_msg(l_ptr, STATE_MSG, 0, 0, 0, 0, 0);
+			tipc_link_send_proto_msg(l_ptr, STATE_MSG, 0, 0, 0, 0, 0);
 		}
 
 protocol_check:
@@ -1770,8 +1770,8 @@ protocol_check:
 				if (likely(msg_is_dest(msg, tipc_own_addr))) {
 deliver:
 					if (likely(msg_isdata(msg))) {
-						node_unlock(n_ptr);
-						port_recv_msg(buf);
+						tipc_node_unlock(n_ptr);
+						tipc_port_recv_msg(buf);
 						continue;
 					}
 					switch (msg_user(msg)) {
@@ -1779,34 +1779,32 @@ deliver:
 						l_ptr->stats.recv_bundles++;
 						l_ptr->stats.recv_bundled += 
 							msg_msgcnt(msg);
-						node_unlock(n_ptr);
-						link_recv_bundle(buf);
+						tipc_node_unlock(n_ptr);
+						tipc_link_recv_bundle(buf);
 						continue;
 					case ROUTE_DISTRIBUTOR:
-						node_unlock(n_ptr);
-						cluster_recv_routing_table(buf);
+						tipc_node_unlock(n_ptr);
+						tipc_cltr_recv_routing_table(buf);
 						continue;
 					case NAME_DISTRIBUTOR:
-						node_unlock(n_ptr);
-						named_recv(buf);
+						tipc_node_unlock(n_ptr);
+						tipc_named_recv(buf);
 						continue;
 					case CONN_MANAGER:
-						node_unlock(n_ptr);
-						port_recv_proto_msg(buf);
+						tipc_node_unlock(n_ptr);
+						tipc_port_recv_proto_msg(buf);
 						continue;
 					case MSG_FRAGMENTER:
 						l_ptr->stats.recv_fragments++;
-						if (link_recv_fragment(
-							&l_ptr->defragm_buf, 
-							&buf, &msg)) {
+						if (tipc_link_recv_fragment(&l_ptr->defragm_buf, 
+									    &buf, &msg)) {
 							l_ptr->stats.recv_fragmented++;
 							goto deliver;
 						}
 						break;
 					case CHANGEOVER_PROTOCOL:
 						type = msg_type(msg);
-						if (link_recv_changeover_msg(
-							&l_ptr, &buf)) {
+						if (link_recv_changeover_msg(&l_ptr, &buf)) {
 							msg = buf_msg(buf);
 							seq_no = msg_seqno(msg);
 							TIPC_SKB_CB(buf)->handle 
@@ -1818,20 +1816,20 @@ deliver:
 						break;
 					}
 				}
-				node_unlock(n_ptr);
-				net_route_msg(buf);
+				tipc_node_unlock(n_ptr);
+				tipc_net_route_msg(buf);
 				continue;
 			}
 			link_handle_out_of_seq_msg(l_ptr, buf);
 			head = link_insert_deferred_queue(l_ptr, head);
-			node_unlock(n_ptr);
+			tipc_node_unlock(n_ptr);
 			continue;
 		}
 
 		if (msg_user(msg) == LINK_PROTOCOL) {
 			link_recv_proto_msg(l_ptr, buf);
 			head = link_insert_deferred_queue(l_ptr, head);
-			node_unlock(n_ptr);
+			tipc_node_unlock(n_ptr);
 			continue;
 		}
 		msg_dbg(msg,"NSEQ<REC<");
@@ -1842,14 +1840,14 @@ deliver:
 			msg_dbg(msg,"RECV-REINS:");
 			buf->next = head;
 			head = buf;
-			node_unlock(n_ptr);
+			tipc_node_unlock(n_ptr);
 			continue;
 		}
-		node_unlock(n_ptr);
+		tipc_node_unlock(n_ptr);
 cont:
 		buf_discard(buf);
 	}
-	read_unlock_bh(&net_lock);
+	read_unlock_bh(&tipc_net_lock);
 }
 
 /* 
@@ -1858,9 +1856,9 @@ cont:
  * Returns the increase of the queue length,i.e. 0 or 1
  */
 
-u32 link_defer_pkt(struct sk_buff **head,
-		   struct sk_buff **tail,
-		   struct sk_buff *buf)
+u32 tipc_link_defer_pkt(struct sk_buff **head,
+			struct sk_buff **tail,
+			struct sk_buff *buf)
 {
 	struct sk_buff *prev = 0;
 	struct sk_buff *crs = *head;
@@ -1939,12 +1937,12 @@ static void link_handle_out_of_seq_msg(s
 		return;
 	}
 
-	if (link_defer_pkt(&l_ptr->oldest_deferred_in,
-			   &l_ptr->newest_deferred_in, buf)) {
+	if (tipc_link_defer_pkt(&l_ptr->oldest_deferred_in,
+				&l_ptr->newest_deferred_in, buf)) {
 		l_ptr->deferred_inqueue_sz++;
 		l_ptr->stats.deferred_recv++;
 		if ((l_ptr->deferred_inqueue_sz % 16) == 1)
-			link_send_proto_msg(l_ptr, STATE_MSG, 0, 0, 0, 0, 0);
+			tipc_link_send_proto_msg(l_ptr, STATE_MSG, 0, 0, 0, 0, 0);
 	} else
 		l_ptr->stats.duplicates++;
 }
@@ -1952,8 +1950,8 @@ static void link_handle_out_of_seq_msg(s
 /*
  * Send protocol message to the other endpoint.
  */
-void link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
-			 u32 gap, u32 tolerance, u32 priority, u32 ack_mtu)
+void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
+			      u32 gap, u32 tolerance, u32 priority, u32 ack_mtu)
 {
 	struct sk_buff *buf = 0;
 	struct tipc_msg *msg = l_ptr->pmsg;
@@ -1964,12 +1962,12 @@ void link_send_proto_msg(struct link *l_
 	msg_set_type(msg, msg_typ);
 	msg_set_net_plane(msg, l_ptr->b_ptr->net_plane);
 	msg_set_bcast_ack(msg, mod(l_ptr->owner->bclink.last_in)); 
-	msg_set_last_bcast(msg, bclink_get_last_sent());
+	msg_set_last_bcast(msg, tipc_bclink_get_last_sent());
 
 	if (msg_typ == STATE_MSG) {
 		u32 next_sent = mod(l_ptr->next_out_no);
 
-		if (!link_is_up(l_ptr))
+		if (!tipc_link_is_up(l_ptr))
 			return;
 		if (l_ptr->next_out)
 			next_sent = msg_seqno(buf_msg(l_ptr->next_out));
@@ -2013,7 +2011,7 @@ void link_send_proto_msg(struct link *l_
 		msg_set_max_pkt(msg, l_ptr->max_pkt_target);
 	}
 
-	if (node_has_redundant_links(l_ptr->owner)) {
+	if (tipc_node_has_redundant_links(l_ptr->owner)) {
 		msg_set_redundant_link(msg);
 	} else {
 		msg_clear_redundant_link(msg);
@@ -2026,7 +2024,7 @@ void link_send_proto_msg(struct link *l_
 
 	/* Congestion? */
 
-	if (bearer_congested(l_ptr->b_ptr, l_ptr)) {
+	if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) {
 		if (!l_ptr->proto_msg_queue) {
 			l_ptr->proto_msg_queue =
 				buf_acquire(sizeof(l_ptr->proto_msg));
@@ -2050,14 +2048,14 @@ void link_send_proto_msg(struct link *l_
 	memcpy(buf->data, (unchar *)msg, sizeof(l_ptr->proto_msg));
         msg_set_size(buf_msg(buf), msg_size);
 
-	if (bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
+	if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
 		l_ptr->unacked_window = 0;
 		buf_discard(buf);
 		return;
 	}
 
 	/* New congestion */
-	bearer_schedule(l_ptr->b_ptr, l_ptr);
+	tipc_bearer_schedule(l_ptr->b_ptr, l_ptr);
 	l_ptr->proto_msg_queue = buf;
 	l_ptr->stats.bearer_congs++;
 }
@@ -2131,7 +2129,7 @@ static void link_recv_proto_msg(struct l
 		l_ptr->peer_bearer_id = msg_bearer_id(msg);
 
 		/* Synchronize broadcast sequence numbers */
-		if (!node_has_redundant_links(l_ptr->owner)) {
+		if (!tipc_node_has_redundant_links(l_ptr->owner)) {
 			l_ptr->owner->bclink.last_in = mod(msg_last_bcast(msg));
 		}
 		break;
@@ -2145,7 +2143,7 @@ static void link_recv_proto_msg(struct l
 			warn("Changing prio <%s>: %u->%u\n",
 			     l_ptr->name, l_ptr->priority, msg_linkprio(msg));
 			l_ptr->priority = msg_linkprio(msg);
-			link_reset(l_ptr); /* Enforce change to take effect */
+			tipc_link_reset(l_ptr); /* Enforce change to take effect */
 			break;
 		}
 		link_state_event(l_ptr, TRAFFIC_MSG_EVT);
@@ -2176,17 +2174,17 @@ static void link_recv_proto_msg(struct l
 
 		/* Protocol message before retransmits, reduce loss risk */
 
-		bclink_check_gap(l_ptr->owner, msg_last_bcast(msg));
+		tipc_bclink_check_gap(l_ptr->owner, msg_last_bcast(msg));
 
 		if (rec_gap || (msg_probe(msg))) {
-			link_send_proto_msg(l_ptr, STATE_MSG,
-					    0, rec_gap, 0, 0, max_pkt_ack);
+			tipc_link_send_proto_msg(l_ptr, STATE_MSG,
+						 0, rec_gap, 0, 0, max_pkt_ack);
 		}
 		if (msg_seq_gap(msg)) {
 			msg_dbg(msg, "With Gap:");
 			l_ptr->stats.recv_nacks++;
-			link_retransmit(l_ptr, l_ptr->first_out,
-					msg_seq_gap(msg));
+			tipc_link_retransmit(l_ptr, l_ptr->first_out,
+					     msg_seq_gap(msg));
 		}
 		break;
 	default:
@@ -2198,20 +2196,20 @@ exit:
 
 
 /*
- * link_tunnel(): Send one message via a link belonging to 
+ * tipc_link_tunnel(): Send one message via a link belonging to 
  * another bearer. Owner node is locked.
  */
-void link_tunnel(struct link *l_ptr, 
-	    struct tipc_msg *tunnel_hdr, 
-	    struct tipc_msg  *msg,
-	    u32 selector)
+void tipc_link_tunnel(struct link *l_ptr, 
+		      struct tipc_msg *tunnel_hdr, 
+		      struct tipc_msg  *msg,
+		      u32 selector)
 {
 	struct link *tunnel;
 	struct sk_buff *buf;
 	u32 length = msg_size(msg);
 
 	tunnel = l_ptr->owner->active_links[selector & 1];
-	if (!link_is_up(tunnel))
+	if (!tipc_link_is_up(tunnel))
 		return;
 	msg_set_size(tunnel_hdr, length + INT_H_SIZE);
 	buf = buf_acquire(length + INT_H_SIZE);
@@ -2222,7 +2220,7 @@ void link_tunnel(struct link *l_ptr, 
 	dbg("%c->%c:", l_ptr->b_ptr->net_plane, tunnel->b_ptr->net_plane);
 	msg_dbg(buf_msg(buf), ">SEND>");
 	assert(tunnel);
-	link_send_buf(tunnel, buf);
+	tipc_link_send_buf(tunnel, buf);
 }
 
 
@@ -2232,12 +2230,12 @@ void link_tunnel(struct link *l_ptr, 
  *               Owner node is locked.
  */
 
-void link_changeover(struct link *l_ptr)
+void tipc_link_changeover(struct link *l_ptr)
 {
 	u32 msgcount = l_ptr->out_queue_size;
 	struct sk_buff *crs = l_ptr->first_out;
 	struct link *tunnel = l_ptr->owner->active_links[0];
-	int split_bundles = node_has_redundant_links(l_ptr->owner);
+	int split_bundles = tipc_node_has_redundant_links(l_ptr->owner);
 	struct tipc_msg tunnel_hdr;
 
 	if (!tunnel)
@@ -2261,7 +2259,7 @@ void link_changeover(struct link *l_ptr)
 			dbg("%c->%c:", l_ptr->b_ptr->net_plane,
 			    tunnel->b_ptr->net_plane);
 			msg_dbg(&tunnel_hdr, "EMPTY>SEND>");
-			link_send_buf(tunnel, buf);
+			tipc_link_send_buf(tunnel, buf);
 		} else {
 			warn("Memory squeeze; link changeover failed\n");
 		}
@@ -2277,20 +2275,20 @@ void link_changeover(struct link *l_ptr)
 
 			while (msgcount--) {
 				msg_set_seqno(m,msg_seqno(msg));
-				link_tunnel(l_ptr, &tunnel_hdr, m,
-					    msg_link_selector(m));
+				tipc_link_tunnel(l_ptr, &tunnel_hdr, m,
+						 msg_link_selector(m));
 				pos += align(msg_size(m));
 				m = (struct tipc_msg *)pos;
 			}
 		} else {
-			link_tunnel(l_ptr, &tunnel_hdr, msg,
-				    msg_link_selector(msg));
+			tipc_link_tunnel(l_ptr, &tunnel_hdr, msg,
+					 msg_link_selector(msg));
 		}
 		crs = crs->next;
 	}
 }
 
-void link_send_duplicate(struct link *l_ptr, struct link *tunnel)
+void tipc_link_send_duplicate(struct link *l_ptr, struct link *tunnel)
 {
 	struct sk_buff *iter;
 	struct tipc_msg tunnel_hdr;
@@ -2320,8 +2318,8 @@ void link_send_duplicate(struct link *l_
 		dbg("%c->%c:", l_ptr->b_ptr->net_plane,
 		    tunnel->b_ptr->net_plane);
 		msg_dbg(buf_msg(outbuf), ">SEND>");
-		link_send_buf(tunnel, outbuf);
-		if (!link_is_up(l_ptr))
+		tipc_link_send_buf(tunnel, outbuf);
+		if (!tipc_link_is_up(l_ptr))
 			return;
 		iter = iter->next;
 	}
@@ -2393,9 +2391,9 @@ static int link_recv_changeover_msg(stru
 
 	/* First original message ?: */
 
-	if (link_is_up(dest_link)) {
+	if (tipc_link_is_up(dest_link)) {
 		msg_dbg(tunnel_msg, "UP/FIRST/<REC<");
-		link_reset(dest_link);
+		tipc_link_reset(dest_link);
 		dest_link->exp_msg_count = msg_count;
 		if (!msg_count)
 			goto exit;
@@ -2436,7 +2434,7 @@ exit:
 /*
  *  Bundler functionality:
  */
-void link_recv_bundle(struct sk_buff *buf)
+void tipc_link_recv_bundle(struct sk_buff *buf)
 {
 	u32 msgcount = msg_msgcnt(buf_msg(buf));
 	u32 pos = INT_H_SIZE;
@@ -2456,7 +2454,7 @@ void link_recv_bundle(struct sk_buff *bu
 		};
 		pos += align(msg_size(buf_msg(obuf)));
 		msg_dbg(buf_msg(obuf), "     /");
-		net_route_msg(obuf);
+		tipc_net_route_msg(obuf);
 	}
 	buf_discard(buf);
 }
@@ -2467,11 +2465,11 @@ void link_recv_bundle(struct sk_buff *bu
 
 
 /* 
- * link_send_long_buf: Entry for buffers needing fragmentation.
+ * tipc_link_send_long_buf: Entry for buffers needing fragmentation.
  * The buffer is complete, inclusive total message length. 
  * Returns user data length.
  */
-int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
+int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
 {
 	struct tipc_msg *inmsg = buf_msg(buf);
 	struct tipc_msg fragm_hdr;
@@ -2521,8 +2519,8 @@ int link_send_long_buf(struct link *l_pt
 		/*  Send queued messages first, if any: */
 
 		l_ptr->stats.sent_fragments++;
-		link_send_buf(l_ptr, fragm);
-		if (!link_is_up(l_ptr))
+		tipc_link_send_buf(l_ptr, fragm);
+		if (!tipc_link_is_up(l_ptr))
 			return dsz;
 		msg_set_fragm_no(&fragm_hdr, ++fragm_no);
 		rest -= fragm_sz;
@@ -2582,11 +2580,11 @@ static inline void incr_timer_cnt(struct
 }
 
 /* 
- * link_recv_fragment(): Called with node lock on. Returns 
+ * tipc_link_recv_fragment(): Called with node lock on. Returns 
  * the reassembled buffer if message is complete.
  */
-int link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb, 
-		       struct tipc_msg **m)
+int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb, 
+			    struct tipc_msg **m)
 {
 	struct sk_buff *prev = 0;
 	struct sk_buff *fbuf = *fb;
@@ -2714,7 +2712,7 @@ static void link_set_supervision_props(s
 }
 
 
-void link_set_queue_limits(struct link *l_ptr, u32 window)
+void tipc_link_set_queue_limits(struct link *l_ptr, u32 window)
 {
 	/* Data messages from this node, inclusive FIRST_FRAGM */
 	l_ptr->queue_limit[DATA_LOW] = window;
@@ -2739,7 +2737,7 @@ void link_set_queue_limits(struct link *
  * @name - ptr to link name string
  * @node - ptr to area to be filled with ptr to associated node
  * 
- * Caller must hold 'net_lock' to ensure node and bearer are not deleted;
+ * Caller must hold 'tipc_net_lock' to ensure node and bearer are not deleted;
  * this also prevents link deletion.
  * 
  * Returns pointer to link (or 0 if invalid link name).
@@ -2754,11 +2752,11 @@ static struct link *link_find_link(const
 	if (!link_name_validate(name, &link_name_parts))
 		return 0;
 
-	b_ptr = bearer_find_interface(link_name_parts.if_local);
+	b_ptr = tipc_bearer_find_interface(link_name_parts.if_local);
 	if (!b_ptr)
 		return 0;
 
-	*node = node_find(link_name_parts.addr_peer); 
+	*node = tipc_node_find(link_name_parts.addr_peer); 
 	if (!*node)
 		return 0;
 
@@ -2769,8 +2767,8 @@ static struct link *link_find_link(const
 	return l_ptr;
 }
 
-struct sk_buff *link_cmd_config(const void *req_tlv_area, int req_tlv_space, 
-			        u16 cmd)
+struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space, 
+				     u16 cmd)
 {
 	struct tipc_link_config *args;
         u32 new_value;
@@ -2779,61 +2777,62 @@ struct sk_buff *link_cmd_config(const vo
         int res;
 
 	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_CONFIG))
-		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
+		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
 
 	args = (struct tipc_link_config *)TLV_DATA(req_tlv_area);
 	new_value = ntohl(args->value);
 
-	if (!strcmp(args->name, bc_link_name)) {
+	if (!strcmp(args->name, tipc_bclink_name)) {
 		if ((cmd == TIPC_CMD_SET_LINK_WINDOW) &&
-		    (bclink_set_queue_limits(new_value) == 0))
-			return cfg_reply_none();
-	       	return cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
-					      " (cannot change setting on broadcast link)");
+		    (tipc_bclink_set_queue_limits(new_value) == 0))
+			return tipc_cfg_reply_none();
+	       	return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
+						   " (cannot change setting on broadcast link)");
 	}
 
-	read_lock_bh(&net_lock);
+	read_lock_bh(&tipc_net_lock);
 	l_ptr = link_find_link(args->name, &node); 
 	if (!l_ptr) {
-		read_unlock_bh(&net_lock);
-	       	return cfg_reply_error_string("link not found");
+		read_unlock_bh(&tipc_net_lock);
+	       	return tipc_cfg_reply_error_string("link not found");
 	}
 
-	node_lock(node);
+	tipc_node_lock(node);
 	res = -EINVAL;
 	switch (cmd) {
 	case TIPC_CMD_SET_LINK_TOL: 
 		if ((new_value >= TIPC_MIN_LINK_TOL) && 
 		    (new_value <= TIPC_MAX_LINK_TOL)) {
 			link_set_supervision_props(l_ptr, new_value);
-			link_send_proto_msg(l_ptr, STATE_MSG, 
-					    0, 0, new_value, 0, 0);
+			tipc_link_send_proto_msg(l_ptr, STATE_MSG, 
+						 0, 0, new_value, 0, 0);
 			res = TIPC_OK;
 		}
 		break;
 	case TIPC_CMD_SET_LINK_PRI: 
-		if (new_value < TIPC_NUM_LINK_PRI) {
+		if ((new_value >= TIPC_MIN_LINK_PRI) &&
+		    (new_value <= TIPC_MAX_LINK_PRI)) {
 			l_ptr->priority = new_value;
-			link_send_proto_msg(l_ptr, STATE_MSG, 
-					    0, 0, 0, new_value, 0);
+			tipc_link_send_proto_msg(l_ptr, STATE_MSG, 
+						 0, 0, 0, new_value, 0);
 			res = TIPC_OK;
 		}
 		break;
 	case TIPC_CMD_SET_LINK_WINDOW: 
 		if ((new_value >= TIPC_MIN_LINK_WIN) && 
 		    (new_value <= TIPC_MAX_LINK_WIN)) {
-			link_set_queue_limits(l_ptr, new_value);
+			tipc_link_set_queue_limits(l_ptr, new_value);
 			res = TIPC_OK;
 		}
 		break;
 	}
-	node_unlock(node);
+	tipc_node_unlock(node);
 
-	read_unlock_bh(&net_lock);
+	read_unlock_bh(&tipc_net_lock);
 	if (res)
-	       	return cfg_reply_error_string("cannot change link setting");
+	       	return tipc_cfg_reply_error_string("cannot change link setting");
 
-	return cfg_reply_none();
+	return tipc_cfg_reply_none();
 }
 
 /**
@@ -2848,34 +2847,34 @@ static void link_reset_statistics(struct
 	l_ptr->stats.recv_info = l_ptr->next_in_no;
 }
 
-struct sk_buff *link_cmd_reset_stats(const void *req_tlv_area, int req_tlv_space)
+struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area, int req_tlv_space)
 {
 	char *link_name;
 	struct link *l_ptr; 
 	struct node *node;
 
 	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME))
-		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
+		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
 
 	link_name = (char *)TLV_DATA(req_tlv_area);
-	if (!strcmp(link_name, bc_link_name)) {
-		if (bclink_reset_stats())
-			return cfg_reply_error_string("link not found");
-		return cfg_reply_none();
+	if (!strcmp(link_name, tipc_bclink_name)) {
+		if (tipc_bclink_reset_stats())
+			return tipc_cfg_reply_error_string("link not found");
+		return tipc_cfg_reply_none();
 	}
 
-	read_lock_bh(&net_lock);
+	read_lock_bh(&tipc_net_lock);
 	l_ptr = link_find_link(link_name, &node); 
 	if (!l_ptr) {
-		read_unlock_bh(&net_lock);
-		return cfg_reply_error_string("link not found");
+		read_unlock_bh(&tipc_net_lock);
+		return tipc_cfg_reply_error_string("link not found");
 	}
 
-	node_lock(node);
+	tipc_node_lock(node);
 	link_reset_statistics(l_ptr);
-	node_unlock(node);
-	read_unlock_bh(&net_lock);
-	return cfg_reply_none();
+	tipc_node_unlock(node);
+	read_unlock_bh(&tipc_net_lock);
+	return tipc_cfg_reply_none();
 }
 
 /**
@@ -2888,7 +2887,7 @@ static u32 percent(u32 count, u32 total)
 }
 
 /**
- * link_stats - print link statistics
+ * tipc_link_stats - print link statistics
  * @name: link name
  * @buf: print buffer area
  * @buf_size: size of print buffer area
@@ -2896,7 +2895,7 @@ static u32 percent(u32 count, u32 total)
  * Returns length of print buffer data string (or 0 if error)
  */
 
-static int link_stats(const char *name, char *buf, const u32 buf_size)
+static int tipc_link_stats(const char *name, char *buf, const u32 buf_size)
 {
 	struct print_buf pb;
 	struct link *l_ptr; 
@@ -2904,22 +2903,22 @@ static int link_stats(const char *name, 
 	char *status;
 	u32 profile_total = 0;
 
-	if (!strcmp(name, bc_link_name))
-		return bclink_stats(buf, buf_size);
+	if (!strcmp(name, tipc_bclink_name))
+		return tipc_bclink_stats(buf, buf_size);
 
-	printbuf_init(&pb, buf, buf_size);
+	tipc_printbuf_init(&pb, buf, buf_size);
 
-	read_lock_bh(&net_lock);
+	read_lock_bh(&tipc_net_lock);
 	l_ptr = link_find_link(name, &node); 
 	if (!l_ptr) {
-		read_unlock_bh(&net_lock);
+		read_unlock_bh(&tipc_net_lock);
 		return 0;
 	}
-	node_lock(node);
+	tipc_node_lock(node);
 
-	if (link_is_active(l_ptr))
+	if (tipc_link_is_active(l_ptr))
 		status = "ACTIVE";
-	else if (link_is_up(l_ptr))
+	else if (tipc_link_is_up(l_ptr))
 		status = "STANDBY";
 	else
 		status = "DEFUNCT";
@@ -2975,33 +2974,33 @@ static int link_stats(const char *name, 
 		    ? (l_ptr->stats.accu_queue_sz / l_ptr->stats.queue_sz_counts)
 		    : 0);
 
-	node_unlock(node);
-	read_unlock_bh(&net_lock);
-	return printbuf_validate(&pb);
+	tipc_node_unlock(node);
+	read_unlock_bh(&tipc_net_lock);
+	return tipc_printbuf_validate(&pb);
 }
 
 #define MAX_LINK_STATS_INFO 2000
 
-struct sk_buff *link_cmd_show_stats(const void *req_tlv_area, int req_tlv_space)
+struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_space)
 {
 	struct sk_buff *buf;
 	struct tlv_desc *rep_tlv;
 	int str_len;
 
 	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME))
-		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
+		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
 
-	buf = cfg_reply_alloc(TLV_SPACE(MAX_LINK_STATS_INFO));
+	buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_LINK_STATS_INFO));
 	if (!buf)
 		return NULL;
 
 	rep_tlv = (struct tlv_desc *)buf->data;
 
-	str_len = link_stats((char *)TLV_DATA(req_tlv_area),
-			     (char *)TLV_DATA(rep_tlv), MAX_LINK_STATS_INFO);
+	str_len = tipc_link_stats((char *)TLV_DATA(req_tlv_area),
+				  (char *)TLV_DATA(rep_tlv), MAX_LINK_STATS_INFO);
 	if (!str_len) {
 		buf_discard(buf);
-	       	return cfg_reply_error_string("link not found");
+	       	return tipc_cfg_reply_error_string("link not found");
 	}
 
 	skb_put(buf, TLV_SPACE(str_len));
@@ -3020,20 +3019,20 @@ int link_control(const char *name, u32 o
 	u32 a;
 
 	a = link_name2addr(name, &bearer_id);
-	read_lock_bh(&net_lock);
-	node = node_find(a);
+	read_lock_bh(&tipc_net_lock);
+	node = tipc_node_find(a);
 	if (node) {
-		node_lock(node);
+		tipc_node_lock(node);
 		l_ptr = node->links[bearer_id];
 		if (l_ptr) {
 			if (op == TIPC_REMOVE_LINK) {
 				struct bearer *b_ptr = l_ptr->b_ptr;
 				spin_lock_bh(&b_ptr->publ.lock);
-				link_delete(l_ptr);
+				tipc_link_delete(l_ptr);
 				spin_unlock_bh(&b_ptr->publ.lock);
 			}
 			if (op == TIPC_CMD_BLOCK_LINK) {
-				link_reset(l_ptr);
+				tipc_link_reset(l_ptr);
 				l_ptr->blocked = 1;
 			}
 			if (op == TIPC_CMD_UNBLOCK_LINK) {
@@ -3041,22 +3040,22 @@ int link_control(const char *name, u32 o
 			}
 			res = TIPC_OK;
 		}
-		node_unlock(node);
+		tipc_node_unlock(node);
 	}
-	read_unlock_bh(&net_lock);
+	read_unlock_bh(&tipc_net_lock);
 	return res;
 }
 #endif
 
 /**
- * link_get_max_pkt - get maximum packet size to use when sending to destination
+ * tipc_link_get_max_pkt - get maximum packet size to use when sending to destination
  * @dest: network address of destination node
  * @selector: used to select from set of active links
  * 
  * If no active link can be found, uses default maximum packet size.
  */
 
-u32 link_get_max_pkt(u32 dest, u32 selector)
+u32 tipc_link_get_max_pkt(u32 dest, u32 selector)
 {
 	struct node *n_ptr;
 	struct link *l_ptr;
@@ -3065,16 +3064,16 @@ u32 link_get_max_pkt(u32 dest, u32 selec
 	if (dest == tipc_own_addr)
 		return MAX_MSG_SIZE;
 
-	read_lock_bh(&net_lock);        
-	n_ptr = node_select(dest, selector);
+	read_lock_bh(&tipc_net_lock);        
+	n_ptr = tipc_node_select(dest, selector);
 	if (n_ptr) {
-		node_lock(n_ptr);
+		tipc_node_lock(n_ptr);
 		l_ptr = n_ptr->active_links[selector & 1];
 		if (l_ptr)
 			res = link_max_pkt(l_ptr);
-		node_unlock(n_ptr);
+		tipc_node_unlock(n_ptr);
 	}
-	read_unlock_bh(&net_lock);       
+	read_unlock_bh(&tipc_net_lock);       
 	return res;
 }
 
diff --git a/net/tipc/link.h b/net/tipc/link.h
index c2553f0..2d3c157 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -221,44 +221,43 @@ struct link {
 
 struct port;
 
-struct link *link_create(struct bearer *b_ptr, const u32 peer,
-			 const struct tipc_media_addr *media_addr);
-void link_delete(struct link *l_ptr);
-void link_changeover(struct link *l_ptr);
-void link_send_duplicate(struct link *l_ptr, struct link *dest);
-void link_reset_fragments(struct link *l_ptr);
-int link_is_up(struct link *l_ptr);
-int link_is_active(struct link *l_ptr);
-void link_start(struct link *l_ptr);
-u32 link_push_packet(struct link *l_ptr);
-void link_stop(struct link *l_ptr);
-struct sk_buff *link_cmd_config(const void *req_tlv_area, int req_tlv_space, u16 cmd);
-struct sk_buff *link_cmd_show_stats(const void *req_tlv_area, int req_tlv_space);
-struct sk_buff *link_cmd_reset_stats(const void *req_tlv_area, int req_tlv_space);
-void link_reset(struct link *l_ptr);
-int link_send(struct sk_buff *buf, u32 dest, u32 selector);
-int link_send_buf(struct link *l_ptr, struct sk_buff *buf);
-u32 link_get_max_pkt(u32 dest,u32 selector);
-int link_send_sections_fast(struct port* sender, 
-			    struct iovec const *msg_sect,
-			    const u32 num_sect, 
-			    u32 destnode);
-
-int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf);
-void link_tunnel(struct link *l_ptr, struct tipc_msg *tnl_hdr,
-		 struct tipc_msg *msg, u32 selector);
-void link_recv_bundle(struct sk_buff *buf);
-int  link_recv_fragment(struct sk_buff **pending,
-			struct sk_buff **fb,
-			struct tipc_msg **msg);
-void link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int prob, u32 gap, 
-			 u32 tolerance, u32 priority, u32 acked_mtu);
-void link_push_queue(struct link *l_ptr);
-u32 link_defer_pkt(struct sk_buff **head, struct sk_buff **tail,
+struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
+			      const struct tipc_media_addr *media_addr);
+void tipc_link_delete(struct link *l_ptr);
+void tipc_link_changeover(struct link *l_ptr);
+void tipc_link_send_duplicate(struct link *l_ptr, struct link *dest);
+void tipc_link_reset_fragments(struct link *l_ptr);
+int tipc_link_is_up(struct link *l_ptr);
+int tipc_link_is_active(struct link *l_ptr);
+void tipc_link_start(struct link *l_ptr);
+u32 tipc_link_push_packet(struct link *l_ptr);
+void tipc_link_stop(struct link *l_ptr);
+struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space, u16 cmd);
+struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_space);
+struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area, int req_tlv_space);
+void tipc_link_reset(struct link *l_ptr);
+int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector);
+int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf);
+u32 tipc_link_get_max_pkt(u32 dest,u32 selector);
+int tipc_link_send_sections_fast(struct port* sender, 
+				 struct iovec const *msg_sect,
+				 const u32 num_sect, 
+				 u32 destnode);
+int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf);
+void tipc_link_tunnel(struct link *l_ptr, struct tipc_msg *tnl_hdr,
+		      struct tipc_msg *msg, u32 selector);
+void tipc_link_recv_bundle(struct sk_buff *buf);
+int  tipc_link_recv_fragment(struct sk_buff **pending,
+			     struct sk_buff **fb,
+			     struct tipc_msg **msg);
+void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int prob, u32 gap, 
+			      u32 tolerance, u32 priority, u32 acked_mtu);
+void tipc_link_push_queue(struct link *l_ptr);
+u32 tipc_link_defer_pkt(struct sk_buff **head, struct sk_buff **tail,
 		   struct sk_buff *buf);
-void link_wakeup_ports(struct link *l_ptr, int all);
-void link_set_queue_limits(struct link *l_ptr, u32 window);
-void link_retransmit(struct link *l_ptr, struct sk_buff *start, u32 retransmits);
+void tipc_link_wakeup_ports(struct link *l_ptr, int all);
+void tipc_link_set_queue_limits(struct link *l_ptr, u32 window);
+void tipc_link_retransmit(struct link *l_ptr, struct sk_buff *start, u32 retransmits);
 
 /*
  * Link sequence number manipulation routines (uses modulo 2**16 arithmetic)
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 03dbc55..3bd345a 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -41,18 +41,7 @@
 #include "bearer.h"
 
 
-void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr *a)
-{
-	memcpy(&((int *)m)[5], a, sizeof(*a));
-}
-
-void msg_get_media_addr(struct tipc_msg *m, struct tipc_media_addr *a)
-{
-	memcpy(a, &((int*)m)[5], sizeof(*a));
-}
-
-
-void msg_print(struct print_buf *buf, struct tipc_msg *msg, const char *str)
+void tipc_msg_print(struct print_buf *buf, struct tipc_msg *msg, const char *str)
 {
 	u32 usr = msg_user(msg);
 	tipc_printf(buf, str);
@@ -318,7 +307,7 @@ void msg_print(struct print_buf *buf, st
 		tipc_printf(buf, ":REQL(%u):", msg_req_links(msg));
 		tipc_printf(buf, ":DDOM(%x):", msg_dest_domain(msg));
 		tipc_printf(buf, ":NETID(%u):", msg_bc_netid(msg));
-		media_addr_printf(buf, orig);
+		tipc_media_addr_printf(buf, orig);
 	}
 	if (msg_user(msg) == BCAST_PROTOCOL) {
 		tipc_printf(buf, "BCNACK:AFTER(%u):", msg_bcgap_after(msg));
@@ -326,9 +315,9 @@ void msg_print(struct print_buf *buf, st
 	}
 	tipc_printf(buf, "\n");
 	if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg))) {
-		msg_print(buf,msg_get_wrapped(msg),"      /");
+		tipc_msg_print(buf,msg_get_wrapped(msg),"      /");
 	}
 	if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT)) {
-		msg_print(buf,msg_get_wrapped(msg),"      /");
+		tipc_msg_print(buf,msg_get_wrapped(msg),"      /");
 	}
 }
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 662c818..6699aaf 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -37,7 +37,7 @@
 #ifndef _TIPC_MSG_H
 #define _TIPC_MSG_H
 
-#include <net/tipc/tipc_msg.h>
+#include "core.h"
 
 #define TIPC_VERSION              2
 #define DATA_LOW                  TIPC_LOW_IMPORTANCE
@@ -805,14 +805,14 @@ static inline int msg_build(struct tipc_
 	return -EFAULT;
 }
 
+static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr *a)
+{
+	memcpy(&((int *)m)[5], a, sizeof(*a));
+}
 
-struct tipc_media_addr;
-
-extern void msg_set_media_addr(struct tipc_msg *m,
-			       struct tipc_media_addr *a);
-
-extern void msg_get_media_addr(struct tipc_msg *m,
-			       struct tipc_media_addr *a);
-
+static inline void msg_get_media_addr(struct tipc_msg *m, struct tipc_media_addr *a)
+{
+	memcpy(a, &((int*)m)[5], sizeof(*a));
+}
 
 #endif
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index 41cbaf1..830f909 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -114,10 +114,10 @@ static struct sk_buff *named_prepare_buf
 }
 
 /**
- * named_publish - tell other nodes about a new publication by this node
+ * tipc_named_publish - tell other nodes about a new publication by this node
  */
 
-void named_publish(struct publication *publ)
+void tipc_named_publish(struct publication *publ)
 {
 	struct sk_buff *buf;
 	struct distr_item *item;
@@ -133,15 +133,15 @@ void named_publish(struct publication *p
 
 	item = (struct distr_item *)msg_data(buf_msg(buf));
 	publ_to_item(item, publ);
-	dbg("named_withdraw: broadcasting publish msg\n");
-	cluster_broadcast(buf);
+	dbg("tipc_named_withdraw: broadcasting publish msg\n");
+	tipc_cltr_broadcast(buf);
 }
 
 /**
- * named_withdraw - tell other nodes about a withdrawn publication by this node
+ * tipc_named_withdraw - tell other nodes about a withdrawn publication by this node
  */
 
-void named_withdraw(struct publication *publ)
+void tipc_named_withdraw(struct publication *publ)
 {
 	struct sk_buff *buf;
 	struct distr_item *item;
@@ -157,15 +157,15 @@ void named_withdraw(struct publication *
 
 	item = (struct distr_item *)msg_data(buf_msg(buf));
 	publ_to_item(item, publ);
-	dbg("named_withdraw: broadcasting withdraw msg\n");
-	cluster_broadcast(buf);
+	dbg("tipc_named_withdraw: broadcasting withdraw msg\n");
+	tipc_cltr_broadcast(buf);
 }
 
 /**
- * named_node_up - tell specified node about all publications by this node
+ * tipc_named_node_up - tell specified node about all publications by this node
  */
 
-void named_node_up(unsigned long node)
+void tipc_named_node_up(unsigned long node)
 {
 	struct publication *publ;
 	struct distr_item *item = 0;
@@ -175,7 +175,7 @@ void named_node_up(unsigned long node)
 	u32 max_item_buf;
 
 	assert(in_own_cluster(node));
-	read_lock_bh(&nametbl_lock); 
+	read_lock_bh(&tipc_nametbl_lock); 
 	max_item_buf = TIPC_MAX_USER_MSG_SIZE / ITEM_SIZE;
 	max_item_buf *= ITEM_SIZE;
 	rest = publ_cnt * ITEM_SIZE;
@@ -196,15 +196,15 @@ void named_node_up(unsigned long node)
 		left -= ITEM_SIZE;
 		if (!left) {
 			msg_set_link_selector(buf_msg(buf), node);
-			dbg("named_node_up: sending publish msg to "
+			dbg("tipc_named_node_up: sending publish msg to "
 			    "<%u.%u.%u>\n", tipc_zone(node), 
 			    tipc_cluster(node), tipc_node(node));
-			link_send(buf, node, node);
+			tipc_link_send(buf, node, node);
 			buf = 0;
 		}
 	}
 exit:
-	read_unlock_bh(&nametbl_lock); 
+	read_unlock_bh(&tipc_nametbl_lock); 
 }
 
 /**
@@ -221,73 +221,73 @@ exit:
 static void node_is_down(struct publication *publ)
 {
 	struct publication *p;
-        write_lock_bh(&nametbl_lock);
+        write_lock_bh(&tipc_nametbl_lock);
 	dbg("node_is_down: withdrawing %u, %u, %u\n", 
 	    publ->type, publ->lower, publ->upper);
         publ->key += 1222345;
-	p = nametbl_remove_publ(publ->type, publ->lower, 
-				publ->node, publ->ref, publ->key);
+	p = tipc_nametbl_remove_publ(publ->type, publ->lower, 
+				     publ->node, publ->ref, publ->key);
         assert(p == publ);
-	write_unlock_bh(&nametbl_lock);
+	write_unlock_bh(&tipc_nametbl_lock);
 	if (publ)
 		kfree(publ);
 }
 
 /**
- * named_recv - process name table update message sent by another node
+ * tipc_named_recv - process name table update message sent by another node
  */
 
-void named_recv(struct sk_buff *buf)
+void tipc_named_recv(struct sk_buff *buf)
 {
 	struct publication *publ;
 	struct tipc_msg *msg = buf_msg(buf);
 	struct distr_item *item = (struct distr_item *)msg_data(msg);
 	u32 count = msg_data_sz(msg) / ITEM_SIZE;
 
-	write_lock_bh(&nametbl_lock); 
+	write_lock_bh(&tipc_nametbl_lock); 
 	while (count--) {
 		if (msg_type(msg) == PUBLICATION) {
-			dbg("named_recv: got publication for %u, %u, %u\n", 
+			dbg("tipc_named_recv: got publication for %u, %u, %u\n", 
 			    ntohl(item->type), ntohl(item->lower),
 			    ntohl(item->upper));
-			publ = nametbl_insert_publ(ntohl(item->type), 
-						   ntohl(item->lower),
-						   ntohl(item->upper),
-						   TIPC_CLUSTER_SCOPE,
-						   msg_orignode(msg), 
-						   ntohl(item->ref),
-						   ntohl(item->key));
+			publ = tipc_nametbl_insert_publ(ntohl(item->type), 
+							ntohl(item->lower),
+							ntohl(item->upper),
+							TIPC_CLUSTER_SCOPE,
+							msg_orignode(msg), 
+							ntohl(item->ref),
+							ntohl(item->key));
 			if (publ) {
-				nodesub_subscribe(&publ->subscr, 
-						  msg_orignode(msg), 
-						  publ,
-						  (net_ev_handler)node_is_down);
+				tipc_nodesub_subscribe(&publ->subscr, 
+						       msg_orignode(msg), 
+						       publ,
+						       (net_ev_handler)node_is_down);
 			}
 		} else if (msg_type(msg) == WITHDRAWAL) {
-			dbg("named_recv: got withdrawl for %u, %u, %u\n", 
+			dbg("tipc_named_recv: got withdrawl for %u, %u, %u\n", 
 			    ntohl(item->type), ntohl(item->lower),
 			    ntohl(item->upper));
-			publ = nametbl_remove_publ(ntohl(item->type),
-						   ntohl(item->lower),
-						   msg_orignode(msg),
-						   ntohl(item->ref),
-						   ntohl(item->key));
+			publ = tipc_nametbl_remove_publ(ntohl(item->type),
+							ntohl(item->lower),
+							msg_orignode(msg),
+							ntohl(item->ref),
+							ntohl(item->key));
 
 			if (publ) {
-				nodesub_unsubscribe(&publ->subscr);
+				tipc_nodesub_unsubscribe(&publ->subscr);
         			kfree(publ);
 			}
 		} else {
-			warn("named_recv: unknown msg\n");
+			warn("tipc_named_recv: unknown msg\n");
 		}
 		item++;
 	}
-	write_unlock_bh(&nametbl_lock); 
+	write_unlock_bh(&tipc_nametbl_lock); 
 	buf_discard(buf);
 }
 
 /**
- * named_reinit - re-initialize local publication list
+ * tipc_named_reinit - re-initialize local publication list
  * 
  * This routine is called whenever TIPC networking is (re)enabled.
  * All existing publications by this node that have "cluster" or "zone" scope
@@ -295,15 +295,15 @@ void named_recv(struct sk_buff *buf)
  * (If the node's address is unchanged, the update loop terminates immediately.)
  */
 
-void named_reinit(void)
+void tipc_named_reinit(void)
 {
 	struct publication *publ;
 
-	write_lock_bh(&nametbl_lock); 
+	write_lock_bh(&tipc_nametbl_lock); 
 	list_for_each_entry(publ, &publ_root, local_list) {
 		if (publ->node == tipc_own_addr)
 			break;
 		publ->node = tipc_own_addr;
 	}
-	write_unlock_bh(&nametbl_lock); 
+	write_unlock_bh(&tipc_nametbl_lock); 
 }
diff --git a/net/tipc/name_distr.h b/net/tipc/name_distr.h
index a04bdea..843da01 100644
--- a/net/tipc/name_distr.h
+++ b/net/tipc/name_distr.h
@@ -39,10 +39,10 @@
 
 #include "name_table.h"
 
-void named_publish(struct publication *publ);
-void named_withdraw(struct publication *publ);
-void named_node_up(unsigned long node);
-void named_recv(struct sk_buff *buf);
-void named_reinit(void);
+void tipc_named_publish(struct publication *publ);
+void tipc_named_withdraw(struct publication *publ);
+void tipc_named_node_up(unsigned long node);
+void tipc_named_recv(struct sk_buff *buf);
+void tipc_named_reinit(void);
 
 #endif
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 972c83e..3f4b23b 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -99,9 +99,9 @@ struct name_table {
 	u32 local_publ_count;
 };
 
-struct name_table table = { NULL } ;
+static struct name_table table = { NULL } ;
 static atomic_t rsv_publ_ok = ATOMIC_INIT(0);
-rwlock_t nametbl_lock = RW_LOCK_UNLOCKED;
+rwlock_t tipc_nametbl_lock = RW_LOCK_UNLOCKED;
 
 
 static inline int hash(int x)
@@ -139,10 +139,10 @@ static struct publication *publ_create(u
 }
 
 /**
- * subseq_alloc - allocate a specified number of sub-sequence structures
+ * tipc_subseq_alloc - allocate a specified number of sub-sequence structures
  */
 
-struct sub_seq *subseq_alloc(u32 cnt)
+struct sub_seq *tipc_subseq_alloc(u32 cnt)
 {
 	u32 sz = cnt * sizeof(struct sub_seq);
 	struct sub_seq *sseq = (struct sub_seq *)kmalloc(sz, GFP_ATOMIC);
@@ -153,16 +153,16 @@ struct sub_seq *subseq_alloc(u32 cnt)
 }
 
 /**
- * nameseq_create - create a name sequence structure for the specified 'type'
+ * tipc_nameseq_create - create a name sequence structure for the specified 'type'
  * 
  * Allocates a single sub-sequence structure and sets it to all 0's.
  */
 
-struct name_seq *nameseq_create(u32 type, struct hlist_head *seq_head)
+struct name_seq *tipc_nameseq_create(u32 type, struct hlist_head *seq_head)
 {
 	struct name_seq *nseq = 
 		(struct name_seq *)kmalloc(sizeof(*nseq), GFP_ATOMIC);
-	struct sub_seq *sseq = subseq_alloc(1);
+	struct sub_seq *sseq = tipc_subseq_alloc(1);
 
 	if (!nseq || !sseq) {
 		warn("Memory squeeze; failed to create name sequence\n");
@@ -175,7 +175,7 @@ struct name_seq *nameseq_create(u32 type
 	nseq->lock = SPIN_LOCK_UNLOCKED;
 	nseq->type = type;
 	nseq->sseqs = sseq;
-	dbg("nameseq_create() nseq = %x type %u, ssseqs %x, ff: %u\n",
+	dbg("tipc_nameseq_create() nseq = %x type %u, ssseqs %x, ff: %u\n",
 	    nseq, type, nseq->sseqs, nseq->first_free);
 	nseq->alloc = 1;
 	INIT_HLIST_NODE(&nseq->ns_list);
@@ -240,10 +240,10 @@ static u32 nameseq_locate_subseq(struct 
 }
 
 /**
- * nameseq_insert_publ - 
+ * tipc_nameseq_insert_publ - 
  */
 
-struct publication *nameseq_insert_publ(struct name_seq *nseq,
+struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
 					u32 type, u32 lower, u32 upper,
 					u32 scope, u32 node, u32 port, u32 key)
 {
@@ -285,7 +285,7 @@ struct publication *nameseq_insert_publ(
 
 		if (nseq->first_free == nseq->alloc) {
 			struct sub_seq *sseqs = nseq->sseqs;
-			nseq->sseqs = subseq_alloc(nseq->alloc * 2);
+			nseq->sseqs = tipc_subseq_alloc(nseq->alloc * 2);
 			if (nseq->sseqs != NULL) {
 				memcpy(nseq->sseqs, sseqs,
 				       nseq->alloc * sizeof (struct sub_seq));
@@ -354,23 +354,23 @@ struct publication *nameseq_insert_publ(
 	 */
 	list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) {
 		dbg("calling report_overlap()\n");
-		subscr_report_overlap(s,
-				      publ->lower,
-				      publ->upper,
-				      TIPC_PUBLISHED,
-				      publ->ref, 
-				      publ->node,
-				      created_subseq);
+		tipc_subscr_report_overlap(s,
+					   publ->lower,
+					   publ->upper,
+					   TIPC_PUBLISHED,
+					   publ->ref, 
+					   publ->node,
+					   created_subseq);
 	}
 	return publ;
 }
 
 /**
- * nameseq_remove_publ -
+ * tipc_nameseq_remove_publ -
  */
 
-struct publication *nameseq_remove_publ(struct name_seq *nseq, u32 inst,
-					u32 node, u32 ref, u32 key)
+struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 inst,
+					     u32 node, u32 ref, u32 key)
 {
 	struct publication *publ;
 	struct publication *prev;
@@ -470,24 +470,24 @@ struct publication *nameseq_remove_publ(
 	 * Any subscriptions waiting ? 
 	 */
 	list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) {
-		subscr_report_overlap(s,
-				      publ->lower,
-				      publ->upper,
-				      TIPC_WITHDRAWN, 
-				      publ->ref, 
-				      publ->node,
-				      removed_subseq);
+		tipc_subscr_report_overlap(s,
+					   publ->lower,
+					   publ->upper,
+					   TIPC_WITHDRAWN, 
+					   publ->ref, 
+					   publ->node,
+					   removed_subseq);
 	}
 	return publ;
 }
 
 /**
- * nameseq_subscribe: attach a subscription, and issue
+ * tipc_nameseq_subscribe: attach a subscription, and issue
  * the prescribed number of events if there is any sub-
  * sequence overlapping with the requested sequence
  */
 
-void nameseq_subscribe(struct name_seq *nseq, struct subscription *s)
+void tipc_nameseq_subscribe(struct name_seq *nseq, struct subscription *s)
 {
 	struct sub_seq *sseq = nseq->sseqs;
 
@@ -498,18 +498,18 @@ void nameseq_subscribe(struct name_seq *
 
 	while (sseq != &nseq->sseqs[nseq->first_free]) {
 		struct publication *zl = sseq->zone_list;
-		if (zl && subscr_overlap(s,sseq->lower,sseq->upper)) {
+		if (zl && tipc_subscr_overlap(s,sseq->lower,sseq->upper)) {
 			struct publication *crs = zl;
 			int must_report = 1;
 
 			do {
-				subscr_report_overlap(s, 
-						       sseq->lower, 
-						       sseq->upper,
-						       TIPC_PUBLISHED,
-						       crs->ref,
-						       crs->node,
-						       must_report);
+				tipc_subscr_report_overlap(s, 
+							   sseq->lower, 
+							   sseq->upper,
+							   TIPC_PUBLISHED,
+							   crs->ref,
+							   crs->node,
+							   must_report);
 				must_report = 0;
 				crs = crs->zone_list_next;
 			} while (crs != zl);
@@ -538,8 +538,8 @@ static struct name_seq *nametbl_find_seq
 	return 0;
 };
 
-struct publication *nametbl_insert_publ(u32 type, u32 lower, u32 upper,
-		    u32 scope, u32 node, u32 port, u32 key)
+struct publication *tipc_nametbl_insert_publ(u32 type, u32 lower, u32 upper,
+					     u32 scope, u32 node, u32 port, u32 key)
 {
 	struct name_seq *seq = nametbl_find_seq(type);
 
@@ -552,19 +552,19 @@ struct publication *nametbl_insert_publ(
 
 	dbg("Publishing <%u,%u,%u> from %x\n", type, lower, upper, node);
 	if (!seq) {
-		seq = nameseq_create(type, &table.types[hash(type)]);
-		dbg("nametbl_insert_publ: created %x\n", seq);
+		seq = tipc_nameseq_create(type, &table.types[hash(type)]);
+		dbg("tipc_nametbl_insert_publ: created %x\n", seq);
 	}
 	if (!seq)
 		return 0;
 
 	assert(seq->type == type);
-	return nameseq_insert_publ(seq, type, lower, upper,
-				   scope, node, port, key);
+	return tipc_nameseq_insert_publ(seq, type, lower, upper,
+					scope, node, port, key);
 }
 
-struct publication *nametbl_remove_publ(u32 type, u32 lower, 
-					u32 node, u32 ref, u32 key)
+struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower, 
+					     u32 node, u32 ref, u32 key)
 {
 	struct publication *publ;
 	struct name_seq *seq = nametbl_find_seq(type);
@@ -573,7 +573,7 @@ struct publication *nametbl_remove_publ(
 		return 0;
 
 	dbg("Withdrawing <%u,%u> from %x\n", type, lower, node);
-	publ = nameseq_remove_publ(seq, lower, node, ref, key);
+	publ = tipc_nameseq_remove_publ(seq, lower, node, ref, key);
 
 	if (!seq->first_free && list_empty(&seq->subscriptions)) {
 		hlist_del_init(&seq->ns_list);
@@ -584,14 +584,14 @@ struct publication *nametbl_remove_publ(
 }
 
 /*
- * nametbl_translate(): Translate tipc_name -> tipc_portid.
+ * tipc_nametbl_translate(): Translate tipc_name -> tipc_portid.
  *                      Very time-critical.
  *
  * Note: on entry 'destnode' is the search domain used during translation;
  *       on exit it passes back the node address of the matching port (if any)
  */
 
-u32 nametbl_translate(u32 type, u32 instance, u32 *destnode)
+u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode)
 {
 	struct sub_seq *sseq;
 	struct publication *publ = 0;
@@ -601,7 +601,7 @@ u32 nametbl_translate(u32 type, u32 inst
 	if (!in_scope(*destnode, tipc_own_addr))
 		return 0;
 
-	read_lock_bh(&nametbl_lock);
+	read_lock_bh(&tipc_nametbl_lock);
 	seq = nametbl_find_seq(type);
 	if (unlikely(!seq))
 		goto not_found;
@@ -619,7 +619,7 @@ found:
 			ref = publ->ref;
 			*destnode = publ->node;
 			spin_unlock_bh(&seq->lock);
-			read_unlock_bh(&nametbl_lock);
+			read_unlock_bh(&tipc_nametbl_lock);
 			return ref;
 		}
 		publ = sseq->cluster_list;
@@ -657,12 +657,12 @@ found:
 	spin_unlock_bh(&seq->lock);
 not_found:
 	*destnode = 0;
-	read_unlock_bh(&nametbl_lock);
+	read_unlock_bh(&tipc_nametbl_lock);
 	return 0;
 }
 
 /**
- * nametbl_mc_translate - find multicast destinations
+ * tipc_nametbl_mc_translate - find multicast destinations
  * 
  * Creates list of all local ports that overlap the given multicast address;
  * also determines if any off-node ports overlap.
@@ -674,15 +674,15 @@ not_found:
  * Returns non-zero if any off-node ports overlap
  */
 
-int nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit,
-			 struct port_list *dports)
+int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit,
+			      struct port_list *dports)
 {
 	struct name_seq *seq;
 	struct sub_seq *sseq;
 	struct sub_seq *sseq_stop;
 	int res = 0;
 
-	read_lock_bh(&nametbl_lock);
+	read_lock_bh(&tipc_nametbl_lock);
 	seq = nametbl_find_seq(type);
 	if (!seq)
 		goto exit;
@@ -700,7 +700,7 @@ int nametbl_mc_translate(u32 type, u32 l
 		if (publ && (publ->scope <= limit))
 			do {
 				if (publ->node == tipc_own_addr)
-					port_list_add(dports, publ->ref);
+					tipc_port_list_add(dports, publ->ref);
 				else
 					res = 1;
 				publ = publ->cluster_list_next;
@@ -709,15 +709,15 @@ int nametbl_mc_translate(u32 type, u32 l
 
 	spin_unlock_bh(&seq->lock);
 exit:
-	read_unlock_bh(&nametbl_lock);
+	read_unlock_bh(&tipc_nametbl_lock);
 	return res;
 }
 
 /**
- * nametbl_publish_rsv - publish port name using a reserved name type
+ * tipc_nametbl_publish_rsv - publish port name using a reserved name type
  */
 
-int nametbl_publish_rsv(u32 ref, unsigned int scope, 
+int tipc_nametbl_publish_rsv(u32 ref, unsigned int scope, 
 			struct tipc_name_seq const *seq)
 {
 	int res;
@@ -729,10 +729,10 @@ int nametbl_publish_rsv(u32 ref, unsigne
 }
 
 /**
- * nametbl_publish - add name publication to network name tables
+ * tipc_nametbl_publish - add name publication to network name tables
  */
 
-struct publication *nametbl_publish(u32 type, u32 lower, u32 upper, 
+struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper, 
 				    u32 scope, u32 port_ref, u32 key)
 {
 	struct publication *publ;
@@ -748,77 +748,77 @@ struct publication *nametbl_publish(u32 
 		return 0;
 	}
 
-	write_lock_bh(&nametbl_lock);
+	write_lock_bh(&tipc_nametbl_lock);
 	table.local_publ_count++;
-	publ = nametbl_insert_publ(type, lower, upper, scope,
+	publ = tipc_nametbl_insert_publ(type, lower, upper, scope,
 				   tipc_own_addr, port_ref, key);
 	if (publ && (scope != TIPC_NODE_SCOPE)) {
-		named_publish(publ);
+		tipc_named_publish(publ);
 	}
-	write_unlock_bh(&nametbl_lock);
+	write_unlock_bh(&tipc_nametbl_lock);
 	return publ;
 }
 
 /**
- * nametbl_withdraw - withdraw name publication from network name tables
+ * tipc_nametbl_withdraw - withdraw name publication from network name tables
  */
 
-int nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key)
+int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key)
 {
 	struct publication *publ;
 
-	dbg("nametbl_withdraw:<%d,%d,%d>\n", type, lower, key);
-	write_lock_bh(&nametbl_lock);
-	publ = nametbl_remove_publ(type, lower, tipc_own_addr, ref, key);
+	dbg("tipc_nametbl_withdraw:<%d,%d,%d>\n", type, lower, key);
+	write_lock_bh(&tipc_nametbl_lock);
+	publ = tipc_nametbl_remove_publ(type, lower, tipc_own_addr, ref, key);
 	if (publ) {
 		table.local_publ_count--;
 		if (publ->scope != TIPC_NODE_SCOPE)
-			named_withdraw(publ);
-		write_unlock_bh(&nametbl_lock);
+			tipc_named_withdraw(publ);
+		write_unlock_bh(&tipc_nametbl_lock);
 		list_del_init(&publ->pport_list);
 		kfree(publ);
 		return 1;
 	}
-	write_unlock_bh(&nametbl_lock);
+	write_unlock_bh(&tipc_nametbl_lock);
 	return 0;
 }
 
 /**
- * nametbl_subscribe - add a subscription object to the name table
+ * tipc_nametbl_subscribe - add a subscription object to the name table
  */
 
 void
-nametbl_subscribe(struct subscription *s)
+tipc_nametbl_subscribe(struct subscription *s)
 {
 	u32 type = s->seq.type;
 	struct name_seq *seq;
 
-        write_lock_bh(&nametbl_lock);
+        write_lock_bh(&tipc_nametbl_lock);
 	seq = nametbl_find_seq(type);
 	if (!seq) {
-		seq = nameseq_create(type, &table.types[hash(type)]);
+		seq = tipc_nameseq_create(type, &table.types[hash(type)]);
 	}
         if (seq){
                 spin_lock_bh(&seq->lock);
-                dbg("nametbl_subscribe:found %x for <%u,%u,%u>\n",
+                dbg("tipc_nametbl_subscribe:found %x for <%u,%u,%u>\n",
                     seq, type, s->seq.lower, s->seq.upper);
                 assert(seq->type == type);
-                nameseq_subscribe(seq, s);
+                tipc_nameseq_subscribe(seq, s);
                 spin_unlock_bh(&seq->lock);
         }
-        write_unlock_bh(&nametbl_lock);
+        write_unlock_bh(&tipc_nametbl_lock);
 }
 
 /**
- * nametbl_unsubscribe - remove a subscription object from name table
+ * tipc_nametbl_unsubscribe - remove a subscription object from name table
  */
 
 void
-nametbl_unsubscribe(struct subscription *s)
+tipc_nametbl_unsubscribe(struct subscription *s)
 {
 	struct name_seq *seq;
 
-        write_lock_bh(&nametbl_lock);
+        write_lock_bh(&tipc_nametbl_lock);
         seq = nametbl_find_seq(s->seq.type);
 	if (seq != NULL){
                 spin_lock_bh(&seq->lock);
@@ -830,7 +830,7 @@ nametbl_unsubscribe(struct subscription 
                         kfree(seq);
                 }
         }
-        write_unlock_bh(&nametbl_lock);
+        write_unlock_bh(&tipc_nametbl_lock);
 }
 
 
@@ -983,17 +983,17 @@ static void nametbl_list(struct print_bu
 	}
 }
 
-void nametbl_print(struct print_buf *buf, const char *str)
+void tipc_nametbl_print(struct print_buf *buf, const char *str)
 {
 	tipc_printf(buf, str);
-	read_lock_bh(&nametbl_lock);
+	read_lock_bh(&tipc_nametbl_lock);
 	nametbl_list(buf, 0, 0, 0, 0);
-	read_unlock_bh(&nametbl_lock);
+	read_unlock_bh(&tipc_nametbl_lock);
 }
 
 #define MAX_NAME_TBL_QUERY 32768
 
-struct sk_buff *nametbl_get(const void *req_tlv_area, int req_tlv_space)
+struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space)
 {
 	struct sk_buff *buf;
 	struct tipc_name_table_query *argv;
@@ -1002,20 +1002,20 @@ struct sk_buff *nametbl_get(const void *
 	int str_len;
 
 	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NAME_TBL_QUERY))
-		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
+		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
 
-	buf = cfg_reply_alloc(TLV_SPACE(MAX_NAME_TBL_QUERY));
+	buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_NAME_TBL_QUERY));
 	if (!buf)
 		return NULL;
 
 	rep_tlv = (struct tlv_desc *)buf->data;
-	printbuf_init(&b, TLV_DATA(rep_tlv), MAX_NAME_TBL_QUERY);
+	tipc_printbuf_init(&b, TLV_DATA(rep_tlv), MAX_NAME_TBL_QUERY);
 	argv = (struct tipc_name_table_query *)TLV_DATA(req_tlv_area);
-	read_lock_bh(&nametbl_lock);
+	read_lock_bh(&tipc_nametbl_lock);
 	nametbl_list(&b, ntohl(argv->depth), ntohl(argv->type), 
 		     ntohl(argv->lowbound), ntohl(argv->upbound));
-	read_unlock_bh(&nametbl_lock);
-	str_len = printbuf_validate(&b);
+	read_unlock_bh(&tipc_nametbl_lock);
+	str_len = tipc_printbuf_validate(&b);
 
 	skb_put(buf, TLV_SPACE(str_len));
 	TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
@@ -1023,12 +1023,12 @@ struct sk_buff *nametbl_get(const void *
 	return buf;
 }
 
-void nametbl_dump(void)
+void tipc_nametbl_dump(void)
 {
-	nametbl_list(CONS, 0, 0, 0, 0);
+	nametbl_list(TIPC_CONS, 0, 0, 0, 0);
 }
 
-int nametbl_init(void)
+int tipc_nametbl_init(void)
 {
 	int array_size = sizeof(struct hlist_head) * tipc_nametbl_size;
 
@@ -1036,14 +1036,14 @@ int nametbl_init(void)
 	if (!table.types)
 		return -ENOMEM;
 
-	write_lock_bh(&nametbl_lock);
+	write_lock_bh(&tipc_nametbl_lock);
 	memset(table.types, 0, array_size);
 	table.local_publ_count = 0;
-	write_unlock_bh(&nametbl_lock);
+	write_unlock_bh(&tipc_nametbl_lock);
 	return 0;
 }
 
-void nametbl_stop(void)
+void tipc_nametbl_stop(void)
 {
 	struct hlist_head *seq_head;
 	struct hlist_node *seq_node;
@@ -1054,7 +1054,7 @@ void nametbl_stop(void)
 	if (!table.types)
 		return;
 
-	write_lock_bh(&nametbl_lock);
+	write_lock_bh(&tipc_nametbl_lock);
 	for (i = 0; i < tipc_nametbl_size; i++) {
 		seq_head = &table.types[i];
 		hlist_for_each_entry_safe(seq, seq_node, tmp, seq_head, ns_list) {
@@ -1075,5 +1075,5 @@ void nametbl_stop(void)
 	}
 	kfree(table.types);
 	table.types = NULL;
-	write_unlock_bh(&nametbl_lock);
+	write_unlock_bh(&tipc_nametbl_lock);
 }
diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h
index f826933..e8a3d71 100644
--- a/net/tipc/name_table.h
+++ b/net/tipc/name_table.h
@@ -85,24 +85,24 @@ struct publication {
 };
 
 
-extern rwlock_t nametbl_lock;
+extern rwlock_t tipc_nametbl_lock;
 
-struct sk_buff *nametbl_get(const void *req_tlv_area, int req_tlv_space);
-u32 nametbl_translate(u32 type, u32 instance, u32 *node);
-int nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit, 
+struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space);
+u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *node);
+int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit, 
 			 struct port_list *dports);
-int nametbl_publish_rsv(u32 ref, unsigned int scope, 
+int tipc_nametbl_publish_rsv(u32 ref, unsigned int scope, 
 			struct tipc_name_seq const *seq);
-struct publication *nametbl_publish(u32 type, u32 lower, u32 upper,
+struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper,
 				    u32 scope, u32 port_ref, u32 key);
-int nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key);
-struct publication *nametbl_insert_publ(u32 type, u32 lower, u32 upper,
+int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key);
+struct publication *tipc_nametbl_insert_publ(u32 type, u32 lower, u32 upper,
 					u32 scope, u32 node, u32 ref, u32 key);
-struct publication *nametbl_remove_publ(u32 type, u32 lower, 
+struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower, 
 					u32 node, u32 ref, u32 key);
-void nametbl_subscribe(struct subscription *s);
-void nametbl_unsubscribe(struct subscription *s);
-int nametbl_init(void);
-void nametbl_stop(void);
+void tipc_nametbl_subscribe(struct subscription *s);
+void tipc_nametbl_unsubscribe(struct subscription *s);
+int tipc_nametbl_init(void);
+void tipc_nametbl_stop(void);
 
 #endif
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 6826b49..074891a 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -58,25 +58,25 @@
  * 1: The routing hierarchy.
  *    Comprises the structures 'zone', 'cluster', 'node', 'link' 
  *    and 'bearer'. The whole hierarchy is protected by a big 
- *    read/write lock, net_lock, to enssure that nothing is added 
+ *    read/write lock, tipc_net_lock, to enssure that nothing is added 
  *    or removed while code is accessing any of these structures. 
  *    This layer must not be called from the two others while they 
  *    hold any of their own locks.
  *    Neither must it itself do any upcalls to the other two before
- *    it has released net_lock and other protective locks.
+ *    it has released tipc_net_lock and other protective locks.
  *
- *   Within the net_lock domain there are two sub-domains;'node' and 
+ *   Within the tipc_net_lock domain there are two sub-domains;'node' and 
  *   'bearer', where local write operations are permitted,
  *   provided that those are protected by individual spin_locks
- *   per instance. Code holding net_lock(read) and a node spin_lock 
+ *   per instance. Code holding tipc_net_lock(read) and a node spin_lock 
  *   is permitted to poke around in both the node itself and its
  *   subordinate links. I.e, it can update link counters and queues, 
  *   change link state, send protocol messages, and alter the 
  *   "active_links" array in the node; but it can _not_ remove a link 
  *   or a node from the overall structure.
  *   Correspondingly, individual bearers may change status within a 
- *   net_lock(read), protected by an individual spin_lock ber bearer 
- *   instance, but it needs net_lock(write) to remove/add any bearers.
+ *   tipc_net_lock(read), protected by an individual spin_lock ber bearer 
+ *   instance, but it needs tipc_net_lock(write) to remove/add any bearers.
  *     
  *
  *  2: The transport level of the protocol. 
@@ -97,91 +97,91 @@
  *       (Nobody is using read-only access to this, so it can just as 
  *       well be changed to a spin_lock)
  *     - A spin lock to protect the registry of kernel/driver users (reg.c)
- *     - A global spin_lock (port_lock), which only task is to ensure 
+ *     - A global spin_lock (tipc_port_lock), which only task is to ensure 
  *       consistency where more than one port is involved in an operation,
  *       i.e., whe a port is part of a linked list of ports.
  *       There are two such lists; 'port_list', which is used for management,
  *       and 'wait_list', which is used to queue ports during congestion.
  *     
  *  3: The name table (name_table.c, name_distr.c, subscription.c)
- *     - There is one big read/write-lock (nametbl_lock) protecting the 
+ *     - There is one big read/write-lock (tipc_nametbl_lock) protecting the 
  *       overall name table structure. Nothing must be added/removed to 
  *       this structure without holding write access to it.
  *     - There is one local spin_lock per sub_sequence, which can be seen
- *       as a sub-domain to the nametbl_lock domain. It is used only
+ *       as a sub-domain to the tipc_nametbl_lock domain. It is used only
  *       for translation operations, and is needed because a translation
  *       steps the root of the 'publication' linked list between each lookup.
- *       This is always used within the scope of a nametbl_lock(read).
+ *       This is always used within the scope of a tipc_nametbl_lock(read).
  *     - A local spin_lock protecting the queue of subscriber events.
 */
 
-rwlock_t net_lock = RW_LOCK_UNLOCKED;
-struct network net = { 0 };
+rwlock_t tipc_net_lock = RW_LOCK_UNLOCKED;
+struct network tipc_net = { 0 };
 
-struct node *net_select_remote_node(u32 addr, u32 ref) 
+struct node *tipc_net_select_remote_node(u32 addr, u32 ref) 
 {
-	return zone_select_remote_node(net.zones[tipc_zone(addr)], addr, ref);
+	return tipc_zone_select_remote_node(tipc_net.zones[tipc_zone(addr)], addr, ref);
 }
 
-u32 net_select_router(u32 addr, u32 ref)
+u32 tipc_net_select_router(u32 addr, u32 ref)
 {
-	return zone_select_router(net.zones[tipc_zone(addr)], addr, ref);
+	return tipc_zone_select_router(tipc_net.zones[tipc_zone(addr)], addr, ref);
 }
 
 
-u32 net_next_node(u32 a)
+u32 tipc_net_next_node(u32 a)
 {
-	if (net.zones[tipc_zone(a)])
-		return zone_next_node(a);
+	if (tipc_net.zones[tipc_zone(a)])
+		return tipc_zone_next_node(a);
 	return 0;
 }
 
-void net_remove_as_router(u32 router)
+void tipc_net_remove_as_router(u32 router)
 {
 	u32 z_num;
 
 	for (z_num = 1; z_num <= tipc_max_zones; z_num++) {
-		if (!net.zones[z_num])
+		if (!tipc_net.zones[z_num])
 			continue;
-		zone_remove_as_router(net.zones[z_num], router);
+		tipc_zone_remove_as_router(tipc_net.zones[z_num], router);
 	}
 }
 
-void net_send_external_routes(u32 dest)
+void tipc_net_send_external_routes(u32 dest)
 {
 	u32 z_num;
 
 	for (z_num = 1; z_num <= tipc_max_zones; z_num++) {
-		if (net.zones[z_num])
-			zone_send_external_routes(net.zones[z_num], dest);
+		if (tipc_net.zones[z_num])
+			tipc_zone_send_external_routes(tipc_net.zones[z_num], dest);
 	}
 }
 
-int net_init(void)
+static int net_init(void)
 {
 	u32 sz = sizeof(struct _zone *) * (tipc_max_zones + 1);
 
-	memset(&net, 0, sizeof(net));
-	net.zones = (struct _zone **)kmalloc(sz, GFP_ATOMIC);
-	if (!net.zones) {
+	memset(&tipc_net, 0, sizeof(tipc_net));
+	tipc_net.zones = (struct _zone **)kmalloc(sz, GFP_ATOMIC);
+	if (!tipc_net.zones) {
 		return -ENOMEM;
 	}
-	memset(net.zones, 0, sz);
+	memset(tipc_net.zones, 0, sz);
 	return TIPC_OK;
 }
 
-void net_stop(void)
+static void net_stop(void)
 {
 	u32 z_num;
 
-	if (!net.zones)
+	if (!tipc_net.zones)
 		return;
 
 	for (z_num = 1; z_num <= tipc_max_zones; z_num++) {
-		zone_delete(net.zones[z_num]);
+		tipc_zone_delete(tipc_net.zones[z_num]);
 	}
-	kfree(net.zones);
-	net.zones = 0;
+	kfree(tipc_net.zones);
+	tipc_net.zones = 0;
 }
 
 static void net_route_named_msg(struct sk_buff *buf)
@@ -191,26 +191,26 @@ static void net_route_named_msg(struct s
 	u32 dport;
 
 	if (!msg_named(msg)) {
-		msg_dbg(msg, "net->drop_nam:");
+		msg_dbg(msg, "tipc_net->drop_nam:");
 		buf_discard(buf);
 		return;
 	}
 
 	dnode = addr_domain(msg_lookup_scope(msg));
-	dport = nametbl_translate(msg_nametype(msg), msg_nameinst(msg), &dnode);
-	dbg("net->lookup<%u,%u>-><%u,%x>\n",
+	dport = tipc_nametbl_translate(msg_nametype(msg), msg_nameinst(msg), &dnode);
+	dbg("tipc_net->lookup<%u,%u>-><%u,%x>\n",
 	    msg_nametype(msg), msg_nameinst(msg), dport, dnode);
 	if (dport) {
 		msg_set_destnode(msg, dnode);
 		msg_set_destport(msg, dport);
-		net_route_msg(buf);
+		tipc_net_route_msg(buf);
 		return;
 	}
-	msg_dbg(msg, "net->rej:NO NAME: ");
+	msg_dbg(msg, "tipc_net->rej:NO NAME: ");
 	tipc_reject_msg(buf, TIPC_ERR_NO_NAME);
 }
 
-void net_route_msg(struct sk_buff *buf)
+void tipc_net_route_msg(struct sk_buff *buf)
 {
 	struct tipc_msg *msg;
 	u32 dnode;
@@ -232,29 +232,29 @@ void net_route_msg(struct sk_buff *buf)
 		return;
 	}
 
-	msg_dbg(msg, "net->rout: ");
+	msg_dbg(msg, "tipc_net->rout: ");
 
 	/* Handle message for this node */
 	dnode = msg_short(msg) ? tipc_own_addr : msg_destnode(msg);
 	if (in_scope(dnode, tipc_own_addr)) {
 		if (msg_isdata(msg)) {
 			if (msg_mcast(msg)) 
-				port_recv_mcast(buf, NULL);
+				tipc_port_recv_mcast(buf, NULL);
 			else if (msg_destport(msg))
-				port_recv_msg(buf);
+				tipc_port_recv_msg(buf);
 			else
 				net_route_named_msg(buf);
 			return;
 		}
 		switch (msg_user(msg)) {
 		case ROUTE_DISTRIBUTOR:
-			cluster_recv_routing_table(buf);
+			tipc_cltr_recv_routing_table(buf);
 			break;
 		case NAME_DISTRIBUTOR:
-			named_recv(buf);
+			tipc_named_recv(buf);
 			break;
 		case CONN_MANAGER:
-			port_recv_proto_msg(buf);
+			tipc_port_recv_proto_msg(buf);
 			break;
 		default:
 			msg_dbg(msg,"DROP/NET/<REC<");
@@ -265,10 +265,10 @@ void net_route_msg(struct sk_buff *buf)
 
 	/* Handle message for another node */
 	msg_dbg(msg, "NET>SEND>: ");
-	link_send(buf, dnode, msg_link_selector(msg));
+	tipc_link_send(buf, dnode, msg_link_selector(msg));
 }
 
-int tipc_start_net(void)
+int tipc_net_start(void)
 {
 	char addr_string[16];
 	int res;
@@ -277,35 +277,35 @@ int tipc_start_net(void)
 		return -ENOPROTOOPT;
 
 	tipc_mode = TIPC_NET_MODE;
-	named_reinit();
-	port_reinit();
+	tipc_named_reinit();
+	tipc_port_reinit();
 
-	if ((res = bearer_init()) ||
+	if ((res = tipc_bearer_init()) ||
 	    (res = net_init()) ||
-	    (res = cluster_init()) ||
-	    (res = bclink_init())) {
+	    (res = tipc_cltr_init()) ||
+	    (res = tipc_bclink_init())) {
 		return res;
 	}
-        subscr_stop();
-	cfg_stop();
-	k_signal((Handler)subscr_start, 0);
-	k_signal((Handler)cfg_init, 0);
+        tipc_subscr_stop();
+	tipc_cfg_stop();
+	tipc_k_signal((Handler)tipc_subscr_start, 0);
+	tipc_k_signal((Handler)tipc_cfg_init, 0);
 	info("Started in network mode\n");
 	info("Own node address %s, network identity %u\n",
 	     addr_string_fill(addr_string, tipc_own_addr), tipc_net_id);
 	return TIPC_OK;
 }
 
-void tipc_stop_net(void)
+void tipc_net_stop(void)
 {
 	if (tipc_mode != TIPC_NET_MODE)
 		return;
-        write_lock_bh(&net_lock);
-	bearer_stop();
+        write_lock_bh(&tipc_net_lock);
+	tipc_bearer_stop();
 	tipc_mode = TIPC_NODE_MODE;
-	bclink_stop();
+	tipc_bclink_stop();
 	net_stop();
-        write_unlock_bh(&net_lock);
+        write_unlock_bh(&tipc_net_lock);
 	info("Left network mode \n");
 }
 
diff --git a/net/tipc/net.h b/net/tipc/net.h
index 948c6d4..f3e0b85 100644
--- a/net/tipc/net.h
+++ b/net/tipc/net.h
@@ -49,18 +49,16 @@ struct network {
 };
 
 
-extern struct network net;
-extern rwlock_t net_lock;
+extern struct network tipc_net;
+extern rwlock_t tipc_net_lock;
 
-int net_init(void);
-void net_stop(void);
-void net_remove_as_router(u32 router);
-void net_send_external_routes(u32 dest);
-void net_route_msg(struct sk_buff *buf);
-struct node *net_select_remote_node(u32 addr, u32 ref);
-u32 net_select_router(u32 addr, u32 ref);
+void tipc_net_remove_as_router(u32 router);
+void tipc_net_send_external_routes(u32 dest);
+void tipc_net_route_msg(struct sk_buff *buf);
+struct node *tipc_net_select_remote_node(u32 addr, u32 ref);
+u32 tipc_net_select_router(u32 addr, u32 ref);
 
-int tipc_start_net(void);
-void tipc_stop_net(void);
+int tipc_net_start(void);
+void tipc_net_stop(void);
 
 #endif
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 19b3f40..eb1bb4d 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -47,13 +47,13 @@ static int handle_cmd(struct sk_buff *sk
 	int hdr_space = NLMSG_SPACE(GENL_HDRLEN + TIPC_GENL_HDRLEN);
 
 	if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN)))
-		rep_buf = cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN);
+		rep_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN);
 	else
-		rep_buf = cfg_do_cmd(req_userhdr->dest,
-				     req_userhdr->cmd,
-				     NLMSG_DATA(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN,
-				     NLMSG_PAYLOAD(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN),
-				     hdr_space);
+		rep_buf = tipc_cfg_do_cmd(req_userhdr->dest,
+					  req_userhdr->cmd,
+					  NLMSG_DATA(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN,
+					  NLMSG_PAYLOAD(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN),
+					  hdr_space);
 
 	if (rep_buf) {
 		skb_push(rep_buf, hdr_space);
@@ -81,7 +81,7 @@ static struct genl_ops ops = {
 
 static int family_registered = 0;
 
-int netlink_start(void)
+int tipc_netlink_start(void)
 {
 
 
@@ -103,7 +103,7 @@ int netlink_start(void)
 	return -EFAULT;
 }
 
-void netlink_stop(void)
+void tipc_netlink_stop(void)
 {
 	if (family_registered) {
 		genl_unregister_family(&family);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 05688d0..6d65010 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -45,17 +45,16 @@
 #include "port.h"
 #include "bearer.h"
 #include "name_distr.h"
-#include "net.h"
 
 void node_print(struct print_buf *buf, struct node *n_ptr, char *str);
 static void node_lost_contact(struct node *n_ptr);
 static void node_established_contact(struct node *n_ptr);
 
-struct node *nodes = NULL;	/* sorted list of nodes within cluster */
+struct node *tipc_nodes = NULL;	/* sorted list of nodes within cluster */
 
 u32 tipc_own_tag = 0;
 
-struct node *node_create(u32 addr)
+struct node *tipc_node_create(u32 addr)
 {
 	struct cluster *c_ptr;
 	struct node *n_ptr;
@@ -68,16 +67,16 @@ struct node *node_create(u32 addr)
                 n_ptr->lock =  SPIN_LOCK_UNLOCKED;	
                 INIT_LIST_HEAD(&n_ptr->nsub);
 	
-		c_ptr = cluster_find(addr);
+		c_ptr = tipc_cltr_find(addr);
                 if (c_ptr == NULL)
-                        c_ptr = cluster_create(addr);
+                        c_ptr = tipc_cltr_create(addr);
                 if (c_ptr != NULL) {
                         n_ptr->owner = c_ptr;
-                        cluster_attach_node(c_ptr, n_ptr);
+                        tipc_cltr_attach_node(c_ptr, n_ptr);
                         n_ptr->last_router = -1;
 
                         /* Insert node into ordered list */
-                        for (curr_node = &nodes; *curr_node; 
+                        for (curr_node = &tipc_nodes; *curr_node; 
 			     curr_node = &(*curr_node)->next) {
                                 if (addr < (*curr_node)->addr) {
                                         n_ptr->next = *curr_node;
@@ -93,13 +92,13 @@ struct node *node_create(u32 addr)
 	return n_ptr;
 }
 
-void node_delete(struct node *n_ptr)
+void tipc_node_delete(struct node *n_ptr)
 {
 	if (!n_ptr)
 		return;
 
 #if 0
-	/* Not needed because links are already deleted via bearer_stop() */
+	/* Not needed because links are already deleted via tipc_bearer_stop() */
 
 	u32 l_num;
 
@@ -114,12 +113,12 @@ void node_delete(struct node *n_ptr)
 
 
 /**
- * node_link_up - handle addition of link
+ * tipc_node_link_up - handle addition of link
  * 
  * Link becomes active (alone or shared) or standby, depending on its priority.
  */
 
-void node_link_up(struct node *n_ptr, struct link *l_ptr)
+void tipc_node_link_up(struct node *n_ptr, struct link *l_ptr)
 {
 	struct link **active = &n_ptr->active_links[0];
 
@@ -136,7 +135,7 @@ void node_link_up(struct node *n_ptr, st
 		info("Link is standby\n");
 		return;
 	}
-	link_send_duplicate(active[0], l_ptr);
+	tipc_link_send_duplicate(active[0], l_ptr);
 	if (l_ptr->priority == active[0]->priority) { 
 		active[0] = l_ptr;
 		return;
@@ -161,7 +160,7 @@ static void node_select_active_links(str
 	for (i = 0; i < MAX_BEARERS; i++) {
                 struct link *l_ptr = n_ptr->links[i];
 
-		if (!l_ptr || !link_is_up(l_ptr) ||
+		if (!l_ptr || !tipc_link_is_up(l_ptr) ||
 		    (l_ptr->priority < highest_prio))
 			continue;
 
@@ -175,14 +174,14 @@ static void node_select_active_links(str
 }
 
 /**
- * node_link_down - handle loss of link
+ * tipc_node_link_down - handle loss of link
  */
 
-void node_link_down(struct node *n_ptr, struct link *l_ptr)
+void tipc_node_link_down(struct node *n_ptr, struct link *l_ptr)
 {
 	struct link **active;
 
-	if (!link_is_active(l_ptr)) {
+	if (!tipc_link_is_active(l_ptr)) {
 		info("Lost standby link <%s> on network plane %c\n",
 		     l_ptr->name, l_ptr->b_ptr->net_plane);
 		return;
@@ -197,40 +196,40 @@ void node_link_down(struct node *n_ptr, 
 		active[1] = active[0];
 	if (active[0] == l_ptr)
 		node_select_active_links(n_ptr);
-	if (node_is_up(n_ptr)) 
-		link_changeover(l_ptr);
+	if (tipc_node_is_up(n_ptr)) 
+		tipc_link_changeover(l_ptr);
 	else 
 		node_lost_contact(n_ptr);
 }
 
-int node_has_active_links(struct node *n_ptr)
+int tipc_node_has_active_links(struct node *n_ptr)
 {
 	return (n_ptr && 
 		((n_ptr->active_links[0]) || (n_ptr->active_links[1])));
 }
 
-int node_has_redundant_links(struct node *n_ptr)
+int tipc_node_has_redundant_links(struct node *n_ptr)
 {
-	return (node_has_active_links(n_ptr) &&
+	return (tipc_node_has_active_links(n_ptr) &&
 		(n_ptr->active_links[0] != n_ptr->active_links[1]));
 }
 
-int node_has_active_routes(struct node *n_ptr)
+int tipc_node_has_active_routes(struct node *n_ptr)
 {
 	return (n_ptr && (n_ptr->last_router >= 0));
 }
 
-int node_is_up(struct node *n_ptr)
+int tipc_node_is_up(struct node *n_ptr)
 {
-	return (node_has_active_links(n_ptr) || node_has_active_routes(n_ptr));
+	return (tipc_node_has_active_links(n_ptr) || tipc_node_has_active_routes(n_ptr));
 }
 
-struct node *node_attach_link(struct link *l_ptr)
+struct node *tipc_node_attach_link(struct link *l_ptr)
 {
-	struct node *n_ptr = node_find(l_ptr->addr);
+	struct node *n_ptr = tipc_node_find(l_ptr->addr);
 
 	if (!n_ptr)
-		n_ptr = node_create(l_ptr->addr);
+		n_ptr = tipc_node_create(l_ptr->addr);
         if (n_ptr) {
 		u32 bearer_id = l_ptr->b_ptr->identity;
 		char addr_string[16];
@@ -246,7 +245,7 @@ struct node *node_attach_link(struct lin
 
                 if (!n_ptr->links[bearer_id]) {
                         n_ptr->links[bearer_id] = l_ptr;
-                        net.zones[tipc_zone(l_ptr->addr)]->links++;
+                        tipc_net.zones[tipc_zone(l_ptr->addr)]->links++;
                         n_ptr->link_cnt++;
                         return n_ptr;
                 }
@@ -257,10 +256,10 @@ struct node *node_attach_link(struct lin
 	return 0;
 }
 
-void node_detach_link(struct node *n_ptr, struct link *l_ptr)
+void tipc_node_detach_link(struct node *n_ptr, struct link *l_ptr)
 {
 	n_ptr->links[l_ptr->b_ptr->identity] = 0;
-	net.zones[tipc_zone(l_ptr->addr)]->links--;
+	tipc_net.zones[tipc_zone(l_ptr->addr)]->links--;
 	n_ptr->link_cnt--;
 }
 
@@ -315,45 +314,45 @@ static void node_established_contact(str
 	struct cluster *c_ptr;
 
 	dbg("node_established_contact:-> %x\n", n_ptr->addr);
-	if (!node_has_active_routes(n_ptr)) { 
-		k_signal((Handler)named_node_up, n_ptr->addr);
+	if (!tipc_node_has_active_routes(n_ptr)) { 
+		tipc_k_signal((Handler)tipc_named_node_up, n_ptr->addr);
 	}
 
         /* Syncronize broadcast acks */
-        n_ptr->bclink.acked = bclink_get_last_sent();
+        n_ptr->bclink.acked = tipc_bclink_get_last_sent();
 
 	if (is_slave(tipc_own_addr))
 		return;
 	if (!in_own_cluster(n_ptr->addr)) {
 		/* Usage case 1 (see above) */
-		c_ptr = cluster_find(tipc_own_addr);
+		c_ptr = tipc_cltr_find(tipc_own_addr);
 		if (!c_ptr)
-			c_ptr = cluster_create(tipc_own_addr);
+			c_ptr = tipc_cltr_create(tipc_own_addr);
                 if (c_ptr)
-                        cluster_bcast_new_route(c_ptr, n_ptr->addr, 1, 
-						tipc_max_nodes);
+                        tipc_cltr_bcast_new_route(c_ptr, n_ptr->addr, 1, 
+						  tipc_max_nodes);
 		return;
 	} 
 
 	c_ptr = n_ptr->owner;
 	if (is_slave(n_ptr->addr)) {
 		/* Usage case 2 (see above) */
-		cluster_bcast_new_route(c_ptr, n_ptr->addr, 1, tipc_max_nodes);
-		cluster_send_local_routes(c_ptr, n_ptr->addr);
+		tipc_cltr_bcast_new_route(c_ptr, n_ptr->addr, 1, tipc_max_nodes);
+		tipc_cltr_send_local_routes(c_ptr, n_ptr->addr);
 		return;
 	}
 
 	if (n_ptr->bclink.supported) {
-		nmap_add(&cluster_bcast_nodes, n_ptr->addr);
+		tipc_nmap_add(&tipc_cltr_bcast_nodes, n_ptr->addr);
 		if (n_ptr->addr < tipc_own_addr)
 			tipc_own_tag++;
 	}
 
 	/* Case 3 (see above) */
-	net_send_external_routes(n_ptr->addr);
-	cluster_send_slave_routes(c_ptr, n_ptr->addr);
-	cluster_bcast_new_route(c_ptr, n_ptr->addr, LOWEST_SLAVE,
-				highest_allowed_slave);
+	tipc_net_send_external_routes(n_ptr->addr);
+	tipc_cltr_send_slave_routes(c_ptr, n_ptr->addr);
+	tipc_cltr_bcast_new_route(c_ptr, n_ptr->addr, LOWEST_SLAVE,
+				  tipc_highest_allowed_slave);
 }
 
 static void node_lost_contact(struct node *n_ptr)
@@ -375,39 +374,39 @@ static void node_lost_contact(struct nod
                 n_ptr->bclink.defragm = NULL;
         }            
         if (in_own_cluster(n_ptr->addr) && n_ptr->bclink.supported) { 
-                bclink_acknowledge(n_ptr, mod(n_ptr->bclink.acked + 10000));
+                tipc_bclink_acknowledge(n_ptr, mod(n_ptr->bclink.acked + 10000));
         }
 
         /* Update routing tables */
 	if (is_slave(tipc_own_addr)) {
-		net_remove_as_router(n_ptr->addr);
+		tipc_net_remove_as_router(n_ptr->addr);
 	} else {
 		if (!in_own_cluster(n_ptr->addr)) { 
 			/* Case 4 (see above) */
-			c_ptr = cluster_find(tipc_own_addr);
-			cluster_bcast_lost_route(c_ptr, n_ptr->addr, 1,
-						 tipc_max_nodes);
+			c_ptr = tipc_cltr_find(tipc_own_addr);
+			tipc_cltr_bcast_lost_route(c_ptr, n_ptr->addr, 1,
+						   tipc_max_nodes);
 		} else {
 			/* Case 5 (see above) */
-			c_ptr = cluster_find(n_ptr->addr);
+			c_ptr = tipc_cltr_find(n_ptr->addr);
 			if (is_slave(n_ptr->addr)) {
-				cluster_bcast_lost_route(c_ptr, n_ptr->addr, 1,
-							 tipc_max_nodes);
+				tipc_cltr_bcast_lost_route(c_ptr, n_ptr->addr, 1,
+							   tipc_max_nodes);
 			} else {
 				if (n_ptr->bclink.supported) {
-					nmap_remove(&cluster_bcast_nodes, 
-						    n_ptr->addr);
+					tipc_nmap_remove(&tipc_cltr_bcast_nodes, 
+							 n_ptr->addr);
 					if (n_ptr->addr < tipc_own_addr)
 						tipc_own_tag--;
 				}
-				net_remove_as_router(n_ptr->addr);
-				cluster_bcast_lost_route(c_ptr, n_ptr->addr,
-							 LOWEST_SLAVE,
-							 highest_allowed_slave);
+				tipc_net_remove_as_router(n_ptr->addr);
+				tipc_cltr_bcast_lost_route(c_ptr, n_ptr->addr,
+							   LOWEST_SLAVE,
+							   tipc_highest_allowed_slave);
 			}
 		}
 	}
-	if (node_has_active_routes(n_ptr))
+	if (tipc_node_has_active_routes(n_ptr))
 		return;
 
 	info("Lost contact with %s\n", 
@@ -420,35 +419,35 @@ static void node_lost_contact(struct nod
 			continue;
 		l_ptr->reset_checkpoint = l_ptr->next_in_no;
 		l_ptr->exp_msg_count = 0;
-		link_reset_fragments(l_ptr);
+		tipc_link_reset_fragments(l_ptr);
 	}
 
 	/* Notify subscribers */
 	list_for_each_entry_safe(ns, tns, &n_ptr->nsub, nodesub_list) {
                 ns->node = 0;
 		list_del_init(&ns->nodesub_list);
-		k_signal((Handler)ns->handle_node_down,
-			 (unsigned long)ns->usr_handle);
+		tipc_k_signal((Handler)ns->handle_node_down,
+			      (unsigned long)ns->usr_handle);
 	}
 }
 
 /**
- * node_select_next_hop - find the next-hop node for a message
+ * tipc_node_select_next_hop - find the next-hop node for a message
  * 
  * Called by when cluster local lookup has failed.
  */
 
-struct node *node_select_next_hop(u32 addr, u32 selector)
+struct node *tipc_node_select_next_hop(u32 addr, u32 selector)
 {
 	struct node *n_ptr;
 	u32 router_addr;
 
-        if (!addr_domain_valid(addr))
+        if (!tipc_addr_domain_valid(addr))
                 return 0;
 
 	/* Look for direct link to destination processsor */
-	n_ptr = node_find(addr);
-	if (n_ptr && node_has_active_links(n_ptr))
+	n_ptr = tipc_node_find(addr);
+	if (n_ptr && tipc_node_has_active_links(n_ptr))
                 return n_ptr;
 
 	/* Cluster local system nodes *must* have direct links */
@@ -456,9 +455,9 @@ struct node *node_select_next_hop(u32 ad
 		return 0;
 
 	/* Look for cluster local router with direct link to node */
-	router_addr = node_select_router(n_ptr, selector);
+	router_addr = tipc_node_select_router(n_ptr, selector);
 	if (router_addr) 
-                return node_select(router_addr, selector);
+                return tipc_node_select(router_addr, selector);
 
 	/* Slave nodes can only be accessed within own cluster via a 
 	   known router with direct link -- if no router was found,give up */
@@ -467,25 +466,25 @@ struct node *node_select_next_hop(u32 ad
 
 	/* Inter zone/cluster -- find any direct link to remote cluster */
 	addr = tipc_addr(tipc_zone(addr), tipc_cluster(addr), 0);
-	n_ptr = net_select_remote_node(addr, selector);
-	if (n_ptr && node_has_active_links(n_ptr))
+	n_ptr = tipc_net_select_remote_node(addr, selector);
+	if (n_ptr && tipc_node_has_active_links(n_ptr))
                 return n_ptr;
 
 	/* Last resort -- look for any router to anywhere in remote zone */
-	router_addr =  net_select_router(addr, selector);
+	router_addr =  tipc_net_select_router(addr, selector);
 	if (router_addr) 
-                return node_select(router_addr, selector);
+                return tipc_node_select(router_addr, selector);
 
         return 0;
 }
 
 /**
- * node_select_router - select router to reach specified node
+ * tipc_node_select_router - select router to reach specified node
  * 
  * Uses a deterministic and fair algorithm for selecting router node. 
  */
 
-u32 node_select_router(struct node *n_ptr, u32 ref)
+u32 tipc_node_select_router(struct node *n_ptr, u32 ref)
 {
 	u32 ulim;
 	u32 mask;
@@ -523,7 +522,7 @@ u32 node_select_router(struct node *n_pt
 	return tipc_addr(own_zone(), own_cluster(), r);
 }
 
-void node_add_router(struct node *n_ptr, u32 router)
+void tipc_node_add_router(struct node *n_ptr, u32 router)
 {
 	u32 r_num = tipc_node(router);
 
@@ -534,7 +533,7 @@ void node_add_router(struct node *n_ptr,
 	       !n_ptr->routers[n_ptr->last_router]);
 }
 
-void node_remove_router(struct node *n_ptr, u32 router)
+void tipc_node_remove_router(struct node *n_ptr, u32 router)
 {
 	u32 r_num = tipc_node(router);
 
@@ -547,7 +546,7 @@ void node_remove_router(struct node *n_p
 	while ((--n_ptr->last_router >= 0) && 
 	       !n_ptr->routers[n_ptr->last_router]);
 
-	if (!node_is_up(n_ptr))
+	if (!tipc_node_is_up(n_ptr))
 		node_lost_contact(n_ptr);
 }
 
@@ -572,16 +571,16 @@ u32 tipc_available_nodes(const u32 domai
 	struct node *n_ptr;
 	u32 cnt = 0;
 
-	for (n_ptr = nodes; n_ptr; n_ptr = n_ptr->next) {
+	for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) {
 		if (!in_scope(domain, n_ptr->addr))
 			continue;
-		if (node_is_up(n_ptr))
+		if (tipc_node_is_up(n_ptr))
 			cnt++;
 	}
 	return cnt;
 }
 
-struct sk_buff *node_get_nodes(const void *req_tlv_area, int req_tlv_space)
+struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
 {
 	u32 domain;
 	struct sk_buff *buf;
@@ -589,40 +588,40 @@ struct sk_buff *node_get_nodes(const voi
         struct tipc_node_info node_info;
 
 	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
-		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
+		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
 
 	domain = *(u32 *)TLV_DATA(req_tlv_area);
 	domain = ntohl(domain);
-	if (!addr_domain_valid(domain))
-		return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
-					      " (network address)");
+	if (!tipc_addr_domain_valid(domain))
+		return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
+						   " (network address)");
 
-        if (!nodes)
-                return cfg_reply_none();
+        if (!tipc_nodes)
+                return tipc_cfg_reply_none();
 
 	/* For now, get space for all other nodes 
 	   (will need to modify this when slave nodes are supported */
 
-	buf = cfg_reply_alloc(TLV_SPACE(sizeof(node_info)) *
-			    (tipc_max_nodes - 1));
+	buf = tipc_cfg_reply_alloc(TLV_SPACE(sizeof(node_info)) *
+				   (tipc_max_nodes - 1));
 	if (!buf)
 		return NULL;
 
 	/* Add TLVs for all nodes in scope */
 
-	for (n_ptr = nodes; n_ptr; n_ptr = n_ptr->next) {
+	for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) {
 		if (!in_scope(domain, n_ptr->addr))
 			continue;
                 node_info.addr = htonl(n_ptr->addr);
-                node_info.up = htonl(node_is_up(n_ptr));
-		cfg_append_tlv(buf, TIPC_TLV_NODE_INFO, 
-			       &node_info, sizeof(node_info));
+                node_info.up = htonl(tipc_node_is_up(n_ptr));
+		tipc_cfg_append_tlv(buf, TIPC_TLV_NODE_INFO, 
+				    &node_info, sizeof(node_info));
 	}
 
 	return buf;
 }
 
-struct sk_buff *node_get_links(const void *req_tlv_area, int req_tlv_space)
+struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
 {
 	u32 domain;
 	struct sk_buff *buf;
@@ -630,22 +629,22 @@ struct sk_buff *node_get_links(const voi
         struct tipc_link_info link_info;
 
 	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
-		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
+		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
 
 	domain = *(u32 *)TLV_DATA(req_tlv_area);
 	domain = ntohl(domain);
-	if (!addr_domain_valid(domain))
-		return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
-					      " (network address)");
+	if (!tipc_addr_domain_valid(domain))
+		return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
+						   " (network address)");
 
-        if (!nodes)
-                return cfg_reply_none();
+        if (!tipc_nodes)
+                return tipc_cfg_reply_none();
 
 	/* For now, get space for 2 links to all other nodes + bcast link 
 	   (will need to modify this when slave nodes are supported */
 
-	buf = cfg_reply_alloc(TLV_SPACE(sizeof(link_info)) *
-			    (2 * (tipc_max_nodes - 1) + 1));
+	buf = tipc_cfg_reply_alloc(TLV_SPACE(sizeof(link_info)) *
+				   (2 * (tipc_max_nodes - 1) + 1));
 	if (!buf)
 		return NULL;
 
@@ -654,12 +653,12 @@ struct sk_buff *node_get_links(const voi
         link_info.dest = tipc_own_addr & 0xfffff00;
 	link_info.dest = htonl(link_info.dest);
         link_info.up = htonl(1);
-        sprintf(link_info.str, bc_link_name);
-	cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, &link_info, sizeof(link_info));
+        sprintf(link_info.str, tipc_bclink_name);
+	tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, &link_info, sizeof(link_info));
 
 	/* Add TLVs for any other links in scope */
 
-	for (n_ptr = nodes; n_ptr; n_ptr = n_ptr->next) {
+	for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) {
                 u32 i;
 
 		if (!in_scope(domain, n_ptr->addr))
@@ -668,10 +667,10 @@ struct sk_buff *node_get_links(const voi
                         if (!n_ptr->links[i]) 
                                 continue;
                         link_info.dest = htonl(n_ptr->addr);
-                        link_info.up = htonl(link_is_up(n_ptr->links[i]));
+                        link_info.up = htonl(tipc_link_is_up(n_ptr->links[i]));
                         strcpy(link_info.str, n_ptr->links[i]->name);
-			cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, 
-				       &link_info, sizeof(link_info));
+			tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, 
+					    &link_info, sizeof(link_info));
                 }
 	}
 
diff --git a/net/tipc/node.h b/net/tipc/node.h
index b39442b..29f7ae6 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -92,31 +92,31 @@ struct node {
 	} bclink;
 };
 
-extern struct node *nodes;
+extern struct node *tipc_nodes;
 extern u32 tipc_own_tag;
 
-struct node *node_create(u32 addr);
-void node_delete(struct node *n_ptr);
-struct node *node_attach_link(struct link *l_ptr);
-void node_detach_link(struct node *n_ptr, struct link *l_ptr);
-void node_link_down(struct node *n_ptr, struct link *l_ptr);
-void node_link_up(struct node *n_ptr, struct link *l_ptr);
-int node_has_active_links(struct node *n_ptr);
-int node_has_redundant_links(struct node *n_ptr);
-u32 node_select_router(struct node *n_ptr, u32 ref);
-struct node *node_select_next_hop(u32 addr, u32 selector);
-int node_is_up(struct node *n_ptr);
-void node_add_router(struct node *n_ptr, u32 router);
-void node_remove_router(struct node *n_ptr, u32 router);
-struct sk_buff *node_get_links(const void *req_tlv_area, int req_tlv_space);
-struct sk_buff *node_get_nodes(const void *req_tlv_area, int req_tlv_space);
+struct node *tipc_node_create(u32 addr);
+void tipc_node_delete(struct node *n_ptr);
+struct node *tipc_node_attach_link(struct link *l_ptr);
+void tipc_node_detach_link(struct node *n_ptr, struct link *l_ptr);
+void tipc_node_link_down(struct node *n_ptr, struct link *l_ptr);
+void tipc_node_link_up(struct node *n_ptr, struct link *l_ptr);
+int tipc_node_has_active_links(struct node *n_ptr);
+int tipc_node_has_redundant_links(struct node *n_ptr);
+u32 tipc_node_select_router(struct node *n_ptr, u32 ref);
+struct node *tipc_node_select_next_hop(u32 addr, u32 selector);
+int tipc_node_is_up(struct node *n_ptr);
+void tipc_node_add_router(struct node *n_ptr, u32 router);
+void tipc_node_remove_router(struct node *n_ptr, u32 router);
+struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space);
+struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space);
 
-static inline struct node *node_find(u32 addr)
+static inline struct node *tipc_node_find(u32 addr)
 {
 	if (likely(in_own_cluster(addr)))
-		return local_nodes[tipc_node(addr)];
-	else if (addr_domain_valid(addr)) {
-		struct cluster *c_ptr = cluster_find(addr);
+		return tipc_local_nodes[tipc_node(addr)];
+	else if (tipc_addr_domain_valid(addr)) {
+		struct cluster *c_ptr = tipc_cltr_find(addr);
 
 		if (c_ptr)
 			return c_ptr->nodes[tipc_node(addr)];
@@ -124,19 +124,19 @@ static inline struct node *node_find(u32
 	return 0;
 }
 
-static inline struct node *node_select(u32 addr, u32 selector)
+static inline struct node *tipc_node_select(u32 addr, u32 selector)
 {
 	if (likely(in_own_cluster(addr)))
-		return local_nodes[tipc_node(addr)];
-	return node_select_next_hop(addr, selector);
+		return tipc_local_nodes[tipc_node(addr)];
+	return tipc_node_select_next_hop(addr, selector);
 }
 
-static inline void node_lock(struct node *n_ptr)
+static inline void tipc_node_lock(struct node *n_ptr)
 {
 	spin_lock_bh(&n_ptr->lock);
 }
 
-static inline void node_unlock(struct node *n_ptr)
+static inline void tipc_node_unlock(struct node *n_ptr)
 {
 	spin_unlock_bh(&n_ptr->lock);
 }
diff --git a/net/tipc/node_subscr.c b/net/tipc/node_subscr.c
index 7937592..afeea12 100644
--- a/net/tipc/node_subscr.c
+++ b/net/tipc/node_subscr.c
@@ -41,39 +41,39 @@
 #include "addr.h"
 
 /**
- * nodesub_subscribe - create "node down" subscription for specified node
+ * tipc_nodesub_subscribe - create "node down" subscription for specified node
  */
 
-void nodesub_subscribe(struct node_subscr *node_sub, u32 addr, 
+void tipc_nodesub_subscribe(struct node_subscr *node_sub, u32 addr, 
 		       void *usr_handle, net_ev_handler handle_down)
 {
 	node_sub->node = 0;
 	if (addr == tipc_own_addr)
 		return;
-	if (!addr_node_valid(addr)) {
+	if (!tipc_addr_node_valid(addr)) {
 		warn("node_subscr with illegal %x\n", addr);
 		return;
 	}
 
 	node_sub->handle_node_down = handle_down;
 	node_sub->usr_handle = usr_handle;
-	node_sub->node = node_find(addr);
+	node_sub->node = tipc_node_find(addr);
 	assert(node_sub->node);
-	node_lock(node_sub->node);
+	tipc_node_lock(node_sub->node);
 	list_add_tail(&node_sub->nodesub_list, &node_sub->node->nsub);
-	node_unlock(node_sub->node);
+	tipc_node_unlock(node_sub->node);
 }
 
 /**
- * nodesub_unsubscribe - cancel "node down" subscription (if any)
+ * tipc_nodesub_unsubscribe - cancel "node down" subscription (if any)
  */
 
-void nodesub_unsubscribe(struct node_subscr *node_sub)
+void tipc_nodesub_unsubscribe(struct node_subscr *node_sub)
 {
 	if (!node_sub->node)
 		return;
 
-	node_lock(node_sub->node);
+	tipc_node_lock(node_sub->node);
 	list_del_init(&node_sub->nodesub_list);
-	node_unlock(node_sub->node);
+	tipc_node_unlock(node_sub->node);
 }
diff --git a/net/tipc/node_subscr.h b/net/tipc/node_subscr.h
index a3b87ac..01751c4 100644
--- a/net/tipc/node_subscr.h
+++ b/net/tipc/node_subscr.h
@@ -56,8 +56,8 @@ struct node_subscr {
 	struct list_head nodesub_list;
 };
 
-void nodesub_subscribe(struct node_subscr *node_sub, u32 addr,
-		       void *usr_handle, net_ev_handler handle_down);
-void nodesub_unsubscribe(struct node_subscr *node_sub);
+void tipc_nodesub_subscribe(struct node_subscr *node_sub, u32 addr,
+			    void *usr_handle, net_ev_handler handle_down);
+void tipc_nodesub_unsubscribe(struct node_subscr *node_sub);
 
 #endif
diff --git a/net/tipc/port.c b/net/tipc/port.c
index 66caca7..72aae52 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -57,10 +57,10 @@
 static struct sk_buff *msg_queue_head = 0;
 static struct sk_buff *msg_queue_tail = 0;
 
-spinlock_t port_list_lock = SPIN_LOCK_UNLOCKED;
+spinlock_t tipc_port_list_lock = SPIN_LOCK_UNLOCKED;
 static spinlock_t queue_lock = SPIN_LOCK_UNLOCKED;
 
-LIST_HEAD(ports);
+static LIST_HEAD(ports);
 static void port_handle_node_down(unsigned long ref);
 static struct sk_buff* port_build_self_abort_msg(struct port *,u32 err);
 static struct sk_buff* port_build_peer_abort_msg(struct port *,u32 err);
@@ -107,7 +107,7 @@ int tipc_multicast(u32 ref, struct tipc_
 	struct sk_buff *buf;
 	struct sk_buff *ibuf = NULL;
 	struct port_list dports = {0, NULL, };
-	struct port *oport = port_deref(ref);
+	struct port *oport = tipc_port_deref(ref);
 	int ext_targets;
 	int res;
 
@@ -129,8 +129,8 @@ int tipc_multicast(u32 ref, struct tipc_
 
 	/* Figure out where to send multicast message */
 
-	ext_targets = nametbl_mc_translate(seq->type, seq->lower, seq->upper,
-					   TIPC_NODE_SCOPE, &dports);
+	ext_targets = tipc_nametbl_mc_translate(seq->type, seq->lower, seq->upper,
+						TIPC_NODE_SCOPE, &dports);
 	
 	/* Send message to destinations (duplicate it only if necessary) */ 
 
@@ -138,12 +138,12 @@ int tipc_multicast(u32 ref, struct tipc_
 		if (dports.count != 0) {
 			ibuf = skb_copy(buf, GFP_ATOMIC);
 			if (ibuf == NULL) {
-				port_list_free(&dports);
+				tipc_port_list_free(&dports);
 				buf_discard(buf);
 				return -ENOMEM;
 			}
 		}
-		res = bclink_send_msg(buf);
+		res = tipc_bclink_send_msg(buf);
 		if ((res < 0) && (dports.count != 0)) {
 			buf_discard(ibuf);
 		}
@@ -153,20 +153,20 @@ int tipc_multicast(u32 ref, struct tipc_
 
 	if (res >= 0) {
 		if (ibuf)
-			port_recv_mcast(ibuf, &dports);
+			tipc_port_recv_mcast(ibuf, &dports);
 	} else {
-		port_list_free(&dports);
+		tipc_port_list_free(&dports);
 	}
 	return res;
 }
 
 /**
- * port_recv_mcast - deliver multicast message to all destination ports
+ * tipc_port_recv_mcast - deliver multicast message to all destination ports
  * 
  * If there is no port list, perform a lookup to create one
  */
 
-void port_recv_mcast(struct sk_buff *buf, struct port_list *dp)
+void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp)
 {
 	struct tipc_msg* msg;
 	struct port_list dports = {0, NULL, };
@@ -179,7 +179,7 @@ void port_recv_mcast(struct sk_buff *buf
 	/* Create destination port list, if one wasn't supplied */
 
 	if (dp == NULL) {
-		nametbl_mc_translate(msg_nametype(msg),
+		tipc_nametbl_mc_translate(msg_nametype(msg),
 				     msg_namelower(msg),
 				     msg_nameupper(msg),
 				     TIPC_CLUSTER_SCOPE,
@@ -192,8 +192,8 @@ void port_recv_mcast(struct sk_buff *buf
 	if (dp->count != 0) {
 		if (dp->count == 1) {
 			msg_set_destport(msg, dp->ports[0]);
-			port_recv_msg(buf);
-			port_list_free(dp);
+			tipc_port_recv_msg(buf);
+			tipc_port_list_free(dp);
 			return;
 		}
 		for (; cnt < dp->count; cnt++) {
@@ -209,12 +209,12 @@ void port_recv_mcast(struct sk_buff *buf
 				item = item->next;
 			}
 			msg_set_destport(buf_msg(b),item->ports[index]);
-			port_recv_msg(b);
+			tipc_port_recv_msg(b);
 		}
 	}
 exit:
 	buf_discard(buf);
-	port_list_free(dp);
+	tipc_port_list_free(dp);
 }
 
 /**
@@ -238,14 +238,14 @@ u32 tipc_createport_raw(void *usr_handle
 		return 0;
 	}
 	memset(p_ptr, 0, sizeof(*p_ptr));
-	ref = ref_acquire(p_ptr, &p_ptr->publ.lock);
+	ref = tipc_ref_acquire(p_ptr, &p_ptr->publ.lock);
 	if (!ref) {
 		warn("Reference Table Exhausted\n");
 		kfree(p_ptr);
 		return 0;
 	}
 
-	port_lock(ref);
+	tipc_port_lock(ref);
 	p_ptr->publ.ref = ref;
 	msg = &p_ptr->publ.phdr;
 	msg_init(msg, DATA_LOW, TIPC_NAMED_MSG, TIPC_OK, LONG_H_SIZE, 0);
@@ -264,12 +264,12 @@ u32 tipc_createport_raw(void *usr_handle
 	p_ptr->wakeup = wakeup;
 	p_ptr->user_port = 0;
 	k_init_timer(&p_ptr->timer, (Handler)port_timeout, ref);
-	spin_lock_bh(&port_list_lock);
+	spin_lock_bh(&tipc_port_list_lock);
 	INIT_LIST_HEAD(&p_ptr->publications);
 	INIT_LIST_HEAD(&p_ptr->port_list);
 	list_add_tail(&p_ptr->port_list, &ports);
-	spin_unlock_bh(&port_list_lock);
-	port_unlock(p_ptr);
+	spin_unlock_bh(&tipc_port_list_lock);
+	tipc_port_unlock(p_ptr);
 	return ref;
 }
 
@@ -279,31 +279,31 @@ int tipc_deleteport(u32 ref)
 	struct sk_buff *buf = 0;
 
 	tipc_withdraw(ref, 0, 0);
-	p_ptr = port_lock(ref);
+	p_ptr = tipc_port_lock(ref);
 	if (!p_ptr) 
 		return -EINVAL;
 
-	ref_discard(ref);
-	port_unlock(p_ptr);
+	tipc_ref_discard(ref);
+	tipc_port_unlock(p_ptr);
 
 	k_cancel_timer(&p_ptr->timer);
 	if (p_ptr->publ.connected) {
 		buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT);
-		nodesub_unsubscribe(&p_ptr->subscription);
+		tipc_nodesub_unsubscribe(&p_ptr->subscription);
 	}
 	if (p_ptr->user_port) {
-		reg_remove_port(p_ptr->user_port);
+		tipc_reg_remove_port(p_ptr->user_port);
 		kfree(p_ptr->user_port);
 	}
 
-	spin_lock_bh(&port_list_lock);
+	spin_lock_bh(&tipc_port_list_lock);
 	list_del(&p_ptr->port_list);
 	list_del(&p_ptr->wait_list);
-	spin_unlock_bh(&port_list_lock);
+	spin_unlock_bh(&tipc_port_list_lock);
 	k_term_timer(&p_ptr->timer);
 	kfree(p_ptr);
 	dbg("Deleted port %u\n", ref);
-	net_route_msg(buf);
+	tipc_net_route_msg(buf);
 	return TIPC_OK;
 }
 
@@ -315,7 +315,7 @@ int tipc_deleteport(u32 ref)
 
 struct tipc_port *tipc_get_port(const u32 ref)
 {
-	return (struct tipc_port *)ref_deref(ref);
+	return (struct tipc_port *)tipc_ref_deref(ref);
 }
 
 /**
@@ -327,11 +327,11 @@ void *tipc_get_handle(const u32 ref)
 	struct port *p_ptr;
 	void * handle;
 
-	p_ptr = port_lock(ref);
+	p_ptr = tipc_port_lock(ref);
 	if (!p_ptr)
 		return 0;
 	handle = p_ptr->publ.usr_handle;
-	port_unlock(p_ptr);
+	tipc_port_unlock(p_ptr);
 	return handle;
 }
 
@@ -344,7 +344,7 @@ int tipc_portunreliable(u32 ref, unsigne
 {
 	struct port *p_ptr;
 	
-	p_ptr = port_lock(ref);
+	p_ptr = tipc_port_lock(ref);
 	if (!p_ptr)
 		return -EINVAL;
 	*isunreliable = port_unreliable(p_ptr);
@@ -356,11 +356,11 @@ int tipc_set_portunreliable(u32 ref, uns
 {
 	struct port *p_ptr;
 	
-	p_ptr = port_lock(ref);
+	p_ptr = tipc_port_lock(ref);
 	if (!p_ptr)
 		return -EINVAL;
 	msg_set_src_droppable(&p_ptr->publ.phdr, (isunreliable != 0));
-	port_unlock(p_ptr);
+	tipc_port_unlock(p_ptr);
 	return TIPC_OK;
 }
 
@@ -373,7 +373,7 @@ int tipc_portunreturnable(u32 ref, unsig
 {
 	struct port *p_ptr;
 	
-	p_ptr = port_lock(ref);
+	p_ptr = tipc_port_lock(ref);
 	if (!p_ptr)
 		return -EINVAL;
 	*isunrejectable = port_unreturnable(p_ptr);
@@ -385,11 +385,11 @@ int tipc_set_portunreturnable(u32 ref, u
 {
 	struct port *p_ptr;
 	
-	p_ptr = port_lock(ref);
+	p_ptr = tipc_port_lock(ref);
 	if (!p_ptr)
 		return -EINVAL;
 	msg_set_dest_droppable(&p_ptr->publ.phdr, (isunrejectable != 0));
-	port_unlock(p_ptr);
+	tipc_port_unlock(p_ptr);
 	return TIPC_OK;
 }
 
@@ -476,25 +476,25 @@ int tipc_reject_msg(struct sk_buff *buf,
 	/* send self-abort message when rejecting on a connected port */
 	if (msg_connected(msg)) {
 		struct sk_buff *abuf = 0;
-		struct port *p_ptr = port_lock(msg_destport(msg));
+		struct port *p_ptr = tipc_port_lock(msg_destport(msg));
 
 		if (p_ptr) {
 			if (p_ptr->publ.connected)
 				abuf = port_build_self_abort_msg(p_ptr, err);
-			port_unlock(p_ptr);
+			tipc_port_unlock(p_ptr);
 		}
-		net_route_msg(abuf);
+		tipc_net_route_msg(abuf);
 	}
 
 	/* send rejected message */
 	buf_discard(buf);
-	net_route_msg(rbuf);
+	tipc_net_route_msg(rbuf);
 	return data_sz;
 }
 
-int port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr,
-			 struct iovec const *msg_sect, u32 num_sect,
-			 int err)
+int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr,
+			      struct iovec const *msg_sect, u32 num_sect,
+			      int err)
 {
 	struct sk_buff *buf;
 	int res;
@@ -509,7 +509,7 @@ int port_reject_sections(struct port *p_
 
 static void port_timeout(unsigned long ref)
 {
-	struct port *p_ptr = port_lock(ref);
+	struct port *p_ptr = tipc_port_lock(ref);
 	struct sk_buff *buf = 0;
 
 	if (!p_ptr || !p_ptr->publ.connected)
@@ -532,21 +532,21 @@ static void port_timeout(unsigned long r
 		p_ptr->probing_state = PROBING;
 		k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
 	}
-	port_unlock(p_ptr);
-	net_route_msg(buf);
+	tipc_port_unlock(p_ptr);
+	tipc_net_route_msg(buf);
 }
 
 
 static void port_handle_node_down(unsigned long ref)
 {
-	struct port *p_ptr = port_lock(ref);
+	struct port *p_ptr = tipc_port_lock(ref);
 	struct sk_buff* buf = 0;
 
 	if (!p_ptr)
 		return;
 	buf = port_build_self_abort_msg(p_ptr, TIPC_ERR_NO_NODE);
-	port_unlock(p_ptr);
-	net_route_msg(buf);
+	tipc_port_unlock(p_ptr);
+	tipc_net_route_msg(buf);
 }
 
 
@@ -589,10 +589,10 @@ static struct sk_buff *port_build_peer_a
 				    0);
 }
 
-void port_recv_proto_msg(struct sk_buff *buf)
+void tipc_port_recv_proto_msg(struct sk_buff *buf)
 {
 	struct tipc_msg *msg = buf_msg(buf);
-	struct port *p_ptr = port_lock(msg_destport(msg));
+	struct port *p_ptr = tipc_port_lock(msg_destport(msg));
 	u32 err = TIPC_OK;
 	struct sk_buff *r_buf = 0;
 	struct sk_buff *abort_buf = 0;
@@ -615,11 +615,11 @@ void port_recv_proto_msg(struct sk_buff 
 			}
 		}
 		if (msg_type(msg) == CONN_ACK) {
-			int wakeup = port_congested(p_ptr) && 
+			int wakeup = tipc_port_congested(p_ptr) && 
 				     p_ptr->publ.congested &&
 				     p_ptr->wakeup;
 			p_ptr->acked += msg_msgcnt(msg);
-			if (port_congested(p_ptr))
+			if (tipc_port_congested(p_ptr))
 				goto exit;
 			p_ptr->publ.congested = 0;
 			if (!wakeup)
@@ -659,9 +659,9 @@ void port_recv_proto_msg(struct sk_buff 
 	port_incr_out_seqno(p_ptr);
 exit:
 	if (p_ptr)
-		port_unlock(p_ptr);
-	net_route_msg(r_buf);
-	net_route_msg(abort_buf);
+		tipc_port_unlock(p_ptr);
+	tipc_net_route_msg(r_buf);
+	tipc_net_route_msg(abort_buf);
 	buf_discard(buf);
 }
 
@@ -704,7 +704,7 @@ static void port_print(struct port *p_pt
 
 #define MAX_PORT_QUERY 32768
 
-struct sk_buff *port_get_ports(void)
+struct sk_buff *tipc_port_get_ports(void)
 {
 	struct sk_buff *buf;
 	struct tlv_desc *rep_tlv;
@@ -712,20 +712,20 @@ struct sk_buff *port_get_ports(void)
 	struct port *p_ptr;
 	int str_len;
 
-	buf = cfg_reply_alloc(TLV_SPACE(MAX_PORT_QUERY));
+	buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_PORT_QUERY));
 	if (!buf)
 		return NULL;
 	rep_tlv = (struct tlv_desc *)buf->data;
 
-	printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_QUERY);
-	spin_lock_bh(&port_list_lock);
+	tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_QUERY);
+	spin_lock_bh(&tipc_port_list_lock);
 	list_for_each_entry(p_ptr, &ports, port_list) {
 		spin_lock_bh(p_ptr->publ.lock);
 		port_print(p_ptr, &pb, 0);
 		spin_unlock_bh(p_ptr->publ.lock);
 	}
-	spin_unlock_bh(&port_list_lock);
-	str_len = printbuf_validate(&pb);
+	spin_unlock_bh(&tipc_port_list_lock);
+	str_len = tipc_printbuf_validate(&pb);
 
 	skb_put(buf, TLV_SPACE(str_len));
 	TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
@@ -752,22 +752,22 @@ struct sk_buff *port_show_stats(const vo
 	ref = *(u32 *)TLV_DATA(req_tlv_area);
 	ref = ntohl(ref);
 
-	p_ptr = port_lock(ref);
+	p_ptr = tipc_port_lock(ref);
 	if (!p_ptr)
 		return cfg_reply_error_string("port not found");
 
-	buf = cfg_reply_alloc(TLV_SPACE(MAX_PORT_STATS));
+	buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_PORT_STATS));
 	if (!buf) {
-		port_unlock(p_ptr);
+		tipc_port_unlock(p_ptr);
 		return NULL;
 	}
 	rep_tlv = (struct tlv_desc *)buf->data;
 
-	printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_STATS);
+	tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_STATS);
 	port_print(p_ptr, &pb, 1);
 	/* NEED TO FILL IN ADDITIONAL PORT STATISTICS HERE */
-	port_unlock(p_ptr);
-	str_len = printbuf_validate(&pb);
+	tipc_port_unlock(p_ptr);
+	str_len = tipc_printbuf_validate(&pb);
 
 	skb_put(buf, TLV_SPACE(str_len));
 	TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
@@ -777,19 +777,19 @@ struct sk_buff *port_show_stats(const vo
 
 #endif
 
-void port_reinit(void)
+void tipc_port_reinit(void)
 {
 	struct port *p_ptr;
 	struct tipc_msg *msg;
 
-	spin_lock_bh(&port_list_lock);
+	spin_lock_bh(&tipc_port_list_lock);
 	list_for_each_entry(p_ptr, &ports, port_list) {
 		msg = &p_ptr->publ.phdr;
 		if (msg_orignode(msg) == tipc_own_addr)
 			break;
 		msg_set_orignode(msg, tipc_own_addr);
 	}
-	spin_unlock_bh(&port_list_lock);
+	spin_unlock_bh(&tipc_port_list_lock);
 }
 
 
@@ -820,7 +820,7 @@ static void port_dispatcher_sigh(void *d
 		struct tipc_msg *msg = buf_msg(buf);
 		u32 dref = msg_destport(msg);
 		
-		p_ptr = port_lock(dref);
+		p_ptr = tipc_port_lock(dref);
 		if (!p_ptr) {
 			/* Port deleted while msg in queue */
 			tipc_reject_msg(buf, TIPC_ERR_NO_PORT);
@@ -976,7 +976,7 @@ static u32 port_dispatcher(struct tipc_p
 		msg_queue_tail = buf;
 	} else {
 		msg_queue_tail = msg_queue_head = buf;
-		k_signal((Handler)port_dispatcher_sigh, 0);
+		tipc_k_signal((Handler)port_dispatcher_sigh, 0);
 	}
 	spin_unlock_bh(&queue_lock);
 	return TIPC_OK;
@@ -994,14 +994,14 @@ static void port_wakeup_sh(unsigned long
 	tipc_continue_event cb = 0;
 	void *uh = 0;
 
-	p_ptr = port_lock(ref);
+	p_ptr = tipc_port_lock(ref);
 	if (p_ptr) {
 		up_ptr = p_ptr->user_port;
 		if (up_ptr) {
 			cb = up_ptr->continue_event_cb;
 			uh = up_ptr->usr_handle;
 		}
-		port_unlock(p_ptr);
+		tipc_port_unlock(p_ptr);
 	}
 	if (cb)
 		cb(uh, ref);
@@ -1010,7 +1010,7 @@ static void port_wakeup_sh(unsigned long
 
 static void port_wakeup(struct tipc_port *p_ptr)
 {
-	k_signal((Handler)port_wakeup_sh, p_ptr->ref);
+	tipc_k_signal((Handler)port_wakeup_sh, p_ptr->ref);
 }
 
 void tipc_acknowledge(u32 ref, u32 ack)
@@ -1018,7 +1018,7 @@ void tipc_acknowledge(u32 ref, u32 ack)
 	struct port *p_ptr;
 	struct sk_buff *buf = 0;
 
-	p_ptr = port_lock(ref);
+	p_ptr = tipc_port_lock(ref);
 	if (!p_ptr)
 		return;
 	if (p_ptr->publ.connected) {
@@ -1033,8 +1033,8 @@ void tipc_acknowledge(u32 ref, u32 ack)
 					   port_out_seqno(p_ptr),
 					   ack);
 	}
-	port_unlock(p_ptr);
-	net_route_msg(buf);
+	tipc_port_unlock(p_ptr);
+	tipc_net_route_msg(buf);
 }
 
 /*
@@ -1063,7 +1063,7 @@ int tipc_createport(u32 user_ref, 
 		return -ENOMEM;
 	}
 	ref = tipc_createport_raw(0, port_dispatcher, port_wakeup, importance);
-	p_ptr = port_lock(ref);
+	p_ptr = tipc_port_lock(ref);
 	if (!p_ptr) {
 		kfree(up_ptr);
 		return -ENOMEM;
@@ -1081,10 +1081,10 @@ int tipc_createport(u32 user_ref, 
 	up_ptr->conn_msg_cb = conn_msg_cb;
 	up_ptr->continue_event_cb = continue_event_cb;
 	INIT_LIST_HEAD(&up_ptr->uport_list);
-	reg_add_port(up_ptr);
+	tipc_reg_add_port(up_ptr);
 	*portref = p_ptr->publ.ref;
 	dbg(" tipc_createport: %x with ref %u\n", p_ptr, p_ptr->publ.ref);        
-	port_unlock(p_ptr);
+	tipc_port_unlock(p_ptr);
 	return TIPC_OK;
 }
 
@@ -1099,7 +1099,7 @@ int tipc_portimportance(u32 ref, unsigne
 {
 	struct port *p_ptr;
 	
-	p_ptr = port_lock(ref);
+	p_ptr = tipc_port_lock(ref);
 	if (!p_ptr)
 		return -EINVAL;
 	*importance = (unsigned int)msg_importance(&p_ptr->publ.phdr);
@@ -1114,7 +1114,7 @@ int tipc_set_portimportance(u32 ref, uns
 	if (imp > TIPC_CRITICAL_IMPORTANCE)
 		return -EINVAL;
 
-	p_ptr = port_lock(ref);
+	p_ptr = tipc_port_lock(ref);
 	if (!p_ptr)
 		return -EINVAL;
 	msg_set_importance(&p_ptr->publ.phdr, (u32)imp);
@@ -1130,7 +1130,7 @@ int tipc_publish(u32 ref, unsigned int s
 	u32 key;
 	int res = -EINVAL;
 
-	p_ptr = port_lock(ref);
+	p_ptr = tipc_port_lock(ref);
 	dbg("tipc_publ %u, p_ptr = %x, conn = %x, scope = %x, "
 	    "lower = %u, upper = %u\n",
 	    ref, p_ptr, p_ptr->publ.connected, scope, seq->lower, seq->upper);
@@ -1147,8 +1147,8 @@ int tipc_publish(u32 ref, unsigned int s
 		res = -EADDRINUSE;
 		goto exit;
 	}
-	publ = nametbl_publish(seq->type, seq->lower, seq->upper,
-			       scope, p_ptr->publ.ref, key);
+	publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper,
+				    scope, p_ptr->publ.ref, key);
 	if (publ) {
 		list_add(&publ->pport_list, &p_ptr->publications);
 		p_ptr->pub_count++;
@@ -1156,7 +1156,7 @@ int tipc_publish(u32 ref, unsigned int s
 		res = TIPC_OK;
 	}
 exit:
-	port_unlock(p_ptr);
+	tipc_port_unlock(p_ptr);
 	return res;
 }
 
@@ -1167,7 +1167,7 @@ int tipc_withdraw(u32 ref, unsigned int 
 	struct publication *tpubl;
 	int res = -EINVAL;
 	
-	p_ptr = port_lock(ref);
+	p_ptr = tipc_port_lock(ref);
 	if (!p_ptr)
 		return -EINVAL;
 	if (!p_ptr->publ.published)
@@ -1175,8 +1175,8 @@ int tipc_withdraw(u32 ref, unsigned int 
 	if (!seq) {
 		list_for_each_entry_safe(publ, tpubl, 
 					 &p_ptr->publications, pport_list) {
-			nametbl_withdraw(publ->type, publ->lower, 
-					 publ->ref, publ->key);
+			tipc_nametbl_withdraw(publ->type, publ->lower, 
+					      publ->ref, publ->key);
 		}
 		res = TIPC_OK;
 	} else {
@@ -1190,8 +1190,8 @@ int tipc_withdraw(u32 ref, unsigned int 
 				continue;
 			if (publ->upper != seq->upper)
 				break;
-			nametbl_withdraw(publ->type, publ->lower, 
-					 publ->ref, publ->key);
+			tipc_nametbl_withdraw(publ->type, publ->lower, 
+					      publ->ref, publ->key);
 			res = TIPC_OK;
 			break;
 		}
@@ -1199,7 +1199,7 @@ int tipc_withdraw(u32 ref, unsigned int 
 	if (list_empty(&p_ptr->publications))
 		p_ptr->publ.published = 0;
 exit:
-	port_unlock(p_ptr);
+	tipc_port_unlock(p_ptr);
 	return res;
 }
 
@@ -1209,7 +1209,7 @@ int tipc_connect2port(u32 ref, struct ti
 	struct tipc_msg *msg;
 	int res = -EINVAL;
 
-	p_ptr = port_lock(ref);
+	p_ptr = tipc_port_lock(ref);
 	if (!p_ptr)
 		return -EINVAL;
 	if (p_ptr->publ.published || p_ptr->publ.connected)
@@ -1234,13 +1234,13 @@ int tipc_connect2port(u32 ref, struct ti
 	p_ptr->publ.connected = 1;
 	k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
 
-	nodesub_subscribe(&p_ptr->subscription,peer->node,
+	tipc_nodesub_subscribe(&p_ptr->subscription,peer->node,
 			  (void *)(unsigned long)ref,
 			  (net_ev_handler)port_handle_node_down);
 	res = TIPC_OK;
 exit:
-	port_unlock(p_ptr);
-	p_ptr->max_pkt = link_get_max_pkt(peer->node, ref);
+	tipc_port_unlock(p_ptr);
+	p_ptr->max_pkt = tipc_link_get_max_pkt(peer->node, ref);
 	return res;
 }
 
@@ -1254,16 +1254,16 @@ int tipc_disconnect(u32 ref)
 	struct port *p_ptr;
 	int res = -ENOTCONN;
 
-	p_ptr = port_lock(ref);
+	p_ptr = tipc_port_lock(ref);
 	if (!p_ptr)
 		return -EINVAL;
 	if (p_ptr->publ.connected) {
 		p_ptr->publ.connected = 0;
 		/* let timer expire on it's own to avoid deadlock! */
-		nodesub_unsubscribe(&p_ptr->subscription);
+		tipc_nodesub_unsubscribe(&p_ptr->subscription);
 		res = TIPC_OK;
 	}
-	port_unlock(p_ptr);
+	tipc_port_unlock(p_ptr);
 	return res;
 }
 
@@ -1275,7 +1275,7 @@ int tipc_shutdown(u32 ref)
 	struct port *p_ptr;
 	struct sk_buff *buf = 0;
 
-	p_ptr = port_lock(ref);
+	p_ptr = tipc_port_lock(ref);
 	if (!p_ptr)
 		return -EINVAL;
 
@@ -1293,8 +1293,8 @@ int tipc_shutdown(u32 ref)
 					   port_out_seqno(p_ptr),
 					   0);
 	}
-	port_unlock(p_ptr);
-	net_route_msg(buf);
+	tipc_port_unlock(p_ptr);
+	tipc_net_route_msg(buf);
 	return tipc_disconnect(ref);
 }
 
@@ -1302,11 +1302,11 @@ int tipc_isconnected(u32 ref, int *iscon
 {
 	struct port *p_ptr;
 	
-	p_ptr = port_lock(ref);
+	p_ptr = tipc_port_lock(ref);
 	if (!p_ptr)
 		return -EINVAL;
 	*isconnected = p_ptr->publ.connected;
-	port_unlock(p_ptr);
+	tipc_port_unlock(p_ptr);
 	return TIPC_OK;
 }
 
@@ -1315,7 +1315,7 @@ int tipc_peer(u32 ref, struct tipc_porti
 	struct port *p_ptr;
 	int res;
 	 
-	p_ptr = port_lock(ref);
+	p_ptr = tipc_port_lock(ref);
 	if (!p_ptr)
 		return -EINVAL;
 	if (p_ptr->publ.connected) {
@@ -1324,23 +1324,23 @@ int tipc_peer(u32 ref, struct tipc_porti
 		res = TIPC_OK;
 	} else
 		res = -ENOTCONN;
-	port_unlock(p_ptr);
+	tipc_port_unlock(p_ptr);
 	return res;
 }
 
 int tipc_ref_valid(u32 ref)
 {
 	/* Works irrespective of type */
-	return !!ref_deref(ref);
+	return !!tipc_ref_deref(ref);
 }
 
 
 /*
- *  port_recv_sections(): Concatenate and deliver sectioned
+ *  tipc_port_recv_sections(): Concatenate and deliver sectioned
  *                        message for this node.
  */
 
-int port_recv_sections(struct port *sender, unsigned int num_sect,
+int tipc_port_recv_sections(struct port *sender, unsigned int num_sect,
 		       struct iovec const *msg_sect)
 {
 	struct sk_buff *buf;
@@ -1349,7 +1349,7 @@ int port_recv_sections(struct port *send
 	res = msg_build(&sender->publ.phdr, msg_sect, num_sect,
 			MAX_MSG_SIZE, !sender->user_port, &buf);
 	if (likely(buf))
-		port_recv_msg(buf);
+		tipc_port_recv_msg(buf);
 	return res;
 }
 
@@ -1363,18 +1363,18 @@ int tipc_send(u32 ref, unsigned int num_
 	u32 destnode;
 	int res;
 
-	p_ptr = port_deref(ref);
+	p_ptr = tipc_port_deref(ref);
 	if (!p_ptr || !p_ptr->publ.connected)
 		return -EINVAL;
 
 	p_ptr->publ.congested = 1;
-	if (!port_congested(p_ptr)) {
+	if (!tipc_port_congested(p_ptr)) {
 		destnode = port_peernode(p_ptr);
 		if (likely(destnode != tipc_own_addr))
-			res = link_send_sections_fast(p_ptr, msg_sect, num_sect,
-						      destnode);
+			res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect,
+							   destnode);
 		else
-			res = port_recv_sections(p_ptr, num_sect, msg_sect);
+			res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect);
 
 		if (likely(res != -ELINKCONG)) {
 			port_incr_out_seqno(p_ptr);
@@ -1404,7 +1404,7 @@ int tipc_send_buf(u32 ref, struct sk_buf
 	u32 sz;
 	u32 res;
 	 
-	p_ptr = port_deref(ref);
+	p_ptr = tipc_port_deref(ref);
 	if (!p_ptr || !p_ptr->publ.connected)
 		return -EINVAL;
 
@@ -1419,11 +1419,11 @@ int tipc_send_buf(u32 ref, struct sk_buf
 	memcpy(buf->data, (unchar *)msg, hsz);
 	destnode = msg_destnode(msg);
 	p_ptr->publ.congested = 1;
-	if (!port_congested(p_ptr)) {
+	if (!tipc_port_congested(p_ptr)) {
 		if (likely(destnode != tipc_own_addr))
 			res = tipc_send_buf_fast(buf, destnode);
 		else {
-			port_recv_msg(buf);
+			tipc_port_recv_msg(buf);
 			res = sz;
 		}
 		if (likely(res != -ELINKCONG)) {
@@ -1458,7 +1458,7 @@ int tipc_forward2name(u32 ref, 
 	u32 destport = 0;
 	int res;
 
-	p_ptr = port_deref(ref);
+	p_ptr = tipc_port_deref(ref);
 	if (!p_ptr || p_ptr->publ.connected)
 		return -EINVAL;
 
@@ -1472,16 +1472,16 @@ int tipc_forward2name(u32 ref, 
 	msg_set_lookup_scope(msg, addr_scope(domain));
 	if (importance <= TIPC_CRITICAL_IMPORTANCE)
 		msg_set_importance(msg,importance);
-	destport = nametbl_translate(name->type, name->instance, &destnode);
+	destport = tipc_nametbl_translate(name->type, name->instance, &destnode);
 	msg_set_destnode(msg, destnode);
 	msg_set_destport(msg, destport);
 
 	if (likely(destport || destnode)) {
 		p_ptr->sent++;
 		if (likely(destnode == tipc_own_addr))
-			return port_recv_sections(p_ptr, num_sect, msg_sect);
-		res = link_send_sections_fast(p_ptr, msg_sect, num_sect, 
-					      destnode);
+			return tipc_port_recv_sections(p_ptr, num_sect, msg_sect);
+		res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, 
+						   destnode);
 		if (likely(res != -ELINKCONG))
 			return res;
 		if (port_unreliable(p_ptr)) {
@@ -1490,8 +1490,8 @@ int tipc_forward2name(u32 ref, 
 		}
 		return -ELINKCONG;
 	}
-	return port_reject_sections(p_ptr, msg, msg_sect, num_sect, 
-				    TIPC_ERR_NO_NAME);
+	return tipc_port_reject_sections(p_ptr, msg, msg_sect, num_sect, 
+					 TIPC_ERR_NO_NAME);
 }
 
 /**
@@ -1530,7 +1530,7 @@ int tipc_forward_buf2name(u32 ref,
 	u32 destport = 0;
 	int res;
 
-	p_ptr = (struct port *)ref_deref(ref);
+	p_ptr = (struct port *)tipc_ref_deref(ref);
 	if (!p_ptr || p_ptr->publ.connected)
 		return -EINVAL;
 
@@ -1545,7 +1545,7 @@ int tipc_forward_buf2name(u32 ref,
 	msg_set_lookup_scope(msg, addr_scope(domain));
 	msg_set_hdr_sz(msg, LONG_H_SIZE);
 	msg_set_size(msg, LONG_H_SIZE + dsz);
-	destport = nametbl_translate(name->type, name->instance, &destnode);
+	destport = tipc_nametbl_translate(name->type, name->instance, &destnode);
 	msg_set_destnode(msg, destnode);
 	msg_set_destport(msg, destport);
 	msg_dbg(msg, "forw2name ==> ");
@@ -1557,7 +1557,7 @@ int tipc_forward_buf2name(u32 ref,
 	if (likely(destport || destnode)) {
 		p_ptr->sent++;
 		if (destnode == tipc_own_addr)
-			return port_recv_msg(buf);
+			return tipc_port_recv_msg(buf);
 		res = tipc_send_buf_fast(buf, destnode);
 		if (likely(res != -ELINKCONG))
 			return res;
@@ -1601,7 +1601,7 @@ int tipc_forward2port(u32 ref,
 	struct tipc_msg *msg;
 	int res;
 
-	p_ptr = port_deref(ref);
+	p_ptr = tipc_port_deref(ref);
 	if (!p_ptr || p_ptr->publ.connected)
 		return -EINVAL;
 
@@ -1616,8 +1616,8 @@ int tipc_forward2port(u32 ref,
 		msg_set_importance(msg, importance);
 	p_ptr->sent++;
 	if (dest->node == tipc_own_addr)
-		return port_recv_sections(p_ptr, num_sect, msg_sect);
-	res = link_send_sections_fast(p_ptr, msg_sect, num_sect, dest->node);
+		return tipc_port_recv_sections(p_ptr, num_sect, msg_sect);
+	res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, dest->node);
 	if (likely(res != -ELINKCONG))
 		return res;
 	if (port_unreliable(p_ptr)) {
@@ -1658,7 +1658,7 @@ int tipc_forward_buf2port(u32 ref,
 	struct tipc_msg *msg;
 	int res;
 
-	p_ptr = (struct port *)ref_deref(ref);
+	p_ptr = (struct port *)tipc_ref_deref(ref);
 	if (!p_ptr || p_ptr->publ.connected)
 		return -EINVAL;
 
@@ -1680,7 +1680,7 @@ int tipc_forward_buf2port(u32 ref,
 	msg_dbg(msg, "buf2port: ");
 	p_ptr->sent++;
 	if (dest->node == tipc_own_addr)
-		return port_recv_msg(buf);
+		return tipc_port_recv_msg(buf);
 	res = tipc_send_buf_fast(buf, dest->node);
 	if (likely(res != -ELINKCONG))
 		return res;
diff --git a/net/tipc/port.h b/net/tipc/port.h
index e829a99..839f100 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -37,7 +37,7 @@
 #ifndef _TIPC_PORT_H
 #define _TIPC_PORT_H
 
-#include <net/tipc/tipc_port.h>
+#include "core.h"
 #include "ref.h"
 #include "net.h"
 #include "msg.h"
@@ -110,65 +110,65 @@ struct port {
 	struct node_subscr subscription;
 };
 
-extern spinlock_t port_list_lock;
+extern spinlock_t tipc_port_list_lock;
 struct port_list;
 
-int port_recv_sections(struct port *p_ptr, u32 num_sect, 
-		       struct iovec const *msg_sect);
-int port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr,
-			 struct iovec const *msg_sect, u32 num_sect,
-			 int err);
-struct sk_buff *port_get_ports(void);
+int tipc_port_recv_sections(struct port *p_ptr, u32 num_sect, 
+			    struct iovec const *msg_sect);
+int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr,
+			      struct iovec const *msg_sect, u32 num_sect,
+			      int err);
+struct sk_buff *tipc_port_get_ports(void);
 struct sk_buff *port_show_stats(const void *req_tlv_area, int req_tlv_space);
-void port_recv_proto_msg(struct sk_buff *buf);
-void port_recv_mcast(struct sk_buff *buf, struct port_list *dp);
-void port_reinit(void);
+void tipc_port_recv_proto_msg(struct sk_buff *buf);
+void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp);
+void tipc_port_reinit(void);
 
 /**
- * port_lock - lock port instance referred to and return its pointer
+ * tipc_port_lock - lock port instance referred to and return its pointer
  */
 
-static inline struct port *port_lock(u32 ref)
+static inline struct port *tipc_port_lock(u32 ref)
 {
-	return (struct port *)ref_lock(ref);
+	return (struct port *)tipc_ref_lock(ref);
 }
 
 /** 
- * port_unlock - unlock a port instance
+ * tipc_port_unlock - unlock a port instance
  * 
- * Can use pointer instead of ref_unlock() since port is already locked.
+ * Can use pointer instead of tipc_ref_unlock() since port is already locked.
  */
 
-static inline void port_unlock(struct port *p_ptr)
+static inline void tipc_port_unlock(struct port *p_ptr)
 {
 	spin_unlock_bh(p_ptr->publ.lock);
 }
 
-static inline struct port* port_deref(u32 ref)
+static inline struct port* tipc_port_deref(u32 ref)
 {
-	return (struct port *)ref_deref(ref);
+	return (struct port *)tipc_ref_deref(ref);
 }
 
-static inline u32 peer_port(struct port *p_ptr)
+static inline u32 tipc_peer_port(struct port *p_ptr)
 {
 	return msg_destport(&p_ptr->publ.phdr);
 }
 
-static inline u32 peer_node(struct port *p_ptr)
+static inline u32 tipc_peer_node(struct port *p_ptr)
 {
 	return msg_destnode(&p_ptr->publ.phdr);
 }
 
-static inline int port_congested(struct port *p_ptr)
+static inline int tipc_port_congested(struct port *p_ptr)
 {
 	return((p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2));
 }
 
 /** 
- * port_recv_msg - receive message from lower layer and deliver to port user
+ * tipc_port_recv_msg - receive message from lower layer and deliver to port user
  */
 
-static inline int port_recv_msg(struct sk_buff *buf)
+static inline int tipc_port_recv_msg(struct sk_buff *buf)
 {
 	struct port *p_ptr;
 	struct tipc_msg *msg = buf_msg(buf);
@@ -178,24 +178,24 @@ static inline int port_recv_msg(struct s
 	
 	/* forward unresolved named message */
 	if (unlikely(!destport)) {
-		net_route_msg(buf);
+		tipc_net_route_msg(buf);
 		return dsz;
 	}
 
 	/* validate destination & pass to port, otherwise reject message */
-	p_ptr = port_lock(destport);
+	p_ptr = tipc_port_lock(destport);
 	if (likely(p_ptr)) {
 		if (likely(p_ptr->publ.connected)) {
-			if ((unlikely(msg_origport(msg) != peer_port(p_ptr))) ||
-			    (unlikely(msg_orignode(msg) != peer_node(p_ptr))) ||
+			if ((unlikely(msg_origport(msg) != tipc_peer_port(p_ptr))) ||
+			    (unlikely(msg_orignode(msg) != tipc_peer_node(p_ptr))) ||
 			    (unlikely(!msg_connected(msg)))) {
 				err = TIPC_ERR_NO_PORT;
-				port_unlock(p_ptr);
+				tipc_port_unlock(p_ptr);
 				goto reject;
 			}
 		}
 		err = p_ptr->dispatcher(&p_ptr->publ, buf);
-		port_unlock(p_ptr);
+		tipc_port_unlock(p_ptr);
 		if (likely(!err))
 			return dsz;
 	} else {
diff --git a/net/tipc/ref.c b/net/tipc/ref.c
index 944093f..5a13c2d 100644
--- a/net/tipc/ref.c
+++ b/net/tipc/ref.c
@@ -61,15 +61,15 @@
  * because entry 0's reference field has the form XXXX|1--1.
  */
 
-struct ref_table ref_table = { 0 };
+struct ref_table tipc_ref_table = { 0 };
 
-rwlock_t reftbl_lock = RW_LOCK_UNLOCKED;
+static rwlock_t ref_table_lock = RW_LOCK_UNLOCKED;
 
 /**
- * ref_table_init - create reference table for objects
+ * tipc_ref_table_init - create reference table for objects
  */
 
-int ref_table_init(u32 requested_size, u32 start)
+int tipc_ref_table_init(u32 requested_size, u32 start)
 {
 	struct reference *table;
 	u32 sz = 1 << 4;
@@ -83,43 +83,43 @@ int ref_table_init(u32 requested_size, u
 	if (table == NULL)
 		return -ENOMEM;
 
-	write_lock_bh(&reftbl_lock);
+	write_lock_bh(&ref_table_lock);
 	index_mask = sz - 1;
 	for (i = sz - 1; i >= 0; i--) {
 		table[i].object = 0;
 		table[i].lock = SPIN_LOCK_UNLOCKED;
 		table[i].data.next_plus_upper = (start & ~index_mask) + i - 1;
 	}
-	ref_table.entries = table;
-	ref_table.index_mask = index_mask;
-	ref_table.first_free = sz - 1;
-	ref_table.last_free = 1;
-	write_unlock_bh(&reftbl_lock);
+	tipc_ref_table.entries = table;
+	tipc_ref_table.index_mask = index_mask;
+	tipc_ref_table.first_free = sz - 1;
+	tipc_ref_table.last_free = 1;
+	write_unlock_bh(&ref_table_lock);
 	return TIPC_OK;
 }
 
 /**
- * ref_table_stop - destroy reference table for objects
+ * tipc_ref_table_stop - destroy reference table for objects
  */
 
-void ref_table_stop(void)
+void tipc_ref_table_stop(void)
 {
-	if (!ref_table.entries)
+	if (!tipc_ref_table.entries)
 		return;
 
-	vfree(ref_table.entries);
-	ref_table.entries = 0;
+	vfree(tipc_ref_table.entries);
+	tipc_ref_table.entries = 0;
 }
 
 /**
- * ref_acquire - create reference to an object
+ * tipc_ref_acquire - create reference to an object
  * 
  * Return a unique reference value which can be translated back to the pointer
  * 'object' at a later time.  Also, pass back a pointer to the lock protecting 
  * the object, but without locking it.
  */
 
-u32 ref_acquire(void *object, spinlock_t **lock)
+u32 tipc_ref_acquire(void *object, spinlock_t **lock)
 {
 	struct reference *entry;
 	u32 index;
@@ -127,17 +127,17 @@ u32 ref_acquire(void *object, spinlock_t
 	u32 next_plus_upper;
 	u32 reference = 0;
 
-	assert(ref_table.entries && object);
+	assert(tipc_ref_table.entries && object);
 
-	write_lock_bh(&reftbl_lock);
-	if (ref_table.first_free) {
-		index = ref_table.first_free;
-		entry = &(ref_table.entries[index]);
-		index_mask = ref_table.index_mask;
+	write_lock_bh(&ref_table_lock);
+	if (tipc_ref_table.first_free) {
+		index = tipc_ref_table.first_free;
+		entry = &(tipc_ref_table.entries[index]);
+		index_mask = tipc_ref_table.index_mask;
 		/* take lock in case a previous user of entry still holds it */ 
 		spin_lock_bh(&entry->lock);  
 		next_plus_upper = entry->data.next_plus_upper;
-		ref_table.first_free = next_plus_upper & index_mask;
+		tipc_ref_table.first_free = next_plus_upper & index_mask;
 		reference = (next_plus_upper & ~index_mask) + index;
 		entry->data.reference = reference;
 		entry->object = object;
@@ -145,45 +145,45 @@ u32 ref_acquire(void *object, spinlock_t
                         *lock = &entry->lock;
 		spin_unlock_bh(&entry->lock);
 	}
-	write_unlock_bh(&reftbl_lock);
+	write_unlock_bh(&ref_table_lock);
 	return reference;
 }
 
 /**
- * ref_discard - invalidate references to an object
+ * tipc_ref_discard - invalidate references to an object
  * 
  * Disallow future references to an object and free up the entry for re-use.
  * Note: The entry's spin_lock may still be busy after discard
  */
 
-void ref_discard(u32 ref)
+void tipc_ref_discard(u32 ref)
 {
 	struct reference *entry;
 	u32 index; 
 	u32 index_mask;
 
-	assert(ref_table.entries);
+	assert(tipc_ref_table.entries);
 	assert(ref != 0);
 
-	write_lock_bh(&reftbl_lock);
-	index_mask = ref_table.index_mask;
+	write_lock_bh(&ref_table_lock);
+	index_mask = tipc_ref_table.index_mask;
 	index = ref & index_mask;
-	entry = &(ref_table.entries[index]);
+	entry = &(tipc_ref_table.entries[index]);
 	assert(entry->object != 0);
 	assert(entry->data.reference == ref);
 
 	/* mark entry as unused */
 	entry->object = 0;
-	if (ref_table.first_free == 0)
-		ref_table.first_free = index;
+	if (tipc_ref_table.first_free == 0)
+		tipc_ref_table.first_free = index;
 	else
 		/* next_plus_upper is always XXXX|0--0 for last free entry */
-		ref_table.entries[ref_table.last_free].data.next_plus_upper 
+		tipc_ref_table.entries[tipc_ref_table.last_free].data.next_plus_upper 
 			|= index;
-	ref_table.last_free = index;
+	tipc_ref_table.last_free = index;
 
 	/* increment upper bits of entry to invalidate subsequent references */
 	entry->data.next_plus_upper = (ref & ~index_mask) + (index_mask + 1);
-	write_unlock_bh(&reftbl_lock);
+	write_unlock_bh(&ref_table_lock);
 }
 
diff --git a/net/tipc/ref.h b/net/tipc/ref.h
index 429cde5..4f8f9f4 100644
--- a/net/tipc/ref.h
+++ b/net/tipc/ref.h
@@ -54,7 +54,7 @@ struct reference {
 };
 
 /**
- * struct ref_table - table of TIPC object reference entries
+ * struct tipc_ref_table - table of TIPC object reference entries
  * @entries: pointer to array of reference entries
  * @index_mask: bitmask for array index portion of reference values
  * @first_free: array index of first unused object reference entry
@@ -68,24 +68,24 @@ struct ref_table {
 	u32 last_free;
 };
 
-extern struct ref_table ref_table;
+extern struct ref_table tipc_ref_table;
 
-int ref_table_init(u32 requested_size, u32 start);
-void ref_table_stop(void);
+int tipc_ref_table_init(u32 requested_size, u32 start);
+void tipc_ref_table_stop(void);
 
-u32 ref_acquire(void *object, spinlock_t **lock);
-void ref_discard(u32 ref);
+u32 tipc_ref_acquire(void *object, spinlock_t **lock);
+void tipc_ref_discard(u32 ref);
 
 
 /**
- * ref_lock - lock referenced object and return pointer to it
+ * tipc_ref_lock - lock referenced object and return pointer to it
  */
 
-static inline void *ref_lock(u32 ref)
+static inline void *tipc_ref_lock(u32 ref)
 {
-	if (likely(ref_table.entries)) {
+	if (likely(tipc_ref_table.entries)) {
 		struct reference *r =
-			&ref_table.entries[ref & ref_table.index_mask];
+			&tipc_ref_table.entries[ref & tipc_ref_table.index_mask];
 
 		spin_lock_bh(&r->lock);
 		if (likely(r->data.reference == ref))
@@ -96,31 +96,31 @@ static inline void *ref_lock(u32 ref)
 }
 
 /**
- * ref_unlock - unlock referenced object 
+ * tipc_ref_unlock - unlock referenced object 
  */
 
-static inline void ref_unlock(u32 ref)
+static inline void tipc_ref_unlock(u32 ref)
 {
-	if (likely(ref_table.entries)) {
+	if (likely(tipc_ref_table.entries)) {
 		struct reference *r =
-			&ref_table.entries[ref & ref_table.index_mask];
+			&tipc_ref_table.entries[ref & tipc_ref_table.index_mask];
 
 		if (likely(r->data.reference == ref))
 			spin_unlock_bh(&r->lock);
 		else
-			err("ref_unlock() invoked using obsolete reference\n");
+			err("tipc_ref_unlock() invoked using obsolete reference\n");
 	}
 }
 
 /**
- * ref_deref - return pointer referenced object (without locking it)
+ * tipc_ref_deref - return pointer referenced object (without locking it)
  */
 
-static inline void *ref_deref(u32 ref)
+static inline void *tipc_ref_deref(u32 ref)
 {
-	if (likely(ref_table.entries)) {
+	if (likely(tipc_ref_table.entries)) {
 		struct reference *r = 
-			&ref_table.entries[ref & ref_table.index_mask];
+			&tipc_ref_table.entries[ref & tipc_ref_table.index_mask];
 
 		if (likely(r->data.reference == ref))
 			return r->object;
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index d21f8c0..67253bf 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -42,9 +42,7 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/poll.h>
-#include <linux/version.h>
 #include <linux/fcntl.h>
-#include <linux/version.h>
 #include <asm/semaphore.h>
 #include <asm/string.h>
 #include <asm/atomic.h>
@@ -1185,7 +1183,7 @@ static u32 dispatch(struct tipc_port *tp
 	if (unlikely(msg_errcode(msg) && (sock->state == SS_CONNECTED))) {
 		sock->state = SS_DISCONNECTING;
 		/* Note: Use signal since port lock is already taken! */
-		k_signal((Handler)async_disconnect, tport->ref);
+		tipc_k_signal((Handler)async_disconnect, tport->ref);
 	}
 
 	/* Enqueue message (finally!) */
@@ -1685,11 +1683,11 @@ static struct proto tipc_proto = {
 };
 
 /**
- * socket_init - initialize TIPC socket interface
+ * tipc_socket_init - initialize TIPC socket interface
  * 
  * Returns 0 on success, errno otherwise
  */
-int socket_init(void)
+int tipc_socket_init(void)
 {
 	int res;
 
@@ -1712,9 +1710,9 @@ int socket_init(void)
 }
 
 /**
- * sock_stop - stop TIPC socket interface
+ * tipc_socket_stop - stop TIPC socket interface
  */
-void socket_stop(void)
+void tipc_socket_stop(void)
 {
 	if (!sockets_enabled)
 		return;
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index 80e219b..5ff38b9 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -118,14 +118,14 @@ static void subscr_send_event(struct sub
 }
 
 /**
- * subscr_overlap - test for subscription overlap with the given values
+ * tipc_subscr_overlap - test for subscription overlap with the given values
  *
  * Returns 1 if there is overlap, otherwise 0.
  */
 
-int subscr_overlap(struct subscription *sub, 
-		   u32 found_lower, 
-		   u32 found_upper)
+int tipc_subscr_overlap(struct subscription *sub, 
+			u32 found_lower, 
+			u32 found_upper)
 
 {
 	if (found_lower < sub->seq.lower)
@@ -138,22 +138,22 @@ int subscr_overlap(struct subscription *
 }
 
 /**
- * subscr_report_overlap - issue event if there is subscription overlap
+ * tipc_subscr_report_overlap - issue event if there is subscription overlap
  * 
  * Protected by nameseq.lock in name_table.c
  */
 
-void subscr_report_overlap(struct subscription *sub, 
-			   u32 found_lower, 
-			   u32 found_upper,
-			   u32 event, 
-			   u32 port_ref, 
-			   u32 node,
-			   int must)
+void tipc_subscr_report_overlap(struct subscription *sub, 
+				u32 found_lower, 
+				u32 found_upper,
+				u32 event, 
+				u32 port_ref, 
+				u32 node,
+				int must)
 {
 	dbg("Rep overlap %u:%u,%u<->%u,%u\n", sub->seq.type, sub->seq.lower,
 	    sub->seq.upper, found_lower, found_upper);
-	if (!subscr_overlap(sub, found_lower, found_upper))
+	if (!tipc_subscr_overlap(sub, found_lower, found_upper))
 		return;
 	if (!must && (sub->filter != TIPC_SUB_PORTS))
 		return;
@@ -172,13 +172,13 @@ static void subscr_timeout(struct subscr
 	/* Validate subscriber reference (in case subscriber is terminating) */
 
 	subscriber_ref = sub->owner->ref;
-	subscriber = (struct subscriber *)ref_lock(subscriber_ref);
+	subscriber = (struct subscriber *)tipc_ref_lock(subscriber_ref);
 	if (subscriber == NULL)
 		return;
 
 	/* Unlink subscription from name table */
 
-	nametbl_unsubscribe(sub);
+	tipc_nametbl_unsubscribe(sub);
 
 	/* Notify subscriber of timeout, then unlink subscription */
 
@@ -192,7 +192,7 @@ static void subscr_timeout(struct subscr
 
 	/* Now destroy subscription */
 
-	ref_unlock(subscriber_ref);
+	tipc_ref_unlock(subscriber_ref);
 	k_term_timer(&sub->timer);
 	kfree(sub);
 	atomic_dec(&topsrv.subscription_count);
@@ -216,7 +216,7 @@ static void subscr_terminate(struct subs
 
 	/* Invalidate subscriber reference */
 
-	ref_discard(subscriber->ref);
+	tipc_ref_discard(subscriber->ref);
 	spin_unlock_bh(subscriber->lock);
 
 	/* Destroy any existing subscriptions for subscriber */
@@ -227,7 +227,7 @@ static void subscr_terminate(struct subs
 			k_cancel_timer(&sub->timer);
 			k_term_timer(&sub->timer);
 		}
-		nametbl_unsubscribe(sub);
+		tipc_nametbl_unsubscribe(sub);
 		list_del(&sub->subscription_list);
 		dbg("Term: Removed sub %u,%u,%u from subscriber %x list\n",
 		    sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber);
@@ -315,7 +315,7 @@ static void subscr_subscribe(struct tipc
 		k_start_timer(&sub->timer, sub->timeout);
 	}
 	sub->owner = subscriber;
-	nametbl_subscribe(sub);
+	tipc_nametbl_subscribe(sub);
 }
 
 /**
@@ -332,7 +332,7 @@ static void subscr_conn_shutdown_event(v
 	struct subscriber *subscriber;
 	spinlock_t *subscriber_lock;
 
-	subscriber = ref_lock((u32)(unsigned long)usr_handle);
+	subscriber = tipc_ref_lock((u32)(unsigned long)usr_handle);
 	if (subscriber == NULL)
 		return;
 
@@ -354,7 +354,7 @@ static void subscr_conn_msg_event(void *
 	struct subscriber *subscriber;
 	spinlock_t *subscriber_lock;
 
-	subscriber = ref_lock((u32)(unsigned long)usr_handle);
+	subscriber = tipc_ref_lock((u32)(unsigned long)usr_handle);
 	if (subscriber == NULL)
 		return;
 
@@ -401,7 +401,7 @@ static void subscr_named_msg_event(void 
 	memset(subscriber, 0, sizeof(struct subscriber));
 	INIT_LIST_HEAD(&subscriber->subscription_list);
 	INIT_LIST_HEAD(&subscriber->subscriber_list);
-	subscriber->ref = ref_acquire(subscriber, &subscriber->lock);
+	subscriber->ref = tipc_ref_acquire(subscriber, &subscriber->lock);
 	if (subscriber->ref == 0) {
 		warn("Failed to acquire subscriber reference\n");
 		kfree(subscriber);
@@ -423,7 +423,7 @@ static void subscr_named_msg_event(void 
 			&subscriber->port_ref);
 	if (subscriber->port_ref == 0) {
 		warn("Memory squeeze; failed to create subscription port\n");
-		ref_discard(subscriber->ref);
+		tipc_ref_discard(subscriber->ref);
 		kfree(subscriber);
 		return;
 	}
@@ -432,7 +432,7 @@ static void subscr_named_msg_event(void 
 
 	/* Add subscriber to topology server's subscriber list */
 
-	ref_lock(subscriber->ref);
+	tipc_ref_lock(subscriber->ref);
 	spin_lock_bh(&topsrv.lock);
 	list_add(&subscriber->subscriber_list, &topsrv.subscriber_list);
 	spin_unlock_bh(&topsrv.lock);
@@ -451,7 +451,7 @@ static void subscr_named_msg_event(void 
 	spin_unlock_bh(subscriber_lock);
 }
 
-int subscr_start(void)
+int tipc_subscr_start(void)
 {
 	struct tipc_name_seq seq = {TIPC_TOP_SRV, TIPC_TOP_SRV, TIPC_TOP_SRV};
 	int res = -1;
@@ -481,7 +481,7 @@ int subscr_start(void)
  	if (res)
 		goto failed;
 
- 	res = nametbl_publish_rsv(topsrv.setup_port, TIPC_NODE_SCOPE, &seq);
+ 	res = tipc_nametbl_publish_rsv(topsrv.setup_port, TIPC_NODE_SCOPE, &seq);
  	if (res)
 		goto failed;
 
@@ -496,7 +496,7 @@ failed:
 	return res;
 }
 
-void subscr_stop(void)
+void tipc_subscr_stop(void)
 {
 	struct subscriber *subscriber;
 	struct subscriber *subscriber_temp;
@@ -507,7 +507,7 @@ void subscr_stop(void)
 		list_for_each_entry_safe(subscriber, subscriber_temp, 
 					 &topsrv.subscriber_list,
 					 subscriber_list) {
-			ref_lock(subscriber->ref);
+			tipc_ref_lock(subscriber->ref);
 			subscriber_lock = subscriber->lock;
 			subscr_terminate(subscriber);
 			spin_unlock_bh(subscriber_lock);
@@ -522,6 +522,6 @@ int tipc_ispublished(struct tipc_name co
 {
 	u32 domain = 0;
 
-	return(nametbl_translate(name->type, name->instance,&domain) != 0);
+	return(tipc_nametbl_translate(name->type, name->instance,&domain) != 0);
 }
 
diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h
index ccff4ef..1e50904 100644
--- a/net/tipc/subscr.h
+++ b/net/tipc/subscr.h
@@ -60,21 +60,21 @@ struct subscription {
 	struct subscriber *owner;
 };
 
-int subscr_overlap(struct subscription * sub, 
-		   u32 found_lower, 
-		   u32 found_upper);
-
-void subscr_report_overlap(struct subscription * sub, 
-			   u32 found_lower, 
-			   u32 found_upper,
-			   u32 event, 
-			   u32 port_ref, 
-			   u32 node,
-			   int must_report);
+int tipc_subscr_overlap(struct subscription * sub, 
+			u32 found_lower, 
+			u32 found_upper);
+
+void tipc_subscr_report_overlap(struct subscription * sub, 
+				u32 found_lower, 
+				u32 found_upper,
+				u32 event, 
+				u32 port_ref, 
+				u32 node,
+				int must_report);
 
-int subscr_start(void);
+int tipc_subscr_start(void);
 
-void subscr_stop(void);
+void tipc_subscr_stop(void);
 
 
 #endif
diff --git a/net/tipc/user_reg.c b/net/tipc/user_reg.c
index 35ec7dc..106200d 100644
--- a/net/tipc/user_reg.c
+++ b/net/tipc/user_reg.c
@@ -114,10 +114,10 @@ static void reg_callback(struct tipc_use
 }
 
 /**
- * reg_start - activate TIPC user registry
+ * tipc_reg_start - activate TIPC user registry
  */
 
-int reg_start(void)
+int tipc_reg_start(void)
 {
 	u32 u;
 	int res;
@@ -127,17 +127,17 @@ int reg_start(void)
 
 	for (u = 1; u <= MAX_USERID; u++) {
 		if (users[u].callback)
-			k_signal((Handler)reg_callback,
-				 (unsigned long)&users[u]);
+			tipc_k_signal((Handler)reg_callback,
+				      (unsigned long)&users[u]);
 	}
 	return TIPC_OK;
 }
 
 /**
- * reg_stop - shut down & delete TIPC user registry
+ * tipc_reg_stop - shut down & delete TIPC user registry
  */
 
-void reg_stop(void)
+void tipc_reg_stop(void)
 {               
 	int id;
 
@@ -184,7 +184,7 @@ int tipc_attach(u32 *userid, tipc_mode_e
 	atomic_inc(&tipc_user_count);
 	
 	if (cb && (tipc_mode != TIPC_NOT_RUNNING))
-		k_signal((Handler)reg_callback, (unsigned long)user_ptr);
+		tipc_k_signal((Handler)reg_callback, (unsigned long)user_ptr);
 	return TIPC_OK;
 }
 
@@ -223,10 +223,10 @@ void tipc_detach(u32 userid)
 }
 
 /**
- * reg_add_port - register a user's driver port
+ * tipc_reg_add_port - register a user's driver port
  */
 
-int reg_add_port(struct user_port *up_ptr)
+int tipc_reg_add_port(struct user_port *up_ptr)
 {
 	struct tipc_user *user_ptr;
 
@@ -245,10 +245,10 @@ int reg_add_port(struct user_port *up_pt
 }
 
 /**
- * reg_remove_port - deregister a user's driver port
+ * tipc_reg_remove_port - deregister a user's driver port
  */
 
-int reg_remove_port(struct user_port *up_ptr)
+int tipc_reg_remove_port(struct user_port *up_ptr)
 {
 	if (up_ptr->user_ref == 0)
 		return TIPC_OK;
diff --git a/net/tipc/user_reg.h b/net/tipc/user_reg.h
index 122ca9b..d0e8879 100644
--- a/net/tipc/user_reg.h
+++ b/net/tipc/user_reg.h
@@ -39,10 +39,10 @@
 
 #include "port.h"
 
-int reg_start(void);
-void reg_stop(void);
+int tipc_reg_start(void);
+void tipc_reg_stop(void);
 
-int reg_add_port(struct user_port *up_ptr);
-int reg_remove_port(struct user_port *up_ptr);
+int tipc_reg_add_port(struct user_port *up_ptr);
+int tipc_reg_remove_port(struct user_port *up_ptr);
 
 #endif
diff --git a/net/tipc/zone.c b/net/tipc/zone.c
index 4eaef66..7c11f7f 100644
--- a/net/tipc/zone.c
+++ b/net/tipc/zone.c
@@ -42,12 +42,12 @@
 #include "cluster.h"
 #include "node.h"
 
-struct _zone *zone_create(u32 addr)
+struct _zone *tipc_zone_create(u32 addr)
 {
 	struct _zone *z_ptr = 0;
 	u32 z_num;
 
-	if (!addr_domain_valid(addr))
+	if (!tipc_addr_domain_valid(addr))
 		return 0;
 
 	z_ptr = (struct _zone *)kmalloc(sizeof(*z_ptr), GFP_ATOMIC);
@@ -55,24 +55,24 @@ struct _zone *zone_create(u32 addr)
 		memset(z_ptr, 0, sizeof(*z_ptr));
 		z_num = tipc_zone(addr);
 		z_ptr->addr = tipc_addr(z_num, 0, 0);
-		net.zones[z_num] = z_ptr;
+		tipc_net.zones[z_num] = z_ptr;
 	}
 	return z_ptr;
 }
 
-void zone_delete(struct _zone *z_ptr)
+void tipc_zone_delete(struct _zone *z_ptr)
 {
 	u32 c_num;
 
 	if (!z_ptr)
 		return;
 	for (c_num = 1; c_num <= tipc_max_clusters; c_num++) {
-		cluster_delete(z_ptr->clusters[c_num]);
+		tipc_cltr_delete(z_ptr->clusters[c_num]);
 	}
 	kfree(z_ptr);
 }
 
-void zone_attach_cluster(struct _zone *z_ptr, struct cluster *c_ptr)
+void tipc_zone_attach_cluster(struct _zone *z_ptr, struct cluster *c_ptr)
 {
 	u32 c_num = tipc_cluster(c_ptr->addr);
 
@@ -82,19 +82,19 @@ void zone_attach_cluster(struct _zone *z
 	z_ptr->clusters[c_num] = c_ptr;
 }
 
-void zone_remove_as_router(struct _zone *z_ptr, u32 router)
+void tipc_zone_remove_as_router(struct _zone *z_ptr, u32 router)
 {
 	u32 c_num;
 
 	for (c_num = 1; c_num <= tipc_max_clusters; c_num++) {
 		if (z_ptr->clusters[c_num]) {
-			cluster_remove_as_router(z_ptr->clusters[c_num], 
-						 router);
+			tipc_cltr_remove_as_router(z_ptr->clusters[c_num], 
+						   router);
 		}
 	}
 }
 
-void zone_send_external_routes(struct _zone *z_ptr, u32 dest)
+void tipc_zone_send_external_routes(struct _zone *z_ptr, u32 dest)
 {
 	u32 c_num;
 
@@ -102,12 +102,12 @@ void zone_send_external_routes(struct _z
 		if (z_ptr->clusters[c_num]) {
 			if (in_own_cluster(z_ptr->addr))
 				continue;
-			cluster_send_ext_routes(z_ptr->clusters[c_num], dest);
+			tipc_cltr_send_ext_routes(z_ptr->clusters[c_num], dest);
 		}
 	}
 }
 
-struct node *zone_select_remote_node(struct _zone *z_ptr, u32 addr, u32 ref)
+struct node *tipc_zone_select_remote_node(struct _zone *z_ptr, u32 addr, u32 ref)
 {
 	struct cluster *c_ptr;
 	struct node *n_ptr;
@@ -118,7 +118,7 @@ struct node *zone_select_remote_node(str
 	c_ptr = z_ptr->clusters[tipc_cluster(addr)];
 	if (!c_ptr)
 		return 0;
-	n_ptr = cluster_select_node(c_ptr, ref);
+	n_ptr = tipc_cltr_select_node(c_ptr, ref);
 	if (n_ptr)
 		return n_ptr;
 
@@ -127,14 +127,14 @@ struct node *zone_select_remote_node(str
 		c_ptr = z_ptr->clusters[c_num];
 		if (!c_ptr)
 			return 0;
-		n_ptr = cluster_select_node(c_ptr, ref);
+		n_ptr = tipc_cltr_select_node(c_ptr, ref);
 		if (n_ptr)
 			return n_ptr;
 	}
 	return 0;
 }
 
-u32 zone_select_router(struct _zone *z_ptr, u32 addr, u32 ref)
+u32 tipc_zone_select_router(struct _zone *z_ptr, u32 addr, u32 ref)
 {
 	struct cluster *c_ptr;
 	u32 c_num;
@@ -143,14 +143,14 @@ u32 zone_select_router(struct _zone *z_p
 	if (!z_ptr)
 		return 0;
 	c_ptr = z_ptr->clusters[tipc_cluster(addr)];
-	router = c_ptr ? cluster_select_router(c_ptr, ref) : 0;
+	router = c_ptr ? tipc_cltr_select_router(c_ptr, ref) : 0;
 	if (router)
 		return router;
 
 	/* Links to any other clusters within the zone? */
 	for (c_num = 1; c_num <= tipc_max_clusters; c_num++) {
 		c_ptr = z_ptr->clusters[c_num];
-		router = c_ptr ? cluster_select_router(c_ptr, ref) : 0;
+		router = c_ptr ? tipc_cltr_select_router(c_ptr, ref) : 0;
 		if (router)
 			return router;
 	}
@@ -158,12 +158,12 @@ u32 zone_select_router(struct _zone *z_p
 }
 
 
-u32 zone_next_node(u32 addr)
+u32 tipc_zone_next_node(u32 addr)
 {
-	struct cluster *c_ptr = cluster_find(addr);
+	struct cluster *c_ptr = tipc_cltr_find(addr);
 
 	if (c_ptr)
-		return cluster_next_node(c_ptr, addr);
+		return tipc_cltr_next_node(c_ptr, addr);
 	return 0;
 }
 
diff --git a/net/tipc/zone.h b/net/tipc/zone.h
index 4326f78..267999c 100644
--- a/net/tipc/zone.h
+++ b/net/tipc/zone.h
@@ -54,18 +54,18 @@ struct _zone {
 	u32 links;
 };
 
-struct node *zone_select_remote_node(struct _zone *z_ptr, u32 addr, u32 ref);
-u32 zone_select_router(struct _zone *z_ptr, u32 addr, u32 ref);
-void zone_remove_as_router(struct _zone *z_ptr, u32 router);
-void zone_send_external_routes(struct _zone *z_ptr, u32 dest);
-struct _zone *zone_create(u32 addr);
-void zone_delete(struct _zone *z_ptr);
-void zone_attach_cluster(struct _zone *z_ptr, struct cluster *c_ptr);
-u32 zone_next_node(u32 addr);
+struct node *tipc_zone_select_remote_node(struct _zone *z_ptr, u32 addr, u32 ref);
+u32 tipc_zone_select_router(struct _zone *z_ptr, u32 addr, u32 ref);
+void tipc_zone_remove_as_router(struct _zone *z_ptr, u32 router);
+void tipc_zone_send_external_routes(struct _zone *z_ptr, u32 dest);
+struct _zone *tipc_zone_create(u32 addr);
+void tipc_zone_delete(struct _zone *z_ptr);
+void tipc_zone_attach_cluster(struct _zone *z_ptr, struct cluster *c_ptr);
+u32 tipc_zone_next_node(u32 addr);
 
-static inline struct _zone *zone_find(u32 addr)
+static inline struct _zone *tipc_zone_find(u32 addr)
 {
-	return net.zones[tipc_zone(addr)];
+	return tipc_net.zones[tipc_zone(addr)];
 }
 
 #endif
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 9fd5f5b..99fe4b7 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -45,7 +45,7 @@ use strict;
 # Note: This only supports 'c'.
 
 # usage:
-# kerneldoc [ -docbook | -html | -text | -man ]
+# kernel-doc [ -docbook | -html | -text | -man ]
 #           [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile
 # or
 #           [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile
@@ -59,7 +59,7 @@ use strict;
 #  -nofunction funcname
 #	If set, then only generate documentation for the other function(s).  All
 #	other functions are ignored. Cannot be used with -function together
-#	(yes thats a bug - perl hackers can fix it 8))
+#	(yes, that's a bug -- perl hackers can fix it 8))
 #
 #  c files - list of 'c' files to process
 #
@@ -90,28 +90,28 @@ use strict;
 #  * my_function - does my stuff
 #  * @my_arg: its mine damnit
 #  *
-#  * Does my stuff explained. 
+#  * Does my stuff explained.
 #  */
 #
 #  or, could also use:
 # /**
 #  * my_function - does my stuff
 #  * @my_arg: its mine damnit
-#  * Description: Does my stuff explained. 
+#  * Description: Does my stuff explained.
 #  */
 # etc.
 #
-# Beside functions you can also write documentation for structs, unions, 
-# enums and typedefs. Instead of the function name you must write the name 
-# of the declaration;  the struct/union/enum/typedef must always precede 
-# the name. Nesting of declarations is not supported. 
+# Beside functions you can also write documentation for structs, unions,
+# enums and typedefs. Instead of the function name you must write the name
+# of the declaration;  the struct/union/enum/typedef must always precede
+# the name. Nesting of declarations is not supported.
 # Use the argument mechanism to document members or constants.
 # e.g.
 # /**
 #  * struct my_struct - short description
 #  * @a: first member
 #  * @b: second member
-#  * 
+#  *
 #  * Longer description
 #  */
 # struct my_struct {
@@ -122,12 +122,12 @@ use strict;
 # };
 #
 # All descriptions can be multiline, except the short function description.
-# 
-# You can also add additional sections. When documenting kernel functions you 
-# should document the "Context:" of the function, e.g. whether the functions 
+#
+# You can also add additional sections. When documenting kernel functions you
+# should document the "Context:" of the function, e.g. whether the functions
 # can be called form interrupts. Unlike other sections you can end it with an
-# empty line. 
-# Example-sections should contain the string EXAMPLE so that they are marked 
+# empty line.
+# Example-sections should contain the string EXAMPLE so that they are marked
 # appropriately in DocBook.
 #
 # Example:
@@ -135,7 +135,7 @@ use strict;
 #  * user_function - function that can only be called in user context
 #  * @a: some argument
 #  * Context: !in_interrupt()
-#  * 
+#  *
 #  * Some description
 #  * Example:
 #  *    user_function(22);
@@ -223,9 +223,9 @@ my %highlights = %highlights_man;
 my $blankline = $blankline_man;
 my $modulename = "Kernel API";
 my $function_only = 0;
-my $man_date = ('January', 'February', 'March', 'April', 'May', 'June', 
-		'July', 'August', 'September', 'October', 
-		'November', 'December')[(localtime)[4]] . 
+my $man_date = ('January', 'February', 'March', 'April', 'May', 'June',
+		'July', 'August', 'September', 'October',
+		'November', 'December')[(localtime)[4]] .
   " " . ((localtime)[5]+1900);
 
 # Essentially these are globals
@@ -236,7 +236,7 @@ my ($function, %function_table,%paramete
 my ($type,$declaration_name,$return_type);
 my ($newsection,$newcontents,$prototype,$filelist, $brcount, %source_map);
 
-# Generated docbook code is inserted in a template at a point where 
+# Generated docbook code is inserted in a template at a point where
 # docbook v3.1 requires a non-zero sequence of RefEntry's; see:
 # http://www.oasis-open.org/docbook/documentation/reference/html/refentry.html
 # We keep track of number of generated entries and generate a dummy
@@ -365,7 +365,7 @@ sub dump_section {
 #  parameterdescs => %parameter descriptions
 #  sectionlist => @list of sections
 #  sections => %descriont descriptions
-#  
+#
 
 sub output_highlight {
     my $contents = join "\n",@_;
@@ -400,7 +400,7 @@ sub output_section_html(%) {
 	print "<blockquote>\n";
 	output_highlight($args{'sections'}{$section});
 	print "</blockquote>\n";
-    }  
+    }
 }
 
 # output enum in html
@@ -434,7 +434,7 @@ sub output_enum_html(%) {
     print "<hr>\n";
 }
 
-# output tyepdef in html
+# output typedef in html
 sub output_typedef_html(%) {
     my %args = %{$_[0]};
     my ($parameter);
@@ -551,7 +551,7 @@ sub output_intro_html(%) {
 
 sub output_section_xml(%) {
     my %args = %{$_[0]};
-    my $section;    
+    my $section;
     # print out each section
     $lineprefix="   ";
     foreach $section (@{$args{'sectionlist'}}) {
@@ -778,7 +778,7 @@ sub output_enum_xml(%) {
     print "</refsynopsisdiv>\n";
 
     print "<refsect1>\n";
-    print " <title>Constants</title>\n";    
+    print " <title>Constants</title>\n";
     print "  <variablelist>\n";
     foreach $parameter (@{$args{'parameterlist'}}) {
       my $parameter_name = $parameter;
@@ -1157,7 +1157,7 @@ sub output_section_text(%) {
     foreach $section (@{$args{'sectionlist'}}) {
 	print "$section:\n\n";
 	output_highlight($args{'sections'}{$section});
-    }  
+    }
     print "\n\n";
 }
 
@@ -1262,8 +1262,8 @@ sub output_declaration {
     my $name = shift;
     my $functype = shift;
     my $func = "output_${functype}_$output_mode";
-    if (($function_only==0) || 
-	( $function_only == 1 && defined($function_table{$name})) || 
+    if (($function_only==0) ||
+	( $function_only == 1 && defined($function_table{$name})) ||
 	( $function_only == 2 && !defined($function_table{$name})))
     {
         &$func(@_);
@@ -1282,7 +1282,7 @@ sub output_intro {
 }
 
 ##
-# takes a declaration (struct, union, enum, typedef) and 
+# takes a declaration (struct, union, enum, typedef) and
 # invokes the right handler. NOT called for functions.
 sub dump_declaration($$) {
     no strict 'refs';
@@ -1352,7 +1352,7 @@ sub dump_enum($$) {
 	    }
 
 	}
-	
+
 	output_declaration($declaration_name,
 			   'enum',
 			   {'enum' => $declaration_name,
@@ -1409,7 +1409,7 @@ sub create_parameterlist($$$) {
     while ($args =~ /(\([^\),]+),/) {
         $args =~ s/(\([^\),]+),/$1#/g;
     }
-    
+
     foreach my $arg (split($splitter, $args)) {
 	# strip comments
 	$arg =~ s/\/\*.*\*\///;
@@ -1529,7 +1529,7 @@ sub dump_function($$) {
     # the following functions' documentation still comes out right:
     # - parport_register_device (function pointer parameters)
     # - atomic_set (macro)
-    # - pci_match_device (long return type)
+    # - pci_match_device, __copy_to_user (long return type)
 
     if ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
 	$prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
@@ -1544,7 +1544,9 @@ sub dump_function($$) {
 	$prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
 	$prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
 	$prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
-	$prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/)  {
+	$prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
+	$prototype =~ m/^(\w+\s+\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
+	$prototype =~ m/^(\w+\s+\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/)  {
 	$return_type = $1;
 	$declaration_name = $2;
 	my $args = $3;
@@ -1556,7 +1558,7 @@ sub dump_function($$) {
 	return;
     }
 
-    output_declaration($declaration_name, 
+    output_declaration($declaration_name,
 		       'function',
 		       {'function' => $declaration_name,
 			'module' => $modulename,
@@ -1615,11 +1617,11 @@ sub reset_state {
     %sections = ();
     @sectionlist = ();
     $prototype = "";
-    
+
     $state = 0;
 }
 
-sub process_state3_function($$) { 
+sub process_state3_function($$) {
     my $x = shift;
     my $file = shift;
 
@@ -1638,7 +1640,7 @@ sub process_state3_function($$) { 
     }
 }
 
-sub process_state3_type($$) { 
+sub process_state3_type($$) {
     my $x = shift;
     my $file = shift;
 
@@ -1778,7 +1780,7 @@ sub process_file($) {
 	    } elsif (/$doc_content/) {
 		# miguel-style comment kludge, look for blank lines after
 		# @parameter line to signify start of description
-		if ($1 eq "" && 
+		if ($1 eq "" &&
 			($section =~ m/^@/ || $section eq $section_context)) {
 		    dump_section($section, xml_escape($contents));
 		    $section = $section_default;
@@ -1788,7 +1790,7 @@ sub process_file($) {
 		}
 	    } else {
 		# i dont know - bad line?  ignore.
-		print STDERR "Warning(${file}:$.): bad line: $_"; 
+		print STDERR "Warning(${file}:$.): bad line: $_";
 		++$warnings;
 	    }
 	} elsif ($state == 3) {	# scanning for function { (end of prototype)
@@ -1843,7 +1845,7 @@ sub process_file($) {
 			else
 			{
 				$contents .= $1 . "\n";
-			}	
+			}
         	}
           }
     }
diff --git a/security/seclvl.c b/security/seclvl.c
index 1caac01..8529ea6 100644
--- a/security/seclvl.c
+++ b/security/seclvl.c
@@ -368,8 +368,8 @@ static int seclvl_capable(struct task_st
  */
 static int seclvl_settime(struct timespec *tv, struct timezone *tz)
 {
-	struct timespec now;
-	if (seclvl > 1) {
+	if (tv && seclvl > 1) {
+		struct timespec now;
 		now = current_kernel_time();
 		if (tv->tv_sec < now.tv_sec ||
 		    (tv->tv_sec == now.tv_sec && tv->tv_nsec < now.tv_nsec)) {
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index b9f8d97..4ae834d 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -127,7 +127,6 @@ static int task_alloc_security(struct ta
 	if (!tsec)
 		return -ENOMEM;
 
-	tsec->magic = SELINUX_MAGIC;
 	tsec->task = task;
 	tsec->osid = tsec->sid = tsec->ptrace_sid = SECINITSID_UNLABELED;
 	task->security = tsec;
@@ -138,10 +137,6 @@ static int task_alloc_security(struct ta
 static void task_free_security(struct task_struct *task)
 {
 	struct task_security_struct *tsec = task->security;
-
-	if (!tsec || tsec->magic != SELINUX_MAGIC)
-		return;
-
 	task->security = NULL;
 	kfree(tsec);
 }
@@ -157,14 +152,10 @@ static int inode_alloc_security(struct i
 
 	init_MUTEX(&isec->sem);
 	INIT_LIST_HEAD(&isec->list);
-	isec->magic = SELINUX_MAGIC;
 	isec->inode = inode;
 	isec->sid = SECINITSID_UNLABELED;
 	isec->sclass = SECCLASS_FILE;
-	if (tsec && tsec->magic == SELINUX_MAGIC)
-		isec->task_sid = tsec->sid;
-	else
-		isec->task_sid = SECINITSID_UNLABELED;
+	isec->task_sid = tsec->sid;
 	inode->i_security = isec;
 
 	return 0;
@@ -175,9 +166,6 @@ static void inode_free_security(struct i
 	struct inode_security_struct *isec = inode->i_security;
 	struct superblock_security_struct *sbsec = inode->i_sb->s_security;
 
-	if (!isec || isec->magic != SELINUX_MAGIC)
-		return;
-
 	spin_lock(&sbsec->isec_lock);
 	if (!list_empty(&isec->list))
 		list_del_init(&isec->list);
@@ -192,19 +180,13 @@ static int file_alloc_security(struct fi
 	struct task_security_struct *tsec = current->security;
 	struct file_security_struct *fsec;
 
-	fsec = kzalloc(sizeof(struct file_security_struct), GFP_ATOMIC);
+	fsec = kzalloc(sizeof(struct file_security_struct), GFP_KERNEL);
 	if (!fsec)
 		return -ENOMEM;
 
-	fsec->magic = SELINUX_MAGIC;
 	fsec->file = file;
-	if (tsec && tsec->magic == SELINUX_MAGIC) {
-		fsec->sid = tsec->sid;
-		fsec->fown_sid = tsec->sid;
-	} else {
-		fsec->sid = SECINITSID_UNLABELED;
-		fsec->fown_sid = SECINITSID_UNLABELED;
-	}
+	fsec->sid = tsec->sid;
+	fsec->fown_sid = tsec->sid;
 	file->f_security = fsec;
 
 	return 0;
@@ -213,10 +195,6 @@ static int file_alloc_security(struct fi
 static void file_free_security(struct file *file)
 {
 	struct file_security_struct *fsec = file->f_security;
-
-	if (!fsec || fsec->magic != SELINUX_MAGIC)
-		return;
-
 	file->f_security = NULL;
 	kfree(fsec);
 }
@@ -233,7 +211,6 @@ static int superblock_alloc_security(str
 	INIT_LIST_HEAD(&sbsec->list);
 	INIT_LIST_HEAD(&sbsec->isec_head);
 	spin_lock_init(&sbsec->isec_lock);
-	sbsec->magic = SELINUX_MAGIC;
 	sbsec->sb = sb;
 	sbsec->sid = SECINITSID_UNLABELED;
 	sbsec->def_sid = SECINITSID_FILE;
@@ -246,9 +223,6 @@ static void superblock_free_security(str
 {
 	struct superblock_security_struct *sbsec = sb->s_security;
 
-	if (!sbsec || sbsec->magic != SELINUX_MAGIC)
-		return;
-
 	spin_lock(&sb_security_lock);
 	if (!list_empty(&sbsec->list))
 		list_del_init(&sbsec->list);
@@ -270,7 +244,6 @@ static int sk_alloc_security(struct sock
 	if (!ssec)
 		return -ENOMEM;
 
-	ssec->magic = SELINUX_MAGIC;
 	ssec->sk = sk;
 	ssec->peer_sid = SECINITSID_UNLABELED;
 	sk->sk_security = ssec;
@@ -282,7 +255,7 @@ static void sk_free_security(struct sock
 {
 	struct sk_security_struct *ssec = sk->sk_security;
 
-	if (sk->sk_family != PF_UNIX || ssec->magic != SELINUX_MAGIC)
+	if (sk->sk_family != PF_UNIX)
 		return;
 
 	sk->sk_security = NULL;
@@ -1483,7 +1456,6 @@ static int selinux_bprm_alloc_security(s
 	if (!bsec)
 		return -ENOMEM;
 
-	bsec->magic = SELINUX_MAGIC;
 	bsec->bprm = bprm;
 	bsec->sid = SECINITSID_UNLABELED;
 	bsec->set = 0;
@@ -2454,35 +2426,27 @@ static int selinux_file_mprotect(struct 
 		prot = reqprot;
 
 #ifndef CONFIG_PPC32
-	if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXECUTABLE) &&
-	   (vma->vm_start >= vma->vm_mm->start_brk &&
-	    vma->vm_end <= vma->vm_mm->brk)) {
-	    	/*
-		 * We are making an executable mapping in the brk region.
-		 * This has an additional execheap check.
-		 */
-		rc = task_has_perm(current, current, PROCESS__EXECHEAP);
-		if (rc)
-			return rc;
-	}
-	if (vma->vm_file != NULL && vma->anon_vma != NULL && (prot & PROT_EXEC)) {
-		/*
-		 * We are making executable a file mapping that has
-		 * had some COW done. Since pages might have been written,
-		 * check ability to execute the possibly modified content.
-		 * This typically should only occur for text relocations.
-		 */
-		int rc = file_has_perm(current, vma->vm_file, FILE__EXECMOD);
-		if (rc)
-			return rc;
-	}
-	if (!vma->vm_file && (prot & PROT_EXEC) &&
-		vma->vm_start <= vma->vm_mm->start_stack &&
-		vma->vm_end >= vma->vm_mm->start_stack) {
-		/* Attempt to make the process stack executable.
-		 * This has an additional execstack check.
-		 */
-		rc = task_has_perm(current, current, PROCESS__EXECSTACK);
+	if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {
+		rc = 0;
+		if (vma->vm_start >= vma->vm_mm->start_brk &&
+		    vma->vm_end <= vma->vm_mm->brk) {
+			rc = task_has_perm(current, current,
+					   PROCESS__EXECHEAP);
+		} else if (!vma->vm_file &&
+			   vma->vm_start <= vma->vm_mm->start_stack &&
+			   vma->vm_end >= vma->vm_mm->start_stack) {
+			rc = task_has_perm(current, current, PROCESS__EXECSTACK);
+		} else if (vma->vm_file && vma->anon_vma) {
+			/*
+			 * We are making executable a file mapping that has
+			 * had some COW done. Since pages might have been
+			 * written, check ability to execute the possibly
+			 * modified content.  This typically should only
+			 * occur for text relocations.
+			 */
+			rc = file_has_perm(current, vma->vm_file,
+					   FILE__EXECMOD);
+		}
 		if (rc)
 			return rc;
 	}
@@ -3642,14 +3606,9 @@ static int ipc_alloc_security(struct tas
 	if (!isec)
 		return -ENOMEM;
 
-	isec->magic = SELINUX_MAGIC;
 	isec->sclass = sclass;
 	isec->ipc_perm = perm;
-	if (tsec) {
-		isec->sid = tsec->sid;
-	} else {
-		isec->sid = SECINITSID_UNLABELED;
-	}
+	isec->sid = tsec->sid;
 	perm->security = isec;
 
 	return 0;
@@ -3658,9 +3617,6 @@ static int ipc_alloc_security(struct tas
 static void ipc_free_security(struct kern_ipc_perm *perm)
 {
 	struct ipc_security_struct *isec = perm->security;
-	if (!isec || isec->magic != SELINUX_MAGIC)
-		return;
-
 	perm->security = NULL;
 	kfree(isec);
 }
@@ -3673,7 +3629,6 @@ static int msg_msg_alloc_security(struct
 	if (!msec)
 		return -ENOMEM;
 
-	msec->magic = SELINUX_MAGIC;
 	msec->msg = msg;
 	msec->sid = SECINITSID_UNLABELED;
 	msg->security = msec;
@@ -3684,8 +3639,6 @@ static int msg_msg_alloc_security(struct
 static void msg_msg_free_security(struct msg_msg *msg)
 {
 	struct msg_security_struct *msec = msg->security;
-	if (!msec || msec->magic != SELINUX_MAGIC)
-		return;
 
 	msg->security = NULL;
 	kfree(msec);
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index 887937c..54c0307 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -27,7 +27,6 @@
 #include "avc.h"
 
 struct task_security_struct {
-        unsigned long magic;           /* magic number for this module */
 	struct task_struct *task;      /* back pointer to task object */
 	u32 osid;            /* SID prior to last execve */
 	u32 sid;             /* current SID */
@@ -37,7 +36,6 @@ struct task_security_struct {
 };
 
 struct inode_security_struct {
-	unsigned long magic;           /* magic number for this module */
         struct inode *inode;           /* back pointer to inode object */
 	struct list_head list;         /* list of inode_security_struct */
 	u32 task_sid;        /* SID of creating task */
@@ -49,14 +47,12 @@ struct inode_security_struct {
 };
 
 struct file_security_struct {
-	unsigned long magic;            /* magic number for this module */
 	struct file *file;              /* back pointer to file object */
 	u32 sid;              /* SID of open file description */
 	u32 fown_sid;         /* SID of file owner (for SIGIO) */
 };
 
 struct superblock_security_struct {
-	unsigned long magic;            /* magic number for this module */
 	struct super_block *sb;         /* back pointer to sb object */
 	struct list_head list;          /* list of superblock_security_struct */
 	u32 sid;              /* SID of file system */
@@ -70,20 +66,17 @@ struct superblock_security_struct {
 };
 
 struct msg_security_struct {
-        unsigned long magic;		/* magic number for this module */
 	struct msg_msg *msg;		/* back pointer */
 	u32 sid;              /* SID of message */
 };
 
 struct ipc_security_struct {
-        unsigned long magic;		/* magic number for this module */
 	struct kern_ipc_perm *ipc_perm; /* back pointer */
 	u16 sclass;	/* security class of this object */
 	u32 sid;              /* SID of IPC resource */
 };
 
 struct bprm_security_struct {
-	unsigned long magic;           /* magic number for this module */
 	struct linux_binprm *bprm;     /* back pointer to bprm object */
 	u32 sid;                       /* SID for transformed process */
 	unsigned char set;
@@ -102,7 +95,6 @@ struct netif_security_struct {
 };
 
 struct sk_security_struct {
-	unsigned long magic;		/* magic number for this module */
 	struct sock *sk;		/* back pointer to sk object */
 	u32 peer_sid;			/* SID of peer */
 };
diff --git a/sound/core/info.c b/sound/core/info.c
index ae88539..af123e3 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -444,8 +444,8 @@ static unsigned int snd_info_entry_poll(
 	return mask;
 }
 
-static inline int _snd_info_entry_ioctl(struct inode *inode, struct file *file,
-					unsigned int cmd, unsigned long arg)
+static long snd_info_entry_ioctl(struct file *file, unsigned int cmd,
+				unsigned long arg)
 {
 	struct snd_info_private_data *data;
 	struct snd_info_entry *entry;
@@ -465,17 +465,6 @@ static inline int _snd_info_entry_ioctl(
 	return -ENOTTY;
 }
 
-/* FIXME: need to unlock BKL to allow preemption */
-static int snd_info_entry_ioctl(struct inode *inode, struct file *file,
-				unsigned int cmd, unsigned long arg)
-{
-	int err;
-	unlock_kernel();
-	err = _snd_info_entry_ioctl(inode, file, cmd, arg);
-	lock_kernel();
-	return err;
-}
-
 static int snd_info_entry_mmap(struct file *file, struct vm_area_struct *vma)
 {
 	struct inode *inode = file->f_dentry->d_inode;
@@ -499,15 +488,15 @@ static int snd_info_entry_mmap(struct fi
 
 static struct file_operations snd_info_entry_operations =
 {
-	.owner =	THIS_MODULE,
-	.llseek =	snd_info_entry_llseek,
-	.read =		snd_info_entry_read,
-	.write =	snd_info_entry_write,
-	.poll =		snd_info_entry_poll,
-	.ioctl =	snd_info_entry_ioctl,
-	.mmap =		snd_info_entry_mmap,
-	.open =		snd_info_entry_open,
-	.release =	snd_info_entry_release,
+	.owner =		THIS_MODULE,
+	.llseek =		snd_info_entry_llseek,
+	.read =			snd_info_entry_read,
+	.write =		snd_info_entry_write,
+	.poll =			snd_info_entry_poll,
+	.unlocked_ioctl =	snd_info_entry_ioctl,
+	.mmap =			snd_info_entry_mmap,
+	.open =			snd_info_entry_open,
+	.release =		snd_info_entry_release,
 };
 
 /**
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index 29676d8..112ddf7 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -789,7 +789,7 @@ static int __init snd_uart16550_create(s
 
 	if ((err = snd_uart16550_detect(uart)) <= 0) {
 		printk(KERN_ERR "no UART detected at 0x%lx\n", iobase);
-		return err;
+		return -ENODEV;
 	}
 
 	if (irq >= 0 && irq != SNDRV_AUTO_IRQ) {
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index bd8e238..fd9bb25 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -109,7 +109,9 @@ module_param_array(wssdma, int, NULL, 04
 MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver.");
 
 static struct platform_device *platform_devices[SNDRV_CARDS];
+#ifdef CONFIG_PNP
 static int pnp_registered;
+#endif
 
 #define CMI8330_RMUX3D    16
 #define CMI8330_MUTEMUX   17
@@ -672,8 +674,10 @@ static void __init_or_module snd_cmi8330
 {
 	int i;
 
+#ifdef CONFIG_PNP
 	if (pnp_registered)
 		pnp_unregister_card_driver(&cmi8330_pnpc_driver);
+#endif
 	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
 		platform_device_unregister(platform_devices[i]);
 	platform_driver_unregister(&snd_cmi8330_driver);
@@ -700,11 +704,13 @@ static int __init alsa_card_cmi8330_init
 		cards++;
 	}
 
+#ifdef CONFIG_PNP
 	err = pnp_register_card_driver(&cmi8330_pnpc_driver);
 	if (err >= 0) {
 		pnp_registered = 1;
 		cards += err;
 	}
+#endif
 
 	if (!cards) {
 #ifdef MODULE
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index e168333..4fa4310 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -75,8 +75,10 @@ MODULE_SUPPORTED_DEVICE("{{Crystal Semic
 
 #ifdef CS4232
 #define IDENT "CS4232"
+#define CS423X_DRIVER "snd_cs4232"
 #else
 #define IDENT "CS4236+"
+#define CS423X_DRIVER "snd_cs4236"
 #endif
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
@@ -125,10 +127,12 @@ module_param_array(dma2, int, NULL, 0444
 MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver.");
 
 static struct platform_device *platform_devices[SNDRV_CARDS];
+#ifdef CONFIG_PNP
 static int pnpc_registered;
 #ifdef CS4232
 static int pnp_registered;
 #endif
+#endif /* CONFIG_PNP */
 
 struct snd_card_cs4236 {
 	struct snd_cs4231 *chip;
@@ -158,7 +162,6 @@ MODULE_DEVICE_TABLE(pnp, snd_cs4232_pnpb
 #endif /* CS4232 */
 
 #ifdef CS4232
-#define CS423X_DRIVER		"snd_cs4232"
 #define CS423X_ISAPNP_DRIVER	"cs4232_isapnp"
 static struct pnp_card_device_id snd_cs423x_pnpids[] = {
 	/* Philips PCA70PS */
@@ -175,11 +178,12 @@ static struct pnp_card_device_id snd_cs4
 	{ .id = "CSC7632", .devs = { { "CSC0000" }, { "CSC0010" }, { "PNPb006" } } },
 	/* SIC CrystalWave 32 (CS4232) */
 	{ .id = "CSCf032", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
+	/* Netfinity 3000 on-board soundcard */
+	{ .id = "CSCe825", .devs = { { "CSC0100" }, { "CSC0110" }, { "CSC010f" } } },
 	/* --- */
 	{ .id = "" }	/* end */
 };
 #else /* CS4236 */
-#define CS423X_DRIVER		"snd_cs4236"
 #define CS423X_ISAPNP_DRIVER	"cs4236_isapnp"
 static struct pnp_card_device_id snd_cs423x_pnpids[] = {
 	/* Intel Marlin Spike Motherboard - CS4235 */
@@ -747,12 +751,14 @@ static void __init_or_module snd_cs423x_
 {
 	int i;
 
+#ifdef CONFIG_PNP
 	if (pnpc_registered)
 		pnp_unregister_card_driver(&cs423x_pnpc_driver);
 #ifdef CS4232
 	if (pnp_registered)
 		pnp_unregister_driver(&cs4232_pnp_driver);
 #endif
+#endif /* CONFIG_PNP */
 	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
 		platform_device_unregister(platform_devices[i]);
 	platform_driver_unregister(&cs423x_nonpnp_driver);
@@ -778,6 +784,7 @@ static int __init alsa_card_cs423x_init(
 		platform_devices[i] = device;
 		cards++;
 	}
+#ifdef CONFIG_PNP
 #ifdef CS4232
 	i = pnp_register_driver(&cs4232_pnp_driver);
 	if (i >= 0) {
@@ -790,6 +797,8 @@ static int __init alsa_card_cs423x_init(
 		pnpc_registered = 1;
 		cards += i;
 	}
+#endif /* CONFIG_PNP */
+
 	if (!cards) {
 #ifdef MODULE
 		printk(KERN_ERR IDENT " soundcard not found or device busy\n");
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index bf5de07..08f032b 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -1878,9 +1878,9 @@ module_param_array(dma2, int, NULL, 0444
 MODULE_PARM_DESC(dma2, "DMA 2 # for ES18xx driver.");
 
 static struct platform_device *platform_devices[SNDRV_CARDS];
-static int pnp_registered;
 
 #ifdef CONFIG_PNP
+static int pnp_registered;
 
 static struct pnp_card_device_id snd_audiodrive_pnpids[] = {
 	/* ESS 1868 (integrated on Compaq dual P-Pro motherboard and Genius 18PnP 3D) */
@@ -2209,8 +2209,10 @@ static void __init_or_module snd_es18xx_
 {
 	int i;
 
+#ifdef CONFIG_PNP
 	if (pnp_registered)
 		pnp_unregister_card_driver(&es18xx_pnpc_driver);
+#endif
 	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
 		platform_device_unregister(platform_devices[i]);
 	platform_driver_unregister(&snd_es18xx_nonpnp_driver);
@@ -2237,11 +2239,13 @@ static int __init alsa_card_es18xx_init(
 		cards++;
 	}
 
+#ifdef CONFIG_PNP
 	i = pnp_register_card_driver(&es18xx_pnpc_driver);
 	if (i >= 0) {
 		pnp_registered = 1;
 		cards += i;
 	}
+#endif
 
 	if(!cards) {
 #ifdef MODULE
diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c
index d1165b9..91c2191 100644
--- a/sound/isa/gus/gusclassic.c
+++ b/sound/isa/gus/gusclassic.c
@@ -195,7 +195,7 @@ static int __init snd_gusclassic_probe(s
 			goto _err;
 	}
 	sprintf(card->longname + strlen(card->longname), " at 0x%lx, irq %d, dma %d", gus->gf1.port, xirq, xdma1);
-	if (dma2 >= 0)
+	if (xdma2 >= 0)
 		sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
 
 	snd_card_set_dev(card, &pdev->dev);
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index ca359e0..9d84319 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -91,8 +91,10 @@ module_param_array(opl3sa3_ymode, int, N
 MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size selection for 3D Enhancement mode: Desktop/Large Notebook/Small Notebook/HiFi.");
 
 static struct platform_device *platform_devices[SNDRV_CARDS];
+#ifdef CONFIG_PNP
 static int pnp_registered;
 static int pnpc_registered;
+#endif
 
 /* control ports */
 #define OPL3SA2_PM_CTRL		0x01
@@ -721,7 +723,7 @@ static int __devinit snd_opl3sa2_probe(s
 	}
 	sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
 		card->shortname, chip->port, xirq, xdma1);
-	if (dma2 >= 0)
+	if (xdma2 >= 0)
 		sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
 
 	return snd_card_register(card);
@@ -779,7 +781,7 @@ static int snd_opl3sa2_pnp_resume(struct
 #endif
 
 static struct pnp_driver opl3sa2_pnp_driver = {
-	.name = "opl3sa2-pnpbios",
+	.name = "snd-opl3sa2-pnpbios",
 	.id_table = snd_opl3sa2_pnpbiosids,
 	.probe = snd_opl3sa2_pnp_detect,
 	.remove = __devexit_p(snd_opl3sa2_pnp_remove),
@@ -846,7 +848,7 @@ static int snd_opl3sa2_pnp_cresume(struc
 
 static struct pnp_card_driver opl3sa2_pnpc_driver = {
 	.flags = PNP_DRIVER_RES_DISABLE,
-	.name = "opl3sa2",
+	.name = "snd-opl3sa2-cpnp",
 	.id_table = snd_opl3sa2_pnpids,
 	.probe = snd_opl3sa2_pnp_cdetect,
 	.remove = __devexit_p(snd_opl3sa2_pnp_cremove),
@@ -929,10 +931,12 @@ static void __init_or_module snd_opl3sa2
 {
 	int i;
 
+#ifdef CONFIG_PNP
 	if (pnpc_registered)
 		pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
 	if (pnp_registered)
 		pnp_unregister_driver(&opl3sa2_pnp_driver);
+#endif
 	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
 		platform_device_unregister(platform_devices[i]);
 	platform_driver_unregister(&snd_opl3sa2_nonpnp_driver);
@@ -961,6 +965,7 @@ static int __init alsa_card_opl3sa2_init
 		cards++;
 	}
 
+#ifdef CONFIG_PNP
 	err = pnp_register_driver(&opl3sa2_pnp_driver);
 	if (err >= 0) {
 		pnp_registered = 1;
@@ -971,6 +976,7 @@ static int __init alsa_card_opl3sa2_init
 		pnpc_registered = 1;
 		cards += err;
 	}
+#endif
 
 	if (!cards) {
 #ifdef MODULE
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index 1ea3944..63d96be 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -1349,7 +1349,7 @@ static int snd_opti93x_pcm(struct snd_op
 	int error;
 	struct snd_pcm *pcm;
 
-	if ((error = snd_pcm_new(codec->card, "OPTi 82C93X", device, 1, 1, &pcm)))
+	if ((error = snd_pcm_new(codec->card, "OPTi 82C93X", device, 1, 1, &pcm)) < 0)
 		return error;
 
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_opti93x_playback_ops);
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index c0be7a5..0667bd1 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -179,6 +179,8 @@ static struct pnp_card_device_id snd_sb1
 	{ .id = "CTL0086", .devs = { { "CTL0041" } } },
 	/* Sound Blaster Vibra16X */
 	{ .id = "CTL00f0", .devs = { { "CTL0043" } } },
+	/* Sound Blaster 16 (Virtual PC 2004) */
+	{ .id = "tBA03b0", .devs = { {.id="PNPb003" } } },
 #else  /* SNDRV_SBAWE defined */
 	/* Sound Blaster AWE 32 PnP */
 	{ .id = "CTL0035", .devs = { { "CTL0031" }, { "CTL0021" } } },
@@ -235,8 +237,6 @@ static struct pnp_card_device_id snd_sb1
 	{ .id = "CTLXXXX" , .devs = { { "CTL0044" }, { "CTL0023" } } },
 	{ .id = "CTLXXXX" , .devs = { { "CTL0045" }, { "CTL0022" } } },
 #endif /* SNDRV_SBAWE */
-	/* Sound Blaster 16 PnP (Virtual PC 2004)*/
-	{ .id = "tBA03b0", .devs = { { "PNPb003" } } },
 	{ .id = "", }
 };
 
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index 5fb981c..29bba8c 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -69,9 +69,9 @@ module_param_array(dma, int, NULL, 0444)
 MODULE_PARM_DESC(dma, "DMA # for SoundScape driver.");
 
 static struct platform_device *platform_devices[SNDRV_CARDS];
-static int pnp_registered;
   
 #ifdef CONFIG_PNP
+static int pnp_registered;
 static struct pnp_card_device_id sscape_pnpids[] = {
 	{ .id = "ENS3081", .devs = { { "ENS0000" } } },
 	{ .id = "" }	/* end */
@@ -1391,8 +1391,10 @@ static void __init_or_module sscape_unre
 {
 	int i;
 
+#ifdef CONFIG_PNP
 	if (pnp_registered)
 		pnp_unregister_card_driver(&sscape_pnpc_driver);
+#endif
 	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
 		platform_device_unregister(platform_devices[i]);
 	platform_driver_unregister(&snd_sscape_driver);
@@ -1466,8 +1468,10 @@ static int __init sscape_init(void)
 	ret = sscape_manual_probe();
 	if (ret < 0)
 		return ret;
+#ifdef CONFIG_PNP
 	if (pnp_register_card_driver(&sscape_pnpc_driver) >= 0)
 		pnp_registered = 1;
+#endif
 	return 0;
 }
 
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index a6dcb2f..fa3ab96 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -84,10 +84,9 @@ module_param_array(use_cs4232_midi, bool
 MODULE_PARM_DESC(use_cs4232_midi, "Use CS4232 MPU-401 interface (inaccessibly located inside your computer)");
 
 static struct platform_device *platform_devices[SNDRV_CARDS];
-static int pnp_registered;
-
 
 #ifdef CONFIG_PNP
+static int pnp_registered;
 
 static struct pnp_card_device_id snd_wavefront_pnpids[] = {
 	/* Tropez */
@@ -695,8 +694,10 @@ static void __init_or_module snd_wavefro
 {
 	int i;
 
+#ifdef CONFIG_PNP
 	if (pnp_registered)
 		pnp_unregister_card_driver(&wavefront_pnpc_driver);
+#endif
 	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
 		platform_device_unregister(platform_devices[i]);
 	platform_driver_unregister(&snd_wavefront_driver);
@@ -725,11 +726,13 @@ static int __init alsa_card_wavefront_in
 		cards++;
 	}
 
+#ifdef CONFIG_PNP
 	i = pnp_register_card_driver(&wavefront_pnpc_driver);
 	if (i >= 0) {
 		pnp_registered = 1;
 		cards += i;
 	}
+#endif
 
 	if (!cards) {
 #ifdef MODULE
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
index ed81eec..68aa091 100644
--- a/sound/isa/wavefront/wavefront_synth.c
+++ b/sound/isa/wavefront/wavefront_synth.c
@@ -866,7 +866,7 @@ wavefront_send_sample (snd_wavefront_t *
 	   divided by 2.
         */
 
-	u16 sample_short;
+	u16 sample_short = 0;
 	u32 length;
 	u16 __user *data_end = NULL;
 	unsigned int i;
diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c
index b963c55..bdee050 100644
--- a/sound/oss/au1550_ac97.c
+++ b/sound/oss/au1550_ac97.c
@@ -462,7 +462,7 @@ stop_dac(struct au1550_state *s)
 	/* Wait for Transmit Busy to show disabled.
 	*/
 	do {
-		stat = readl((void *)PSC_AC97STAT);
+		stat = au_readl(PSC_AC97STAT);
 		au_sync();
 	} while ((stat & PSC_AC97STAT_TB) != 0);
 
@@ -491,7 +491,7 @@ stop_adc(struct au1550_state *s)
 	/* Wait for Receive Busy to show disabled.
 	*/
 	do {
-		stat = readl((void *)PSC_AC97STAT);
+		stat = au_readl(PSC_AC97STAT);
 		au_sync();
 	} while ((stat & PSC_AC97STAT_RB) != 0);
 
@@ -541,7 +541,7 @@ set_xmit_slots(int num_channels)
 	/* Wait for Device ready.
 	*/
 	do {
-		stat = readl((void *)PSC_AC97STAT);
+		stat = au_readl(PSC_AC97STAT);
 		au_sync();
 	} while ((stat & PSC_AC97STAT_DR) == 0);
 }
@@ -573,7 +573,7 @@ set_recv_slots(int num_channels)
 	/* Wait for Device ready.
 	*/
 	do {
-		stat = readl((void *)PSC_AC97STAT);
+		stat = au_readl(PSC_AC97STAT);
 		au_sync();
 	} while ((stat & PSC_AC97STAT_DR) == 0);
 }
@@ -1995,7 +1995,7 @@ au1550_probe(void)
 	/* Wait for PSC ready.
 	*/
 	do {
-		val = readl((void *)PSC_AC97STAT);
+		val = au_readl(PSC_AC97STAT);
 		au_sync();
 	} while ((val & PSC_AC97STAT_SR) == 0);
 
@@ -2018,7 +2018,7 @@ au1550_probe(void)
 	/* Wait for Device ready.
 	*/
 	do {
-		val = readl((void *)PSC_AC97STAT);
+		val = au_readl(PSC_AC97STAT);
 		au_sync();
 	} while ((val & PSC_AC97STAT_DR) == 0);
 
diff --git a/sound/oss/trident.c b/sound/oss/trident.c
index 5f0ad6b..a21c663 100644
--- a/sound/oss/trident.c
+++ b/sound/oss/trident.c
@@ -278,16 +278,14 @@ static char *card_names[] = {
 };
 
 static struct pci_device_id trident_pci_tbl[] = {
-	{PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX,
-	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, TRIDENT_4D_DX},
-	{PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX,
-	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, TRIDENT_4D_NX},
-	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7018,
-	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_7018},
-	{PCI_VENDOR_ID_ALI, PCI_DEVICE_ID_ALI_5451,
-	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, ALI_5451},
-	{PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5050,
-	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, CYBER5050},
+	{PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX),
+		PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, TRIDENT_4D_DX},
+	{PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX),
+		0, 0, TRIDENT_4D_NX},
+	{PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7018), 0, 0, SIS_7018},
+	{PCI_DEVICE(PCI_VENDOR_ID_ALI, PCI_DEVICE_ID_ALI_5451), 0, 0, ALI_5451},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5050),
+		0, 0, CYBER5050},
 	{0,}
 };
 
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 4aa5fdc..a444a78 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -1621,8 +1621,27 @@ static const struct snd_kcontrol_new snd
 	AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0),
 };
 
+/* black list to avoid HP/Line jack-sense controls
+ * (SS vendor << 16 | device)
+ */
+static unsigned int ad1981_jacks_blacklist[] = {
+	0x10140554, /* Thinkpad T42p/R50p */
+	0 /* end */
+};
+
+static int check_list(struct snd_ac97 *ac97, const unsigned int *list)
+{
+	u32 subid = ((u32)ac97->subsystem_vendor << 16) | ac97->subsystem_device;
+	for (; *list; list++)
+		if (*list == subid)
+			return 1;
+	return 0;
+}
+
 static int patch_ad1981a_specific(struct snd_ac97 * ac97)
 {
+	if (check_list(ac97, ad1981_jacks_blacklist))
+		return 0;
 	return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense,
 				    ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
 }
@@ -1635,22 +1654,26 @@ static struct snd_ac97_build_ops patch_a
 #endif
 };
 
+/* white list to enable HP jack-sense bits
+ * (SS vendor << 16 | device)
+ */
+static unsigned int ad1981_jacks_whitelist[] = {
+	0x0e11005a, /* HP nc4000/4010 */
+	0x103c0890, /* HP nc6000 */
+	0x103c0938, /* HP nc4220 */
+	0x103c099c, /* HP nx6110 */
+	0x103c0944, /* HP nc6220 */
+	0x103c0934, /* HP nc8220 */
+	0x103c006d, /* HP nx9105 */
+	0x17340088, /* FSC Scenic-W */
+	0 /* end */
+};
+
 static void check_ad1981_hp_jack_sense(struct snd_ac97 *ac97)
 {
-	u32 subid = ((u32)ac97->subsystem_vendor << 16) | ac97->subsystem_device;
-	switch (subid) {
-	case 0x0e11005a: /* HP nc4000/4010 */
-	case 0x103c0890: /* HP nc6000 */
-	case 0x103c0938: /* HP nc4220 */
-	case 0x103c099c: /* HP nx6110 */
-	case 0x103c0944: /* HP nc6220 */
-	case 0x103c0934: /* HP nc8220 */
-	case 0x103c006d: /* HP nx9105 */
-	case 0x17340088: /* FSC Scenic-W */
+	if (check_list(ac97, ad1981_jacks_whitelist))
 		/* enable headphone jack sense */
 		snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11);
-		break;
-	}
 }
 
 int patch_ad1981a(struct snd_ac97 *ac97)
@@ -1672,6 +1695,8 @@ static int patch_ad1981b_specific(struct
 
 	if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0)
 		return err;
+	if (check_list(ac97, ad1981_jacks_blacklist))
+		return 0;
 	return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense,
 				    ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
 }
@@ -2210,9 +2235,9 @@ static void alc850_update_jacks(struct s
 	/* Vref disable (bit12), 1kOhm (bit13) */
 	snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<12)|(1<<13),
 			     shared ? (1<<12) : (1<<13));
-	/* MIC-IN = 1, CENTER-LFE = 2 */
+	/* MIC-IN = 1, CENTER-LFE = 5 */
 	snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 4,
-			     shared ? (2<<4) : (1<<4));
+			     shared ? (5<<4) : (1<<4));
 }
 
 static const struct snd_kcontrol_new snd_ac97_controls_alc850[] = {
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index bc4d1ef..e264136 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -279,7 +279,7 @@ struct snd_ali {
 };
 
 static struct pci_device_id snd_ali_ids[] = {
-	{0x10b9, 0x5451, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
+	{PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5451), 0, 0, 0},
 	{0, }
 };
 MODULE_DEVICE_TABLE(pci, snd_ali_ids);
diff --git a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c
index 13bc8ed..c8280f8 100644
--- a/sound/pci/au88x0/au88x0_eq.c
+++ b/sound/pci/au88x0/au88x0_eq.c
@@ -849,7 +849,7 @@ static int
 snd_vortex_peaks_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
-	int i, count;
+	int i, count = 0;
 	u16 peaks[20];
 
 	vortex_Eqlzr_GetAllPeaks(vortex, peaks, &count);
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index dc9cd30..c840a4c 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -781,6 +781,8 @@ static struct pci_device_id snd_bt87x_id
 	BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000),
 	/* Viewcast Osprey 200 */
 	BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100),
+	/* AVerMedia Studio No. 103, 203, ...? */
+	BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1461, 0x0003, 48000),
 	{ }
 };
 MODULE_DEVICE_TABLE(pci, snd_bt87x_ids);
@@ -808,7 +810,7 @@ static int __devinit snd_bt87x_detect_ca
 	const struct pci_device_id *supported;
 
 	supported = pci_match_device(&driver, pci);
-	if (supported)
+	if (supported && supported->driver_data > 0)
 		return supported->driver_data;
 
 	for (i = 0; i < ARRAY_SIZE(blacklist); ++i)
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 6ed7c0b..9477838 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -199,7 +199,8 @@ static struct snd_ca0106_details ca0106_
 	   .name   = "MSI K8N Diamond MB [SB0438]",
 	   .gpio_type = 1,
 	   .i2c_adc = 1 } ,
-	 /* Shuttle XPC SD31P which has an onboard Creative Labs Sound Blaster Live! 24-bit EAX
+	 /* Shuttle XPC SD31P which has an onboard Creative Labs
+	  * Sound Blaster Live! 24-bit EAX
 	  * high-definition 7.1 audio processor".
 	  * Added using info from andrewvegan in alsa bug #1298
 	  */
@@ -207,6 +208,15 @@ static struct snd_ca0106_details ca0106_
 	   .name   = "Shuttle XPC SD31P [SD31P]",
 	   .gpio_type = 1,
 	   .i2c_adc = 1 } ,
+	/* Shuttle XPC SD11G5 which has an onboard Creative Labs
+	 * Sound Blaster Live! 24-bit EAX
+	 * high-definition 7.1 audio processor".
+	 * Fixes ALSA bug#1600
+         */
+	{ .serial = 0x30411297,
+	  .name = "Shuttle XPC SD11G5 [SD11G5]",
+	  .gpio_type = 1,
+	  .i2c_adc = 1 } ,
 	 { .serial = 0,
 	   .name   = "AudigyLS [Unknown]" }
 };
diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c
index 509aa2b..d4e0fb3 100644
--- a/sound/pci/cs46xx/dsp_spos_scb_lib.c
+++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c
@@ -675,7 +675,7 @@ cs46xx_dsp_create_src_task_scb(struct sn
 		if (pass_through) {
 			/* wont work with any other rate than
 			   the native DSP rate */
-			snd_assert (rate = 48000);
+			snd_assert (rate == 48000);
 
 			scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&src_task_scb,
 							    dest,"DMAREADER",parent_scb,
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index f36ede8..02e3721 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -46,8 +46,10 @@ static char *id[SNDRV_CARDS] = SNDRV_DEF
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
 
 static struct pci_device_id snd_cs5535audio_ids[] = {
-	{ PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_AUDIO, PCI_ANY_ID,
-		PCI_ANY_ID, 0, 0, 0, },
+	{ PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_AUDIO,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
+	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
 	{}
 };
 
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index 2e86a90..2a9d12d 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -759,6 +759,8 @@ int __devinit snd_emu10k1_mixer(struct s
 		"Master Mono Playback Volume",
 		"PCM Out Path & Mute",
 		"Mono Output Select",
+		"Front Playback Switch",
+		"Front Playback Volume",
 		"Surround Playback Switch",
 		"Surround Playback Volume",
 		"Center Playback Switch",
@@ -829,9 +831,9 @@ int __devinit snd_emu10k1_mixer(struct s
 		}
 		if (emu->audigy) {
 			/* set master volume to 0 dB */
-			snd_ac97_write(emu->ac97, AC97_MASTER, 0x0000);
+			snd_ac97_write_cache(emu->ac97, AC97_MASTER, 0x0000);
 			/* set capture source to mic */
-			snd_ac97_write(emu->ac97, AC97_REC_SEL, 0x0000);
+			snd_ac97_write_cache(emu->ac97, AC97_REC_SEL, 0x0000);
 			c = audigy_remove_ctls;
 		} else {
 			/*
@@ -844,8 +846,8 @@ int __devinit snd_emu10k1_mixer(struct s
 				snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT);
 			}
 			/* remove unused AC97 controls */
-			snd_ac97_write(emu->ac97, AC97_SURROUND_MASTER, 0x0202);
-			snd_ac97_write(emu->ac97, AC97_CENTER_LFE_MASTER, 0x0202);
+			snd_ac97_write_cache(emu->ac97, AC97_SURROUND_MASTER, 0x0202);
+			snd_ac97_write_cache(emu->ac97, AC97_CENTER_LFE_MASTER, 0x0202);
 			c = emu10k1_remove_ctls;
 		}
 		for (; *c; c++)
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index a983deb..fd12b69 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -75,6 +75,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},
 			 "{Intel, ICH6M},"
 			 "{Intel, ICH7},"
 			 "{Intel, ESB2},"
+			 "{Intel, ICH8},"
 			 "{ATI, SB450},"
 			 "{VIA, VT8251},"
 			 "{VIA, VT8237A},"
@@ -1586,6 +1587,7 @@ static struct pci_device_id azx_ids[] = 
 	{ 0x8086, 0x2668, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH6 */
 	{ 0x8086, 0x27d8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH7 */
 	{ 0x8086, 0x269a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ESB2 */
+	{ 0x8086, 0x284b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH8 */
 	{ 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB450 */
 	{ 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */
 	{ 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index ad9e501..b767552 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1668,6 +1668,7 @@ static struct hda_board_config alc880_cf
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x8196, .config = ALC880_6ST }, /* ASUS P5GD1-HVM */
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x81b4, .config = ALC880_6ST },
 	{ .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_6ST }, /* Acer APFV */
+	{ .pci_subvendor = 0x1458, .pci_subdevice = 0xa102, .config = ALC880_6ST }, /* Gigabyte K8N51 */
 
 	{ .modelname = "6stack-digout", .config = ALC880_6ST_DIG },
 	{ .pci_subvendor = 0x2668, .pci_subdevice = 0x8086, .config = ALC880_6ST_DIG },
@@ -2475,7 +2476,7 @@ static struct hda_verb alc260_init_verbs
 	/* LINE-2 is used for line-out in rear */
 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 	/* select line-out */
-	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
 	/* LINE-OUT pin */
 	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 	/* enable HP */
@@ -2945,6 +2946,8 @@ static int alc260_auto_init(struct hda_c
  */
 static struct hda_board_config alc260_cfg_tbl[] = {
 	{ .modelname = "basic", .config = ALC260_BASIC },
+	{ .pci_subvendor = 0x104d, .pci_subdevice = 0x81bb,
+	  .config = ALC260_BASIC }, /* Sony VAIO */
 	{ .modelname = "hp", .config = ALC260_HP },
 	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP },
 	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP },
@@ -3414,12 +3417,12 @@ static struct snd_kcontrol_new alc882_ca
  * configuration and preset
  */
 static struct hda_board_config alc882_cfg_tbl[] = {
-	{ .modelname = "3stack-dig", .config = ALC861_3ST_DIG },
-	{ .modelname = "6stack-dig", .config = ALC861_6ST_DIG },
+	{ .modelname = "3stack-dig", .config = ALC882_3ST_DIG },
+	{ .modelname = "6stack-dig", .config = ALC882_6ST_DIG },
 	{ .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* MSI  */
 	{ .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* Foxconn */
 	{ .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* ECS */
-	{ .modelname = "auto", .config = ALC861_AUTO },
+	{ .modelname = "auto", .config = ALC882_AUTO },
 	{}
 };
 
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index 8f8840e..250242c 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -297,6 +297,7 @@ static int patch_si3054(struct hda_codec
 struct hda_codec_preset snd_hda_preset_si3054[] = {
  	{ .id = 0x163c3055, .name = "Si3054", .patch = patch_si3054 },
  	{ .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 },
+ 	{ .id = 0x11c13026, .name = "Si3054", .patch = patch_si3054 },
 	{}
 };
 
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 6190384..35c2823 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -50,10 +50,11 @@ struct sigmatel_spec {
 	unsigned int surr_switch: 1;
 	unsigned int line_switch: 1;
 	unsigned int mic_switch: 1;
+	unsigned int alt_switch: 1;
 
 	/* playback */
 	struct hda_multi_out multiout;
-	hda_nid_t dac_nids[4];
+	hda_nid_t dac_nids[5];
 
 	/* capture */
 	hda_nid_t *adc_nids;
@@ -73,7 +74,7 @@ struct sigmatel_spec {
 
 	/* capture source */
 	struct hda_input_mux *input_mux;
-	unsigned int cur_mux[2];
+	unsigned int cur_mux[3];
 
 	/* i/o switches */
 	unsigned int io_switch[2];
@@ -107,6 +108,14 @@ static hda_nid_t stac922x_mux_nids[2] = 
         0x12, 0x13,
 };
 
+static hda_nid_t stac927x_adc_nids[3] = {
+        0x07, 0x08, 0x09
+};
+
+static hda_nid_t stac927x_mux_nids[3] = {
+        0x15, 0x16, 0x17
+};
+
 static hda_nid_t stac9200_pin_nids[8] = {
 	0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
 };
@@ -116,6 +125,12 @@ static hda_nid_t stac922x_pin_nids[10] =
 	0x0f, 0x10, 0x11, 0x15, 0x1b,
 };
 
+static hda_nid_t stac927x_pin_nids[14] = {
+	0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
+	0x0f, 0x10, 0x11, 0x12, 0x13,
+	0x14, 0x21, 0x22, 0x23,
+};
+
 static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
@@ -155,6 +170,12 @@ static struct hda_verb stac922x_core_ini
 	{}
 };
 
+static struct hda_verb stac927x_core_init[] = {
+	/* set master volume and direct control */	
+	{ 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
+	{}
+};
+
 static struct snd_kcontrol_new stac9200_mixer[] = {
 	HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
 	HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
@@ -183,10 +204,26 @@ static struct snd_kcontrol_new stac922x_
 		.put = stac92xx_mux_enum_put,
 	},
 	HDA_CODEC_VOLUME("Capture Volume", 0x17, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x17, 0x0, HDA_INPUT),
 	HDA_CODEC_VOLUME("Mux Capture Volume", 0x12, 0x0, HDA_OUTPUT),
 	{ } /* end */
 };
 
+static snd_kcontrol_new_t stac927x_mixer[] = {
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Input Source",
+		.count = 1,
+		.info = stac92xx_mux_enum_info,
+		.get = stac92xx_mux_enum_get,
+		.put = stac92xx_mux_enum_put,
+	},
+	HDA_CODEC_VOLUME("InMux Capture Volume", 0x15, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("InVol Capture Volume", 0x18, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("ADCMux Capture Switch", 0x1b, 0x0, HDA_OUTPUT),
+	{ } /* end */
+};
+
 static int stac92xx_build_controls(struct hda_codec *codec)
 {
 	struct sigmatel_spec *spec = codec->spec;
@@ -240,14 +277,14 @@ static unsigned int ref922x_pin_configs[
 };
 
 static unsigned int d945gtp3_pin_configs[10] = {
-	0x0221401f, 0x01a19022, 0x01813021, 0x01114010,
+	0x0221401f, 0x01a19022, 0x01813021, 0x01014010,
 	0x40000100, 0x40000100, 0x40000100, 0x40000100,
 	0x02a19120, 0x40000100,
 };
 
 static unsigned int d945gtp5_pin_configs[10] = {
-	0x0221401f, 0x01111012, 0x01813024, 0x01114010,
-	0x01a19021, 0x01116011, 0x01452130, 0x40000100,
+	0x0221401f, 0x01011012, 0x01813024, 0x01014010,
+	0x01a19021, 0x01016011, 0x01452130, 0x40000100,
 	0x02a19320, 0x40000100,
 };
 
@@ -274,6 +311,28 @@ static struct hda_board_config stac922x_
 	{ .pci_subvendor = PCI_VENDOR_ID_INTEL,
 	  .pci_subdevice = 0x0013,
 	  .config = STAC_D945GTP5 },	/* Intel D955XBK - 5 Stack */
+	{ .pci_subvendor = PCI_VENDOR_ID_INTEL,
+	  .pci_subdevice = 0x0417,
+	  .config = STAC_D945GTP5 },	/* Intel D975XBK - 5 Stack */
+	{} /* terminator */
+};
+
+static unsigned int ref927x_pin_configs[14] = {
+	0x01813122, 0x01a19021, 0x01014010, 0x01016011,
+	0x01012012, 0x01011014, 0x40000100, 0x40000100, 
+	0x40000100, 0x40000100, 0x40000100, 0x01441030,
+	0x01c41030, 0x40000100,
+};
+
+static unsigned int *stac927x_brd_tbl[] = {
+	ref927x_pin_configs,
+};
+
+static struct hda_board_config stac927x_cfg_tbl[] = {
+	{ .modelname = "ref",
+	  .pci_subvendor = PCI_VENDOR_ID_INTEL,
+	  .pci_subdevice = 0x2668,	/* DFI LanParty */
+	  .config = STAC_REF },		/* SigmaTel reference board */
 	{} /* terminator */
 };
 
@@ -408,11 +467,23 @@ static struct hda_pcm_stream stac92xx_pc
 	},
 };
 
+static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 2,
+	.nid = 0x06, /* NID to query formats and rates */
+	.ops = {
+		.open = stac92xx_playback_pcm_open,
+		.prepare = stac92xx_playback_pcm_prepare,
+		.cleanup = stac92xx_playback_pcm_cleanup
+	},
+};
+
 static struct hda_pcm_stream stac92xx_pcm_analog_capture = {
 	.substreams = 2,
 	.channels_min = 2,
 	.channels_max = 2,
-	.nid = 0x06, /* NID to query formats and rates */
+	/* NID is set in stac92xx_build_pcms */
 	.ops = {
 		.prepare = stac92xx_capture_pcm_prepare,
 		.cleanup = stac92xx_capture_pcm_cleanup
@@ -430,6 +501,14 @@ static int stac92xx_build_pcms(struct hd
 	info->name = "STAC92xx Analog";
 	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback;
 	info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture;
+	info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
+
+	if (spec->alt_switch) {
+		codec->num_pcms++;
+		info++;
+		info->name = "STAC92xx Analog Alt";
+		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_alt_playback;
+	}
 
 	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
 		codec->num_pcms++;
@@ -588,6 +667,16 @@ static int stac92xx_add_dyn_out_pins(str
 	return 0;
 }
 
+/*
+ * XXX The line_out pin widget connection list may not be set to the
+ * desired DAC nid. This is the case on 927x where ports A and B can
+ * be routed to several DACs.
+ *
+ * This requires an analysis of the line-out/hp pin configuration
+ * to provide a best fit for pin/DAC configurations that are routable.
+ * For now, 927x DAC4 is not supported and 927x DAC1 output to ports
+ * A and B is not supported.
+ */
 /* fill in the dac_nids table from the parsed pin configuration */
 static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
 {
@@ -602,7 +691,13 @@ static int stac92xx_auto_fill_dac_nids(s
 					AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
 	}
 
-	spec->multiout.num_dacs = cfg->line_outs;
+	if (cfg->line_outs)
+		spec->multiout.num_dacs = cfg->line_outs;
+	else if (cfg->hp_pin) {
+		spec->multiout.dac_nids[0] = snd_hda_codec_read(codec, cfg->hp_pin, 0,
+					AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
+		spec->multiout.num_dacs = 1;
+	}
 
 	return 0;
 }
@@ -753,19 +848,21 @@ static void stac92xx_auto_init_hp_out(st
 		stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
 }
 
-static int stac922x_parse_auto_config(struct hda_codec *codec)
+static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in)
 {
 	struct sigmatel_spec *spec = codec->spec;
 	int err;
 
 	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
 		return err;
+	if (! spec->autocfg.line_outs && ! spec->autocfg.hp_pin)
+		return 0; /* can't find valid pin config */
+	stac92xx_auto_init_multi_out(codec);
+	stac92xx_auto_init_hp_out(codec);
 	if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0)
 		return err;
 	if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
 		return err;
-	if (! spec->autocfg.line_outs && ! spec->autocfg.hp_pin)
-		return 0; /* can't find valid pin config */
 
 	if ((err = stac92xx_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
 	    (err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg)) < 0 ||
@@ -777,11 +874,11 @@ static int stac922x_parse_auto_config(st
 		spec->surr_switch = 1;
 
 	if (spec->autocfg.dig_out_pin) {
-		spec->multiout.dig_out_nid = 0x08;
+		spec->multiout.dig_out_nid = dig_out;
 		stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_out_pin, AC_PINCTL_OUT_EN);
 	}
 	if (spec->autocfg.dig_in_pin) {
-		spec->dig_in_nid = 0x09;
+		spec->dig_in_nid = dig_in;
 		stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_in_pin, AC_PINCTL_IN_EN);
 	}
 
@@ -827,9 +924,6 @@ static int stac92xx_init(struct hda_code
 
 	snd_hda_sequence_write(codec, spec->init);
 
-	stac92xx_auto_init_multi_out(codec);
-	stac92xx_auto_init_hp_out(codec);
-
 	return 0;
 }
 
@@ -996,7 +1090,47 @@ static int patch_stac922x(struct hda_cod
 
 	spec->multiout.dac_nids = spec->dac_nids;
 
-	err = stac922x_parse_auto_config(codec);
+	err = stac92xx_parse_auto_config(codec, 0x08, 0x09);
+	if (err < 0) {
+		stac92xx_free(codec);
+		return err;
+	}
+
+	codec->patch_ops = stac92xx_patch_ops;
+
+	return 0;
+}
+
+static int patch_stac927x(struct hda_codec *codec)
+{
+	struct sigmatel_spec *spec;
+	int err;
+
+	spec  = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if (spec == NULL)
+		return -ENOMEM;
+
+	codec->spec = spec;
+	spec->board_config = snd_hda_check_board_config(codec, stac927x_cfg_tbl);
+	if (spec->board_config < 0)
+                snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC927x, using BIOS defaults\n");
+	else {
+		spec->num_pins = 14;
+		spec->pin_nids = stac927x_pin_nids;
+		spec->pin_configs = stac927x_brd_tbl[spec->board_config];
+		stac92xx_set_config_regs(codec);
+	}
+
+	spec->adc_nids = stac927x_adc_nids;
+	spec->mux_nids = stac927x_mux_nids;
+	spec->num_muxes = 3;
+
+	spec->init = stac927x_core_init;
+	spec->mixer = stac927x_mixer;
+
+	spec->multiout.dac_nids = spec->dac_nids;
+
+	err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);
 	if (err < 0) {
 		stac92xx_free(codec);
 		return err;
@@ -1018,5 +1152,15 @@ struct hda_codec_preset snd_hda_preset_s
  	{ .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x },
  	{ .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x },
  	{ .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x },
+ 	{ .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x },
+ 	{ .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x },
+ 	{ .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x },
+ 	{ .id = 0x83847623, .name = "STAC9273D", .patch = patch_stac927x },
+ 	{ .id = 0x83847624, .name = "STAC9272X", .patch = patch_stac927x },
+ 	{ .id = 0x83847625, .name = "STAC9272D", .patch = patch_stac927x },
+ 	{ .id = 0x83847626, .name = "STAC9271X", .patch = patch_stac927x },
+ 	{ .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x },
+ 	{ .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x },
+ 	{ .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x },
 	{} /* terminator */
 };
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 5466b1f..174237f 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -427,6 +427,7 @@ static struct pci_device_id snd_intel8x0
 	{ 0x10de, 0x008a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE },	/* CK8 */
 	{ 0x10de, 0x00da, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE },	/* NFORCE3 */
 	{ 0x10de, 0x00ea, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE },	/* CK8S */
+	{ 0x10de, 0x026b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE },	/* MCP51 */
 	{ 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL },	/* AMD8111 */
 	{ 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL },	/* AMD768 */
 	{ 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI },   /* Ali5455 */
@@ -1805,6 +1806,12 @@ static struct ac97_quirk ac97_quirks[] _
 	},
 	{
 		.subvendor = 0x1028,
+		.subdevice = 0x0151,
+		.name = "Dell Optiplex GX270",  /* AD1981B */
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.subvendor = 0x1028,
 		.subdevice = 0x0163,
 		.name = "Dell Unknown",	/* STAC9750/51 */
 		.type = AC97_TUNE_HP_ONLY
@@ -1847,12 +1854,6 @@ static struct ac97_quirk ac97_quirks[] _
 	},
 	{
 		.subvendor = 0x103c,
-		.subdevice = 0x099c,
-		.name = "HP nx6110",	/* AD1981B */
-		.type = AC97_TUNE_HP_ONLY
-	},
-	{
-		.subvendor = 0x103c,
 		.subdevice = 0x129d,
 		.name = "HP xw8000",
 		.type = AC97_TUNE_HP_ONLY
@@ -1866,7 +1867,7 @@ static struct ac97_quirk ac97_quirks[] _
 	{
 		.subvendor = 0x103c,
 		.subdevice = 0x099c,
-		.name = "HP nc6120",
+		.name = "HP nx6110/nc6120",
 		.type = AC97_TUNE_HP_MUTE_LED
 	},
 	{
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index b8c0853..b2cba75 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -454,7 +454,7 @@ static int pcxhr_update_r_buffer(struct 
 	is_capture = (subs->stream == SNDRV_PCM_STREAM_CAPTURE);
 	stream_num = is_capture ? 0 : subs->number;
 
-	snd_printdd("pcxhr_update_r_buffer(pcm%c%d) : addr(%p) bytes(%x) subs(%d)\n",
+	snd_printdd("pcxhr_update_r_buffer(pcm%c%d) : addr(%p) bytes(%zx) subs(%d)\n",
 		    is_capture ? 'c' : 'p',
 		    chip->chip_idx, (void*)subs->runtime->dma_addr,
 		    subs->runtime->dma_bytes, subs->number);
@@ -744,13 +744,14 @@ static int pcxhr_prepare(struct snd_pcm_
 		/* only the first stream can choose the sample rate */
 		/* the further opened streams will be limited to its frequency (see open) */
 		/* set the clock only once (first stream) */
-		if (mgr->sample_rate == 0) {
+		if (mgr->sample_rate != subs->runtime->rate) {
 			err = pcxhr_set_clock(mgr, subs->runtime->rate);
 			if (err)
 				break;
+			if (mgr->sample_rate == 0)
+				/* start the DSP-timer */
+				err = pcxhr_hardware_timer(mgr, 1);
 			mgr->sample_rate = subs->runtime->rate;
-
-			err = pcxhr_hardware_timer(mgr, 1);	/* start the DSP-timer */
 		}
 	} while(0);	/* do only once (so we can use break instead of goto) */
 
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 3dec616..103b4d7 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -3324,11 +3324,11 @@ static int __devinit snd_hdspm_prealloca
 						   snd_dma_pci_data(hdspm->pci),
 						   wanted,
 						   wanted)) < 0) {
-		snd_printdd("Could not preallocate %d  Bytes\n", wanted);
+		snd_printdd("Could not preallocate %zd Bytes\n", wanted);
 
 		return err;
 	} else
-		snd_printdd(" Preallocated %d  Bytes\n", wanted);
+		snd_printdd(" Preallocated %zd Bytes\n", wanted);
 
 	return 0;
 }
@@ -3510,7 +3510,7 @@ static int __devinit snd_hdspm_create(st
 
 	hdspm->monitor_outs = enable_monitor;
 
-	snd_printdd("kmalloc Mixer memory of %d Bytes\n",
+	snd_printdd("kmalloc Mixer memory of %zd Bytes\n",
 		   sizeof(struct hdspm_mixer));
 	if ((hdspm->mixer = kmalloc(sizeof(struct hdspm_mixer), GFP_KERNEL))
 	    == NULL) {
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index 2b21df1..b453804 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -64,9 +64,11 @@ module_param_array(wavetable_size, int, 
 MODULE_PARM_DESC(wavetable_size, "Maximum memory size in kB for wavetable synth.");
 
 static struct pci_device_id snd_trident_ids[] = {
-	{ 0x1023, 0x2000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },	/* Trident 4DWave DX PCI Audio */
-	{ 0x1023, 0x2001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },	/* Trident 4DWave NX PCI Audio */
-	{ 0x1039, 0x7018, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },	/* SiS SI7018 PCI Audio */
+	{PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX), 
+		PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
+	{PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX), 
+		0, 0, 0},
+	{PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7018), 0, 0, 0},
 	{ 0, }
 };
 
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index ed26a15..4237413 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -2340,6 +2340,7 @@ static int __devinit check_dxs_list(stru
 		{ .subvendor = 0x1043, .subdevice = 0x80b0, .action = VIA_DXS_NO_VRA }, /* ASUS A7V600 & K8V*/ 
 		{ .subvendor = 0x1043, .subdevice = 0x810d, .action = VIA_DXS_SRC }, /* ASUS */
 		{ .subvendor = 0x1043, .subdevice = 0x812a, .action = VIA_DXS_SRC    }, /* ASUS A8V Deluxe */ 
+		{ .subvendor = 0x1043, .subdevice = 0x8174, .action = VIA_DXS_SRC    }, /* ASUS */
 		{ .subvendor = 0x1071, .subdevice = 0x8375, .action = VIA_DXS_NO_VRA }, /* Vobis/Yakumo/Mitac notebook */
 		{ .subvendor = 0x1071, .subdevice = 0x8399, .action = VIA_DXS_NO_VRA }, /* Umax AB 595T (VIA K8N800A - VT8237) */
 		{ .subvendor = 0x10cf, .subdevice = 0x118e, .action = VIA_DXS_ENABLE }, /* FSC laptop */
@@ -2358,6 +2359,7 @@ static int __devinit check_dxs_list(stru
 		{ .subvendor = 0x1462, .subdevice = 0x7023, .action = VIA_DXS_NO_VRA }, /* MSI K8T Neo2-FI */
 		{ .subvendor = 0x1462, .subdevice = 0x7120, .action = VIA_DXS_ENABLE }, /* MSI KT4V */
 		{ .subvendor = 0x1462, .subdevice = 0x7142, .action = VIA_DXS_ENABLE }, /* MSI K8MM-V */
+		{ .subvendor = 0x1462, .subdevice = 0xb012, .action = VIA_DXS_SRC }, /* P4M800/VIA8237R */
 		{ .subvendor = 0x147b, .subdevice = 0x1401, .action = VIA_DXS_ENABLE }, /* ABIT KD7(-RAID) */
 		{ .subvendor = 0x147b, .subdevice = 0x1411, .action = VIA_DXS_ENABLE }, /* ABIT VA-20 */
 		{ .subvendor = 0x147b, .subdevice = 0x1413, .action = VIA_DXS_ENABLE }, /* ABIT KV8 Pro */
@@ -2371,6 +2373,9 @@ static int __devinit check_dxs_list(stru
 		{ .subvendor = 0x161f, .subdevice = 0x2032, .action = VIA_DXS_48K }, /* m680x machines */
 		{ .subvendor = 0x1631, .subdevice = 0xe004, .action = VIA_DXS_ENABLE }, /* Easy Note 3174, Packard Bell */
 		{ .subvendor = 0x1695, .subdevice = 0x3005, .action = VIA_DXS_ENABLE }, /* EPoX EP-8K9A */
+		{ .subvendor = 0x1695, .subdevice = 0x300e, .action = VIA_DXS_SRC }, /* EPoX 9HEAI */
+		{ .subvendor = 0x16f3, .subdevice = 0x6405, .action = VIA_DXS_SRC }, /* Jetway K8M8MS */
+		{ .subvendor = 0x1734, .subdevice = 0x1093, .action = VIA_DXS_SRC }, /* FSC */
 		{ .subvendor = 0x1849, .subdevice = 0x3059, .action = VIA_DXS_NO_VRA }, /* ASRock K7VM2 */
 		{ .subvendor = 0x1849, .subdevice = 0x9761, .action = VIA_DXS_SRC }, /* ASRock mobo(?) */
 		{ .subvendor = 0x1919, .subdevice = 0x200a, .action = VIA_DXS_NO_VRA }, /* Soltek SL-K8Tpro-939 */
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 1dfc723..a1aa74b 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -1229,6 +1229,7 @@ static int snd_ymfpci_spdif_default_get(
 	spin_lock_irq(&chip->reg_lock);
 	ucontrol->value.iec958.status[0] = (chip->spdif_bits >> 0) & 0xff;
 	ucontrol->value.iec958.status[1] = (chip->spdif_bits >> 8) & 0xff;
+	ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_48000;
 	spin_unlock_irq(&chip->reg_lock);
 	return 0;
 }
@@ -1303,6 +1304,7 @@ static int snd_ymfpci_spdif_stream_get(s
 	spin_lock_irq(&chip->reg_lock);
 	ucontrol->value.iec958.status[0] = (chip->spdif_pcm_bits >> 0) & 0xff;
 	ucontrol->value.iec958.status[1] = (chip->spdif_pcm_bits >> 8) & 0xff;
+	ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_48000;
 	spin_unlock_irq(&chip->reg_lock);
 	return 0;
 }
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index a642e4c..4988f87 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -1216,7 +1216,7 @@ int __init snd_pmac_new(struct snd_card 
 			goto __error;
 		}
 		for (i = 0; i < 3; i ++) {
-			if (of_address_to_resource(np->parent, i,
+			if (of_address_to_resource(np, i,
 						   &chip->rsrc[i])) {
 				printk(KERN_ERR "snd: can't translate rsrc "
 				       " %d (%s)\n", i, rnames[i]);
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index e9086e9..fd65439 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -69,13 +69,14 @@ struct sbus_dma_info {
 };
 #endif
 
+struct snd_cs4231;
 struct cs4231_dma_control {
         void		(*prepare)(struct cs4231_dma_control *dma_cont, int dir);
         void		(*enable)(struct cs4231_dma_control *dma_cont, int on);
         int		(*request)(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len);
         unsigned int	(*address)(struct cs4231_dma_control *dma_cont);
         void		(*reset)(struct snd_cs4231 *chip); 
-        void		(*preallocate)(struct snd_cs4231 *chip, struct snd_snd_pcm *pcm); 
+        void		(*preallocate)(struct snd_cs4231 *chip, struct snd_pcm *pcm); 
 #ifdef EBUS_SUPPORT
 	struct		ebus_dma_info	ebus_info;
 #endif
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index a1bd804..d501338 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -478,22 +478,38 @@ static int retire_playback_sync_urb_hs(s
 /*
  * Prepare urb for streaming before playback starts.
  *
- * We don't care about (or have) any data, so we just send a transfer delimiter.
+ * We don't yet have data, so we send a frame of silence.
  */
 static int prepare_startup_playback_urb(struct snd_usb_substream *subs,
 					struct snd_pcm_runtime *runtime,
 					struct urb *urb)
 {
-	unsigned int i;
+	unsigned int i, offs, counts;
 	struct snd_urb_ctx *ctx = urb->context;
+	int stride = runtime->frame_bits >> 3;
 
+	offs = 0;
 	urb->dev = ctx->subs->dev;
 	urb->number_of_packets = subs->packs_per_ms;
 	for (i = 0; i < subs->packs_per_ms; ++i) {
-		urb->iso_frame_desc[i].offset = 0;
-		urb->iso_frame_desc[i].length = 0;
+		/* calculate the size of a packet */
+		if (subs->fill_max)
+			counts = subs->maxframesize; /* fixed */
+		else {
+			subs->phase = (subs->phase & 0xffff)
+				+ (subs->freqm << subs->datainterval);
+			counts = subs->phase >> 16;
+			if (counts > subs->maxframesize)
+				counts = subs->maxframesize;
+		}
+		urb->iso_frame_desc[i].offset = offs * stride;
+		urb->iso_frame_desc[i].length = counts * stride;
+		offs += counts;
 	}
-	urb->transfer_buffer_length = 0;
+	urb->transfer_buffer_length = offs * stride;
+	memset(urb->transfer_buffer,
+	       subs->cur_audiofmt->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0,
+	       offs * stride);
 	return 0;
 }
 
@@ -2477,12 +2493,13 @@ static int parse_audio_format(struct snd
 	if (err < 0)
 		return err;
 #if 1
-	/* FIXME: temporary hack for extigy/audigy 2 nx */
+	/* FIXME: temporary hack for extigy/audigy 2 nx/zs */
 	/* extigy apparently supports sample rates other than 48k
 	 * but not in ordinary way.  so we enable only 48k atm.
 	 */
 	if (chip->usb_id == USB_ID(0x041e, 0x3000) ||
-	    chip->usb_id == USB_ID(0x041e, 0x3020)) {
+	    chip->usb_id == USB_ID(0x041e, 0x3020) ||
+	    chip->usb_id == USB_ID(0x041e, 0x3061)) {
 		if (fmt[3] == USB_FORMAT_TYPE_I &&
 		    fp->rates != SNDRV_PCM_RATE_48000 &&
 		    fp->rates != SNDRV_PCM_RATE_96000)
