Merge master.kernel.org:/pub/scm/linux/kernel/git/bunk/trivial
diff --git a/Documentation/Changes b/Documentation/Changes
index 783ddc3..86b8639 100644
--- a/Documentation/Changes
+++ b/Documentation/Changes
@@ -139,9 +139,14 @@
 Ksymoops
 --------
 
-If the unthinkable happens and your kernel oopses, you'll need a 2.4
-version of ksymoops to decode the report; see REPORTING-BUGS in the
-root of the Linux source for more information.
+If the unthinkable happens and your kernel oopses, you may need the
+ksymoops tool to decode it, but in most cases you don't.
+In the 2.6 kernel it is generally preferred to build the kernel with
+CONFIG_KALLSYMS so that it produces readable dumps that can be used as-is
+(this also produces better output than ksymoops).
+If for some reason your kernel is not build with CONFIG_KALLSYMS and
+you have no way to rebuild and reproduce the Oops with that option, then
+you can still decode that Oops with ksymoops.
 
 Module-Init-Tools
 -----------------
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index fa3e29a..7018f5c 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -10,7 +10,7 @@
 	    kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
 	    procfs-guide.xml writing_usb_driver.xml \
 	    sis900.xml kernel-api.xml journal-api.xml lsm.xml usb.xml \
-	    gadget.xml libata.xml mtdnand.xml librs.xml
+	    gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml
 
 ###
 # The build process is as follows (targets):
diff --git a/Documentation/DocBook/journal-api.tmpl b/Documentation/DocBook/journal-api.tmpl
index 341aaa4..2077f9a 100644
--- a/Documentation/DocBook/journal-api.tmpl
+++ b/Documentation/DocBook/journal-api.tmpl
@@ -306,7 +306,7 @@
 </para>
 	<sect1><title>Journal Level</title>
 !Efs/jbd/journal.c
-!Efs/jbd/recovery.c
+!Ifs/jbd/recovery.c
 	</sect1>
 	<sect1><title>Transasction Level</title>
 !Efs/jbd/transaction.c	
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index ec474e5..a8316b1 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -118,7 +118,7 @@
      </sect1>
      <sect1><title>User Space Memory Access</title>
 !Iinclude/asm-i386/uaccess.h
-!Iarch/i386/lib/usercopy.c
+!Earch/i386/lib/usercopy.c
      </sect1>
      <sect1><title>More Memory Management Functions</title>
 !Iinclude/linux/rmap.h
@@ -174,7 +174,6 @@
      <title>The Linux VFS</title>
      <sect1><title>The Filesystem types</title>
 !Iinclude/linux/fs.h
-!Einclude/linux/fs.h
      </sect1>
      <sect1><title>The Directory Cache</title>
 !Efs/dcache.c
@@ -266,7 +265,7 @@
   <chapter id="hardware">
      <title>Hardware Interfaces</title>
      <sect1><title>Interrupt Handling</title>
-!Ikernel/irq/manage.c
+!Ekernel/irq/manage.c
      </sect1>
 
      <sect1><title>Resources Management</title>
@@ -501,7 +500,7 @@
 !Edrivers/video/modedb.c
      </sect1>
      <sect1><title>Frame Buffer Macintosh Video Mode Database</title>
-!Idrivers/video/macmodes.c
+!Edrivers/video/macmodes.c
      </sect1>
      <sect1><title>Frame Buffer Fonts</title>
         <para>
diff --git a/Documentation/DocBook/rapidio.tmpl b/Documentation/DocBook/rapidio.tmpl
new file mode 100644
index 0000000..1becf27
--- /dev/null
+++ b/Documentation/DocBook/rapidio.tmpl
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+	<!ENTITY rapidio SYSTEM "rapidio.xml">
+	]>
+
+<book id="RapidIO-Guide">
+ <bookinfo>
+  <title>RapidIO Subsystem Guide</title>
+
+  <authorgroup>
+   <author>
+    <firstname>Matt</firstname>
+    <surname>Porter</surname>
+    <affiliation>
+     <address>
+      <email>mporter@kernel.crashing.org</email>
+      <email>mporter@mvista.com</email>
+     </address>
+    </affiliation>
+   </author>
+  </authorgroup>
+
+  <copyright>
+   <year>2005</year>
+   <holder>MontaVista Software, Inc.</holder>
+  </copyright>
+
+  <legalnotice>
+   <para>
+     This documentation 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.
+   </para>
+
+   <para>
+     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.
+   </para>
+
+   <para>
+     You should have received a copy of the GNU General Public
+     License along with this program; if not, write to the Free
+     Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+     MA 02111-1307 USA
+   </para>
+
+   <para>
+     For more details see the file COPYING in the source
+     distribution of Linux.
+   </para>
+  </legalnotice>
+ </bookinfo>
+
+<toc></toc>
+
+  <chapter id="intro">
+      <title>Introduction</title>
+  <para>
+	RapidIO is a high speed switched fabric interconnect with
+	features aimed at the embedded market.  RapidIO provides
+	support for memory-mapped I/O as well as message-based
+	transactions over the switched fabric network. RapidIO has
+	a standardized discovery mechanism not unlike the PCI bus
+	standard that allows simple detection of devices in a
+	network.
+  </para>
+  <para>
+  	This documentation is provided for developers intending
+	to support RapidIO on new architectures, write new drivers,
+	or to understand the subsystem internals.
+  </para>
+  </chapter>
+
+  <chapter id="bugs">
+     <title>Known Bugs and Limitations</title>
+
+     <sect1>
+     	<title>Bugs</title>
+	  <para>None. ;)</para>
+     </sect1>
+     <sect1>
+     	<title>Limitations</title>
+	  <para>
+	    <orderedlist>
+	      <listitem><para>Access/management of RapidIO memory regions is not supported</para></listitem>
+	      <listitem><para>Multiple host enumeration is not supported</para></listitem>
+	    </orderedlist>
+	 </para>
+     </sect1>
+  </chapter>
+
+  <chapter id="drivers">
+     	<title>RapidIO driver interface</title>
+	<para>
+		Drivers are provided a set of calls in order
+		to interface with the subsystem to gather info
+		on devices, request/map memory region resources,
+		and manage mailboxes/doorbells.
+	</para>
+	<sect1>
+		<title>Functions</title>
+!Iinclude/linux/rio_drv.h
+!Edrivers/rapidio/rio-driver.c
+!Edrivers/rapidio/rio.c
+	</sect1>
+  </chapter>
+
+  <chapter id="internals">
+     <title>Internals</title>
+
+     <para>
+     This chapter contains the autogenerated documentation of the RapidIO
+     subsystem.
+     </para>
+
+     <sect1><title>Structures</title>
+!Iinclude/linux/rio.h
+     </sect1>
+     <sect1><title>Enumeration and Discovery</title>
+!Idrivers/rapidio/rio-scan.c
+     </sect1>
+     <sect1><title>Driver functionality</title>
+!Idrivers/rapidio/rio.c
+!Idrivers/rapidio/rio-access.c
+     </sect1>
+     <sect1><title>Device model support</title>
+!Idrivers/rapidio/rio-driver.c
+     </sect1>
+     <sect1><title>Sysfs support</title>
+!Idrivers/rapidio/rio-sysfs.c
+     </sect1>
+     <sect1><title>PPC32 support</title>
+!Iarch/ppc/kernel/rio.c
+!Earch/ppc/syslib/ppc85xx_rio.c
+!Iarch/ppc/syslib/ppc85xx_rio.c
+     </sect1>
+  </chapter>
+
+  <chapter id="credits">
+     <title>Credits</title>
+	<para>
+		The following people have contributed to the RapidIO
+		subsystem directly or indirectly:
+		<orderedlist>
+			<listitem><para>Matt Porter<email>mporter@kernel.crashing.org</email></para></listitem>
+			<listitem><para>Randy Vinson<email>rvinson@mvista.com</email></para></listitem>
+			<listitem><para>Dan Malek<email>dan@embeddedalley.com</email></para></listitem>
+		</orderedlist>
+	</para>
+	<para>
+		The following people have contributed to this document:
+		<orderedlist>
+			<listitem><para>Matt Porter<email>mporter@kernel.crashing.org</email></para></listitem>
+		</orderedlist>
+	</para>
+  </chapter>
+</book>
diff --git a/Documentation/MSI-HOWTO.txt b/Documentation/MSI-HOWTO.txt
index 63edc5f..3ec6c72 100644
--- a/Documentation/MSI-HOWTO.txt
+++ b/Documentation/MSI-HOWTO.txt
@@ -10,14 +10,22 @@
 This guide describes the basics of Message Signaled Interrupts (MSI),
 the advantages of using MSI over traditional interrupt mechanisms,
 and how to enable your driver to use MSI or MSI-X. Also included is
-a Frequently Asked Questions.
+a Frequently Asked Questions (FAQ) section.
+
+1.1 Terminology
+
+PCI devices can be single-function or multi-function.  In either case,
+when this text talks about enabling or disabling MSI on a "device
+function," it is referring to one specific PCI device and function and
+not to all functions on a PCI device (unless the PCI device has only
+one function).
 
 2. Copyright 2003 Intel Corporation
 
 3. What is MSI/MSI-X?
 
 Message Signaled Interrupt (MSI), as described in the PCI Local Bus
-Specification Revision 2.3 or latest, is an optional feature, and a
+Specification Revision 2.3 or later, is an optional feature, and a
 required feature for PCI Express devices. MSI enables a device function
 to request service by sending an Inbound Memory Write on its PCI bus to
 the FSB as a Message Signal Interrupt transaction. Because MSI is
@@ -27,7 +35,7 @@
 
 A PCI device that supports MSI must also support pin IRQ assertion
 interrupt mechanism to provide backward compatibility for systems that
-do not support MSI. In Systems, which support MSI, the bus driver is
+do not support MSI. In systems which support MSI, the bus driver is
 responsible for initializing the message address and message data of
 the device function's MSI/MSI-X capability structure during device
 initial configuration.
@@ -61,17 +69,17 @@
 
         - MSI and MSI-X both support per-vector masking. Per-vector
 	masking is an optional extension of MSI but a required
-	feature for MSI-X. Per-vector masking provides the kernel
-	the ability to mask/unmask MSI when servicing its software
-	interrupt service routing handler. If per-vector masking is
+	feature for MSI-X. Per-vector masking provides the kernel the
+	ability to mask/unmask a single MSI while running its
+	interrupt service routine. If per-vector masking is
 	not supported, then the device driver should provide the
 	hardware/software synchronization to ensure that the device
 	generates MSI when the driver wants it to do so.
 
 4. Why use MSI?
 
-As a benefit the simplification of board design, MSI allows board
-designers to remove out of band interrupt routing. MSI is another
+As a benefit to the simplification of board design, MSI allows board
+designers to remove out-of-band interrupt routing. MSI is another
 step towards a legacy-free environment.
 
 Due to increasing pressure on chipset and processor packages to
@@ -87,7 +95,7 @@
 support for better interrupt performance.
 
 Using MSI enables the device functions to support two or more
-vectors, which can be configured to target different CPU's to
+vectors, which can be configured to target different CPUs to
 increase scalability.
 
 5. Configuring a driver to use MSI/MSI-X
@@ -119,13 +127,13 @@
 
 int pci_enable_msi(struct pci_dev *dev)
 
-With this new API, any existing device driver, which like to have
-MSI enabled on its device function, must call this API to enable MSI
+With this new API, a device driver that wants to have MSI
+enabled on its device function must call this API to enable MSI.
 A successful call will initialize the MSI capability structure
 with ONE vector, regardless of whether a device function is
 capable of supporting multiple messages. This vector replaces the
-pre-assigned dev->irq with a new MSI vector. To avoid the conflict
-of new assigned vector with existing pre-assigned vector requires
+pre-assigned dev->irq with a new MSI vector. To avoid a conflict
+of the new assigned vector with existing pre-assigned vector requires
 a device driver to call this API before calling request_irq().
 
 5.2.2 API pci_disable_msi
@@ -137,14 +145,14 @@
 the pre-assigned IOAPIC vector and switches a device's interrupt
 mode to PCI pin-irq assertion/INTx emulation mode.
 
-Note that a device driver should always call free_irq() on MSI vector
-it has done request_irq() on before calling this API. Failure to do
-so results a BUG_ON() and a device will be left with MSI enabled and
+Note that a device driver should always call free_irq() on the MSI vector
+that it has done request_irq() on before calling this API. Failure to do
+so results in a BUG_ON() and a device will be left with MSI enabled and
 leaks its vector.
 
 5.2.3 MSI mode vs. legacy mode diagram
 
-The below diagram shows the events, which switches the interrupt
+The below diagram shows the events which switch the interrupt
 mode on the MSI-capable device function between MSI mode and
 PIN-IRQ assertion mode.
 
@@ -155,9 +163,9 @@
  	 ------------	pci_disable_msi  ------------------------
 
 
-Figure 1.0 MSI Mode vs. Legacy Mode
+Figure 1. MSI Mode vs. Legacy Mode
 
-In Figure 1.0, a device operates by default in legacy mode. Legacy
+In Figure 1, a device operates by default in legacy mode. Legacy
 in this context means PCI pin-irq assertion or PCI-Express INTx
 emulation. A successful MSI request (using pci_enable_msi()) switches
 a device's interrupt mode to MSI mode. A pre-assigned IOAPIC vector
@@ -166,11 +174,11 @@
 
 To return back to its default mode, a device driver should always call
 pci_disable_msi() to undo the effect of pci_enable_msi(). Note that a
-device driver should always call free_irq() on MSI vector it has done
-request_irq() on before calling pci_disable_msi(). Failure to do so
-results a BUG_ON() and a device will be left with MSI enabled and
+device driver should always call free_irq() on the MSI vector it has
+done request_irq() on before calling pci_disable_msi(). Failure to do
+so results in a BUG_ON() and a device will be left with MSI enabled and
 leaks its vector. Otherwise, the PCI subsystem restores a device's
-dev->irq with a pre-assigned IOAPIC vector and marks released
+dev->irq with a pre-assigned IOAPIC vector and marks the released
 MSI vector as unused.
 
 Once being marked as unused, there is no guarantee that the PCI
@@ -178,8 +186,8 @@
 the availability of current PCI vector resources and the number of
 MSI/MSI-X requests from other drivers, this MSI may be re-assigned.
 
-For the case where the PCI subsystem re-assigned this MSI vector
-another driver, a request to switching back to MSI mode may result
+For the case where the PCI subsystem re-assigns this MSI vector to
+another driver, a request to switch back to MSI mode may result
 in being assigned a different MSI vector or a failure if no more
 vectors are available.
 
@@ -208,12 +216,12 @@
 does not replace the pre-assigned IOAPIC dev->irq with a new MSI
 vector because the PCI subsystem writes the 1:1 vector-to-entry mapping
 into the field vector of each element contained in a second argument.
-Note that the pre-assigned IO-APIC dev->irq is valid only if the device
-operates in PIN-IRQ assertion mode. In MSI-X mode, any attempt of
+Note that the pre-assigned IOAPIC dev->irq is valid only if the device
+operates in PIN-IRQ assertion mode. In MSI-X mode, any attempt at
 using dev->irq by the device driver to request for interrupt service
 may result unpredictabe behavior.
 
-For each MSI-X vector granted, a device driver is responsible to call
+For each MSI-X vector granted, a device driver is responsible for calling
 other functions like request_irq(), enable_irq(), etc. to enable
 this vector with its corresponding interrupt service handler. It is
 a device driver's choice to assign all vectors with the same
@@ -224,13 +232,13 @@
 
 The PCI 3.0 specification has implementation notes that MMIO address
 space for a device's MSI-X structure should be isolated so that the
-software system can set different page for controlling accesses to
-the MSI-X structure. The implementation of MSI patch requires the PCI
+software system can set different pages for controlling accesses to the
+MSI-X structure. The implementation of MSI support requires the PCI
 subsystem, not a device driver, to maintain full control of the MSI-X
-table/MSI-X PBA and MMIO address space of the MSI-X table/MSI-X PBA.
-A device driver is prohibited from requesting the MMIO address space
-of the MSI-X table/MSI-X PBA. Otherwise, the PCI subsystem will fail
-enabling MSI-X on its hardware device when it calls the function
+table/MSI-X PBA (Pending Bit Array) and MMIO address space of the MSI-X
+table/MSI-X PBA.  A device driver is prohibited from requesting the MMIO
+address space of the MSI-X table/MSI-X PBA. Otherwise, the PCI subsystem
+will fail enabling MSI-X on its hardware device when it calls the function
 pci_enable_msix().
 
 5.3.2 Handling MSI-X allocation
@@ -274,9 +282,9 @@
 than requested, the function pci_enable_msix() will return the
 maximum number of MSI-X vectors available to the caller. A device
 driver may re-send its request with fewer or equal vectors indicated
-in a return. For example, if a device driver requests 5 vectors, but
-the number of available vectors is 3 vectors, a value of 3 will be a
-return as a result of pci_enable_msix() call. A function could be
+in the return. For example, if a device driver requests 5 vectors, but
+the number of available vectors is 3 vectors, a value of 3 will be
+returned as a result of pci_enable_msix() call. A function could be
 designed for its driver to use only 3 MSI-X table entries as
 different combinations as ABC--, A-B-C, A--CB, etc. Note that this
 patch does not support multiple entries with the same vector. Such
@@ -285,49 +293,46 @@
 pci_enable_msix(). Below are the reasons why supporting multiple
 entries with the same vector is an undesirable solution.
 
-	- The PCI subsystem can not determine which entry, which
-	  generated the message, to mask/unmask MSI while handling
+	- The PCI subsystem cannot determine the entry that
+	  generated the message to mask/unmask MSI while handling
 	  software driver ISR. Attempting to walk through all MSI-X
 	  table entries (2048 max) to mask/unmask any match vector
 	  is an undesirable solution.
 
-	- Walk through all MSI-X table entries (2048 max) to handle
+	- Walking through all MSI-X table entries (2048 max) to handle
 	  SMP affinity of any match vector is an undesirable solution.
 
 5.3.4 API pci_enable_msix
 
-int pci_enable_msix(struct pci_dev *dev, u32 *entries, int nvec)
+int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec)
 
 This API enables a device driver to request the PCI subsystem
-for enabling MSI-X messages on its hardware device. Depending on
+to enable MSI-X messages on its hardware device. Depending on
 the availability of PCI vectors resources, the PCI subsystem enables
-either all or nothing.
+either all or none of the requested vectors.
 
-Argument dev points to the device (pci_dev) structure.
+Argument 'dev' points to the device (pci_dev) structure.
 
-Argument entries is a pointer of unsigned integer type. The number of
-elements is indicated in argument nvec. The content of each element
-will be mapped to the following struct defined in /driver/pci/msi.h.
+Argument 'entries' is a pointer to an array of msix_entry structs.
+The number of entries is indicated in argument 'nvec'.
+struct msix_entry is defined in /driver/pci/msi.h:
 
 struct msix_entry {
 	u16 	vector; /* kernel uses to write alloc vector */
 	u16	entry; /* driver uses to specify entry */
 };
 
-A device driver is responsible for initializing the field entry of
-each element with unique entry supported by MSI-X table. Otherwise,
+A device driver is responsible for initializing the field 'entry' of
+each element with a unique entry supported by MSI-X table. Otherwise,
 -EINVAL will be returned as a result. A successful return of zero
-indicates the PCI subsystem completes initializing each of requested
+indicates the PCI subsystem completed initializing each of the requested
 entries of the MSI-X table with message address and message data.
 Last but not least, the PCI subsystem will write the 1:1
-vector-to-entry mapping into the field vector of each element. A
-device driver is responsible of keeping track of allocated MSI-X
+vector-to-entry mapping into the field 'vector' of each element. A
+device driver is responsible for keeping track of allocated MSI-X
 vectors in its internal data structure.
 
-Argument nvec is an integer indicating the number of messages
-requested.
-
-A return of zero indicates that the number of MSI-X vectors is
+A return of zero indicates that the number of MSI-X vectors was
 successfully allocated. A return of greater than zero indicates
 MSI-X vector shortage. Or a return of less than zero indicates
 a failure. This failure may be a result of duplicate entries
@@ -341,12 +346,12 @@
 This API should always be used to undo the effect of pci_enable_msix()
 when a device driver is unloading. Note that a device driver should
 always call free_irq() on all MSI-X vectors it has done request_irq()
-on before calling this API. Failure to do so results a BUG_ON() and
+on before calling this API. Failure to do so results in a BUG_ON() and
 a device will be left with MSI-X enabled and leaks its vectors.
 
 5.3.6 MSI-X mode vs. legacy mode diagram
 
-The below diagram shows the events, which switches the interrupt
+The below diagram shows the events which switch the interrupt
 mode on the MSI-X capable device function between MSI-X mode and
 PIN-IRQ assertion mode (legacy).
 
@@ -356,22 +361,22 @@
 	| 	     | ===============>	    |			     |
  	 ------------	pci_disable_msix     ------------------------
 
-Figure 2.0 MSI-X Mode vs. Legacy Mode
+Figure 2. MSI-X Mode vs. Legacy Mode
 
-In Figure 2.0, a device operates by default in legacy mode. A
+In Figure 2, a device operates by default in legacy mode. A
 successful MSI-X request (using pci_enable_msix()) switches a
 device's interrupt mode to MSI-X mode. A pre-assigned IOAPIC vector
 stored in dev->irq will be saved by the PCI subsystem; however,
 unlike MSI mode, the PCI subsystem will not replace dev->irq with
 assigned MSI-X vector because the PCI subsystem already writes the 1:1
-vector-to-entry mapping into the field vector of each element
+vector-to-entry mapping into the field 'vector' of each element
 specified in second argument.
 
 To return back to its default mode, a device driver should always call
 pci_disable_msix() to undo the effect of pci_enable_msix(). Note that
 a device driver should always call free_irq() on all MSI-X vectors it
 has done request_irq() on before calling pci_disable_msix(). Failure
-to do so results a BUG_ON() and a device will be left with MSI-X
+to do so results in a BUG_ON() and a device will be left with MSI-X
 enabled and leaks its vectors. Otherwise, the PCI subsystem switches a
 device function's interrupt mode from MSI-X mode to legacy mode and
 marks all allocated MSI-X vectors as unused.
@@ -383,53 +388,56 @@
 re-assigned.
 
 For the case where the PCI subsystem re-assigned these MSI-X vectors
-to other driver, a request to switching back to MSI-X mode may result
+to other drivers, a request to switch back to MSI-X mode may result
 being assigned with another set of MSI-X vectors or a failure if no
 more vectors are available.
 
-5.4 Handling function implementng both MSI and MSI-X capabilities
+5.4 Handling function implementing both MSI and MSI-X capabilities
 
 For the case where a function implements both MSI and MSI-X
 capabilities, the PCI subsystem enables a device to run either in MSI
 mode or MSI-X mode but not both. A device driver determines whether it
 wants MSI or MSI-X enabled on its hardware device. Once a device
-driver requests for MSI, for example, it is prohibited to request for
+driver requests for MSI, for example, it is prohibited from requesting
 MSI-X; in other words, a device driver is not permitted to ping-pong
 between MSI mod MSI-X mode during a run-time.
 
 5.5 Hardware requirements for MSI/MSI-X support
+
 MSI/MSI-X support requires support from both system hardware and
 individual hardware device functions.
 
 5.5.1 System hardware support
+
 Since the target of MSI address is the local APIC CPU, enabling
-MSI/MSI-X support in Linux kernel is dependent on whether existing
-system hardware supports local APIC. Users should verify their
-system whether it runs when CONFIG_X86_LOCAL_APIC=y.
+MSI/MSI-X support in the Linux kernel is dependent on whether existing
+system hardware supports local APIC. Users should verify that their
+system supports local APIC operation by testing that it runs when
+CONFIG_X86_LOCAL_APIC=y.
 
 In SMP environment, CONFIG_X86_LOCAL_APIC is automatically set;
 however, in UP environment, users must manually set
 CONFIG_X86_LOCAL_APIC. Once CONFIG_X86_LOCAL_APIC=y, setting
-CONFIG_PCI_MSI enables the VECTOR based scheme and
-the option for MSI-capable device drivers to selectively enable
-MSI/MSI-X.
+CONFIG_PCI_MSI enables the VECTOR based scheme and the option for
+MSI-capable device drivers to selectively enable MSI/MSI-X.
 
 Note that CONFIG_X86_IO_APIC setting is irrelevant because MSI/MSI-X
 vector is allocated new during runtime and MSI/MSI-X support does not
 depend on BIOS support. This key independency enables MSI/MSI-X
-support on future IOxAPIC free platform.
+support on future IOxAPIC free platforms.
 
 5.5.2 Device hardware support
+
 The hardware device function supports MSI by indicating the
 MSI/MSI-X capability structure on its PCI capability list. By
 default, this capability structure will not be initialized by
 the kernel to enable MSI during the system boot. In other words,
 the device function is running on its default pin assertion mode.
 Note that in many cases the hardware supporting MSI have bugs,
-which may result in system hang. The software driver of specific
-MSI-capable hardware is responsible for whether calling
+which may result in system hangs. The software driver of specific
+MSI-capable hardware is responsible for deciding whether to call
 pci_enable_msi or not. A return of zero indicates the kernel
-successfully initializes the MSI/MSI-X capability structure of the
+successfully initialized the MSI/MSI-X capability structure of the
 device function. The device function is now running on MSI/MSI-X mode.
 
 5.6 How to tell whether MSI/MSI-X is enabled on device function
@@ -439,10 +447,10 @@
 its device function is initialized successfully and ready to run in
 MSI/MSI-X mode.
 
-At the user level, users can use command 'cat /proc/interrupts'
-to display the vector allocated for a device and its interrupt
-MSI/MSI-X mode ("PCI MSI"/"PCI MSIX"). Below shows below MSI mode is
-enabled on a SCSI Adaptec 39320D Ultra320.
+At the user level, users can use the command 'cat /proc/interrupts'
+to display the vectors allocated for devices and their interrupt
+MSI/MSI-X modes ("PCI-MSI"/"PCI-MSI-X"). Below shows MSI mode is
+enabled on a SCSI Adaptec 39320D Ultra320 controller.
 
            CPU0       CPU1
   0:     324639          0    IO-APIC-edge  timer
@@ -453,8 +461,8 @@
  15:          1          0    IO-APIC-edge  ide1
 169:          0          0   IO-APIC-level  uhci-hcd
 185:          0          0   IO-APIC-level  uhci-hcd
-193:        138         10         PCI MSI  aic79xx
-201:         30          0         PCI MSI  aic79xx
+193:        138         10         PCI-MSI  aic79xx
+201:         30          0         PCI-MSI  aic79xx
 225:         30          0   IO-APIC-level  aic7xxx
 233:         30          0   IO-APIC-level  aic7xxx
 NMI:          0          0
@@ -490,8 +498,8 @@
 specification 2.3 or latest, then it should work.
 
 Q4. From the driver point of view, if the MSI is lost because
-of the errors occur during inbound memory write, then it may
-wait for ever. Is there a mechanism for it to recover?
+of errors occurring during inbound memory write, then it may
+wait forever. Is there a mechanism for it to recover?
 
 A4. Since the target of the transaction is an inbound memory
 write, all transaction termination conditions (Retry,
diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt
index 354d89c..15da168 100644
--- a/Documentation/RCU/whatisRCU.txt
+++ b/Documentation/RCU/whatisRCU.txt
@@ -772,8 +772,6 @@
 	list_for_each_entry_rcu
 	list_for_each_continue_rcu	(to be deprecated in favor of new
 					 list_for_each_entry_continue_rcu)
-	hlist_for_each_rcu		(to be deprecated in favor of
-					 hlist_for_each_entry_rcu)
 	hlist_for_each_entry_rcu
 
 RCU pointer update:
diff --git a/Documentation/device-mapper/snapshot.txt b/Documentation/device-mapper/snapshot.txt
index dca274f..a5009c8 100644
--- a/Documentation/device-mapper/snapshot.txt
+++ b/Documentation/device-mapper/snapshot.txt
@@ -19,7 +19,6 @@
 *) snapshot-origin <origin>
 
 which will normally have one or more snapshots based on it.
-You must create the snapshot-origin device before you can create snapshots.
 Reads will be mapped directly to the backing device. For each write, the
 original data will be saved in the <COW device> of each snapshot to keep
 its visible content unchanged, at least until the <COW device> fills up.
@@ -27,7 +26,7 @@
 
 *) snapshot <origin> <COW device> <persistent?> <chunksize>
 
-A snapshot is created of the <origin> block device. Changed chunks of
+A snapshot of the <origin> block device is created. Changed chunks of
 <chunksize> sectors will be stored on the <COW device>.  Writes will
 only go to the <COW device>.  Reads will come from the <COW device> or
 from <origin> for unchanged data.  <COW device> will often be
@@ -37,6 +36,8 @@
 
 <persistent?> is P (Persistent) or N (Not persistent - will not survive
 after reboot).
+The difference is that for transient snapshots less metadata must be
+saved on disk - they can be kept in memory by the kernel.
 
 
 How this is used by LVM2
diff --git a/Documentation/fb/vesafb.txt b/Documentation/fb/vesafb.txt
index 62db675..ee277dd 100644
--- a/Documentation/fb/vesafb.txt
+++ b/Documentation/fb/vesafb.txt
@@ -146,10 +146,10 @@
 
 mtrr:n	setup memory type range registers for the vesafb framebuffer
 	where n:
-	      0 - disabled (equivalent to nomtrr)
+	      0 - disabled (equivalent to nomtrr) (default)
 	      1 - uncachable
 	      2 - write-back
-	      3 - write-combining (default)
+	      3 - write-combining
 	      4 - write-through
 
 	If you see the following in dmesg, choose the type that matches the
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index b67189a..decdf99 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -69,6 +69,22 @@
 
 ---------------------------
 
+What:	remove EXPORT_SYMBOL(panic_timeout)
+When:	April 2006
+Files:	kernel/panic.c
+Why:	No modular usage in the kernel.
+Who:	Adrian Bunk <bunk@stusta.de>
+
+---------------------------
+
+What:	remove EXPORT_SYMBOL(insert_resource)
+When:	April 2006
+Files:	kernel/resource.c
+Why:	No modular usage in the kernel.
+Who:	Adrian Bunk <bunk@stusta.de>
+
+---------------------------
+
 What:	PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl])
 When:	November 2005
 Files:	drivers/pcmcia/: pcmcia_ioctl.c
diff --git a/Documentation/filesystems/dentry-locking.txt b/Documentation/filesystems/dentry-locking.txt
new file mode 100644
index 0000000..4c0c575
--- /dev/null
+++ b/Documentation/filesystems/dentry-locking.txt
@@ -0,0 +1,173 @@
+RCU-based dcache locking model
+==============================
+
+On many workloads, the most common operation on dcache is to look up a
+dentry, given a parent dentry and the name of the child. Typically,
+for every open(), stat() etc., the dentry corresponding to the
+pathname will be looked up by walking the tree starting with the first
+component of the pathname and using that dentry along with the next
+component to look up the next level and so on. Since it is a frequent
+operation for workloads like multiuser environments and web servers,
+it is important to optimize this path.
+
+Prior to 2.5.10, dcache_lock was acquired in d_lookup and thus in
+every component during path look-up. Since 2.5.10 onwards, fast-walk
+algorithm changed this by holding the dcache_lock at the beginning and
+walking as many cached path component dentries as possible. This
+significantly decreases the number of acquisition of
+dcache_lock. However it also increases the lock hold time
+significantly and affects performance in large SMP machines. Since
+2.5.62 kernel, dcache has been using a new locking model that uses RCU
+to make dcache look-up lock-free.
+
+The current dcache locking model is not very different from the
+existing dcache locking model. Prior to 2.5.62 kernel, dcache_lock
+protected the hash chain, d_child, d_alias, d_lru lists as well as
+d_inode and several other things like mount look-up. RCU-based changes
+affect only the way the hash chain is protected. For everything else
+the dcache_lock must be taken for both traversing as well as
+updating. The hash chain updates too take the dcache_lock.  The
+significant change is the way d_lookup traverses the hash chain, it
+doesn't acquire the dcache_lock for this and rely on RCU to ensure
+that the dentry has not been *freed*.
+
+
+Dcache locking details
+======================
+
+For many multi-user workloads, open() and stat() on files are very
+frequently occurring operations. Both involve walking of path names to
+find the dentry corresponding to the concerned file. In 2.4 kernel,
+dcache_lock was held during look-up of each path component. Contention
+and cache-line bouncing of this global lock caused significant
+scalability problems. With the introduction of RCU in Linux kernel,
+this was worked around by making the look-up of path components during
+path walking lock-free.
+
+
+Safe lock-free look-up of dcache hash table
+===========================================
+
+Dcache is a complex data structure with the hash table entries also
+linked together in other lists. In 2.4 kernel, dcache_lock protected
+all the lists. We applied RCU only on hash chain walking. The rest of
+the lists are still protected by dcache_lock.  Some of the important
+changes are :
+
+1. The deletion from hash chain is done using hlist_del_rcu() macro
+   which doesn't initialize next pointer of the deleted dentry and
+   this allows us to walk safely lock-free while a deletion is
+   happening.
+
+2. Insertion of a dentry into the hash table is done using
+   hlist_add_head_rcu() which take care of ordering the writes - the
+   writes to the dentry must be visible before the dentry is
+   inserted. This works in conjunction with hlist_for_each_rcu() while
+   walking the hash chain. The only requirement is that all
+   initialization to the dentry must be done before
+   hlist_add_head_rcu() since we don't have dcache_lock protection
+   while traversing the hash chain. This isn't different from the
+   existing code.
+
+3. The dentry looked up without holding dcache_lock by cannot be
+   returned for walking if it is unhashed. It then may have a NULL
+   d_inode or other bogosity since RCU doesn't protect the other
+   fields in the dentry. We therefore use a flag DCACHE_UNHASHED to
+   indicate unhashed dentries and use this in conjunction with a
+   per-dentry lock (d_lock). Once looked up without the dcache_lock,
+   we acquire the per-dentry lock (d_lock) and check if the dentry is
+   unhashed. If so, the look-up is failed. If not, the reference count
+   of the dentry is increased and the dentry is returned.
+
+4. Once a dentry is looked up, it must be ensured during the path walk
+   for that component it doesn't go away. In pre-2.5.10 code, this was
+   done holding a reference to the dentry. dcache_rcu does the same.
+   In some sense, dcache_rcu path walking looks like the pre-2.5.10
+   version.
+
+5. All dentry hash chain updates must take the dcache_lock as well as
+   the per-dentry lock in that order. dput() does this to ensure that
+   a dentry that has just been looked up in another CPU doesn't get
+   deleted before dget() can be done on it.
+
+6. There are several ways to do reference counting of RCU protected
+   objects. One such example is in ipv4 route cache where deferred
+   freeing (using call_rcu()) is done as soon as the reference count
+   goes to zero. This cannot be done in the case of dentries because
+   tearing down of dentries require blocking (dentry_iput()) which
+   isn't supported from RCU callbacks. Instead, tearing down of
+   dentries happen synchronously in dput(), but actual freeing happens
+   later when RCU grace period is over. This allows safe lock-free
+   walking of the hash chains, but a matched dentry may have been
+   partially torn down. The checking of DCACHE_UNHASHED flag with
+   d_lock held detects such dentries and prevents them from being
+   returned from look-up.
+
+
+Maintaining POSIX rename semantics
+==================================
+
+Since look-up of dentries is lock-free, it can race against a
+concurrent rename operation. For example, during rename of file A to
+B, look-up of either A or B must succeed.  So, if look-up of B happens
+after A has been removed from the hash chain but not added to the new
+hash chain, it may fail.  Also, a comparison while the name is being
+written concurrently by a rename may result in false positive matches
+violating rename semantics.  Issues related to race with rename are
+handled as described below :
+
+1. Look-up can be done in two ways - d_lookup() which is safe from
+   simultaneous renames and __d_lookup() which is not.  If
+   __d_lookup() fails, it must be followed up by a d_lookup() to
+   correctly determine whether a dentry is in the hash table or
+   not. d_lookup() protects look-ups using a sequence lock
+   (rename_lock).
+
+2. The name associated with a dentry (d_name) may be changed if a
+   rename is allowed to happen simultaneously. To avoid memcmp() in
+   __d_lookup() go out of bounds due to a rename and false positive
+   comparison, the name comparison is done while holding the
+   per-dentry lock. This prevents concurrent renames during this
+   operation.
+
+3. Hash table walking during look-up may move to a different bucket as
+   the current dentry is moved to a different bucket due to rename.
+   But we use hlists in dcache hash table and they are
+   null-terminated.  So, even if a dentry moves to a different bucket,
+   hash chain walk will terminate. [with a list_head list, it may not
+   since termination is when the list_head in the original bucket is
+   reached].  Since we redo the d_parent check and compare name while
+   holding d_lock, lock-free look-up will not race against d_move().
+
+4. There can be a theoretical race when a dentry keeps coming back to
+   original bucket due to double moves. Due to this look-up may
+   consider that it has never moved and can end up in a infinite loop.
+   But this is not any worse that theoretical livelocks we already
+   have in the kernel.
+
+
+Important guidelines for filesystem developers related to dcache_rcu
+====================================================================
+
+1. Existing dcache interfaces (pre-2.5.62) exported to filesystem
+   don't change. Only dcache internal implementation changes. However
+   filesystems *must not* delete from the dentry hash chains directly
+   using the list macros like allowed earlier. They must use dcache
+   APIs like d_drop() or __d_drop() depending on the situation.
+
+2. d_flags is now protected by a per-dentry lock (d_lock). All access
+   to d_flags must be protected by it.
+
+3. For a hashed dentry, checking of d_count needs to be protected by
+   d_lock.
+
+
+Papers and other documentation on dcache locking
+================================================
+
+1. Scaling dcache with RCU (http://linuxjournal.com/article.php?sid=7124).
+
+2. http://lse.sourceforge.net/locking/dcache/dcache.html
+
+
+
diff --git a/Documentation/filesystems/devfs/README b/Documentation/filesystems/devfs/README
index 54366ec..aabfba2 100644
--- a/Documentation/filesystems/devfs/README
+++ b/Documentation/filesystems/devfs/README
@@ -1812,11 +1812,6 @@
 you can
 
 
-if you get an Oops, run ksymoops to decode it so that the
-names of the offending functions are provided. A non-decoded Oops is
-pretty useless
-
-
 send a copy of your devfsd configuration file(s)
 
 send the bug report to me first.
diff --git a/Documentation/filesystems/ramfs-rootfs-initramfs.txt b/Documentation/filesystems/ramfs-rootfs-initramfs.txt
new file mode 100644
index 0000000..b3404a0
--- /dev/null
+++ b/Documentation/filesystems/ramfs-rootfs-initramfs.txt
@@ -0,0 +1,195 @@
+ramfs, rootfs and initramfs
+October 17, 2005
+Rob Landley <rob@landley.net>
+=============================
+
+What is ramfs?
+--------------
+
+Ramfs is a very simple filesystem that exports Linux's disk caching
+mechanisms (the page cache and dentry cache) as a dynamically resizable
+ram-based filesystem.
+
+Normally all files are cached in memory by Linux.  Pages of data read from
+backing store (usually the block device the filesystem is mounted on) are kept
+around in case it's needed again, but marked as clean (freeable) in case the
+Virtual Memory system needs the memory for something else.  Similarly, data
+written to files is marked clean as soon as it has been written to backing
+store, but kept around for caching purposes until the VM reallocates the
+memory.  A similar mechanism (the dentry cache) greatly speeds up access to
+directories.
+
+With ramfs, there is no backing store.  Files written into ramfs allocate
+dentries and page cache as usual, but there's nowhere to write them to.
+This means the pages are never marked clean, so they can't be freed by the
+VM when it's looking to recycle memory.
+
+The amount of code required to implement ramfs is tiny, because all the
+work is done by the existing Linux caching infrastructure.  Basically,
+you're mounting the disk cache as a filesystem.  Because of this, ramfs is not
+an optional component removable via menuconfig, since there would be negligible
+space savings.
+
+ramfs and ramdisk:
+------------------
+
+The older "ram disk" mechanism created a synthetic block device out of
+an area of ram and used it as backing store for a filesystem.  This block
+device was of fixed size, so the filesystem mounted on it was of fixed
+size.  Using a ram disk also required unnecessarily copying memory from the
+fake block device into the page cache (and copying changes back out), as well
+as creating and destroying dentries.  Plus it needed a filesystem driver
+(such as ext2) to format and interpret this data.
+
+Compared to ramfs, this wastes memory (and memory bus bandwidth), creates
+unnecessary work for the CPU, and pollutes the CPU caches.  (There are tricks
+to avoid this copying by playing with the page tables, but they're unpleasantly
+complicated and turn out to be about as expensive as the copying anyway.)
+More to the point, all the work ramfs is doing has to happen _anyway_,
+since all file access goes through the page and dentry caches.  The ram
+disk is simply unnecessary, ramfs is internally much simpler.
+
+Another reason ramdisks are semi-obsolete is that the introduction of
+loopback devices offered a more flexible and convenient way to create
+synthetic block devices, now from files instead of from chunks of memory.
+See losetup (8) for details.
+
+ramfs and tmpfs:
+----------------
+
+One downside of ramfs is you can keep writing data into it until you fill
+up all memory, and the VM can't free it because the VM thinks that files
+should get written to backing store (rather than swap space), but ramfs hasn't
+got any backing store.  Because of this, only root (or a trusted user) should
+be allowed write access to a ramfs mount.
+
+A ramfs derivative called tmpfs was created to add size limits, and the ability
+to write the data to swap space.  Normal users can be allowed write access to
+tmpfs mounts.  See Documentation/filesystems/tmpfs.txt for more information.
+
+What is rootfs?
+---------------
+
+Rootfs is a special instance of ramfs, which is always present in 2.6 systems.
+(It's used internally as the starting and stopping point for searches of the
+kernel's doubly-linked list of mount points.)
+
+Most systems just mount another filesystem over it and ignore it.  The
+amount of space an empty instance of ramfs takes up is tiny.
+
+What is initramfs?
+------------------
+
+All 2.6 Linux kernels contain a gzipped "cpio" format archive, which is
+extracted into rootfs when the kernel boots up.  After extracting, the kernel
+checks to see if rootfs contains a file "init", and if so it executes it as PID
+1.  If found, this init process is responsible for bringing the system the
+rest of the way up, including locating and mounting the real root device (if
+any).  If rootfs does not contain an init program after the embedded cpio
+archive is extracted into it, the kernel will fall through to the older code
+to locate and mount a root partition, then exec some variant of /sbin/init
+out of that.
+
+All this differs from the old initrd in several ways:
+
+  - The old initrd was a separate file, while the initramfs archive is linked
+    into the linux kernel image.  (The directory linux-*/usr is devoted to
+    generating this archive during the build.)
+
+  - The old initrd file was a gzipped filesystem image (in some file format,
+    such as ext2, that had to be built into the kernel), while the new
+    initramfs archive is a gzipped cpio archive (like tar only simpler,
+    see cpio(1) and Documentation/early-userspace/buffer-format.txt).
+
+  - The program run by the old initrd (which was called /initrd, not /init) did
+    some setup and then returned to the kernel, while the init program from
+    initramfs is not expected to return to the kernel.  (If /init needs to hand
+    off control it can overmount / with a new root device and exec another init
+    program.  See the switch_root utility, below.)
+
+  - When switching another root device, initrd would pivot_root and then
+    umount the ramdisk.  But initramfs is rootfs: you can neither pivot_root
+    rootfs, nor unmount it.  Instead delete everything out of rootfs to
+    free up the space (find -xdev / -exec rm '{}' ';'), overmount rootfs
+    with the new root (cd /newmount; mount --move . /; chroot .), attach
+    stdin/stdout/stderr to the new /dev/console, and exec the new init.
+
+    Since this is a remarkably persnickity process (and involves deleting
+    commands before you can run them), the klibc package introduced a helper
+    program (utils/run_init.c) to do all this for you.  Most other packages
+    (such as busybox) have named this command "switch_root".
+
+Populating initramfs:
+---------------------
+
+The 2.6 kernel build process always creates a gzipped cpio format initramfs
+archive and links it into the resulting kernel binary.  By default, this
+archive is empty (consuming 134 bytes on x86).  The config option
+CONFIG_INITRAMFS_SOURCE (for some reason buried under devices->block devices
+in menuconfig, and living in usr/Kconfig) can be used to specify a source for
+the initramfs archive, which will automatically be incorporated into the
+resulting binary.  This option can point to an existing gzipped cpio archive, a
+directory containing files to be archived, or a text file specification such
+as the following example:
+
+  dir /dev 755 0 0
+  nod /dev/console 644 0 0 c 5 1
+  nod /dev/loop0 644 0 0 b 7 0
+  dir /bin 755 1000 1000
+  slink /bin/sh busybox 777 0 0
+  file /bin/busybox initramfs/busybox 755 0 0
+  dir /proc 755 0 0
+  dir /sys 755 0 0
+  dir /mnt 755 0 0
+  file /init initramfs/init.sh 755 0 0
+
+One advantage of the text file is that root access is not required to
+set permissions or create device nodes in the new archive.  (Note that those
+two example "file" entries expect to find files named "init.sh" and "busybox" in
+a directory called "initramfs", under the linux-2.6.* directory.  See
+Documentation/early-userspace/README for more details.)
+
+If you don't already understand what shared libraries, devices, and paths
+you need to get a minimal root filesystem up and running, here are some
+references:
+http://www.tldp.org/HOWTO/Bootdisk-HOWTO/
+http://www.tldp.org/HOWTO/From-PowerUp-To-Bash-Prompt-HOWTO.html
+http://www.linuxfromscratch.org/lfs/view/stable/
+
+The "klibc" package (http://www.kernel.org/pub/linux/libs/klibc) is
+designed to be a tiny C library to statically link early userspace
+code against, along with some related utilities.  It is BSD licensed.
+
+I use uClibc (http://www.uclibc.org) and busybox (http://www.busybox.net)
+myself.  These are LGPL and GPL, respectively.
+
+In theory you could use glibc, but that's not well suited for small embedded
+uses like this.  (A "hello world" program statically linked against glibc is
+over 400k.  With uClibc it's 7k.  Also note that glibc dlopens libnss to do
+name lookups, even when otherwise statically linked.)
+
+Future directions:
+------------------
+
+Today (2.6.14), initramfs is always compiled in, but not always used.  The
+kernel falls back to legacy boot code that is reached only if initramfs does
+not contain an /init program.  The fallback is legacy code, there to ensure a
+smooth transition and allowing early boot functionality to gradually move to
+"early userspace" (I.E. initramfs).
+
+The move to early userspace is necessary because finding and mounting the real
+root device is complex.  Root partitions can span multiple devices (raid or
+separate journal).  They can be out on the network (requiring dhcp, setting a
+specific mac address, logging into a server, etc).  They can live on removable
+media, with dynamically allocated major/minor numbers and persistent naming
+issues requiring a full udev implementation to sort out.  They can be
+compressed, encrypted, copy-on-write, loopback mounted, strangely partitioned,
+and so on.
+
+This kind of complexity (which inevitably includes policy) is rightly handled
+in userspace.  Both klibc and busybox/uClibc are working on simple initramfs
+packages to drop into a kernel build, and when standard solutions are ready
+and widely deployed, the kernel's legacy early boot code will become obsolete
+and a candidate for the feature removal schedule.
+
+But that's a while off yet.
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index f042c12..ee4c0a8 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -3,7 +3,7 @@
 
 	Original author: Richard Gooch <rgooch@atnf.csiro.au>
 
-		  Last updated on August 25, 2005
+		  Last updated on October 28, 2005
 
   Copyright (C) 1999 Richard Gooch
   Copyright (C) 2005 Pekka Enberg
@@ -11,62 +11,61 @@
   This file is released under the GPLv2.
 
 
-What is it?
-===========
+Introduction
+============
 
-The Virtual File System (otherwise known as the Virtual Filesystem
-Switch) is the software layer in the kernel that provides the
-filesystem interface to userspace programs. It also provides an
-abstraction within the kernel which allows different filesystem
-implementations to coexist.
+The Virtual File System (also known as the Virtual Filesystem Switch)
+is the software layer in the kernel that provides the filesystem
+interface to userspace programs. It also provides an abstraction
+within the kernel which allows different filesystem implementations to
+coexist.
+
+VFS system calls open(2), stat(2), read(2), write(2), chmod(2) and so
+on are called from a process context. Filesystem locking is described
+in the document Documentation/filesystems/Locking.
 
 
-A Quick Look At How It Works
-============================
+Directory Entry Cache (dcache)
+------------------------------
 
-In this section I'll briefly describe how things work, before
-launching into the details. I'll start with describing what happens
-when user programs open and manipulate files, and then look from the
-other view which is how a filesystem is supported and subsequently
-mounted.
+The VFS implements the open(2), stat(2), chmod(2), and similar system
+calls. The pathname argument that is passed to them is used by the VFS
+to search through the directory entry cache (also known as the dentry
+cache or dcache). This provides a very fast look-up mechanism to
+translate a pathname (filename) into a specific dentry. Dentries live
+in RAM and are never saved to disc: they exist only for performance.
+
+The dentry cache is meant to be a view into your entire filespace. As
+most computers cannot fit all dentries in the RAM at the same time,
+some bits of the cache are missing. In order to resolve your pathname
+into a dentry, the VFS may have to resort to creating dentries along
+the way, and then loading the inode. This is done by looking up the
+inode.
 
 
-Opening a File
---------------
+The Inode Object
+----------------
 
-The VFS implements the open(2), stat(2), chmod(2) and similar system
-calls. The pathname argument is used by the VFS to search through the
-directory entry cache (dentry cache or "dcache"). This provides a very
-fast look-up mechanism to translate a pathname (filename) into a
-specific dentry.
+An individual dentry usually has a pointer to an inode. Inodes are
+filesystem objects such as regular files, directories, FIFOs and other
+beasts.  They live either on the disc (for block device filesystems)
+or in the memory (for pseudo filesystems). Inodes that live on the
+disc are copied into the memory when required and changes to the inode
+are written back to disc. A single inode can be pointed to by multiple
+dentries (hard links, for example, do this).
 
-An individual dentry usually has a pointer to an inode. Inodes are the
-things that live on disc drives, and can be regular files (you know:
-those things that you write data into), directories, FIFOs and other
-beasts. Dentries live in RAM and are never saved to disc: they exist
-only for performance. Inodes live on disc and are copied into memory
-when required. Later any changes are written back to disc. The inode
-that lives in RAM is a VFS inode, and it is this which the dentry
-points to. A single inode can be pointed to by multiple dentries
-(think about hardlinks).
+To look up an inode requires that the VFS calls the lookup() method of
+the parent directory inode. This method is installed by the specific
+filesystem implementation that the inode lives in. Once the VFS has
+the required dentry (and hence the inode), we can do all those boring
+things like open(2) the file, or stat(2) it to peek at the inode
+data. The stat(2) operation is fairly simple: once the VFS has the
+dentry, it peeks at the inode data and passes some of it back to
+userspace.
 
-The dcache is meant to be a view into your entire filespace. Unlike
-Linus, most of us losers can't fit enough dentries into RAM to cover
-all of our filespace, so the dcache has bits missing. In order to
-resolve your pathname into a dentry, the VFS may have to resort to
-creating dentries along the way, and then loading the inode. This is
-done by looking up the inode.
 
-To look up an inode (usually read from disc) requires that the VFS
-calls the lookup() method of the parent directory inode. This method
-is installed by the specific filesystem implementation that the inode
-lives in. There will be more on this later.
-
-Once the VFS has the required dentry (and hence the inode), we can do
-all those boring things like open(2) the file, or stat(2) it to peek
-at the inode data. The stat(2) operation is fairly simple: once the
-VFS has the dentry, it peeks at the inode data and passes some of it
-back to userspace.
+The File Object
+---------------
 
 Opening a file requires another operation: allocation of a file
 structure (this is the kernel-side implementation of file
@@ -74,51 +73,39 @@
 a pointer to the dentry and a set of file operation member functions.
 These are taken from the inode data. The open() file method is then
 called so the specific filesystem implementation can do it's work. You
-can see that this is another switch performed by the VFS.
-
-The file structure is placed into the file descriptor table for the
-process.
+can see that this is another switch performed by the VFS. The file
+structure is placed into the file descriptor table for the process.
 
 Reading, writing and closing files (and other assorted VFS operations)
 is done by using the userspace file descriptor to grab the appropriate
-file structure, and then calling the required file structure method
-function to do whatever is required.
-
-For as long as the file is open, it keeps the dentry "open" (in use),
-which in turn means that the VFS inode is still in use.
-
-All VFS system calls (i.e. open(2), stat(2), read(2), write(2),
-chmod(2) and so on) are called from a process context. You should
-assume that these calls are made without any kernel locks being
-held. This means that the processes may be executing the same piece of
-filesystem or driver code at the same time, on different
-processors. You should ensure that access to shared resources is
-protected by appropriate locks.
+file structure, and then calling the required file structure method to
+do whatever is required. For as long as the file is open, it keeps the
+dentry in use, which in turn means that the VFS inode is still in use.
 
 
 Registering and Mounting a Filesystem
--------------------------------------
+=====================================
 
-If you want to support a new kind of filesystem in the kernel, all you
-need to do is call register_filesystem(). You pass a structure
-describing the filesystem implementation (struct file_system_type)
-which is then added to an internal table of supported filesystems. You
-can do:
+To register and unregister a filesystem, use the following API
+functions:
 
-% cat /proc/filesystems
+   #include <linux/fs.h>
 
-to see what filesystems are currently available on your system.
+   extern int register_filesystem(struct file_system_type *);
+   extern int unregister_filesystem(struct file_system_type *);
 
-When a request is made to mount a block device onto a directory in
-your filespace the VFS will call the appropriate method for the
-specific filesystem. The dentry for the mount point will then be
-updated to point to the root inode for the new filesystem.
+The passed struct file_system_type describes your filesystem. When a
+request is made to mount a device onto a directory in your filespace,
+the VFS will call the appropriate get_sb() method for the specific
+filesystem. The dentry for the mount point will then be updated to
+point to the root inode for the new filesystem.
 
-It's now time to look at things in more detail.
+You can see all filesystems that are registered to the kernel in the
+file /proc/filesystems.
 
 
 struct file_system_type
-=======================
+-----------------------
 
 This describes the filesystem. As of kernel 2.6.13, the following
 members are defined:
@@ -197,8 +184,14 @@
   int silent: whether or not to be silent on error
 
 
+The Superblock Object
+=====================
+
+A superblock object represents a mounted filesystem.
+
+
 struct super_operations
-=======================
+-----------------------
 
 This describes how the VFS can manipulate the superblock of your
 filesystem. As of kernel 2.6.13, the following members are defined:
@@ -286,9 +279,9 @@
   	a superblock. The second parameter indicates whether the method
 	should wait until the write out has been completed. Optional.
 
-  write_super_lockfs: called when VFS is locking a filesystem and forcing
-  	it into a consistent state.  This function is currently used by the
-	Logical Volume Manager (LVM).
+  write_super_lockfs: called when VFS is locking a filesystem and
+  	forcing it into a consistent state.  This method is currently
+  	used by the Logical Volume Manager (LVM).
 
   unlockfs: called when VFS is unlocking a filesystem and making it writable
   	again.
@@ -317,8 +310,14 @@
 describes the methods that can be performed on individual inodes.
 
 
+The Inode Object
+================
+
+An inode object represents an object within the filesystem.
+
+
 struct inode_operations
-=======================
+-----------------------
 
 This describes how the VFS can manipulate an inode in your
 filesystem. As of kernel 2.6.13, the following members are defined:
@@ -394,51 +393,62 @@
 	will probably need to call d_instantiate() just as you would
 	in the create() method
 
+  rename: called by the rename(2) system call to rename the object to
+	have the parent and name given by the second inode and dentry.
+
   readlink: called by the readlink(2) system call. Only required if
 	you want to support reading symbolic links
 
   follow_link: called by the VFS to follow a symbolic link to the
 	inode it points to.  Only required if you want to support
-	symbolic links.  This function returns a void pointer cookie
+	symbolic links.  This method returns a void pointer cookie
 	that is passed to put_link().
 
   put_link: called by the VFS to release resources allocated by
-  	follow_link().  The cookie returned by follow_link() is passed to
-	to this function as the last parameter.  It is used by filesystems
-	such as NFS where page cache is not stable (i.e. page that was
-	installed when the symbolic link walk started might not be in the
-	page cache at the end of the walk).
+  	follow_link().  The cookie returned by follow_link() is passed
+  	to to this method as the last parameter.  It is used by
+  	filesystems such as NFS where page cache is not stable
+  	(i.e. page that was installed when the symbolic link walk
+  	started might not be in the page cache at the end of the
+  	walk).
 
-  truncate: called by the VFS to change the size of a file.  The i_size
- 	field of the inode is set to the desired size by the VFS before
-	this function is called.  This function is called by the truncate(2)
-	system call and related functionality.
+  truncate: called by the VFS to change the size of a file.  The
+ 	i_size field of the inode is set to the desired size by the
+ 	VFS before this method is called.  This method is called by
+ 	the truncate(2) system call and related functionality.
 
   permission: called by the VFS to check for access rights on a POSIX-like
   	filesystem.
 
-  setattr: called by the VFS to set attributes for a file.  This function is
-  	called by chmod(2) and related system calls.
+  setattr: called by the VFS to set attributes for a file. This method
+  	is called by chmod(2) and related system calls.
 
-  getattr: called by the VFS to get attributes of a file.  This function is
-  	called by stat(2) and related system calls.
+  getattr: called by the VFS to get attributes of a file. This method
+  	is called by stat(2) and related system calls.
 
   setxattr: called by the VFS to set an extended attribute for a file.
-  	Extended attribute is a name:value pair associated with an inode. This
-	function is called by setxattr(2) system call.
+  	Extended attribute is a name:value pair associated with an
+  	inode. This method is called by setxattr(2) system call.
 
-  getxattr: called by the VFS to retrieve the value of an extended attribute
-  	name.  This function is called by getxattr(2) function call.
+  getxattr: called by the VFS to retrieve the value of an extended
+  	attribute name. This method is called by getxattr(2) function
+  	call.
 
-  listxattr: called by the VFS to list all extended attributes for a given
-  	file.  This function is called by listxattr(2) system call.
+  listxattr: called by the VFS to list all extended attributes for a
+  	given file. This method is called by listxattr(2) system call.
 
-  removexattr: called by the VFS to remove an extended attribute from a file.
-  	This function is called by removexattr(2) system call.
+  removexattr: called by the VFS to remove an extended attribute from
+  	a file. This method is called by removexattr(2) system call.
+
+
+The Address Space Object
+========================
+
+The address space object is used to identify pages in the page cache.
 
 
 struct address_space_operations
-===============================
+-------------------------------
 
 This describes how the VFS can manipulate mapping of a file to page cache in
 your filesystem. As of kernel 2.6.13, the following members are defined:
@@ -502,8 +512,14 @@
 	it.  An example implementation can be found in fs/ext2/xip.c.
 
 
+The File Object
+===============
+
+A file object represents a file opened by a process.
+
+
 struct file_operations
-======================
+----------------------
 
 This describes how the VFS can manipulate an open file. As of kernel
 2.6.13, the following members are defined:
@@ -661,7 +677,7 @@
 directory.
 
 
-Directory Entry Cache APIs
+Directory Entry Cache API
 --------------------------
 
 There are a number of functions defined which permit a filesystem to
@@ -705,178 +721,24 @@
 	and the dentry is returned. The caller must use d_put()
 	to free the dentry when it finishes using it.
 
-
-RCU-based dcache locking model
-------------------------------
-
-On many workloads, the most common operation on dcache is
-to look up a dentry, given a parent dentry and the name
-of the child. Typically, for every open(), stat() etc.,
-the dentry corresponding to the pathname will be looked
-up by walking the tree starting with the first component
-of the pathname and using that dentry along with the next
-component to look up the next level and so on. Since it
-is a frequent operation for workloads like multiuser
-environments and web servers, it is important to optimize
-this path.
-
-Prior to 2.5.10, dcache_lock was acquired in d_lookup and thus
-in every component during path look-up. Since 2.5.10 onwards,
-fast-walk algorithm changed this by holding the dcache_lock
-at the beginning and walking as many cached path component
-dentries as possible. This significantly decreases the number
-of acquisition of dcache_lock. However it also increases the
-lock hold time significantly and affects performance in large
-SMP machines. Since 2.5.62 kernel, dcache has been using
-a new locking model that uses RCU to make dcache look-up
-lock-free.
-
-The current dcache locking model is not very different from the existing
-dcache locking model. Prior to 2.5.62 kernel, dcache_lock
-protected the hash chain, d_child, d_alias, d_lru lists as well
-as d_inode and several other things like mount look-up. RCU-based
-changes affect only the way the hash chain is protected. For everything
-else the dcache_lock must be taken for both traversing as well as
-updating. The hash chain updates too take the dcache_lock.
-The significant change is the way d_lookup traverses the hash chain,
-it doesn't acquire the dcache_lock for this and rely on RCU to
-ensure that the dentry has not been *freed*.
+For further information on dentry locking, please refer to the document
+Documentation/filesystems/dentry-locking.txt.
 
 
-Dcache locking details
-----------------------
+Resources
+=========
 
-For many multi-user workloads, open() and stat() on files are
-very frequently occurring operations. Both involve walking
-of path names to find the dentry corresponding to the
-concerned file. In 2.4 kernel, dcache_lock was held
-during look-up of each path component. Contention and
-cache-line bouncing of this global lock caused significant
-scalability problems. With the introduction of RCU
-in Linux kernel, this was worked around by making
-the look-up of path components during path walking lock-free.
+(Note some of these resources are not up-to-date with the latest kernel
+ version.)
 
+Creating Linux virtual filesystems. 2002
+    <http://lwn.net/Articles/13325/>
 
-Safe lock-free look-up of dcache hash table
-===========================================
+The Linux Virtual File-system Layer by Neil Brown. 1999
+    <http://www.cse.unsw.edu.au/~neilb/oss/linux-commentary/vfs.html>
 
-Dcache is a complex data structure with the hash table entries
-also linked together in other lists. In 2.4 kernel, dcache_lock
-protected all the lists. We applied RCU only on hash chain
-walking. The rest of the lists are still protected by dcache_lock.
-Some of the important changes are :
+A tour of the Linux VFS by Michael K. Johnson. 1996
+    <http://www.tldp.org/LDP/khg/HyperNews/get/fs/vfstour.html>
 
-1. The deletion from hash chain is done using hlist_del_rcu() macro which
-   doesn't initialize next pointer of the deleted dentry and this
-   allows us to walk safely lock-free while a deletion is happening.
-
-2. Insertion of a dentry into the hash table is done using
-   hlist_add_head_rcu() which take care of ordering the writes -
-   the writes to the dentry must be visible before the dentry
-   is inserted. This works in conjunction with hlist_for_each_rcu()
-   while walking the hash chain. The only requirement is that
-   all initialization to the dentry must be done before hlist_add_head_rcu()
-   since we don't have dcache_lock protection while traversing
-   the hash chain. This isn't different from the existing code.
-
-3. The dentry looked up without holding dcache_lock by cannot be
-   returned for walking if it is unhashed. It then may have a NULL
-   d_inode or other bogosity since RCU doesn't protect the other
-   fields in the dentry. We therefore use a flag DCACHE_UNHASHED to
-   indicate unhashed  dentries and use this in conjunction with a
-   per-dentry lock (d_lock). Once looked up without the dcache_lock,
-   we acquire the per-dentry lock (d_lock) and check if the
-   dentry is unhashed. If so, the look-up is failed. If not, the
-   reference count of the dentry is increased and the dentry is returned.
-
-4. Once a dentry is looked up, it must be ensured during the path
-   walk for that component it doesn't go away. In pre-2.5.10 code,
-   this was done holding a reference to the dentry. dcache_rcu does
-   the same.  In some sense, dcache_rcu path walking looks like
-   the pre-2.5.10 version.
-
-5. All dentry hash chain updates must take the dcache_lock as well as
-   the per-dentry lock in that order. dput() does this to ensure
-   that a dentry that has just been looked up in another CPU
-   doesn't get deleted before dget() can be done on it.
-
-6. There are several ways to do reference counting of RCU protected
-   objects. One such example is in ipv4 route cache where
-   deferred freeing (using call_rcu()) is done as soon as
-   the reference count goes to zero. This cannot be done in
-   the case of dentries because tearing down of dentries
-   require blocking (dentry_iput()) which isn't supported from
-   RCU callbacks. Instead, tearing down of dentries happen
-   synchronously in dput(), but actual freeing happens later
-   when RCU grace period is over. This allows safe lock-free
-   walking of the hash chains, but a matched dentry may have
-   been partially torn down. The checking of DCACHE_UNHASHED
-   flag with d_lock held detects such dentries and prevents
-   them from being returned from look-up.
-
-
-Maintaining POSIX rename semantics
-==================================
-
-Since look-up of dentries is lock-free, it can race against
-a concurrent rename operation. For example, during rename
-of file A to B, look-up of either A or B must succeed.
-So, if look-up of B happens after A has been removed from the
-hash chain but not added to the new hash chain, it may fail.
-Also, a comparison while the name is being written concurrently
-by a rename may result in false positive matches violating
-rename semantics.  Issues related to race with rename are
-handled as described below :
-
-1. Look-up can be done in two ways - d_lookup() which is safe
-   from simultaneous renames and __d_lookup() which is not.
-   If __d_lookup() fails, it must be followed up by a d_lookup()
-   to correctly determine whether a dentry is in the hash table
-   or not. d_lookup() protects look-ups using a sequence
-   lock (rename_lock).
-
-2. The name associated with a dentry (d_name) may be changed if
-   a rename is allowed to happen simultaneously. To avoid memcmp()
-   in __d_lookup() go out of bounds due to a rename and false
-   positive comparison, the name comparison is done while holding the
-   per-dentry lock. This prevents concurrent renames during this
-   operation.
-
-3. Hash table walking during look-up may move to a different bucket as
-   the current dentry is moved to a different bucket due to rename.
-   But we use hlists in dcache hash table and they are null-terminated.
-   So, even if a dentry moves to a different bucket, hash chain
-   walk will terminate. [with a list_head list, it may not since
-   termination is when the list_head in the original bucket is reached].
-   Since we redo the d_parent check and compare name while holding
-   d_lock, lock-free look-up will not race against d_move().
-
-4. There can be a theoretical race when a dentry keeps coming back
-   to original bucket due to double moves. Due to this look-up may
-   consider that it has never moved and can end up in a infinite loop.
-   But this is not any worse that theoretical livelocks we already
-   have in the kernel.
-
-
-Important guidelines for filesystem developers related to dcache_rcu
-====================================================================
-
-1. Existing dcache interfaces (pre-2.5.62) exported to filesystem
-   don't change. Only dcache internal implementation changes. However
-   filesystems *must not* delete from the dentry hash chains directly
-   using the list macros like allowed earlier. They must use dcache
-   APIs like d_drop() or __d_drop() depending on the situation.
-
-2. d_flags is now protected by a per-dentry lock (d_lock). All
-   access to d_flags must be protected by it.
-
-3. For a hashed dentry, checking of d_count needs to be protected
-   by d_lock.
-
-
-Papers and other documentation on dcache locking
-================================================
-
-1. Scaling dcache with RCU (http://linuxjournal.com/article.php?sid=7124).
-
-2. http://lse.sourceforge.net/locking/dcache/dcache.html
+A small trail through the Linux kernel by Andries Brouwer. 2001
+    <http://www.win.tue.nl/~aeb/linux/vfs/trail.html>
diff --git a/Documentation/hpet.txt b/Documentation/hpet.txt
index 4e7cc8d..e524575 100644
--- a/Documentation/hpet.txt
+++ b/Documentation/hpet.txt
@@ -1,18 +1,21 @@
 		High Precision Event Timer Driver for Linux
 
-The High Precision Event Timer (HPET) hardware is the future replacement for the 8254 and Real
-Time Clock (RTC) periodic timer functionality.  Each HPET can have up two 32 timers.  It is possible
-to configure the first two timers as legacy replacements for 8254 and RTC periodic.  A specification
-done by INTEL and Microsoft can be found at http://www.intel.com/labs/platcomp/hpet/hpetspec.htm.
+The High Precision Event Timer (HPET) hardware is the future replacement
+for the 8254 and Real Time Clock (RTC) periodic timer functionality.
+Each HPET can have up two 32 timers.  It is possible to configure the
+first two timers as legacy replacements for 8254 and RTC periodic timers.
+A specification done by Intel and Microsoft can be found at
+<http://www.intel.com/hardwaredesign/hpetspec.htm>.
 
-The driver supports detection of HPET driver allocation and initialization of the HPET before the
-driver module_init routine is called.  This enables platform code which uses timer 0 or 1 as the
-main timer to intercept HPET initialization.  An example of this initialization can be found in
+The driver supports detection of HPET driver allocation and initialization
+of the HPET before the driver module_init routine is called.  This enables
+platform code which uses timer 0 or 1 as the main timer to intercept HPET
+initialization.  An example of this initialization can be found in
 arch/i386/kernel/time_hpet.c.
 
-The driver provides two APIs which are very similar to the API found in the rtc.c driver.
-There is a user space API and a kernel space API.  An example user space program is provided
-below.
+The driver provides two APIs which are very similar to the API found in
+the rtc.c driver.  There is a user space API and a kernel space API.
+An example user space program is provided below.
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -290,9 +293,8 @@
 	hpet_unregister(struct hpet_task *tp)
 	hpet_control(struct hpet_task *tp, unsigned int cmd, unsigned long arg)
 
-The kernel module using this interface fills in the ht_func and ht_data members of the
-hpet_task structure before calling hpet_register.  hpet_control simply vectors to the hpet_ioctl
-routine and has the same commands and respective arguments as the user API.  hpet_unregister
+The kernel module using this interface fills in the ht_func and ht_data
+members of the hpet_task structure before calling hpet_register.
+hpet_control simply vectors to the hpet_ioctl routine and has the same
+commands and respective arguments as the user API.  hpet_unregister
 is used to terminate usage of the HPET timer reserved by hpet_register.
-
-
diff --git a/Documentation/magic-number.txt b/Documentation/magic-number.txt
index bd8eefa..af67fac 100644
--- a/Documentation/magic-number.txt
+++ b/Documentation/magic-number.txt
@@ -120,7 +120,7 @@
 SAVEKMSG_MAGIC2       0x4B4D5347  savekmsg          arch/*/amiga/config.c
 STLI_BOARDMAGIC       0x4bc6c825  stlibrd           include/linux/istallion.h
 CS_STATE_MAGIC        0x4c4f4749  cs_state          sound/oss/cs46xx.c
-SLAB_C_MAGIC          0x4f17a36d  kmem_cache_s      mm/slab.c
+SLAB_C_MAGIC          0x4f17a36d  kmem_cache        mm/slab.c
 COW_MAGIC             0x4f4f4f4d  cow_header_v1     arch/um/drivers/ubd_user.c
 I810_CARD_MAGIC       0x5072696E  i810_card         sound/oss/i810_audio.c
 TRIDENT_CARD_MAGIC    0x5072696E  trident_card      sound/oss/trident.c
diff --git a/Documentation/networking/decnet.txt b/Documentation/networking/decnet.txt
index c6bd25f..e6c39c5 100644
--- a/Documentation/networking/decnet.txt
+++ b/Documentation/networking/decnet.txt
@@ -176,8 +176,6 @@
  - Which client caused the problem ?
  - How much data was being transferred ?
  - Was the network congested ?
- - If there was a kernel panic, please run the output through ksymoops
-   before sending it to me, otherwise its _useless_.
  - How can the problem be reproduced ?
  - Can you use tcpdump to get a trace ? (N.B. Most (all?) versions of 
    tcpdump don't understand how to dump DECnet properly, so including
diff --git a/Documentation/oops-tracing.txt b/Documentation/oops-tracing.txt
index 66eaaab..c563842 100644
--- a/Documentation/oops-tracing.txt
+++ b/Documentation/oops-tracing.txt
@@ -1,6 +1,6 @@
 NOTE: ksymoops is useless on 2.6.  Please use the Oops in its original format
 (from dmesg, etc).  Ignore any references in this or other docs to "decoding
-the Oops" or "running it through ksymoops".  If you post an Oops fron 2.6 that
+the Oops" or "running it through ksymoops".  If you post an Oops from 2.6 that
 has been run through ksymoops, people will just tell you to repost it.
 
 Quick Summary
diff --git a/Documentation/power/video.txt b/Documentation/power/video.txt
index 526d6dd..912bed8 100644
--- a/Documentation/power/video.txt
+++ b/Documentation/power/video.txt
@@ -11,9 +11,9 @@
 driver -- vesafb and vgacon are widely used).
 
 This is not problem for swsusp, because during swsusp resume, BIOS is
-run normally so video card is normally initialized. S3 has absolutely
-no chance of working with SMP/HT. Be sure it to turn it off before
-testing (swsusp should work ok, OTOH).
+run normally so video card is normally initialized. It should not be
+problem for S1 standby, because hardware should retain its state over
+that.
 
 There are a few types of systems where video works after S3 resume:
 
@@ -64,7 +64,7 @@
 (proper X, knowing your hardware, not XF68_FBcon) might have better
 chance of working.
 
-Table of known working systems:
+Table of known working notebooks:
 
 Model                           hack (or "how to do it")
 ------------------------------------------------------------------------------
@@ -73,7 +73,7 @@
 Acer TM C110			video_post (8)
 Acer TM C300                    vga=normal (only suspend on console, not in X), vbetool (6) or video_post (8)
 Acer TM 4052LCi		        s3_bios (2)
-Acer TM 636Lci			s3_bios vga=normal (2)
+Acer TM 636Lci			s3_bios,s3_mode (4)
 Acer TM 650 (Radeon M7)		vga=normal plus boot-radeon (5) gets text console back
 Acer TM 660			??? (*)
 Acer TM 800			vga=normal, X patches, see webpage (5) or vbetool (6)
@@ -137,6 +137,13 @@
 Toshiba M30                     (2) xor X with nvidia driver using internal AGP
 Uniwill 244IIO			??? (*)
 
+Known working desktop systems
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Mainboard	    Graphics card                 hack (or "how to do it")
+------------------------------------------------------------------------------
+Asus A7V8X	    nVidia RIVA TNT2 model 64	  s3_bios,s3_mode (4)
+
 
 (*) from http://www.ubuntulinux.org/wiki/HoaryPMResults, not sure
     which options to use. If you know, please tell me.
diff --git a/Documentation/s390/driver-model.txt b/Documentation/s390/driver-model.txt
index 1946195..df09758 100644
--- a/Documentation/s390/driver-model.txt
+++ b/Documentation/s390/driver-model.txt
@@ -8,11 +8,10 @@
 even if they aren't actually driven by ccws.
 
 All ccw devices are accessed via a subchannel, this is reflected in the 
-structures under root/:
+structures under devices/:
 
-root/
-     - sys
-     - legacy
+devices/
+     - system/
      - css0/
            - 0.0.0000/0.0.0815/
 	   - 0.0.0001/0.0.4711/
@@ -36,7 +35,7 @@
 
 online:     An interface to set the device online and offline.
 	    In the special case of the device being disconnected (see the
-	    notify function under 1.2), piping 0 to online will focibly delete
+	    notify function under 1.2), piping 0 to online will forcibly delete
 	    the device.
 
 The device drivers can add entries to export per-device data and interfaces.
@@ -222,7 +221,7 @@
 Please note, that unlike /proc/chpids in 2.4, the channel path objects reflect
 only the logical state and not the physical state, since we cannot track the
 latter consistently due to lacking machine support (we don't need to be aware
-of anyway).
+of it anyway).
 
 status - Can be 'online' or 'offline'.
 	 Piping 'on' or 'off' sets the chpid logically online/offline.
@@ -235,12 +234,16 @@
 3. System devices
 -----------------
 
-Note: cpus may yet be added here.
-
 3.1 xpram 
 ---------
 
-xpram shows up under sys/ as 'xpram'.
+xpram shows up under devices/system/ as 'xpram'.
+
+3.2 cpus
+--------
+
+For each cpu, a directory is created under devices/system/cpu/. Each cpu has an
+attribute 'online' which can be 0 or 1.
 
 
 4. Other devices
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 13cba95..2f27f39 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -167,7 +167,7 @@
     spdif           - Support SPDIF I/O
     		    - Default: disabled
 
-    Module supports autoprobe and multiple chips (max 8).
+    This module supports one chip and autoprobe.
 
     The power-management is supported.
 
@@ -206,7 +206,7 @@
 			  See "AC97 Quirk Option" section below.
     spdif_aclink	- S/PDIF transfer over AC-link (default = 1)
 
-    This module supports up to 8 cards and autoprobe.
+    This module supports one card and autoprobe.
 
     ATI IXP has two different methods to control SPDIF output.  One is
     over AC-link and another is over the "direct" SPDIF output.  The
@@ -218,7 +218,7 @@
 
     Module for ATI IXP 150/200/250 AC97 modem controllers.
 
-    Module supports up to 8 cards.
+    This module supports one card and autoprobe.
 
     Note: The default index value of this module is -2, i.e. the first
           slot is excluded.
@@ -637,7 +637,7 @@
     model	- force the model name
     position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)
 
-    Module supports up to 8 cards.
+    This module supports one card and autoprobe.
 
     Each codec may have a model table for different configurations.
     If your machine isn't listed there, the default (usually minimal)
@@ -663,6 +663,10 @@
 			adjusted.  Appearing only when compiled with
 			$CONFIG_SND_DEBUG=y
 
+	ALC260
+	  hp		HP machines
+	  fujitsu	Fujitsu S7020
+
 	CMI9880
 	  minimal	3-jack in back
 	  min_fp	3-jack in back, 2-jack in front
@@ -811,7 +815,7 @@
 		    semaphores (e.g. on some ASUS laptops)
 		    (default off)
 
-    Module supports autoprobe and multiple bus-master chips (max 8).
+    This module supports one chip and autoprobe.
 
     Note: the latest driver supports auto-detection of chip clock.
     if you still encounter too fast playback, specify the clock
@@ -830,7 +834,7 @@
 
     ac97_clock	  - AC'97 codec clock base (0 = auto-detect)
 
-    This module supports up to 8 cards and autoprobe.
+    This module supports one card and autoprobe.
 
     Note: The default index value of this module is -2, i.e. the first
           slot is excluded.
@@ -950,8 +954,10 @@
     use_cache        - 0 or 1 (disabled by default)
     vaio_hack        - alias buffer_top=0x25a800
     reset_workaround - enable AC97 RESET workaround for some laptops
+    reset_workaround2 - enable extended AC97 RESET workaround for some
+		      other laptops
 
-    Module supports autoprobe and multiple chips (max 8).
+    This module supports one chip and autoprobe.
 
     The power-management is supported.
 
@@ -980,6 +986,11 @@
     workaround is enabled automatically.  For other laptops with a
     hard freeze, you can try reset_workaround=1 option.
 
+    Note: Dell Latitude CSx laptops have another problem regarding
+    AC97 RESET.  On these laptops, reset_workaround2 option is
+    turned on as default.  This option is worth to try if the
+    previous reset_workaround option doesn't help.
+
     Note: This driver is really crappy.  It's a porting from the
     OSS driver, which is a result of black-magic reverse engineering.
     The detection of codec will fail if the driver is loaded *after*
@@ -1310,7 +1321,7 @@
     ac97_quirk  - AC'97 workaround for strange hardware
 		  See "AC97 Quirk Option" section below.
 
-    Module supports autoprobe and multiple bus-master chips (max 8).
+    This module supports one chip and autoprobe.
 
     Note: on some SMP motherboards like MSI 694D the interrupts might
           not be generated properly.  In such a case, please try to
@@ -1352,7 +1363,7 @@
 
     ac97_clock	- AC'97 codec clock base (default 48000Hz)
 
-    Module supports up to 8 cards.
+    This module supports one card and autoprobe.
 
     Note: The default index value of this module is -2, i.e. the first
           slot is excluded.
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
index 24e8552..260334c 100644
--- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
@@ -18,8 +18,8 @@
       </affiliation>
      </author>
 
-     <date>March 6, 2005</date>
-     <edition>0.3.4</edition>
+     <date>October 6, 2005</date>
+     <edition>0.3.5</edition>
 
     <abstract>
       <para>
@@ -30,7 +30,7 @@
 
     <legalnotice>
     <para>
-    Copyright (c) 2002-2004  Takashi Iwai <email>tiwai@suse.de</email>
+    Copyright (c) 2002-2005  Takashi Iwai <email>tiwai@suse.de</email>
     </para>
 
     <para>
@@ -1433,25 +1433,10 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  if (chip->res_port) {
-          release_resource(chip->res_port);
-          kfree_nocheck(chip->res_port);
-  }
+  release_and_free_resource(chip->res_port);
 ]]>
           </programlisting>
         </informalexample>
-
-      As you can see, the resource pointer is also to be freed
-      via <function>kfree_nocheck()</function> after
-      <function>release_resource()</function> is called. You
-      cannot use <function>kfree()</function> here, because on ALSA,
-      <function>kfree()</function> may be a wrapper to its own
-      allocator with the memory debugging. Since the resource pointer
-      is allocated externally outside the ALSA, it must be released
-      via the native
-      <function>kfree()</function>.
-      <function>kfree_nocheck()</function> is used for that; it calls
-      the native <function>kfree()</function> without wrapper. 
       </para>
 
       <para>
@@ -2190,8 +2175,7 @@
 	unsigned int rate_den;
 
 	/* -- SW params -- */
-	int tstamp_timespec;		/* use timeval (0) or timespec (1) */
-	snd_pcm_tstamp_t tstamp_mode;	/* mmap timestamp is updated */
+	struct timespec tstamp_mode;	/* mmap timestamp is updated */
   	unsigned int period_step;
 	unsigned int sleep_min;		/* min ticks to sleep */
 	snd_pcm_uframes_t xfer_align;	/* xfer size need to be a multiple */
@@ -3709,8 +3693,7 @@
         <para>
           Here, the chip instance is retrieved via
         <function>snd_kcontrol_chip()</function> macro.  This macro
-        converts from kcontrol-&gt;private_data to the type defined by
-        <type>chip_t</type>. The
+        just accesses to kcontrol-&gt;private_data. The
         kcontrol-&gt;private_data field is 
         given as the argument of <function>snd_ctl_new()</function>
         (see the later subsection
@@ -5998,32 +5981,23 @@
         The first argument is the expression to evaluate, and the
       second argument is the action if it fails. When
       <constant>CONFIG_SND_DEBUG</constant>, is set, it will show an
-      error message such as <computeroutput>BUG? (xxx) (called from
-      yyy)</computeroutput>. When no debug flag is set, this is
-      ignored. 
+      error message such as <computeroutput>BUG? (xxx)</computeroutput>
+      together with stack trace.
       </para>
-    </section>
-
-    <section id="useful-functions-snd-runtime-check">
-      <title><function>snd_runtime_check()</function></title>
       <para>
-        This macro is quite similar with
-      <function>snd_assert()</function>. Unlike
-      <function>snd_assert()</function>, the expression is always
-      evaluated regardless of
-      <constant>CONFIG_SND_DEBUG</constant>. When
-      <constant>CONFIG_SND_DEBUG</constant> is set, the macro will
-      show a message like <computeroutput>ERROR (xx) (called from
-      yyy)</computeroutput>. 
+	 When no debug flag is set, this macro is ignored. 
       </para>
     </section>
 
     <section id="useful-functions-snd-bug">
       <title><function>snd_BUG()</function></title>
       <para>
-        It calls <function>snd_assert(0,)</function> -- that is, just
-      prints the error message at the point. It's useful to show that
-      a fatal error happens there. 
+        It shows <computeroutput>BUG?</computeroutput> message and
+      stack trace as well as <function>snd_assert</function> at the point.
+      It's useful to show that a fatal error happens there. 
+      </para>
+      <para>
+	 When no debug flag is set, this macro is ignored. 
       </para>
     </section>
   </chapter>
diff --git a/Documentation/sparse.txt b/Documentation/sparse.txt
index 1829009..3f1c546 100644
--- a/Documentation/sparse.txt
+++ b/Documentation/sparse.txt
@@ -41,9 +41,9 @@
 vs cpu-endian vs whatever), and there the constant "0" really _is_
 special.
 
-Modify top-level Makefile to say
+Use
 
-CHECK           = sparse -Wbitwise
+	make C=[12] CF=-Wbitwise
 
 or you don't get any checking at all.
 
diff --git a/Documentation/video4linux/bttv/README.freeze b/Documentation/video4linux/bttv/README.freeze
index 51f8d43..4259dcc 100644
--- a/Documentation/video4linux/bttv/README.freeze
+++ b/Documentation/video4linux/bttv/README.freeze
@@ -27,9 +27,9 @@
 protection faults (so-called "kernel oops").
 
 If you run into some kind of deadlock, you can try to dump a call trace
-for each process using sysrq-t (see Documentation/sysrq.txt).  ksymoops
-will translate these dumps into kernel symbols too.  This way it is
-possible to figure where *exactly* some process in "D" state is stuck.
+for each process using sysrq-t (see Documentation/sysrq.txt).
+This way it is possible to figure where *exactly* some process in "D"
+state is stuck.
 
 I've seen reports that bttv 0.7.x crashes whereas 0.8.x works rock solid
 for some people.  Thus probably a small buglet left somewhere in bttv
diff --git a/Documentation/vm/hugetlbpage.txt b/Documentation/vm/hugetlbpage.txt
index 1b9bcd1..1ad9af1 100644
--- a/Documentation/vm/hugetlbpage.txt
+++ b/Documentation/vm/hugetlbpage.txt
@@ -13,12 +13,13 @@
 Users can use the huge page support in Linux kernel by either using the mmap
 system call or standard SYSv shared memory system calls (shmget, shmat).
 
-First the Linux kernel needs to be built with CONFIG_HUGETLB_PAGE (present
-under Processor types and feature)  and CONFIG_HUGETLBFS (present under file
-system option on config menu) config options.
+First the Linux kernel needs to be built with the CONFIG_HUGETLBFS
+(present under "File systems") and CONFIG_HUGETLB_PAGE (selected
+automatically when CONFIG_HUGETLBFS is selected) configuration
+options.
 
 The kernel built with hugepage support should show the number of configured
-hugepages in the system by running the "cat /proc/meminfo" command.  
+hugepages in the system by running the "cat /proc/meminfo" command.
 
 /proc/meminfo also provides information about the total number of hugetlb
 pages configured in the kernel.  It also displays information about the
@@ -38,19 +39,19 @@
 
 /proc/sys/vm/nr_hugepages indicates the current number of configured hugetlb
 pages in the kernel.  Super user can dynamically request more (or free some
-pre-configured) hugepages. 
-The allocation( or deallocation) of hugetlb pages is posible only if there are
+pre-configured) hugepages.
+The allocation (or deallocation) of hugetlb pages is possible only if there are
 enough physically contiguous free pages in system (freeing of hugepages is
-possible only if there are enough hugetlb pages free that can be transfered 
+possible only if there are enough hugetlb pages free that can be transfered
 back to regular memory pool).
 
 Pages that are used as hugetlb pages are reserved inside the kernel and can
-not be used for other purposes. 
+not be used for other purposes.
 
 Once the kernel with Hugetlb page support is built and running, a user can
 use either the mmap system call or shared memory system calls to start using
 the huge pages.  It is required that the system administrator preallocate
-enough memory for huge page purposes.  
+enough memory for huge page purposes.
 
 Use the following command to dynamically allocate/deallocate hugepages:
 
@@ -80,9 +81,9 @@
 rounded down to HPAGE_SIZE.  The option nr_inode sets the maximum number of
 inodes that /mnt/huge can use.  If the size or nr_inode options are not
 provided on command line then no limits are set.  For size and nr_inodes
-options, you can use [G|g]/[M|m]/[K|k] to represent giga/mega/kilo. For 
-example, size=2K has the same meaning as size=2048. An example is given at 
-the end of this document. 
+options, you can use [G|g]/[M|m]/[K|k] to represent giga/mega/kilo. For
+example, size=2K has the same meaning as size=2048. An example is given at
+the end of this document.
 
 read and write system calls are not supported on files that reside on hugetlb
 file systems.
diff --git a/MAINTAINERS b/MAINTAINERS
index 08dd21f..995bfd8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1077,6 +1077,26 @@
 M:	perex@suse.cz
 S:	Maintained
 
+HPET:	High Precision Event Timers driver (hpet.c)
+P:	Clemens Ladisch
+M:	clemens@ladisch.de
+S:	Maintained
+
+HPET:	i386
+P:	Venkatesh Pallipadi (Venki)
+M:	venkatesh.pallipadi@intel.com
+S:	Maintained
+
+HPET:	x86_64
+P:	Andi Kleen and Vojtech Pavlik
+M:	ak@muc.de and vojtech@suse.cz
+S:	Maintained
+
+HPET:	ACPI hpet.c
+P:	Bob Picco
+M:	bob.picco@hp.com
+S:	Maintained
+
 HPFS FILESYSTEM
 P:	Mikulas Patocka
 M:	mikulas@artax.karlin.mff.cuni.cz
@@ -2051,6 +2071,12 @@
 M:	mpm@selenic.com
 S:	Maintained
 
+RAPIDIO SUBSYSTEM
+P:	Matt Porter
+M:	mporter@kernel.crashing.org
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+
 REAL TIME CLOCK DRIVER
 P:	Paul Gortmaker
 M:	p_gortmaker@yahoo.com
diff --git a/Makefile b/Makefile
index 2dac801..ea96da1 100644
--- a/Makefile
+++ b/Makefile
@@ -583,7 +583,7 @@
 
 
 ifeq ($(KBUILD_EXTMOD),)
-core-y		+= kernel/ mm/ fs/ ipc/ security/ crypto/
+core-y		+= kernel/ mm/ fs/ ipc/ security/ crypto/ block/
 
 vmlinux-dirs	:= $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
 		     $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 9bd8609..9a340e7 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -648,7 +648,7 @@
 
 #endif
 
-static int do_ptrace(int request, struct task_struct *child, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
 	unsigned long tmp;
 	int ret;
@@ -782,53 +782,6 @@
 	return ret;
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
-{
-	struct task_struct *child;
-	int ret;
-
-	lock_kernel();
-	ret = -EPERM;
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-		ret = security_ptrace(current->parent, current);
-		if (ret)
-			goto out;
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
-		goto out;
-	}
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (!child)
-		goto out;
-
-	ret = -EPERM;
-	if (pid == 1)		/* you may not mess with init */
-		goto out_tsk;
-
-	if (request == PTRACE_ATTACH) {
-		ret = ptrace_attach(child);
-		goto out_tsk;
-	}
-	ret = ptrace_check_attach(child, request == PTRACE_KILL);
-	if (ret == 0)
-		ret = do_ptrace(request, child, addr, data);
-
-out_tsk:
-	put_task_struct(child);
-out:
-	unlock_kernel();
-	return ret;
-}
-
 asmlinkage void syscall_trace(int why, struct pt_regs *regs)
 {
 	unsigned long ip;
diff --git a/arch/arm/mach-aaec2000/clock.c b/arch/arm/mach-aaec2000/clock.c
index 99e0191..0340ddc 100644
--- a/arch/arm/mach-aaec2000/clock.c
+++ b/arch/arm/mach-aaec2000/clock.c
@@ -14,6 +14,7 @@
 #include <linux/list.h>
 #include <linux/errno.h>
 #include <linux/err.h>
+#include <linux/string.h>
 
 #include <asm/semaphore.h>
 #include <asm/hardware/clock.h>
diff --git a/arch/arm/mach-epxa10db/mm.c b/arch/arm/mach-epxa10db/mm.c
index e8832d0..cfd0d21 100644
--- a/arch/arm/mach-epxa10db/mm.c
+++ b/arch/arm/mach-epxa10db/mm.c
@@ -25,6 +25,7 @@
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/sizes.h>
+#include <asm/page.h>
  
 #include <asm/mach/map.h>
 
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index a1b153d..a4bafee 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -420,8 +420,7 @@
  free_impd1:
 	if (impd1 && impd1->base)
 		iounmap(impd1->base);
-	if (impd1)
-		kfree(impd1);
+	kfree(impd1);
  release_lm:
 	release_mem_region(dev->resource.start, SZ_4K);
 	return ret;
diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c
index 54162ba..698eb06 100644
--- a/arch/arm/mach-pxa/corgi_lcd.c
+++ b/arch/arm/mach-pxa/corgi_lcd.c
@@ -19,6 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
+#include <linux/string.h>
 #include <asm/arch/akita.h>
 #include <asm/arch/corgi.h>
 #include <asm/arch/hardware.h>
diff --git a/arch/arm26/kernel/ptrace.c b/arch/arm26/kernel/ptrace.c
index cf7e977..4e6b735 100644
--- a/arch/arm26/kernel/ptrace.c
+++ b/arch/arm26/kernel/ptrace.c
@@ -546,7 +546,7 @@
 			      sizeof(struct user_fp)) ? -EFAULT : 0;
 }
 
-static int do_ptrace(int request, struct task_struct *child, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
 	unsigned long tmp;
 	int ret;
@@ -665,53 +665,6 @@
 	return ret;
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
-{
-	struct task_struct *child;
-	int ret;
-
-	lock_kernel();
-	ret = -EPERM;
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-		ret = security_ptrace(current->parent, current);
-		if (ret)
-			goto out;
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
-		goto out;
-	}
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (!child)
-		goto out;
-
-	ret = -EPERM;
-	if (pid == 1)		/* you may not mess with init */
-		goto out_tsk;
-
-	if (request == PTRACE_ATTACH) {
-		ret = ptrace_attach(child);
-		goto out_tsk;
-	}
-	ret = ptrace_check_attach(child, request == PTRACE_KILL);
-	if (ret == 0)
-		ret = do_ptrace(request, child, addr, data);
-
-out_tsk:
-	put_task_struct(child);
-out:
-	unlock_kernel();
-	return ret;
-}
-
 asmlinkage void syscall_trace(int why, struct pt_regs *regs)
 {
 	unsigned long ip;
diff --git a/arch/cris/arch-v10/README.mm b/arch/cris/arch-v10/README.mm
index 6f08903..517d1f0 100644
--- a/arch/cris/arch-v10/README.mm
+++ b/arch/cris/arch-v10/README.mm
@@ -177,7 +177,7 @@
 Given the top-level Page Directory, the offset in that directory is calculated
 using the upper 8 bits:
 
-extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
+static inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
 {
 	return mm->pgd + (address >> PGDIR_SHIFT);
 }
@@ -190,14 +190,14 @@
 
 Since the Middle Directory does not exist, it is a unity mapping:
 
-extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
+static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
 {
 	return (pmd_t *) dir;
 }
 
 The Page Table provides the final lookup by using bits 13 to 23 as index:
 
-extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address)
+static inline pte_t * pte_offset(pmd_t * dir, unsigned long address)
 {
 	return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) &
 					   (PTRS_PER_PTE - 1));
diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c
index 130dd21..6cbd34a 100644
--- a/arch/cris/arch-v10/kernel/ptrace.c
+++ b/arch/cris/arch-v10/kernel/ptrace.c
@@ -76,55 +76,11 @@
  * (in user space) where the result of the ptrace call is written (instead of
  * being returned).
  */
-asmlinkage int 
-sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-	struct task_struct *child;
 	int ret;
 	unsigned long __user *datap = (unsigned long __user *)data;
 
-	lock_kernel();
-	ret = -EPERM;
-	
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-		ret = security_ptrace(current->parent, current);
-		if (ret)
-			goto out;
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
-		goto out;
-	}
-	
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	
-	if (child)
-		get_task_struct(child);
-	
-	read_unlock(&tasklist_lock);
-	
-	if (!child)
-		goto out;
-	
-	ret = -EPERM;
-	
-	if (pid == 1)		/* Leave the init process alone! */
-		goto out_tsk;
-	
-	if (request == PTRACE_ATTACH) {
-		ret = ptrace_attach(child);
-		goto out_tsk;
-	}
-	
-	ret = ptrace_check_attach(child, request == PTRACE_KILL);
-	if (ret < 0)
-		goto out_tsk;
-
 	switch (request) {
 		/* Read word at location address. */ 
 		case PTRACE_PEEKTEXT:
@@ -289,10 +245,7 @@
 			ret = ptrace_request(child, request, addr, data);
 			break;
 	}
-out_tsk:
-	put_task_struct(child);
-out:
-	unlock_kernel();
+
 	return ret;
 }
 
diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c
index 6937719..19bcad0 100644
--- a/arch/cris/arch-v10/kernel/signal.c
+++ b/arch/cris/arch-v10/kernel/signal.c
@@ -476,7 +476,7 @@
  * OK, we're invoking a handler
  */	
 
-extern inline void
+static inline void
 handle_signal(int canrestart, unsigned long sig,
 	      siginfo_t *info, struct k_sigaction *ka,
               sigset_t *oldset, struct pt_regs * regs)
diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c
index ca72076..501fa52 100644
--- a/arch/cris/arch-v32/drivers/cryptocop.c
+++ b/arch/cris/arch-v32/drivers/cryptocop.c
@@ -277,7 +277,7 @@
 static void free_cdesc(struct cryptocop_dma_desc *cdesc)
 {
 	DEBUG(printk("free_cdesc: cdesc 0x%p, from_pool=%d\n", cdesc, cdesc->from_pool));
-	if (cdesc->free_buf) kfree(cdesc->free_buf);
+	kfree(cdesc->free_buf);
 
 	if (cdesc->from_pool) {
 		unsigned long int flags;
@@ -2950,15 +2950,15 @@
 		put_page(outpages[i]);
 	}
 
-	if (digest_result) kfree(digest_result);
-	if (inpages) kfree(inpages);
-	if (outpages) kfree(outpages);
+	kfree(digest_result);
+	kfree(inpages);
+	kfree(outpages);
 	if (cop){
-		if (cop->tfrm_op.indata) kfree(cop->tfrm_op.indata);
-		if (cop->tfrm_op.outdata) kfree(cop->tfrm_op.outdata);
+		kfree(cop->tfrm_op.indata);
+		kfree(cop->tfrm_op.outdata);
 		kfree(cop);
 	}
-	if (jc) kfree(jc);
+	kfree(jc);
 
 	DEBUG(print_lock_status());
 
diff --git a/arch/cris/arch-v32/kernel/ptrace.c b/arch/cris/arch-v32/kernel/ptrace.c
index 208489d..5528b83 100644
--- a/arch/cris/arch-v32/kernel/ptrace.c
+++ b/arch/cris/arch-v32/kernel/ptrace.c
@@ -99,55 +99,11 @@
 }
 
 
-asmlinkage int
-sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-	struct task_struct *child;
 	int ret;
 	unsigned long __user *datap = (unsigned long __user *)data;
 
-	lock_kernel();
-	ret = -EPERM;
-
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-		ret = security_ptrace(current->parent, current);
-		if (ret)
-			goto out;
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
-		goto out;
-	}
-
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-
-	if (child)
-		get_task_struct(child);
-
-	read_unlock(&tasklist_lock);
-
-	if (!child)
-		goto out;
-
-	ret = -EPERM;
-
-	if (pid == 1)		/* Leave the init process alone! */
-		goto out_tsk;
-
-	if (request == PTRACE_ATTACH) {
-		ret = ptrace_attach(child);
-		goto out_tsk;
-	}
-
-	ret = ptrace_check_attach(child, request == PTRACE_KILL);
-	if (ret < 0)
-		goto out_tsk;
-
 	switch (request) {
 		/* Read word at location address. */
 		case PTRACE_PEEKTEXT:
@@ -347,10 +303,7 @@
 			ret = ptrace_request(child, request, addr, data);
 			break;
 	}
-out_tsk:
-	put_task_struct(child);
-out:
-	unlock_kernel();
+
 	return ret;
 }
 
diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c
index 0a3614d..99e59b3 100644
--- a/arch/cris/arch-v32/kernel/signal.c
+++ b/arch/cris/arch-v32/kernel/signal.c
@@ -513,7 +513,7 @@
 }
 
 /* Invoke a singal handler to, well, handle the signal. */
-extern inline void
+static inline void
 handle_signal(int canrestart, unsigned long sig,
 	      siginfo_t *info, struct k_sigaction *ka,
               sigset_t *oldset, struct pt_regs * regs)
diff --git a/arch/cris/mm/ioremap.c b/arch/cris/mm/ioremap.c
index a92ac98..1780df3 100644
--- a/arch/cris/mm/ioremap.c
+++ b/arch/cris/mm/ioremap.c
@@ -16,7 +16,7 @@
 #include <asm/tlbflush.h>
 #include <asm/arch/memmap.h>
 
-extern inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
+static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
 	unsigned long phys_addr, pgprot_t prot)
 {
 	unsigned long end;
diff --git a/arch/frv/kernel/ptrace.c b/arch/frv/kernel/ptrace.c
index cb335a1..f953484 100644
--- a/arch/frv/kernel/ptrace.c
+++ b/arch/frv/kernel/ptrace.c
@@ -106,48 +106,11 @@
 	child->thread.frame0->__status |= REG__STATUS_STEP;
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-	struct task_struct *child;
 	unsigned long tmp;
 	int ret;
 
-	lock_kernel();
-	ret = -EPERM;
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-		ret = security_ptrace(current->parent, current);
-		if (ret)
-			goto out;
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
-		goto out;
-	}
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (!child)
-		goto out;
-
-	ret = -EPERM;
-	if (pid == 1)		/* you may not mess with init */
-		goto out_tsk;
-
-	if (request == PTRACE_ATTACH) {
-		ret = ptrace_attach(child);
-		goto out_tsk;
-	}
-
-	ret = ptrace_check_attach(child, request == PTRACE_KILL);
-	if (ret < 0)
-		goto out_tsk;
-
 	switch (request) {
 		/* when I and D space are separate, these will need to be fixed. */
 	case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -351,10 +314,6 @@
 		ret = -EIO;
 		break;
 	}
-out_tsk:
-	put_task_struct(child);
-out:
-	unlock_kernel();
 	return ret;
 }
 
diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c
index a569fe4..0ff6f79 100644
--- a/arch/h8300/kernel/ptrace.c
+++ b/arch/h8300/kernel/ptrace.c
@@ -57,43 +57,10 @@
 	h8300_disable_trace(child);
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-	struct task_struct *child;
 	int ret;
 
-	lock_kernel();
-	ret = -EPERM;
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
-		goto out;
-	}
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (!child)
-		goto out;
-
-	ret = -EPERM;
-	if (pid == 1)		/* you may not mess with init */
-		goto out_tsk;
-
-	if (request == PTRACE_ATTACH) {
-		ret = ptrace_attach(child);
-		goto out_tsk;
-	}
-	ret = ptrace_check_attach(child, request == PTRACE_KILL);
-	if (ret < 0)
-		goto out_tsk;
-
 	switch (request) {
 		case PTRACE_PEEKTEXT: /* read word at location addr. */ 
 		case PTRACE_PEEKDATA: {
@@ -251,10 +218,6 @@
 			ret = -EIO;
 			break;
 	}
-out_tsk:
-	put_task_struct(child);
-out:
-	unlock_kernel();
 	return ret;
 }
 
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index bac0da7..dbf90ad 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -997,8 +997,21 @@
 
 source "fs/Kconfig"
 
+menu "Instrumentation Support"
+	depends on EXPERIMENTAL
+
 source "arch/i386/oprofile/Kconfig"
 
+config KPROBES
+	bool "Kprobes (EXPERIMENTAL)"
+	help
+	  Kprobes allows you to trap at almost any kernel address and
+	  execute a callback function.  register_kprobe() establishes
+	  a probepoint and specifies the callback.  Kprobes is useful
+	  for kernel debugging, non-intrusive instrumentation and testing.
+	  If in doubt, say "N".
+endmenu
+
 source "arch/i386/Kconfig.debug"
 
 source "security/Kconfig"
diff --git a/arch/i386/Kconfig.debug b/arch/i386/Kconfig.debug
index 5228c40..c48b424 100644
--- a/arch/i386/Kconfig.debug
+++ b/arch/i386/Kconfig.debug
@@ -22,16 +22,6 @@
 	  This option will cause messages to be printed if free stack space
 	  drops below a certain limit.
 
-config KPROBES
-	bool "Kprobes"
-	depends on DEBUG_KERNEL
-	help
-	  Kprobes allows you to trap at almost any kernel address and
-	  execute a callback function.  register_kprobe() establishes
-	  a probepoint and specifies the callback.  Kprobes is useful
-	  for kernel debugging, non-intrusive instrumentation and testing.
-	  If in doubt, say "N".
-
 config DEBUG_STACK_USAGE
 	bool "Stack utilization instrumentation"
 	depends on DEBUG_KERNEL
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index 7c724ff..496a2c9 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -559,14 +559,20 @@
  * If Linux enabled the LAPIC against the BIOS default
  * disable it down before re-entering the BIOS on shutdown.
  * Otherwise the BIOS may get confused and not power-off.
+ * Additionally clear all LVT entries before disable_local_APIC
+ * for the case where Linux didn't enable the LAPIC.
  */
 void lapic_shutdown(void)
 {
-	if (!cpu_has_apic || !enabled_via_apicbase)
+	if (!cpu_has_apic)
 		return;
 
 	local_irq_disable();
-	disable_local_APIC();
+	clear_local_APIC();
+
+	if (enabled_via_apicbase)
+		disable_local_APIC();
+
 	local_irq_enable();
 }
 
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index d2ef0c2..86e80c5 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -447,8 +447,7 @@
 	"system standby resume",
 	"capabilities change"
 };
-#define NR_APM_EVENT_NAME	\
-		(sizeof(apm_event_name) / sizeof(apm_event_name[0]))
+#define NR_APM_EVENT_NAME ARRAY_SIZE(apm_event_name)
 
 typedef struct lookup_t {
 	int	key;
@@ -479,7 +478,7 @@
 	{ APM_NO_ERROR,		"BIOS did not set a return code" },
 	{ APM_NOT_PRESENT,	"No APM present" }
 };
-#define ERROR_COUNT	(sizeof(error_table)/sizeof(lookup_t))
+#define ERROR_COUNT	ARRAY_SIZE(error_table)
 
 /**
  *	apm_error	-	display an APM error
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 74145a3..c145fb3 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -30,8 +30,6 @@
 
 struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
 
-extern void mcheck_init(struct cpuinfo_x86 *c);
-
 extern int disable_pse;
 
 static void default_init(struct cpuinfo_x86 * c)
@@ -429,9 +427,8 @@
 	}
 
 	/* Init Machine Check Exception if available. */
-#ifdef CONFIG_X86_MCE
 	mcheck_init(c);
-#endif
+
 	if (c == &boot_cpu_data)
 		sysenter_setup();
 	enable_sep_cpu();
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
index 1465974..0ea010a 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -67,7 +67,7 @@
 	[CPU_MP4HT_D0]	= {15,  3, 4 },
 	[CPU_MP4HT_E0]	= {15,  4, 1 },
 };
-#define N_IDS	(sizeof(cpu_ids)/sizeof(cpu_ids[0]))
+#define N_IDS	ARRAY_SIZE(cpu_ids)
 
 struct cpu_model
 {
diff --git a/arch/i386/kernel/cpu/mcheck/k7.c b/arch/i386/kernel/cpu/mcheck/k7.c
index 7c6b9c7..fc5d521 100644
--- a/arch/i386/kernel/cpu/mcheck/k7.c
+++ b/arch/i386/kernel/cpu/mcheck/k7.c
@@ -68,7 +68,7 @@
 
 
 /* AMD K7 machine check is Intel like */
-void __devinit amd_mcheck_init(struct cpuinfo_x86 *c)
+void amd_mcheck_init(struct cpuinfo_x86 *c)
 {
 	u32 l, h;
 	int i;
diff --git a/arch/i386/kernel/cpu/mcheck/mce.c b/arch/i386/kernel/cpu/mcheck/mce.c
index 2cf25d2..6170af3 100644
--- a/arch/i386/kernel/cpu/mcheck/mce.c
+++ b/arch/i386/kernel/cpu/mcheck/mce.c
@@ -16,7 +16,7 @@
 
 #include "mce.h"
 
-int mce_disabled __devinitdata = 0;
+int mce_disabled = 0;
 int nr_mce_banks;
 
 EXPORT_SYMBOL_GPL(nr_mce_banks);	/* non-fatal.o */
@@ -31,7 +31,7 @@
 void fastcall (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check;
 
 /* This has to be run for each processor */
-void __devinit mcheck_init(struct cpuinfo_x86 *c)
+void mcheck_init(struct cpuinfo_x86 *c)
 {
 	if (mce_disabled==1)
 		return;
diff --git a/arch/i386/kernel/cpu/mcheck/p4.c b/arch/i386/kernel/cpu/mcheck/p4.c
index 1d1e885..fd2c459 100644
--- a/arch/i386/kernel/cpu/mcheck/p4.c
+++ b/arch/i386/kernel/cpu/mcheck/p4.c
@@ -77,7 +77,7 @@
 }
 
 /* P4/Xeon Thermal regulation detect and init */
-static void __devinit intel_init_thermal(struct cpuinfo_x86 *c)
+static void intel_init_thermal(struct cpuinfo_x86 *c)
 {
 	u32 l, h;
 	unsigned int cpu = smp_processor_id();
@@ -231,7 +231,7 @@
 }
 
 
-void __devinit intel_p4_mcheck_init(struct cpuinfo_x86 *c)
+void intel_p4_mcheck_init(struct cpuinfo_x86 *c)
 {
 	u32 l, h;
 	int i;
diff --git a/arch/i386/kernel/cpu/mcheck/p5.c b/arch/i386/kernel/cpu/mcheck/p5.c
index 3a2e24b..94bc43d 100644
--- a/arch/i386/kernel/cpu/mcheck/p5.c
+++ b/arch/i386/kernel/cpu/mcheck/p5.c
@@ -28,7 +28,7 @@
 }
 
 /* Set up machine check reporting for processors with Intel style MCE */
-void __devinit intel_p5_mcheck_init(struct cpuinfo_x86 *c)
+void intel_p5_mcheck_init(struct cpuinfo_x86 *c)
 {
 	u32 l, h;
 	
diff --git a/arch/i386/kernel/cpu/mcheck/p6.c b/arch/i386/kernel/cpu/mcheck/p6.c
index 979b18b..deeae42 100644
--- a/arch/i386/kernel/cpu/mcheck/p6.c
+++ b/arch/i386/kernel/cpu/mcheck/p6.c
@@ -79,7 +79,7 @@
 }
 
 /* Set up machine check reporting for processors with Intel style MCE */
-void __devinit intel_p6_mcheck_init(struct cpuinfo_x86 *c)
+void intel_p6_mcheck_init(struct cpuinfo_x86 *c)
 {
 	u32 l, h;
 	int i;
diff --git a/arch/i386/kernel/cpu/mcheck/winchip.c b/arch/i386/kernel/cpu/mcheck/winchip.c
index 5b9d2dd..9e424b6 100644
--- a/arch/i386/kernel/cpu/mcheck/winchip.c
+++ b/arch/i386/kernel/cpu/mcheck/winchip.c
@@ -22,7 +22,7 @@
 }
 
 /* Set up machine check reporting on the Winchip C6 series */
-void __devinit winchip_mcheck_init(struct cpuinfo_x86 *c)
+void winchip_mcheck_init(struct cpuinfo_x86 *c)
 {
 	u32 lo, hi;
 	machine_check_vector = winchip_machine_check;
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index 6345b43..32b0c24 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -31,22 +31,16 @@
 #include <linux/config.h>
 #include <linux/kprobes.h>
 #include <linux/ptrace.h>
-#include <linux/spinlock.h>
 #include <linux/preempt.h>
 #include <asm/cacheflush.h>
 #include <asm/kdebug.h>
 #include <asm/desc.h>
 
-static struct kprobe *current_kprobe;
-static unsigned long kprobe_status, kprobe_old_eflags, kprobe_saved_eflags;
-static struct kprobe *kprobe_prev;
-static unsigned long kprobe_status_prev, kprobe_old_eflags_prev, kprobe_saved_eflags_prev;
-static struct pt_regs jprobe_saved_regs;
-static long *jprobe_saved_esp;
-/* copy of the kernel stack at the probe fire time */
-static kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
 void jprobe_return_end(void);
 
+DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+
 /*
  * returns non-zero if opcode modifies the interrupt flag.
  */
@@ -91,29 +85,30 @@
 {
 }
 
-static inline void save_previous_kprobe(void)
+static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-	kprobe_prev = current_kprobe;
-	kprobe_status_prev = kprobe_status;
-	kprobe_old_eflags_prev = kprobe_old_eflags;
-	kprobe_saved_eflags_prev = kprobe_saved_eflags;
+	kcb->prev_kprobe.kp = kprobe_running();
+	kcb->prev_kprobe.status = kcb->kprobe_status;
+	kcb->prev_kprobe.old_eflags = kcb->kprobe_old_eflags;
+	kcb->prev_kprobe.saved_eflags = kcb->kprobe_saved_eflags;
 }
 
-static inline void restore_previous_kprobe(void)
+static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-	current_kprobe = kprobe_prev;
-	kprobe_status = kprobe_status_prev;
-	kprobe_old_eflags = kprobe_old_eflags_prev;
-	kprobe_saved_eflags = kprobe_saved_eflags_prev;
+	__get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+	kcb->kprobe_status = kcb->prev_kprobe.status;
+	kcb->kprobe_old_eflags = kcb->prev_kprobe.old_eflags;
+	kcb->kprobe_saved_eflags = kcb->prev_kprobe.saved_eflags;
 }
 
-static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs)
+static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
+				struct kprobe_ctlblk *kcb)
 {
-	current_kprobe = p;
-	kprobe_saved_eflags = kprobe_old_eflags
+	__get_cpu_var(current_kprobe) = p;
+	kcb->kprobe_saved_eflags = kcb->kprobe_old_eflags
 		= (regs->eflags & (TF_MASK | IF_MASK));
 	if (is_IF_modifier(p->opcode))
-		kprobe_saved_eflags &= ~IF_MASK;
+		kcb->kprobe_saved_eflags &= ~IF_MASK;
 }
 
 static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
@@ -127,6 +122,7 @@
 		regs->eip = (unsigned long)&p->ainsn.insn;
 }
 
+/* Called with kretprobe_lock held */
 void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
 				      struct pt_regs *regs)
 {
@@ -157,9 +153,15 @@
 	int ret = 0;
 	kprobe_opcode_t *addr = NULL;
 	unsigned long *lp;
+	struct kprobe_ctlblk *kcb;
 
-	/* We're in an interrupt, but this is clear and BUG()-safe. */
+	/*
+	 * We don't want to be preempted for the entire
+	 * duration of kprobe processing
+	 */
 	preempt_disable();
+	kcb = get_kprobe_ctlblk();
+
 	/* Check if the application is using LDT entry for its code segment and
 	 * calculate the address by reading the base address from the LDT entry.
 	 */
@@ -173,15 +175,12 @@
 	}
 	/* Check we're not actually recursing */
 	if (kprobe_running()) {
-		/* We *are* holding lock here, so this is safe.
-		   Disarm the probe we just hit, and ignore it. */
 		p = get_kprobe(addr);
 		if (p) {
-			if (kprobe_status == KPROBE_HIT_SS &&
+			if (kcb->kprobe_status == KPROBE_HIT_SS &&
 				*p->ainsn.insn == BREAKPOINT_INSTRUCTION) {
 				regs->eflags &= ~TF_MASK;
-				regs->eflags |= kprobe_saved_eflags;
-				unlock_kprobes();
+				regs->eflags |= kcb->kprobe_saved_eflags;
 				goto no_kprobe;
 			}
 			/* We have reentered the kprobe_handler(), since
@@ -190,26 +189,23 @@
 			 * just single step on the instruction of the new probe
 			 * without calling any user handlers.
 			 */
-			save_previous_kprobe();
-			set_current_kprobe(p, regs);
+			save_previous_kprobe(kcb);
+			set_current_kprobe(p, regs, kcb);
 			p->nmissed++;
 			prepare_singlestep(p, regs);
-			kprobe_status = KPROBE_REENTER;
+			kcb->kprobe_status = KPROBE_REENTER;
 			return 1;
 		} else {
-			p = current_kprobe;
+			p = __get_cpu_var(current_kprobe);
 			if (p->break_handler && p->break_handler(p, regs)) {
 				goto ss_probe;
 			}
 		}
-		/* If it's not ours, can't be delete race, (we hold lock). */
 		goto no_kprobe;
 	}
 
-	lock_kprobes();
 	p = get_kprobe(addr);
 	if (!p) {
-		unlock_kprobes();
 		if (regs->eflags & VM_MASK) {
 			/* We are in virtual-8086 mode. Return 0 */
 			goto no_kprobe;
@@ -232,8 +228,8 @@
 		goto no_kprobe;
 	}
 
-	kprobe_status = KPROBE_HIT_ACTIVE;
-	set_current_kprobe(p, regs);
+	set_current_kprobe(p, regs, kcb);
+	kcb->kprobe_status = KPROBE_HIT_ACTIVE;
 
 	if (p->pre_handler && p->pre_handler(p, regs))
 		/* handler has already set things up, so skip ss setup */
@@ -241,7 +237,7 @@
 
 ss_probe:
 	prepare_singlestep(p, regs);
-	kprobe_status = KPROBE_HIT_SS;
+	kcb->kprobe_status = KPROBE_HIT_SS;
 	return 1;
 
 no_kprobe:
@@ -269,9 +265,10 @@
         struct kretprobe_instance *ri = NULL;
         struct hlist_head *head;
         struct hlist_node *node, *tmp;
-	unsigned long orig_ret_address = 0;
+	unsigned long flags, orig_ret_address = 0;
 	unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
 
+	spin_lock_irqsave(&kretprobe_lock, flags);
         head = kretprobe_inst_table_head(current);
 
 	/*
@@ -310,14 +307,15 @@
 	BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
 	regs->eip = orig_ret_address;
 
-	unlock_kprobes();
+	reset_current_kprobe();
+	spin_unlock_irqrestore(&kretprobe_lock, flags);
 	preempt_enable_no_resched();
 
-        /*
-         * By returning a non-zero value, we are telling
-         * kprobe_handler() that we have handled unlocking
-         * and re-enabling preemption.
-         */
+	/*
+	 * By returning a non-zero value, we are telling
+	 * kprobe_handler() that we don't want the post_handler
+	 * to run (and have re-enabled preemption)
+	 */
         return 1;
 }
 
@@ -343,7 +341,8 @@
  * that is atop the stack is the address following the copied instruction.
  * We need to make it the address following the original instruction.
  */
-static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes resume_execution(struct kprobe *p,
+		struct pt_regs *regs, struct kprobe_ctlblk *kcb)
 {
 	unsigned long *tos = (unsigned long *)&regs->esp;
 	unsigned long next_eip = 0;
@@ -353,7 +352,7 @@
 	switch (p->ainsn.insn[0]) {
 	case 0x9c:		/* pushfl */
 		*tos &= ~(TF_MASK | IF_MASK);
-		*tos |= kprobe_old_eflags;
+		*tos |= kcb->kprobe_old_eflags;
 		break;
 	case 0xc3:		/* ret/lret */
 	case 0xcb:
@@ -394,27 +393,30 @@
 
 /*
  * Interrupts are disabled on entry as trap1 is an interrupt gate and they
- * remain disabled thoroughout this function.  And we hold kprobe lock.
+ * remain disabled thoroughout this function.
  */
 static inline int post_kprobe_handler(struct pt_regs *regs)
 {
-	if (!kprobe_running())
+	struct kprobe *cur = kprobe_running();
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	if (!cur)
 		return 0;
 
-	if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
-		kprobe_status = KPROBE_HIT_SSDONE;
-		current_kprobe->post_handler(current_kprobe, regs, 0);
+	if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
+		kcb->kprobe_status = KPROBE_HIT_SSDONE;
+		cur->post_handler(cur, regs, 0);
 	}
 
-	resume_execution(current_kprobe, regs);
-	regs->eflags |= kprobe_saved_eflags;
+	resume_execution(cur, regs, kcb);
+	regs->eflags |= kcb->kprobe_saved_eflags;
 
 	/*Restore back the original saved kprobes variables and continue. */
-	if (kprobe_status == KPROBE_REENTER) {
-		restore_previous_kprobe();
+	if (kcb->kprobe_status == KPROBE_REENTER) {
+		restore_previous_kprobe(kcb);
 		goto out;
 	}
-	unlock_kprobes();
+	reset_current_kprobe();
 out:
 	preempt_enable_no_resched();
 
@@ -429,18 +431,19 @@
 	return 1;
 }
 
-/* Interrupts disabled, kprobe_lock held. */
 static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 {
-	if (current_kprobe->fault_handler
-	    && current_kprobe->fault_handler(current_kprobe, regs, trapnr))
+	struct kprobe *cur = kprobe_running();
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
 		return 1;
 
-	if (kprobe_status & KPROBE_HIT_SS) {
-		resume_execution(current_kprobe, regs);
-		regs->eflags |= kprobe_old_eflags;
+	if (kcb->kprobe_status & KPROBE_HIT_SS) {
+		resume_execution(cur, regs, kcb);
+		regs->eflags |= kcb->kprobe_old_eflags;
 
-		unlock_kprobes();
+		reset_current_kprobe();
 		preempt_enable_no_resched();
 	}
 	return 0;
@@ -453,39 +456,41 @@
 				       unsigned long val, void *data)
 {
 	struct die_args *args = (struct die_args *)data;
+	int ret = NOTIFY_DONE;
+
 	switch (val) {
 	case DIE_INT3:
 		if (kprobe_handler(args->regs))
-			return NOTIFY_STOP;
+			ret = NOTIFY_STOP;
 		break;
 	case DIE_DEBUG:
 		if (post_kprobe_handler(args->regs))
-			return NOTIFY_STOP;
+			ret = NOTIFY_STOP;
 		break;
 	case DIE_GPF:
-		if (kprobe_running() &&
-		    kprobe_fault_handler(args->regs, args->trapnr))
-			return NOTIFY_STOP;
-		break;
 	case DIE_PAGE_FAULT:
+		/* kprobe_running() needs smp_processor_id() */
+		preempt_disable();
 		if (kprobe_running() &&
 		    kprobe_fault_handler(args->regs, args->trapnr))
-			return NOTIFY_STOP;
+			ret = NOTIFY_STOP;
+		preempt_enable();
 		break;
 	default:
 		break;
 	}
-	return NOTIFY_DONE;
+	return ret;
 }
 
 int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct jprobe *jp = container_of(p, struct jprobe, kp);
 	unsigned long addr;
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 
-	jprobe_saved_regs = *regs;
-	jprobe_saved_esp = &regs->esp;
-	addr = (unsigned long)jprobe_saved_esp;
+	kcb->jprobe_saved_regs = *regs;
+	kcb->jprobe_saved_esp = &regs->esp;
+	addr = (unsigned long)(kcb->jprobe_saved_esp);
 
 	/*
 	 * TBD: As Linus pointed out, gcc assumes that the callee
@@ -494,7 +499,8 @@
 	 * we also save and restore enough stack bytes to cover
 	 * the argument area.
 	 */
-	memcpy(jprobes_stack, (kprobe_opcode_t *) addr, MIN_STACK_SIZE(addr));
+	memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr,
+			MIN_STACK_SIZE(addr));
 	regs->eflags &= ~IF_MASK;
 	regs->eip = (unsigned long)(jp->entry);
 	return 1;
@@ -502,36 +508,40 @@
 
 void __kprobes jprobe_return(void)
 {
-	preempt_enable_no_resched();
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
 	asm volatile ("       xchgl   %%ebx,%%esp     \n"
 		      "       int3			\n"
 		      "       .globl jprobe_return_end	\n"
 		      "       jprobe_return_end:	\n"
 		      "       nop			\n"::"b"
-		      (jprobe_saved_esp):"memory");
+		      (kcb->jprobe_saved_esp):"memory");
 }
 
 int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 	u8 *addr = (u8 *) (regs->eip - 1);
-	unsigned long stack_addr = (unsigned long)jprobe_saved_esp;
+	unsigned long stack_addr = (unsigned long)(kcb->jprobe_saved_esp);
 	struct jprobe *jp = container_of(p, struct jprobe, kp);
 
 	if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) {
-		if (&regs->esp != jprobe_saved_esp) {
+		if (&regs->esp != kcb->jprobe_saved_esp) {
 			struct pt_regs *saved_regs =
-			    container_of(jprobe_saved_esp, struct pt_regs, esp);
+			    container_of(kcb->jprobe_saved_esp,
+					    struct pt_regs, esp);
 			printk("current esp %p does not match saved esp %p\n",
-			       &regs->esp, jprobe_saved_esp);
+			       &regs->esp, kcb->jprobe_saved_esp);
 			printk("Saved registers for jprobe %p\n", jp);
 			show_registers(saved_regs);
 			printk("Current registers\n");
 			show_registers(regs);
 			BUG();
 		}
-		*regs = jprobe_saved_regs;
-		memcpy((kprobe_opcode_t *) stack_addr, jprobes_stack,
+		*regs = kcb->jprobe_saved_regs;
+		memcpy((kprobe_opcode_t *) stack_addr, kcb->jprobes_stack,
 		       MIN_STACK_SIZE(stack_addr));
+		preempt_enable_no_resched();
 		return 1;
 	}
 	return 0;
diff --git a/arch/i386/kernel/ldt.c b/arch/i386/kernel/ldt.c
index fe1ffa5..983f957 100644
--- a/arch/i386/kernel/ldt.c
+++ b/arch/i386/kernel/ldt.c
@@ -18,6 +18,7 @@
 #include <asm/system.h>
 #include <asm/ldt.h>
 #include <asm/desc.h>
+#include <asm/mmu_context.h>
 
 #ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
 static void flush_ldt(void *null)
diff --git a/arch/i386/kernel/mca.c b/arch/i386/kernel/mca.c
index 8600fae..558bb20 100644
--- a/arch/i386/kernel/mca.c
+++ b/arch/i386/kernel/mca.c
@@ -132,7 +132,7 @@
 	{ .start = 0x100, .end = 0x107, .name = "POS (MCA)" }
 };
 
-#define MCA_STANDARD_RESOURCES	(sizeof(mca_standard_resources)/sizeof(struct resource))
+#define MCA_STANDARD_RESOURCES	ARRAY_SIZE(mca_standard_resources)
 
 /**
  *	mca_read_and_store_pos - read the POS registers into a memory buffer
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index efd11f0..5ffbb4b 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -354,49 +354,12 @@
 	return 0;
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-	struct task_struct *child;
 	struct user * dummy = NULL;
 	int i, ret;
 	unsigned long __user *datap = (unsigned long __user *)data;
 
-	lock_kernel();
-	ret = -EPERM;
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-		ret = security_ptrace(current->parent, current);
-		if (ret)
-			goto out;
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
-		goto out;
-	}
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (!child)
-		goto out;
-
-	ret = -EPERM;
-	if (pid == 1)		/* you may not mess with init */
-		goto out_tsk;
-
-	if (request == PTRACE_ATTACH) {
-		ret = ptrace_attach(child);
-		goto out_tsk;
-	}
-
-	ret = ptrace_check_attach(child, request == PTRACE_KILL);
-	if (ret < 0)
-		goto out_tsk;
-
 	switch (request) {
 	/* when I and D space are separate, these will need to be fixed. */
 	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
@@ -663,10 +626,7 @@
 		ret = ptrace_request(child, request, addr, data);
 		break;
 	}
-out_tsk:
-	put_task_struct(child);
-out:
-	unlock_kernel();
+ out_tsk:
 	return ret;
 }
 
diff --git a/arch/i386/kernel/reboot_fixups.c b/arch/i386/kernel/reboot_fixups.c
index c9b8733..10e21a4 100644
--- a/arch/i386/kernel/reboot_fixups.c
+++ b/arch/i386/kernel/reboot_fixups.c
@@ -10,6 +10,7 @@
 
 #include <asm/delay.h>
 #include <linux/pci.h>
+#include <linux/reboot_fixups.h>
 
 static void cs5530a_warm_reset(struct pci_dev *dev)
 {
@@ -42,7 +43,7 @@
 	struct pci_dev *dev;
 	int i;
 
-	for (i=0; i < (sizeof(fixups_table)/sizeof(fixups_table[0])); i++) {
+	for (i=0; i < ARRAY_SIZE(fixups_table); i++) {
 		cur = &(fixups_table[i]);
 		dev = pci_get_device(cur->vendor, cur->device, NULL);
 		if (!dev)
diff --git a/arch/i386/kernel/scx200.c b/arch/i386/kernel/scx200.c
index 69e203a..9c968ae 100644
--- a/arch/i386/kernel/scx200.c
+++ b/arch/i386/kernel/scx200.c
@@ -12,6 +12,7 @@
 #include <linux/pci.h>
 
 #include <linux/scx200.h>
+#include <linux/scx200_gpio.h>
 
 /* Verify that the configuration block really is there */
 #define scx200_cb_probe(base) (inw((base) + SCx200_CBA) == (base))
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 01b618e..47ec767 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -68,11 +68,9 @@
 
 /* Package ID of each logical CPU */
 int phys_proc_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
-EXPORT_SYMBOL(phys_proc_id);
 
 /* Core ID of each logical CPU */
 int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
-EXPORT_SYMBOL(cpu_core_id);
 
 cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
 EXPORT_SYMBOL(cpu_sibling_map);
@@ -612,7 +610,7 @@
 
 	printk("Inquiring remote APIC #%d...\n", apicid);
 
-	for (i = 0; i < sizeof(regs) / sizeof(*regs); i++) {
+	for (i = 0; i < ARRAY_SIZE(regs); i++) {
 		printk("... APIC #%d %s: ", apicid, names[i]);
 
 		/*
diff --git a/arch/i386/oprofile/Kconfig b/arch/i386/oprofile/Kconfig
index 5ade198..d8a8408 100644
--- a/arch/i386/oprofile/Kconfig
+++ b/arch/i386/oprofile/Kconfig
@@ -1,7 +1,3 @@
-
-menu "Profiling support"
-	depends on EXPERIMENTAL
-
 config PROFILING
 	bool "Profiling support (EXPERIMENTAL)"
 	help
@@ -19,5 +15,3 @@
 
 	  If unsure, say N.
 
-endmenu
-
diff --git a/arch/i386/power/cpu.c b/arch/i386/power/cpu.c
index 1f15726..50a0bef 100644
--- a/arch/i386/power/cpu.c
+++ b/arch/i386/power/cpu.c
@@ -118,6 +118,7 @@
 	fix_processor_context();
 	do_fpu_end();
 	mtrr_ap_init();
+	mcheck_init(&boot_cpu_data);
 }
 
 void restore_processor_state(void)
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 3b4248c..9f2093c 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -426,8 +426,21 @@
 
 source "arch/ia64/hp/sim/Kconfig"
 
+menu "Instrumentation Support"
+        depends on EXPERIMENTAL
+
 source "arch/ia64/oprofile/Kconfig"
 
+config KPROBES
+	bool "Kprobes (EXPERIMENTAL)"
+	help
+	  Kprobes allows you to trap at almost any kernel address and
+	  execute a callback function.  register_kprobe() establishes
+	  a probepoint and specifies the callback.  Kprobes is useful
+	  for kernel debugging, non-intrusive instrumentation and testing.
+	  If in doubt, say "N".
+endmenu
+
 source "arch/ia64/Kconfig.debug"
 
 source "security/Kconfig"
diff --git a/arch/ia64/Kconfig.debug b/arch/ia64/Kconfig.debug
index fda67ac..de9d507 100644
--- a/arch/ia64/Kconfig.debug
+++ b/arch/ia64/Kconfig.debug
@@ -2,17 +2,6 @@
 
 source "lib/Kconfig.debug"
 
-config KPROBES
-        bool "Kprobes"
-        depends on DEBUG_KERNEL
-        help
-          Kprobes allows you to trap at almost any kernel address and
-          execute a callback function.  register_kprobe() establishes
-          a probepoint and specifies the callback.  Kprobes is useful
-          for kernel debugging, non-intrusive instrumentation and testing.
-          If in doubt, say "N".
-
-
 choice
 	prompt "Physical memory granularity"
 	default IA64_GRANULE_64MB
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
index b42ec37..19ee635 100644
--- a/arch/ia64/hp/sim/simserial.c
+++ b/arch/ia64/hp/sim/simserial.c
@@ -642,10 +642,8 @@
 	info->event = 0;
 	info->tty = 0;
 	if (info->blocked_open) {
-		if (info->close_delay) {
-			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(info->close_delay);
-		}
+		if (info->close_delay)
+			schedule_timeout_interruptible(info->close_delay);
 		wake_up_interruptible(&info->open_wait);
 	}
 	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 471086b..96736a1 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -26,7 +26,6 @@
 #include <linux/config.h>
 #include <linux/kprobes.h>
 #include <linux/ptrace.h>
-#include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/preempt.h>
@@ -38,13 +37,8 @@
 
 extern void jprobe_inst_return(void);
 
-/* kprobe_status settings */
-#define KPROBE_HIT_ACTIVE	0x00000001
-#define KPROBE_HIT_SS		0x00000002
-
-static struct kprobe *current_kprobe, *kprobe_prev;
-static unsigned long kprobe_status, kprobe_status_prev;
-static struct pt_regs jprobe_saved_regs;
+DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
 enum instruction_type {A, I, M, F, B, L, X, u};
 static enum instruction_type bundle_encoding[32][3] = {
@@ -313,21 +307,22 @@
 	return 0;
 }
 
-static inline void save_previous_kprobe(void)
+static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-	kprobe_prev = current_kprobe;
-	kprobe_status_prev = kprobe_status;
+	kcb->prev_kprobe.kp = kprobe_running();
+	kcb->prev_kprobe.status = kcb->kprobe_status;
 }
 
-static inline void restore_previous_kprobe(void)
+static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-	current_kprobe = kprobe_prev;
-	kprobe_status = kprobe_status_prev;
+	__get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+	kcb->kprobe_status = kcb->prev_kprobe.status;
 }
 
-static inline void set_current_kprobe(struct kprobe *p)
+static inline void set_current_kprobe(struct kprobe *p,
+			struct kprobe_ctlblk *kcb)
 {
-	current_kprobe = p;
+	__get_cpu_var(current_kprobe) = p;
 }
 
 static void kretprobe_trampoline(void)
@@ -347,10 +342,11 @@
 	struct kretprobe_instance *ri = NULL;
 	struct hlist_head *head;
 	struct hlist_node *node, *tmp;
-	unsigned long orig_ret_address = 0;
+	unsigned long flags, orig_ret_address = 0;
 	unsigned long trampoline_address =
 		((struct fnptr *)kretprobe_trampoline)->ip;
 
+	spin_lock_irqsave(&kretprobe_lock, flags);
         head = kretprobe_inst_table_head(current);
 
 	/*
@@ -389,17 +385,19 @@
 	BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
 	regs->cr_iip = orig_ret_address;
 
-	unlock_kprobes();
+	reset_current_kprobe();
+	spin_unlock_irqrestore(&kretprobe_lock, flags);
 	preempt_enable_no_resched();
 
-        /*
-         * By returning a non-zero value, we are telling
-         * kprobe_handler() that we have handled unlocking
-         * and re-enabling preemption.
-         */
+	/*
+	 * By returning a non-zero value, we are telling
+	 * kprobe_handler() that we don't want the post_handler
+	 * to run (and have re-enabled preemption)
+	 */
         return 1;
 }
 
+/* Called with kretprobe_lock held */
 void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
 				      struct pt_regs *regs)
 {
@@ -606,17 +604,22 @@
 	int ret = 0;
 	struct pt_regs *regs = args->regs;
 	kprobe_opcode_t *addr = (kprobe_opcode_t *)instruction_pointer(regs);
+	struct kprobe_ctlblk *kcb;
 
+	/*
+	 * We don't want to be preempted for the entire
+	 * duration of kprobe processing
+	 */
 	preempt_disable();
+	kcb = get_kprobe_ctlblk();
 
 	/* Handle recursion cases */
 	if (kprobe_running()) {
 		p = get_kprobe(addr);
 		if (p) {
-			if ( (kprobe_status == KPROBE_HIT_SS) &&
+			if ((kcb->kprobe_status == KPROBE_HIT_SS) &&
 	 		     (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) {
   				ia64_psr(regs)->ss = 0;
-				unlock_kprobes();
 				goto no_kprobe;
 			}
 			/* We have reentered the pre_kprobe_handler(), since
@@ -625,17 +628,17 @@
 			 * just single step on the instruction of the new probe
 			 * without calling any user handlers.
 			 */
-			save_previous_kprobe();
-			set_current_kprobe(p);
+			save_previous_kprobe(kcb);
+			set_current_kprobe(p, kcb);
 			p->nmissed++;
 			prepare_ss(p, regs);
-			kprobe_status = KPROBE_REENTER;
+			kcb->kprobe_status = KPROBE_REENTER;
 			return 1;
 		} else if (args->err == __IA64_BREAK_JPROBE) {
 			/*
 			 * jprobe instrumented function just completed
 			 */
-			p = current_kprobe;
+			p = __get_cpu_var(current_kprobe);
 			if (p->break_handler && p->break_handler(p, regs)) {
 				goto ss_probe;
 			}
@@ -645,10 +648,8 @@
 		}
 	}
 
-	lock_kprobes();
 	p = get_kprobe(addr);
 	if (!p) {
-		unlock_kprobes();
 		if (!is_ia64_break_inst(regs)) {
 			/*
 			 * The breakpoint instruction was removed right
@@ -665,8 +666,8 @@
 		goto no_kprobe;
 	}
 
-	kprobe_status = KPROBE_HIT_ACTIVE;
-	set_current_kprobe(p);
+	set_current_kprobe(p, kcb);
+	kcb->kprobe_status = KPROBE_HIT_ACTIVE;
 
 	if (p->pre_handler && p->pre_handler(p, regs))
 		/*
@@ -678,7 +679,7 @@
 
 ss_probe:
 	prepare_ss(p, regs);
-	kprobe_status = KPROBE_HIT_SS;
+	kcb->kprobe_status = KPROBE_HIT_SS;
 	return 1;
 
 no_kprobe:
@@ -688,23 +689,25 @@
 
 static int __kprobes post_kprobes_handler(struct pt_regs *regs)
 {
-	if (!kprobe_running())
+	struct kprobe *cur = kprobe_running();
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	if (!cur)
 		return 0;
 
-	if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
-		kprobe_status = KPROBE_HIT_SSDONE;
-		current_kprobe->post_handler(current_kprobe, regs, 0);
+	if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
+		kcb->kprobe_status = KPROBE_HIT_SSDONE;
+		cur->post_handler(cur, regs, 0);
 	}
 
-	resume_execution(current_kprobe, regs);
+	resume_execution(cur, regs);
 
 	/*Restore back the original saved kprobes variables and continue. */
-	if (kprobe_status == KPROBE_REENTER) {
-		restore_previous_kprobe();
+	if (kcb->kprobe_status == KPROBE_REENTER) {
+		restore_previous_kprobe(kcb);
 		goto out;
 	}
-
-	unlock_kprobes();
+	reset_current_kprobe();
 
 out:
 	preempt_enable_no_resched();
@@ -713,16 +716,15 @@
 
 static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr)
 {
-	if (!kprobe_running())
-		return 0;
+	struct kprobe *cur = kprobe_running();
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 
-	if (current_kprobe->fault_handler &&
-	    current_kprobe->fault_handler(current_kprobe, regs, trapnr))
+	if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
 		return 1;
 
-	if (kprobe_status & KPROBE_HIT_SS) {
-		resume_execution(current_kprobe, regs);
-		unlock_kprobes();
+	if (kcb->kprobe_status & KPROBE_HIT_SS) {
+		resume_execution(cur, regs);
+		reset_current_kprobe();
 		preempt_enable_no_resched();
 	}
 
@@ -733,31 +735,38 @@
 				       unsigned long val, void *data)
 {
 	struct die_args *args = (struct die_args *)data;
+	int ret = NOTIFY_DONE;
+
 	switch(val) {
 	case DIE_BREAK:
 		if (pre_kprobes_handler(args))
-			return NOTIFY_STOP;
+			ret = NOTIFY_STOP;
 		break;
 	case DIE_SS:
 		if (post_kprobes_handler(args->regs))
-			return NOTIFY_STOP;
+			ret = NOTIFY_STOP;
 		break;
 	case DIE_PAGE_FAULT:
-		if (kprobes_fault_handler(args->regs, args->trapnr))
-			return NOTIFY_STOP;
+		/* kprobe_running() needs smp_processor_id() */
+		preempt_disable();
+		if (kprobe_running() &&
+			kprobes_fault_handler(args->regs, args->trapnr))
+			ret = NOTIFY_STOP;
+		preempt_enable();
 	default:
 		break;
 	}
-	return NOTIFY_DONE;
+	return ret;
 }
 
 int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct jprobe *jp = container_of(p, struct jprobe, kp);
 	unsigned long addr = ((struct fnptr *)(jp->entry))->ip;
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 
 	/* save architectural state */
-	jprobe_saved_regs = *regs;
+	kcb->jprobe_saved_regs = *regs;
 
 	/* after rfi, execute the jprobe instrumented function */
 	regs->cr_iip = addr & ~0xFULL;
@@ -775,7 +784,10 @@
 
 int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
-	*regs = jprobe_saved_regs;
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	*regs = kcb->jprobe_saved_regs;
+	preempt_enable_no_resched();
 	return 1;
 }
 
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index f7dfc10..410d480 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -4940,7 +4940,7 @@
 	if (call_made && PFM_CMD_RW_ARG(cmd) && copy_to_user(arg, args_k, base_sz*count)) ret = -EFAULT;
 
 error_args:
-	if (args_k) kfree(args_k);
+	kfree(args_k);
 
 	DPRINT(("cmd=%s ret=%ld\n", PFM_CMD_NAME(cmd), ret));
 
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index fc56ca2..3af6de3 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -92,6 +92,13 @@
 extern char _text[], _end[], _etext[];
 
 unsigned long ia64_max_cacheline_size;
+
+int dma_get_cache_alignment(void)
+{
+        return ia64_max_cacheline_size;
+}
+EXPORT_SYMBOL(dma_get_cache_alignment);
+
 unsigned long ia64_iobase;	/* virtual address for I/O accesses */
 EXPORT_SYMBOL(ia64_iobase);
 struct io_space io_space[MAX_IO_SPACES];
diff --git a/arch/ia64/oprofile/Kconfig b/arch/ia64/oprofile/Kconfig
index 56e6f61..97271ab 100644
--- a/arch/ia64/oprofile/Kconfig
+++ b/arch/ia64/oprofile/Kconfig
@@ -1,7 +1,3 @@
-
-menu "Profiling support"
-	depends on EXPERIMENTAL
-
 config PROFILING
 	bool "Profiling support (EXPERIMENTAL)"
 	help
@@ -22,5 +18,3 @@
 
 	  If unsure, say N.
 
-endmenu
-
diff --git a/arch/m68k/atari/time.c b/arch/m68k/atari/time.c
index 6df7fb6..e79bbc9 100644
--- a/arch/m68k/atari/time.c
+++ b/arch/m68k/atari/time.c
@@ -212,10 +212,8 @@
      * additionally the RTC_SET bit is set to prevent an update cycle.
      */
 
-    while( RTC_READ(RTC_FREQ_SELECT) & RTC_UIP ) {
-        current->state = TASK_INTERRUPTIBLE;
-        schedule_timeout(HWCLK_POLL_INTERVAL);
-    }
+    while( RTC_READ(RTC_FREQ_SELECT) & RTC_UIP )
+        schedule_timeout_interruptible(HWCLK_POLL_INTERVAL);
 
     local_irq_save(flags);
     RTC_WRITE( RTC_CONTROL, ctrl | RTC_SET );
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
index f7f1d2e..7e54422 100644
--- a/arch/m68k/kernel/ptrace.c
+++ b/arch/m68k/kernel/ptrace.c
@@ -121,48 +121,11 @@
 	child->thread.work.syscall_trace = 0;
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-	struct task_struct *child;
 	unsigned long tmp;
 	int i, ret = 0;
 
-	lock_kernel();
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED) {
-			ret = -EPERM;
-			goto out;
-		}
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		goto out;
-	}
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (unlikely(!child)) {
-		ret = -ESRCH;
-		goto out;
-	}
-
-	/* you may not mess with init */
-	if (unlikely(pid == 1)) {
-		ret = -EPERM;
-		goto out_tsk;
-	}
-
-	if (request == PTRACE_ATTACH) {
-		ret = ptrace_attach(child);
-		goto out_tsk;
-	}
-
-	ret = ptrace_check_attach(child, request == PTRACE_KILL);
-	if (ret)
-		goto out_tsk;
-
 	switch (request) {
 	/* when I and D space are separate, these will need to be fixed. */
 	case PTRACE_PEEKTEXT:	/* read word at location addr. */
@@ -317,14 +280,10 @@
 		ret = ptrace_request(child, request, addr, data);
 		break;
 	}
-out_tsk:
-	put_task_struct(child);
-out:
-	unlock_kernel();
+
 	return ret;
 out_eio:
-	ret = -EIO;
-	goto out_tsk;
+	return -EIO;
 }
 
 asmlinkage void syscall_trace(void)
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index 8520df9..b964981 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -71,6 +71,11 @@
 	help
 	  Motorola ColdFire 5206e processor support.
 
+config M520x
+	bool "MCF520x"
+	help
+	   Freescale Coldfire 5207/5208 processor support.
+
 config M523x
 	bool "MCF523x"
 	help
@@ -120,7 +125,7 @@
 
 config COLDFIRE
 	bool
-	depends on (M5206 || M5206e || M523x || M5249 || M527x || M5272 || M528x || M5307 || M5407)
+	depends on (M5206 || M5206e || M520x || M523x || M5249 || M527x || M5272 || M528x || M5307 || M5407)
 	default y
 
 choice
@@ -322,6 +327,12 @@
 	help
 	  Support for the Motorola M5206eLITE board.
 
+config M5208EVB
+	bool "Freescale M5208EVB board support"
+	depends on M520x
+	help
+	  Support for the Freescale Coldfire M5208EVB.
+
 config M5235EVB
 	bool "Freescale M5235EVB support"
 	depends on M523x
@@ -465,10 +476,10 @@
 	default y
 	depends on (ARN5206 || ARN5307)
 
-config MOTOROLA
+config FREESCALE
 	bool
 	default y
-	depends on (M5206eC3 || M5235EVB || M5249C3 || M5271EVB || M5272C3 || M5275EVB || M5282EVB || M5307C3 || M5407C3)
+	depends on (M5206eC3 || M5208EVB || M5235EVB || M5249C3 || M5271EVB || M5272C3 || M5275EVB || M5282EVB || M5307C3 || M5407C3)
 
 config HW_FEITH
 	bool
diff --git a/arch/m68knommu/Makefile b/arch/m68knommu/Makefile
index b8fdf19..b6b5c14 100644
--- a/arch/m68knommu/Makefile
+++ b/arch/m68knommu/Makefile
@@ -14,6 +14,7 @@
 platform-$(CONFIG_M68360)	:= 68360
 platform-$(CONFIG_M5206)	:= 5206
 platform-$(CONFIG_M5206e)	:= 5206e
+platform-$(CONFIG_M520x)	:= 520x
 platform-$(CONFIG_M523x)	:= 523x
 platform-$(CONFIG_M5249)	:= 5249
 platform-$(CONFIG_M527x)	:= 527x
@@ -29,7 +30,7 @@
 board-$(CONFIG_UCQUICC)		:= uCquicc
 board-$(CONFIG_DRAGEN2)		:= de2
 board-$(CONFIG_ARNEWSH)		:= ARNEWSH
-board-$(CONFIG_MOTOROLA)	:= MOTOROLA
+board-$(CONFIG_FREESCALE)	:= FREESCALE
 board-$(CONFIG_M5235EVB)	:= M5235EVB
 board-$(CONFIG_M5271EVB)	:= M5271EVB
 board-$(CONFIG_M5275EVB)	:= M5275EVB
@@ -41,6 +42,7 @@
 board-$(CONFIG_CLEOPATRA)	:= CLEOPATRA
 board-$(CONFIG_senTec)		:= senTec
 board-$(CONFIG_SNEHA) 	        := SNEHA
+board-$(CONFIG_M5208EVB)	:= M5208EVB
 board-$(CONFIG_MOD5272)		:= MOD5272
 BOARD := $(board-y)
 
@@ -56,6 +58,7 @@
 #
 cpuclass-$(CONFIG_M5206)	:= 5307
 cpuclass-$(CONFIG_M5206e)	:= 5307
+cpuclass-$(CONFIG_M520x)	:= 5307
 cpuclass-$(CONFIG_M523x)	:= 5307
 cpuclass-$(CONFIG_M5249)	:= 5307
 cpuclass-$(CONFIG_M527x)	:= 5307
@@ -80,6 +83,7 @@
 #
 cflags-$(CONFIG_M5206)		:= -m5200 -Wa,-S -Wa,-m5200
 cflags-$(CONFIG_M5206e)		:= -m5200 -Wa,-S -Wa,-m5200
+cflags-$(CONFIG_M520x)		:= -m5307 -Wa,-S -Wa,-m5307
 cflags-$(CONFIG_M523x)		:= -m5307 -Wa,-S -Wa,-m5307
 cflags-$(CONFIG_M5249)		:= -m5200 -Wa,-S -Wa,-m5200
 cflags-$(CONFIG_M527x)		:= -m5307 -Wa,-S -Wa,-m5307
@@ -95,7 +99,6 @@
 AFLAGS += $(cflags-y)
 
 CFLAGS += $(cflags-y)
-CFLAGS += -fno-builtin
 CFLAGS += -O1 -g
 CFLAGS += -D__linux__
 CFLAGS += -DUTS_SYSNAME=\"uClinux\"
diff --git a/arch/m68knommu/kernel/asm-offsets.c b/arch/m68knommu/kernel/asm-offsets.c
index cd3ffe1..b988c7b 100644
--- a/arch/m68knommu/kernel/asm-offsets.c
+++ b/arch/m68knommu/kernel/asm-offsets.c
@@ -15,6 +15,7 @@
 #include <linux/hardirq.h>
 #include <asm/bootinfo.h>
 #include <asm/irq.h>
+#include <asm/irqnode.h>
 #include <asm/thread_info.h>
 
 #define DEFINE(sym, val) \
diff --git a/arch/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c
index 621d7b9..262ab8c 100644
--- a/arch/m68knommu/kernel/ptrace.c
+++ b/arch/m68knommu/kernel/ptrace.c
@@ -101,43 +101,10 @@
 	put_reg(child, PT_SR, tmp);
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(truct task_struct *child, long request, long addr, long data)
 {
-	struct task_struct *child;
 	int ret;
 
-	lock_kernel();
-	ret = -EPERM;
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
-		goto out;
-	}
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (!child)
-		goto out;
-
-	ret = -EPERM;
-	if (pid == 1)		/* you may not mess with init */
-		goto out_tsk;
-
-	if (request == PTRACE_ATTACH) {
-		ret = ptrace_attach(child);
-		goto out_tsk;
-	}
-	ret = ptrace_check_attach(child, request == PTRACE_KILL);
-	if (ret < 0)
-		goto out_tsk;
-
 	switch (request) {
 		/* when I and D space are separate, these will need to be fixed. */
 		case PTRACE_PEEKTEXT: /* read word at location addr. */ 
@@ -357,10 +324,6 @@
 			ret = -EIO;
 			break;
 	}
-out_tsk:
-	put_task_struct(child);
-out:
-	unlock_kernel();
 	return ret;
 }
 
diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c
index a220345..abb80fa 100644
--- a/arch/m68knommu/kernel/setup.c
+++ b/arch/m68knommu/kernel/setup.c
@@ -107,6 +107,9 @@
 #if defined(CONFIG_M5206e)
 	#define	CPU "COLDFIRE(m5206e)"
 #endif
+#if defined(CONFIG_M520x)
+	#define CPU "COLDFIRE(m520x)"
+#endif
 #if defined(CONFIG_M523x)
 	#define CPU "COLDFIRE(m523x)"
 #endif
@@ -132,7 +135,7 @@
 	#define	CPU "COLDFIRE(m5407)"
 #endif
 #ifndef CPU
-	#define	CPU "UNKOWN"
+	#define	CPU "UNKNOWN"
 #endif
 
 /* (es) */
diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S
index 47f0678..0eab92c 100644
--- a/arch/m68knommu/kernel/vmlinux.lds.S
+++ b/arch/m68knommu/kernel/vmlinux.lds.S
@@ -125,6 +125,14 @@
 #endif
 
 /*
+ *	The Freescale 5208EVB board has 32MB of RAM.
+ */
+#if defined(CONFIG_M5208EVB)
+#define	RAM_START	0x40020000
+#define	RAM_LENGTH	0x01e00000
+#endif
+
+/*
  *	The senTec COBRA5272 board has nearly the same memory layout as 
  *	the M5272C3. We assume 16MiB ram.
  */
@@ -275,6 +283,7 @@
 		*(__ksymtab_strings)
 
 		/* Built-in module parameters */
+		. = ALIGN(4) ;
 		__start___param = .;
 		*(__param)
 		__stop___param = .;
diff --git a/arch/m68knommu/platform/520x/Makefile b/arch/m68knommu/platform/520x/Makefile
new file mode 100644
index 0000000..e861b05
--- /dev/null
+++ b/arch/m68knommu/platform/520x/Makefile
@@ -0,0 +1,19 @@
+#
+# Makefile for the M5208 specific file.
+#
+
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs.  You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+ifdef CONFIG_FULLDEBUG
+AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+obj-y := config.o
diff --git a/arch/m68knommu/platform/520x/config.c b/arch/m68knommu/platform/520x/config.c
new file mode 100644
index 0000000..71dea2e
--- /dev/null
+++ b/arch/m68knommu/platform/520x/config.c
@@ -0,0 +1,65 @@
+/***************************************************************************/
+
+/*
+ *  linux/arch/m68knommu/platform/520x/config.c
+ *
+ *  Copyright (C) 2005,      Freescale (www.freescale.com)
+ *  Copyright (C) 2005,      Intec Automation (mike@steroidmicros.com)
+ *  Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com)
+ *  Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <asm/machdep.h>
+#include <asm/dma.h>
+
+/***************************************************************************/
+
+/*
+ *	DMA channel base address table.
+ */
+unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS];
+unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+
+/***************************************************************************/
+
+void coldfire_pit_tick(void);
+void coldfire_pit_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
+unsigned long coldfire_pit_offset(void);
+void coldfire_trap_init(void);
+void coldfire_reset(void);
+
+/***************************************************************************/
+
+/*
+ *  Program the vector to be an auto-vectored.
+ */
+
+void mcf_autovector(unsigned int vec)
+{
+    /* Everything is auto-vectored on the 520x devices */
+}
+
+/***************************************************************************/
+
+void config_BSP(char *commandp, int size)
+{
+#ifdef CONFIG_BOOTPARAM
+    strncpy(commandp, CONFIG_BOOTPARAM_STRING, size);
+    commandp[size-1] = 0;
+#else
+    memset(commandp, 0, size);
+#endif
+
+    mach_sched_init = coldfire_pit_init;
+    mach_tick = coldfire_pit_tick;
+    mach_gettimeoffset = coldfire_pit_offset;
+    mach_trap_init = coldfire_trap_init;
+    mach_reset = coldfire_reset;
+}
+
+/***************************************************************************/
diff --git a/arch/m68knommu/platform/5307/Makefile b/arch/m68knommu/platform/5307/Makefile
index 6fe5a2b..8d1619d 100644
--- a/arch/m68knommu/platform/5307/Makefile
+++ b/arch/m68knommu/platform/5307/Makefile
@@ -19,6 +19,7 @@
 obj-$(CONFIG_COLDFIRE)	+= entry.o vectors.o ints.o
 obj-$(CONFIG_M5206)	+= timers.o
 obj-$(CONFIG_M5206e)	+= timers.o
+obj-$(CONFIG_M520x)	+= pit.o
 obj-$(CONFIG_M523x)	+= pit.o
 obj-$(CONFIG_M5249)	+= timers.o
 obj-$(CONFIG_M527x)     += pit.o
diff --git a/arch/m68knommu/platform/5307/head.S b/arch/m68knommu/platform/5307/head.S
index 7f4ba83..c30c462 100644
--- a/arch/m68knommu/platform/5307/head.S
+++ b/arch/m68knommu/platform/5307/head.S
@@ -113,6 +113,9 @@
 #define MEM_BASE	0x02000000
 #define VBR_BASE	0x20000000	/* vectors in SRAM */
 #endif
+#if defined(CONFIG_M5208EVB)
+#define MEM_BASE	0x40000000
+#endif
 
 #ifndef MEM_BASE
 #define	MEM_BASE	0x00000000	/* memory base at address 0 */
diff --git a/arch/m68knommu/platform/5307/ints.c b/arch/m68knommu/platform/5307/ints.c
index 0117754..a134fb2 100644
--- a/arch/m68knommu/platform/5307/ints.c
+++ b/arch/m68knommu/platform/5307/ints.c
@@ -26,6 +26,7 @@
 
 #include <asm/system.h>
 #include <asm/irq.h>
+#include <asm/irqnode.h>
 #include <asm/traps.h>
 #include <asm/page.h>
 #include <asm/machdep.h>
diff --git a/arch/m68knommu/platform/5307/pit.c b/arch/m68knommu/platform/5307/pit.c
index a9b2c2e..323f267 100644
--- a/arch/m68knommu/platform/5307/pit.c
+++ b/arch/m68knommu/platform/5307/pit.c
@@ -3,7 +3,7 @@
 /*
  *	pit.c -- Motorola ColdFire PIT timer. Currently this type of
  *	         hardware timer only exists in the Motorola ColdFire
- *		 5270/5271 and 5282 CPUs.
+ *		 5270/5271, 5282 and other CPUs.
  *
  *	Copyright (C) 1999-2004, Greg Ungerer (gerg@snapgear.com)
  *	Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com)
@@ -47,10 +47,10 @@
 
 	icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 +
 		MCFINTC_ICR0 + MCFINT_PIT1);
-	*icrp = 0x2b; /* PIT1 with level 5, priority 3 */
+	*icrp = ICR_INTRCONF;
 
-	imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
-	*imrp &= ~(1 << (MCFINT_PIT1 - 32));
+	imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFPIT_IMR);
+	*imrp &= ~MCFPIT_IMR_IBIT;
 
 	/* Set up PIT timer 1 as poll clock */
 	tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
@@ -70,7 +70,7 @@
 	unsigned long pmr, pcntr, offset;
 
 	tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
-	ipr = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IPRH);
+	ipr = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFPIT_IMR);
 
 	pmr = *(&tp->pmr);
 	pcntr = *(&tp->pcntr);
@@ -80,7 +80,7 @@
 	 * timer interupt is pending, then add on a ticks worth of time.
 	 */
 	offset = ((pmr - pcntr) * (1000000 / HZ)) / pmr;
-	if ((offset < (1000000 / HZ / 2)) && (*ipr & (1 << (MCFINT_PIT1 - 32))))
+	if ((offset < (1000000 / HZ / 2)) && (*ipr & MCFPIT_IMR_IBIT))
 		offset += 1000000 / HZ;
 	return offset;	
 }
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index f1b0f3e..510da5f 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -174,51 +174,10 @@
 	return 0;
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-	struct task_struct *child;
 	int ret;
 
-#if 0
-	printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n",
-	       (int) request, (int) pid, (unsigned long) addr,
-	       (unsigned long) data);
-#endif
-	lock_kernel();
-	ret = -EPERM;
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-		if ((ret = security_ptrace(current->parent, current)))
-			goto out;
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
-		goto out;
-	}
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (!child)
-		goto out;
-
-	ret = -EPERM;
-	if (pid == 1)		/* you may not mess with init */
-		goto out_tsk;
-
-	if (request == PTRACE_ATTACH) {
-		ret = ptrace_attach(child);
-		goto out_tsk;
-	}
-
-	ret = ptrace_check_attach(child, request == PTRACE_KILL);
-	if (ret < 0)
-		goto out_tsk;
-
 	switch (request) {
 	/* when I and D space are separate, these will need to be fixed. */
 	case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -319,7 +278,7 @@
 			if (!cpu_has_dsp) {
 				tmp = 0;
 				ret = -EIO;
-				goto out_tsk;
+				goto out;
 			}
 			if (child->thread.dsp.used_dsp) {
 				dregs = __get_dsp_regs(child);
@@ -333,14 +292,14 @@
 			if (!cpu_has_dsp) {
 				tmp = 0;
 				ret = -EIO;
-				goto out_tsk;
+				goto out;
 			}
 			tmp = child->thread.dsp.dspcontrol;
 			break;
 		default:
 			tmp = 0;
 			ret = -EIO;
-			goto out_tsk;
+			goto out;
 		}
 		ret = put_user(tmp, (unsigned long __user *) data);
 		break;
@@ -495,11 +454,7 @@
 		ret = ptrace_request(child, request, addr, data);
 		break;
 	}
-
-out_tsk:
-	put_task_struct(child);
-out:
-	unlock_kernel();
+ out:
 	return ret;
 }
 
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index 18130c3..b6fe202 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -78,52 +78,13 @@
 	pa_psw(child)->l = 0;
 }
 
-long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-	struct task_struct *child;
 	long ret;
 #ifdef DEBUG_PTRACE
 	long oaddr=addr, odata=data;
 #endif
 
-	lock_kernel();
-	ret = -EPERM;
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-
-		ret = security_ptrace(current->parent, current);
-		if (ret) 
-			goto out;
-
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
-		goto out;
-	}
-
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (!child)
-		goto out;
-	ret = -EPERM;
-	if (pid == 1)		/* no messing around with init! */
-		goto out_tsk;
-
-	if (request == PTRACE_ATTACH) {
-		ret = ptrace_attach(child);
-		goto out_tsk;
-	}
-
-	ret = ptrace_check_attach(child, request == PTRACE_KILL);
-	if (ret < 0)
-		goto out_tsk;
-
 	switch (request) {
 	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
 	case PTRACE_PEEKDATA: {
@@ -383,11 +344,11 @@
 
 	case PTRACE_GETEVENTMSG:
                 ret = put_user(child->ptrace_message, (unsigned int __user *) data);
-		goto out_tsk;
+		goto out;
 
 	default:
 		ret = ptrace_request(child, request, addr, data);
-		goto out_tsk;
+		goto out;
 	}
 
 out_wake_notrap:
@@ -396,10 +357,7 @@
 	wake_up_process(child);
 	ret = 0;
 out_tsk:
-	put_task_struct(child);
-out:
-	unlock_kernel();
-	DBG("sys_ptrace(%ld, %d, %lx, %lx) returning %ld\n",
+	DBG("arch_ptrace(%ld, %d, %lx, %lx) returning %ld\n",
 		request, pid, oaddr, odata, ret);
 	return ret;
 }
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index ca7acb0..6ffae2d 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -605,6 +605,7 @@
 
 config PPC_64K_PAGES
 	bool "64k page size"
+	depends on PPC64
 	help
 	  This option changes the kernel logical page size to 64k. On machines
           without processor support for 64k pages, the kernel will simulate
@@ -916,8 +917,21 @@
 
 source "lib/Kconfig"
 
+menu "Instrumentation Support"
+        depends on EXPERIMENTAL
+
 source "arch/powerpc/oprofile/Kconfig"
 
+config KPROBES
+	bool "Kprobes (EXPERIMENTAL)"
+	help
+	  Kprobes allows you to trap at almost any kernel address and
+	  execute a callback function.  register_kprobe() establishes
+	  a probepoint and specifies the callback.  Kprobes is useful
+	  for kernel debugging, non-intrusive instrumentation and testing.
+	  If in doubt, say "N".
+endmenu
+
 source "arch/powerpc/Kconfig.debug"
 
 source "security/Kconfig"
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 0baf64e..30a30bf 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -9,16 +9,6 @@
 	  This option will cause messages to be printed if free stack space
 	  drops below a certain limit.
 
-config KPROBES
-	bool "Kprobes"
-	depends on DEBUG_KERNEL && PPC64
-	help
-	  Kprobes allows you to trap at almost any kernel address and
-	  execute a callback function.  register_kprobe() establishes
-	  a probepoint and specifies the callback.  Kprobes is useful
-	  for kernel debugging, non-intrusive instrumentation and testing.
-	  If in doubt, say "N".
-
 config DEBUG_STACK_USAGE
 	bool "Stack utilization instrumentation"
 	depends on DEBUG_KERNEL && PPC64
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 33c63bc..cc4e9eb 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -929,6 +929,16 @@
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 	},
+	{ /* 440SPe Rev. A */
+		.pvr_mask		= 0xff000fff,
+		.pvr_value		= 0x53000890,
+		.cpu_name		= "440SPe Rev. A",
+		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+			CPU_FTR_USE_TB,
+		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+		.icache_bsize		= 32,
+		.dcache_bsize		= 32,
+	},
 #endif /* CONFIG_44x */
 #ifdef CONFIG_FSL_BOOKE
 	{	/* e200z5 */
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 568ea33..3d2abd9 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -248,46 +248,10 @@
 	clear_single_step(child);
 }
 
-long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-	struct task_struct *child;
 	int ret = -EPERM;
 
-	lock_kernel();
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-		ret = security_ptrace(current->parent, current);
-		if (ret)
-			goto out;
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
-		goto out;
-	}
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (!child)
-		goto out;
-
-	ret = -EPERM;
-	if (pid == 1)		/* you may not mess with init */
-		goto out_tsk;
-
-	if (request == PTRACE_ATTACH) {
-		ret = ptrace_attach(child);
-		goto out_tsk;
-	}
-
-	ret = ptrace_check_attach(child, request == PTRACE_KILL);
-	if (ret < 0)
-		goto out_tsk;
-
 	switch (request) {
 	/* when I and D space are separate, these will need to be fixed. */
 	case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -540,10 +504,7 @@
 		ret = ptrace_request(child, request, addr, data);
 		break;
 	}
-out_tsk:
-	put_task_struct(child);
-out:
-	unlock_kernel();
+
 	return ret;
 }
 
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 6996a59..b1c89bc 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -69,6 +69,7 @@
 #include <asm/iseries/it_lp_queue.h>
 #include <asm/iseries/hv_call_xm.h>
 #endif
+#include <asm/smp.h>
 
 /* keep track of when we need to update the rtc */
 time_t last_rtc_update;
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index b2f3dbc..f15dfb9 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -329,12 +329,14 @@
 	 */
 	if (mmu_psize_defs[MMU_PAGE_16M].shift)
 		mmu_huge_psize = MMU_PAGE_16M;
+	/* With 4k/4level pagetables, we can't (for now) cope with a
+	 * huge page size < PMD_SIZE */
 	else if (mmu_psize_defs[MMU_PAGE_1M].shift)
 		mmu_huge_psize = MMU_PAGE_1M;
 
 	/* Calculate HPAGE_SHIFT and sanity check it */
-	if (mmu_psize_defs[mmu_huge_psize].shift > 16 &&
-	    mmu_psize_defs[mmu_huge_psize].shift < 28)
+	if (mmu_psize_defs[mmu_huge_psize].shift > MIN_HUGEPTE_SHIFT &&
+	    mmu_psize_defs[mmu_huge_psize].shift < SID_SHIFT)
 		HPAGE_SHIFT = mmu_psize_defs[mmu_huge_psize].shift;
 	else
 		HPAGE_SHIFT = 0; /* No huge pages dude ! */
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 0073a04..426c269 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -212,6 +212,12 @@
 
 	BUG_ON(area >= NUM_HIGH_AREAS);
 
+	/* Hack, so that each addresses is controlled by exactly one
+	 * of the high or low area bitmaps, the first high area starts
+	 * at 4GB, not 0 */
+	if (start == 0)
+		start = 0x100000000UL;
+
 	/* Check no VMAs are in the region */
 	vma = find_vma(mm, start);
 	if (vma && (vma->vm_start < end))
diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
index d137abd..ed7fcfe 100644
--- a/arch/powerpc/mm/ppc_mmu_32.c
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -188,9 +188,9 @@
 
 	if (Hash == 0)
 		return;
-	pmd = pmd_offset(pgd_offset(vma->vm_mm, address), address);
+	pmd = pmd_offset(pgd_offset(mm, ea), ea);
 	if (!pmd_none(*pmd))
-		add_hash_page(vma->vm_mm->context, address, pmd_val(*pmd));
+		add_hash_page(mm->context, ea, pmd_val(*pmd));
 }
 
 /*
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
index 3e18241..950ffc5 100644
--- a/arch/powerpc/mm/slb_low.S
+++ b/arch/powerpc/mm/slb_low.S
@@ -80,12 +80,17 @@
 BEGIN_FTR_SECTION
 	b	1f
 END_FTR_SECTION_IFCLR(CPU_FTR_16M_PAGE)
+	cmpldi	r10,16
+
+	lhz	r9,PACALOWHTLBAREAS(r13)
+	mr	r11,r10
+	blt	5f
+
 	lhz	r9,PACAHIGHHTLBAREAS(r13)
 	srdi	r11,r10,(HTLB_AREA_SHIFT-SID_SHIFT)
-	srd	r9,r9,r11
-	lhz	r11,PACALOWHTLBAREAS(r13)
-	srd	r11,r11,r10
-	or.	r9,r9,r11
+
+5:	srd	r9,r9,r11
+	andi.	r9,r9,1
 	beq	1f
 _GLOBAL(slb_miss_user_load_huge)
 	li	r11,0
diff --git a/arch/powerpc/oprofile/Kconfig b/arch/powerpc/oprofile/Kconfig
index 19d3773..eb2dece 100644
--- a/arch/powerpc/oprofile/Kconfig
+++ b/arch/powerpc/oprofile/Kconfig
@@ -1,7 +1,3 @@
-
-menu "Profiling support"
-	depends on EXPERIMENTAL
-
 config PROFILING
 	bool "Profiling support (EXPERIMENTAL)"
 	help
@@ -19,5 +15,3 @@
 
 	  If unsure, say N.
 
-endmenu
-
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 58c6121..d7d4003 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -286,10 +286,8 @@
 	return new;
 
 cleanup:
-	if (new->name)
-		kfree(new->name);
-	if (new->value)
-		kfree(new->value);
+	kfree(new->name);
+	kfree(new->value);
 	kfree(new);
 	return NULL;
 }
diff --git a/arch/ppc/4xx_io/serial_sicc.c b/arch/ppc/4xx_io/serial_sicc.c
index e95c48d..84d96b8 100644
--- a/arch/ppc/4xx_io/serial_sicc.c
+++ b/arch/ppc/4xx_io/serial_sicc.c
@@ -1145,8 +1145,8 @@
     info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) |
                (info->flags & ASYNC_INTERNAL_FLAGS));
     state->custom_divisor = new_serial.custom_divisor;
-    state->close_delay = new_serial.close_delay * HZ / 100;
-    state->closing_wait = new_serial.closing_wait * HZ / 100;
+    state->close_delay = msecs_to_jiffies(10 * new_serial.close_delay);
+    state->closing_wait = msecs_to_jiffies(10 * new_serial.closing_wait);
     info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
     port->fifosize = new_serial.xmit_fifo_size;
 
@@ -1465,10 +1465,8 @@
     info->event = 0;
     info->tty = NULL;
     if (info->blocked_open) {
-        if (info->state->close_delay) {
-            set_current_state(TASK_INTERRUPTIBLE);
-            schedule_timeout(info->state->close_delay);
-        }
+        if (info->state->close_delay)
+            schedule_timeout_interruptible(info->state->close_delay);
         wake_up_interruptible(&info->open_wait);
     }
     info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
@@ -1496,7 +1494,7 @@
      * Note: we have to use pretty tight timings here to satisfy
      * the NIST-PCTS.
      */
-    char_time = (info->timeout - HZ/50) / info->port->fifosize;
+    char_time = (info->timeout - msecs_to_jiffies(20)) / info->port->fifosize;
     char_time = char_time / 5;
     if (char_time == 0)
         char_time = 1;
@@ -1521,8 +1519,7 @@
            tty->index, jiffies,
            expire, char_time);
     while ((readb(info->port->uart_base + BL_SICC_LSR) & _LSR_TX_ALL) != _LSR_TX_ALL) {
-        set_current_state(TASK_INTERRUPTIBLE);
-        schedule_timeout(char_time);
+        schedule_timeout_interruptible(char_time);
         if (signal_pending(current))
             break;
         if (timeout && time_after(jiffies, expire))
@@ -1773,7 +1770,7 @@
     for (i = 0; i < SERIAL_SICC_NR; i++) {
         struct SICC_state *state = sicc_state + i;
         state->line     = i;
-        state->close_delay  = 5 * HZ / 10;
+        state->close_delay  = msecs_to_jiffies(500);
         state->closing_wait = 30 * HZ;
 	spin_lock_init(&state->sicc_lock);
     }
diff --git a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c
index 2086c6a..4edeede 100644
--- a/arch/ppc/8260_io/fcc_enet.c
+++ b/arch/ppc/8260_io/fcc_enet.c
@@ -1309,8 +1309,7 @@
 
 	/* Davicom takes a bit to come up after a reset,
 	 * so wait here for a bit */
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(timeout);
+	schedule_timeout_uninterruptible(timeout);
 }
 
 static phy_info_t phy_info_dm9161 = {
diff --git a/arch/ppc/8xx_io/cs4218_tdm.c b/arch/ppc/8xx_io/cs4218_tdm.c
index 532caa3..49eb2a7 100644
--- a/arch/ppc/8xx_io/cs4218_tdm.c
+++ b/arch/ppc/8xx_io/cs4218_tdm.c
@@ -1013,8 +1013,7 @@
 	*/
 	cpm_free_handler(CPMVEC_SMC2);
 
-	if (beep_buf)
-		kfree(beep_buf);
+	kfree(beep_buf);
 	kd_mksound = orig_mksound;
 }
 #endif /* MODULE */
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 114b90f..8fa51b0 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -746,6 +746,16 @@
 	bool
 	default y if MPC834x_SYS
 
+config CPM1
+	bool
+	depends on 8xx
+	default y
+	help
+	  The CPM1 (Communications Processor Module) is a coprocessor on
+	  embedded CPUs made by Motorola.  Selecting this option means that
+	  you wish to build a kernel for a machine with a CPM1 coprocessor
+	  on it (8xx, 827x, 8560).
+
 config CPM2
 	bool
 	depends on 8260 || MPC8560 || MPC8555
@@ -1247,6 +1257,14 @@
 
 source "drivers/pcmcia/Kconfig"
 
+config RAPIDIO
+	bool "RapidIO support" if MPC8540 || MPC8560
+	help
+	  If you say Y here, the kernel will include drivers and
+	  infrastructure code to support RapidIO interconnect devices.
+
+source "drivers/rapidio/Kconfig"
+
 endmenu
 
 menu "Advanced setup"
diff --git a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile
index b7bd8f6..82df88b 100644
--- a/arch/ppc/boot/simple/Makefile
+++ b/arch/ppc/boot/simple/Makefile
@@ -67,6 +67,12 @@
   entrypoint-$(CONFIG_BAMBOO)		:= 0x01000000
      extra.o-$(CONFIG_BAMBOO)		:= pibs.o
 
+      zimage-$(CONFIG_BUBINGA)		:= zImage-TREE
+zimageinitrd-$(CONFIG_BUBINGA)		:= zImage.initrd-TREE
+         end-$(CONFIG_BUBINGA)		:= bubinga
+  entrypoint-$(CONFIG_BUBINGA)		:= 0x01000000
+     extra.o-$(CONFIG_BUBINGA)		:= openbios.o
+
       zimage-$(CONFIG_EBONY)		:= zImage-TREE
 zimageinitrd-$(CONFIG_EBONY)		:= zImage.initrd-TREE
          end-$(CONFIG_EBONY)		:= ebony
@@ -79,12 +85,30 @@
   entrypoint-$(CONFIG_LUAN)		:= 0x01000000
      extra.o-$(CONFIG_LUAN)		:= pibs.o
 
+      zimage-$(CONFIG_YUCCA)		:= zImage-TREE
+zimageinitrd-$(CONFIG_YUCCA)		:= zImage.initrd-TREE
+         end-$(CONFIG_YUCCA)		:= yucca
+  entrypoint-$(CONFIG_YUCCA)		:= 0x01000000
+     extra.o-$(CONFIG_YUCCA)		:= pibs.o
+
       zimage-$(CONFIG_OCOTEA)		:= zImage-TREE
 zimageinitrd-$(CONFIG_OCOTEA)		:= zImage.initrd-TREE
          end-$(CONFIG_OCOTEA)		:= ocotea
   entrypoint-$(CONFIG_OCOTEA)		:= 0x01000000
      extra.o-$(CONFIG_OCOTEA)		:= pibs.o
 
+      zimage-$(CONFIG_SYCAMORE)		:= zImage-TREE
+zimageinitrd-$(CONFIG_SYCAMORE)		:= zImage.initrd-TREE
+         end-$(CONFIG_SYCAMORE)		:= sycamore
+  entrypoint-$(CONFIG_SYCAMORE)		:= 0x01000000
+     extra.o-$(CONFIG_SYCAMORE)		:= openbios.o
+
+      zimage-$(CONFIG_WALNUT)		:= zImage-TREE
+zimageinitrd-$(CONFIG_WALNUT)		:= zImage.initrd-TREE
+         end-$(CONFIG_WALNUT)		:= walnut
+  entrypoint-$(CONFIG_WALNUT)		:= 0x01000000
+     extra.o-$(CONFIG_WALNUT)		:= openbios.o
+
      extra.o-$(CONFIG_EV64260)		:= misc-ev64260.o
          end-$(CONFIG_EV64260)		:= ev64260
    cacheflag-$(CONFIG_EV64260)		:= -include $(clear_L2_L3)
@@ -162,7 +186,8 @@
 
 # head.o and relocate.o must be at the start.
 boot-y				:= head.o relocate.o $(extra.o-y) $(misc-y)
-boot-$(CONFIG_40x)		+= embed_config.o
+boot-$(CONFIG_REDWOOD_5)	+= embed_config.o
+boot-$(CONFIG_REDWOOD_6)	+= embed_config.o
 boot-$(CONFIG_8xx)		+= embed_config.o
 boot-$(CONFIG_8260)		+= embed_config.o
 boot-$(CONFIG_BSEIP)		+= iic.o
diff --git a/arch/ppc/boot/simple/misc.c b/arch/ppc/boot/simple/misc.c
index e02de5b..f415d6c 100644
--- a/arch/ppc/boot/simple/misc.c
+++ b/arch/ppc/boot/simple/misc.c
@@ -23,7 +23,7 @@
 #include <asm/page.h>
 #include <asm/mmu.h>
 #include <asm/bootinfo.h>
-#ifdef CONFIG_44x
+#ifdef CONFIG_4xx
 #include <asm/ibm4xx.h>
 #endif
 #include <asm/reg.h>
@@ -88,6 +88,14 @@
 	return 0;
 }
 
+#if defined(CONFIG_40x)
+#define PPC4xx_EMAC0_MR0	EMAC0_BASE
+#endif
+
+#if defined(CONFIG_44x) && defined(PPC44x_EMAC0_MR0)
+#define PPC4xx_EMAC0_MR0	PPC44x_EMAC0_MR0
+#endif
+
 struct bi_record *
 decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
 {
@@ -103,13 +111,13 @@
 	com_port = serial_init(0, NULL);
 #endif
 
-#if defined(CONFIG_44x) && defined(PPC44x_EMAC0_MR0)
+#if defined(PPC4xx_EMAC0_MR0)
 	/* Reset MAL */
 	mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR);
 	/* Wait for reset */
 	while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {};
 	/* Reset EMAC */
-	*(volatile unsigned long *)PPC44x_EMAC0_MR0 = 0x20000000;
+	*(volatile unsigned long *)PPC4xx_EMAC0_MR0 = 0x20000000;
 	__asm__ __volatile__("eieio");
 #endif
 
@@ -164,7 +172,9 @@
 		puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n");
 	}
 
+#ifndef CONFIG_40x /* don't overwrite the 40x image located at 0x00400000! */
 	avail_ram = (char *)0x00400000;
+#endif
 	end_avail = (char *)0x00800000;
 	puts("avail ram:     "); puthex((unsigned long)avail_ram); puts(" ");
 	puthex((unsigned long)end_avail); puts("\n");
diff --git a/arch/ppc/boot/simple/openbios.c b/arch/ppc/boot/simple/openbios.c
index c732b6d..81f11d8 100644
--- a/arch/ppc/boot/simple/openbios.c
+++ b/arch/ppc/boot/simple/openbios.c
@@ -1,19 +1,43 @@
 /*
  * arch/ppc/boot/simple/openbios.c
  *
- * 2005 (c) SYSGO AG - g.jaeger@sysgo.com
+ * Copyright (c) 2005 DENX Software Engineering
+ * Stefan Roese <sr@denx.de>
+ *
+ * Based on original work by
+ *      2005 (c) SYSGO AG - g.jaeger@sysgo.com
+ *
  * This file is licensed under the terms of the GNU General Public
  * License version 2.  This program is licensed "as is" without
  * any warranty of any kind, whether express or implied.
  *
- * Derived from arch/ppc/boot/simple/pibs.c (from MontaVista)
  */
 
 #include <linux/types.h>
 #include <linux/config.h>
 #include <linux/string.h>
 #include <asm/ppcboot.h>
-#include <platforms/4xx/ebony.h>
+#include <asm/ibm4xx.h>
+#include <asm/reg.h>
+#ifdef CONFIG_40x
+#include <asm/io.h>
+#endif
+
+#if defined(CONFIG_BUBINGA)
+#define BOARD_INFO_VECTOR       0xFFF80B50 /* openbios 1.19 moved this vector down  - armin */
+#else
+#define BOARD_INFO_VECTOR	0xFFFE0B50
+#endif
+
+#ifdef CONFIG_40x
+/* Supply a default Ethernet address for those eval boards that don't
+ * ship with one.  This is an address from the MBX board I have, so
+ * it is unlikely you will find it on your network.
+ */
+static	ushort	def_enet_addr[] = { 0x0800, 0x3e26, 0x1559 };
+
+extern unsigned long timebase_period_ns;
+#endif /* CONFIG_40x */
 
 extern unsigned long decompress_kernel(unsigned long load_addr, int num_words,
 				       unsigned long cksum);
@@ -23,15 +47,85 @@
 bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot")));
 bd_t *hold_residual = &hold_resid_buf;
 
+typedef struct openbios_board_info {
+        unsigned char    bi_s_version[4];       /* Version of this structure */
+        unsigned char    bi_r_version[30];      /* Version of the IBM ROM */
+        unsigned int     bi_memsize;            /* DRAM installed, in bytes */
+#ifdef CONFIG_405EP
+        unsigned char    bi_enetaddr[2][6];     /* Local Ethernet MAC address */
+#else /* CONFIG_405EP */
+        unsigned char    bi_enetaddr[6];        /* Local Ethernet MAC address */
+#endif /* CONFIG_405EP */
+        unsigned char    bi_pci_enetaddr[6];    /* PCI Ethernet MAC address */
+        unsigned int     bi_intfreq;            /* Processor speed, in Hz */
+        unsigned int     bi_busfreq;            /* PLB Bus speed, in Hz */
+        unsigned int     bi_pci_busfreq;        /* PCI Bus speed, in Hz */
+#ifdef CONFIG_405EP
+        unsigned int     bi_opb_busfreq;        /* OPB Bus speed, in Hz */
+        unsigned int     bi_pllouta_freq;       /* PLL OUTA speed, in Hz */
+#endif /* CONFIG_405EP */
+} openbios_bd_t;
+
 void *
 load_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
 		void *ign1, void *ign2)
 {
-	decompress_kernel(load_addr, num_words, cksum);
+#ifdef CONFIG_40x
+	openbios_bd_t *openbios_bd = NULL;
+	openbios_bd_t *(*get_board_info)(void) =
+		(openbios_bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR);
 
+	/*
+	 * On 40x platforms we not only need the MAC-addresses, but also the
+	 * clocks and memsize. Now try to get all values using the OpenBIOS
+	 * "get_board_info()" callback.
+	 */
+	if ((openbios_bd = get_board_info()) != NULL) {
+		/*
+		 * Copy bd_info from OpenBIOS struct into U-Boot struct
+		 * used by kernel
+		 */
+	        hold_residual->bi_memsize = openbios_bd->bi_memsize;
+	        hold_residual->bi_intfreq = openbios_bd->bi_intfreq;
+	        hold_residual->bi_busfreq = openbios_bd->bi_busfreq;
+	        hold_residual->bi_pci_busfreq = openbios_bd->bi_pci_busfreq;
+		memcpy(hold_residual->bi_pci_enetaddr, openbios_bd->bi_pci_enetaddr, 6);
+#ifdef CONFIG_405EP
+		memcpy(hold_residual->bi_enetaddr, openbios_bd->bi_enetaddr[0], 6);
+		memcpy(hold_residual->bi_enet1addr, openbios_bd->bi_enetaddr[1], 6);
+	        hold_residual->bi_opbfreq = openbios_bd->bi_opb_busfreq;
+	        hold_residual->bi_procfreq = openbios_bd->bi_pllouta_freq;
+#else /* CONFIG_405EP */
+		memcpy(hold_residual->bi_enetaddr, openbios_bd->bi_enetaddr, 6);
+#endif /* CONFIG_405EP */
+	} else {
+		/* Hmmm...better try to stuff some defaults.
+		 */
+		hold_residual->bi_memsize = 16 * 1024 * 1024;
+		hold_residual->bi_intfreq = 200000000;
+		hold_residual->bi_busfreq = 100000000;
+		hold_residual->bi_pci_busfreq = 66666666;
+
+		/*
+		 * Only supply one mac-address in this fallback
+		 */
+		memcpy(hold_residual->bi_enetaddr, (void *)def_enet_addr, 6);
+#ifdef CONFIG_405EP
+	        hold_residual->bi_opbfreq = 50000000;
+	        hold_residual->bi_procfreq = 200000000;
+#endif /* CONFIG_405EP */
+	}
+
+	timebase_period_ns = 1000000000 / hold_residual->bi_intfreq;
+#endif /* CONFIG_40x */
+
+#ifdef CONFIG_440GP
 	/* simply copy the MAC addresses */
-	memcpy(hold_residual->bi_enetaddr,  (char *)EBONY_OPENBIOS_MAC_BASE, 6);
-	memcpy(hold_residual->bi_enet1addr, (char *)(EBONY_OPENBIOS_MAC_BASE+EBONY_OPENBIOS_MAC_OFFSET), 6);
+	memcpy(hold_residual->bi_enetaddr,  (char *)OPENBIOS_MAC_BASE, 6);
+	memcpy(hold_residual->bi_enet1addr, (char *)(OPENBIOS_MAC_BASE+OPENBIOS_MAC_OFFSET), 6);
+#endif /* CONFIG_440GP */
+
+	decompress_kernel(load_addr, num_words, cksum);
 
 	return (void *)hold_residual;
 }
diff --git a/arch/ppc/configs/ev64360_defconfig b/arch/ppc/configs/ev64360_defconfig
index de9bbb7..d471e57 100644
--- a/arch/ppc/configs/ev64360_defconfig
+++ b/arch/ppc/configs/ev64360_defconfig
@@ -1,17 +1,17 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 15:18:23 2005
+# Linux kernel version: 2.6.14
+# Fri Oct 28 19:15:34 2005
 #
 CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
 CONFIG_PPC=y
 CONFIG_PPC32=y
 CONFIG_GENERIC_NVRAM=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
 
 #
 # Code maturity level options
@@ -26,6 +26,7 @@
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
@@ -35,6 +36,7 @@
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -74,7 +76,7 @@
 # CONFIG_TAU_AVERAGE is not set
 # CONFIG_KEXEC is not set
 # CONFIG_CPU_FREQ is not set
-# CONFIG_PM is not set
+# CONFIG_WANT_EARLY_SERIAL is not set
 CONFIG_PPC_STD_MMU=y
 CONFIG_NOT_COHERENT_CACHE=y
 
@@ -86,22 +88,18 @@
 # CONFIG_KATANA is not set
 # CONFIG_WILLOW is not set
 # CONFIG_CPCI690 is not set
-# CONFIG_PCORE is not set
 # CONFIG_POWERPMC250 is not set
 # CONFIG_CHESTNUT is not set
 # CONFIG_SPRUCE is not set
 # CONFIG_HDPU is not set
 # CONFIG_EV64260 is not set
 # CONFIG_LOPEC is not set
-# CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
 # CONFIG_PPLUS is not set
 # CONFIG_PRPMC750 is not set
 # CONFIG_PRPMC800 is not set
 # CONFIG_SANDPOINT is not set
 # CONFIG_RADSTONE_PPC7D is not set
-# CONFIG_ADIR is not set
-# CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
 # CONFIG_EST8260 is not set
@@ -138,10 +136,13 @@
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=y
 CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="console=ttyMM0,115200 root=/dev/mtdblock1 rw rootfstype=jffs2"
+# CONFIG_PM is not set
+# CONFIG_SOFTWARE_SUSPEND is not set
 CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
 
@@ -152,7 +153,6 @@
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 # CONFIG_PCI_LEGACY_PROC is not set
-# CONFIG_PCI_NAMES is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -206,14 +206,19 @@
 # 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_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_IP_SCTP is not set
@@ -239,6 +244,7 @@
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
 
 #
 # Device Drivers
@@ -252,6 +258,11 @@
 # CONFIG_FW_LOADER is not set
 
 #
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
 # Memory Technology Devices (MTD)
 #
 CONFIG_MTD=y
@@ -358,7 +369,6 @@
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=32768
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
 
@@ -379,6 +389,7 @@
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 
 #
@@ -420,6 +431,10 @@
 # CONFIG_ARCNET is not set
 
 #
+# PHY device support
+#
+
+#
 # Ethernet (10 or 100Mbit)
 #
 # CONFIG_NET_ETHERNET is not set
@@ -434,6 +449,7 @@
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
@@ -446,6 +462,7 @@
 #
 # Ethernet (10000 Mbit)
 #
+# CONFIG_CHELSIO_T1 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 
@@ -547,7 +564,20 @@
 #
 # Watchdog Cards
 #
-# CONFIG_WATCHDOG is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_MV64X60_WDT=y
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
 # CONFIG_NVRAM is not set
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X is not set
@@ -571,7 +601,6 @@
 # I2C support
 #
 # CONFIG_I2C is not set
-# CONFIG_I2C_SENSOR is not set
 
 #
 # Dallas's 1-wire bus
@@ -582,6 +611,7 @@
 # Hardware Monitoring support
 #
 CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
@@ -589,6 +619,10 @@
 #
 
 #
+# Multimedia Capabilities Port drivers
+#
+
+#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
@@ -651,10 +685,6 @@
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-
-#
-# XFS support
-#
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -663,6 +693,7 @@
 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
@@ -683,11 +714,10 @@
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
-# CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -735,6 +765,7 @@
 # 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
@@ -751,6 +782,7 @@
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
@@ -767,6 +799,7 @@
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_SERIAL_TEXT_DEBUG is not set
 
 #
 # Security options
diff --git a/arch/ppc/configs/stx_gp3_defconfig b/arch/ppc/configs/stx_gp3_defconfig
index 66dae83..3fedc43 100644
--- a/arch/ppc/configs/stx_gp3_defconfig
+++ b/arch/ppc/configs/stx_gp3_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 14:32:58 2005
+# Linux kernel version: 2.6.12-rc4
+# Tue May 24 18:11:04 2005
 #
 CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
@@ -11,6 +11,7 @@
 CONFIG_PPC=y
 CONFIG_PPC32=y
 CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 
 #
 # Code maturity level options
@@ -18,6 +19,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -29,7 +31,6 @@
 # CONFIG_BSD_PROCESS_ACCT 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
@@ -37,6 +38,9 @@
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -46,6 +50,7 @@
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -69,9 +74,11 @@
 CONFIG_E500=y
 CONFIG_BOOKE=y
 CONFIG_FSL_BOOKE=y
+# CONFIG_PHYS_64BIT is not set
 # CONFIG_SPE is not set
 CONFIG_MATH_EMULATION=y
 # CONFIG_CPU_FREQ is not set
+# CONFIG_PM is not set
 CONFIG_85xx=y
 CONFIG_PPC_INDIRECT_PCI_BE=y
 
@@ -96,6 +103,7 @@
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=m
 # CONFIG_CMDLINE_BOOL is not set
+CONFIG_ISA_DMA_API=y
 
 #
 # Bus options
@@ -104,15 +112,15 @@
 CONFIG_PCI_DOMAINS=y
 # CONFIG_PCI_LEGACY_PROC is not set
 # CONFIG_PCI_NAMES is not set
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
 # CONFIG_PCCARD is not set
-
-#
-# PC-card bridges
-#
+CONFIG_RAPIDIO=y
+CONFIG_RAPIDIO_8_BIT_TRANSPORT=y
+CONFIG_RAPIDIO_DISC_TIMEOUT=30
 
 #
 # Advanced setup
@@ -152,7 +160,7 @@
 CONFIG_PARPORT_PC=m
 # CONFIG_PARPORT_PC_FIFO is not set
 # CONFIG_PARPORT_PC_SUPERIO is not set
-# CONFIG_PARPORT_OTHER is not set
+# CONFIG_PARPORT_GSC is not set
 # CONFIG_PARPORT_1284 is not set
 
 #
@@ -264,7 +272,6 @@
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_IPS is not set
@@ -274,7 +281,6 @@
 # CONFIG_SCSI_IMM is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 CONFIG_SCSI_QLA2XXX=m
@@ -283,6 +289,7 @@
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
@@ -322,7 +329,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -431,7 +437,7 @@
 #
 # Network testing
 #
-# CONFIG_NET_PKTGEN is not set
+CONFIG_NET_PKTGEN=y
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
 # CONFIG_HAMRADIO is not set
@@ -499,6 +505,7 @@
 # Wan interfaces
 #
 # CONFIG_WAN is not set
+CONFIG_RIONET=y
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
@@ -536,20 +543,6 @@
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PARKBD is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
@@ -567,6 +560,19 @@
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -590,6 +596,7 @@
 # CONFIG_SERIAL_CPM_SCC4 is not set
 # CONFIG_SERIAL_CPM_SMC1 is not set
 # CONFIG_SERIAL_CPM_SMC2 is not set
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -626,6 +633,11 @@
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
 # I2C support
 #
 CONFIG_I2C=m
@@ -648,12 +660,12 @@
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
 # CONFIG_I2C_MPC is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_SCx200_ACB is not set
@@ -677,7 +689,9 @@
 # CONFIG_SENSORS_ASB100 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
 # CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
 # CONFIG_SENSORS_LM75 is not set
@@ -688,9 +702,11 @@
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_W83781D is not set
@@ -700,10 +716,12 @@
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_M41T00 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -732,7 +750,6 @@
 # Graphics support
 #
 # CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -752,13 +769,9 @@
 #
 # USB support
 #
-# CONFIG_USB is not set
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
 
 #
 # USB Gadget Support
@@ -789,6 +802,10 @@
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -859,7 +876,6 @@
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
-# CONFIG_EXPORTFS is not set
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -942,8 +958,10 @@
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index c610ca9..76a55a4 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -22,6 +22,7 @@
 obj-$(CONFIG_MODULES)		+= module.o ppc_ksyms.o
 obj-$(CONFIG_NOT_COHERENT_CACHE)	+= dma-mapping.o
 obj-$(CONFIG_PCI)		+= pci.o
+obj-$(CONFIG_RAPIDIO)		+= rio.o
 obj-$(CONFIG_KGDB)		+= ppc-stub.o
 obj-$(CONFIG_SMP)		+= smp.o smp-tbsync.o
 obj-$(CONFIG_TAU)		+= temp.o
diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S
index 8b49679..677c571 100644
--- a/arch/ppc/kernel/head_44x.S
+++ b/arch/ppc/kernel/head_44x.S
@@ -190,8 +190,8 @@
 
 	/* xlat fields */
 	lis	r4,UART0_PHYS_IO_BASE@h		/* RPN depends on SoC */
-#ifndef CONFIG_440EP
-	ori	r4,r4,0x0001		/* ERPN is 1 for second 4GB page */
+#ifdef UART0_PHYS_ERPN
+	ori	r4,r4,UART0_PHYS_ERPN		/* Add ERPN if above 4GB */
 #endif
 
 	/* attrib fields */
diff --git a/arch/ppc/kernel/rio.c b/arch/ppc/kernel/rio.c
new file mode 100644
index 0000000..29487fe
--- /dev/null
+++ b/arch/ppc/kernel/rio.c
@@ -0,0 +1,52 @@
+/*
+ * RapidIO PPC32 support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/rio.h>
+
+#include <asm/rio.h>
+
+/**
+ * platform_rio_init - Do platform specific RIO init
+ *
+ * Any platform specific initialization of RapdIO
+ * hardware is done here as well as registration
+ * of any active master ports in the system.
+ */
+void __attribute__ ((weak))
+    platform_rio_init(void)
+{
+	printk(KERN_WARNING "RIO: No platform_rio_init() present\n");
+}
+
+/**
+ * ppc_rio_init - Do PPC32 RIO init
+ *
+ * Calls platform-specific RIO init code and then calls
+ * rio_init_mports() to initialize any master ports that
+ * have been registered with the RIO subsystem.
+ */
+static int __init ppc_rio_init(void)
+{
+	printk(KERN_INFO "RIO: RapidIO init\n");
+
+	/* Platform specific initialization */
+	platform_rio_init();
+
+	/* Enumerate all registered ports */
+	rio_init_mports();
+
+	return 0;
+}
+
+subsys_initcall(ppc_rio_init);
diff --git a/arch/ppc/platforms/4xx/Kconfig b/arch/ppc/platforms/4xx/Kconfig
index 76f4476..d883791 100644
--- a/arch/ppc/platforms/4xx/Kconfig
+++ b/arch/ppc/platforms/4xx/Kconfig
@@ -82,6 +82,12 @@
 	help
 	  This option enables support for the IBM PPC440SP evaluation board.
 
+config YUCCA
+	bool "Yucca"
+	select WANT_EARLY_SERIAL
+	help
+	  This option enables support for the AMCC PPC440SPe evaluation board.
+
 config OCOTEA
 	bool "Ocotea"
 	select WANT_EARLY_SERIAL
@@ -124,9 +130,14 @@
 	depends on LUAN
 	default y
 
+config 440SPE
+	bool
+	depends on YUCCA
+	default y
+
 config 440
 	bool
-	depends on 440GP || 440SP || 440EP
+	depends on 440GP || 440SP || 440SPE || 440EP
 	default y
 
 config 440A
@@ -158,7 +169,7 @@
 
 config IBM_OCP
 	bool
-	depends on ASH || BAMBOO || BUBINGA || CPCI405 || EBONY || EP405 || LUAN || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
+	depends on ASH || BAMBOO || BUBINGA || CPCI405 || EBONY || EP405 || LUAN || YUCCA || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
 	default y
 
 config XILINX_OCP
@@ -168,7 +179,7 @@
 
 config IBM_EMAC4
 	bool
-	depends on 440GX || 440SP
+	depends on 440GX || 440SP || 440SPE
 	default y
 
 config BIOS_FIXUP
@@ -214,7 +225,7 @@
 
 config IBM_OPENBIOS
 	bool
-	depends on ASH || BUBINGA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
+	depends on ASH || REDWOOD_5 || REDWOOD_6
 	default y
 
 config PPC4xx_DMA
diff --git a/arch/ppc/platforms/4xx/Makefile b/arch/ppc/platforms/4xx/Makefile
index 1dd6d7f..c9bb611 100644
--- a/arch/ppc/platforms/4xx/Makefile
+++ b/arch/ppc/platforms/4xx/Makefile
@@ -7,6 +7,7 @@
 obj-$(CONFIG_EP405)		+= ep405.o
 obj-$(CONFIG_BUBINGA)		+= bubinga.o
 obj-$(CONFIG_LUAN)		+= luan.o
+obj-$(CONFIG_YUCCA)		+= yucca.o
 obj-$(CONFIG_OCOTEA)		+= ocotea.o
 obj-$(CONFIG_REDWOOD_5)		+= redwood5.o
 obj-$(CONFIG_REDWOOD_6)		+= redwood6.o
@@ -22,6 +23,7 @@
 obj-$(CONFIG_440GP)		+= ibm440gp.o
 obj-$(CONFIG_440GX)		+= ibm440gx.o
 obj-$(CONFIG_440SP)		+= ibm440sp.o
+obj-$(CONFIG_440SPE)		+= ppc440spe.o
 obj-$(CONFIG_405EP)		+= ibm405ep.o
 obj-$(CONFIG_405GPR)		+= ibm405gpr.o
 obj-$(CONFIG_VIRTEX_II_PRO)	+= virtex-ii_pro.o
diff --git a/arch/ppc/platforms/4xx/bubinga.c b/arch/ppc/platforms/4xx/bubinga.c
index 3678abf..8110f55 100644
--- a/arch/ppc/platforms/4xx/bubinga.c
+++ b/arch/ppc/platforms/4xx/bubinga.c
@@ -89,7 +89,7 @@
           * by 16.
           */
 	uart_div = (mfdcr(DCRN_CPC0_UCR_BASE) & DCRN_CPC0_UCR_U0DIV);
-	uart_clock = __res.bi_pllouta_freq / uart_div;
+	uart_clock = __res.bi_procfreq / uart_div;
 
 	/* Setup serial port access */
 	memset(&port, 0, sizeof(port));
diff --git a/arch/ppc/platforms/4xx/bubinga.h b/arch/ppc/platforms/4xx/bubinga.h
index b1df856..b5380cf 100644
--- a/arch/ppc/platforms/4xx/bubinga.h
+++ b/arch/ppc/platforms/4xx/bubinga.h
@@ -1,52 +1,34 @@
 /*
- * Support for IBM PPC 405EP evaluation board (Bubinga).
+ * arch/ppc/platforms/4xx/bubinga.h
  *
- * Author: SAW (IBM), derived from walnut.h.
- *         Maintained by MontaVista Software <source@mvista.com>
+ * Bubinga board definitions
  *
- * 2003 (c) MontaVista Softare Inc.  This file is licensed under the
- * terms of the GNU General Public License version 2. This program is
- * licensed "as is" without any warranty of any kind, whether express
- * or implied.
+ * Copyright (c) 2005 DENX Software Engineering
+ * Stefan Roese <sr@denx.de>
+ *
+ * Based on original work by
+ *	SAW (IBM)
+ *	2003 (c) MontaVista Softare Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
  */
 
 #ifdef __KERNEL__
 #ifndef __BUBINGA_H__
 #define __BUBINGA_H__
 
-/* 405EP */
+#include <linux/config.h>
 #include <platforms/4xx/ibm405ep.h>
-
-#ifndef __ASSEMBLY__
-/*
- * Data structure defining board information maintained by the boot
- * ROM on IBM's evaluation board. An effort has been made to
- * keep the field names consistent with the 8xx 'bd_t' board info
- * structures.
- */
-
-typedef struct board_info {
-        unsigned char    bi_s_version[4];       /* Version of this structure */
-        unsigned char    bi_r_version[30];      /* Version of the IBM ROM */
-        unsigned int     bi_memsize;            /* DRAM installed, in bytes */
-        unsigned char    bi_enetaddr[2][6];     /* Local Ethernet MAC address */        unsigned char    bi_pci_enetaddr[6];    /* PCI Ethernet MAC address */
-        unsigned int     bi_intfreq;            /* Processor speed, in Hz */
-        unsigned int     bi_busfreq;            /* PLB Bus speed, in Hz */
-        unsigned int     bi_pci_busfreq;        /* PCI Bus speed, in Hz */
-        unsigned int     bi_opb_busfreq;        /* OPB Bus speed, in Hz */
-        unsigned int     bi_pllouta_freq;       /* PLL OUTA speed, in Hz */
-} bd_t;
-
-/* Some 4xx parts use a different timebase frequency from the internal clock.
-*/
-#define bi_tbfreq bi_intfreq
-
+#include <asm/ppcboot.h>
 
 /* Memory map for the Bubinga board.
  * Generic 4xx plus RTC.
  */
 
-extern void *bubinga_rtc_base;
 #define BUBINGA_RTC_PADDR	((uint)0xf0000000)
 #define BUBINGA_RTC_VADDR	BUBINGA_RTC_PADDR
 #define BUBINGA_RTC_SIZE	((uint)8*1024)
@@ -58,12 +40,18 @@
  * for typical configurations at various CPU speeds.
  * The base baud is calculated as (FWDA / EXT UART DIV / 16)
  */
-#define BASE_BAUD       0
+#define BASE_BAUD		0
 
-#define BUBINGA_FPGA_BASE      0xF0300000
+/* Flash */
+#define PPC40x_FPGA_BASE	0xF0300000
+#define PPC40x_FPGA_REG_OFFS	1	/* offset to flash map reg */
+#define PPC40x_FLASH_ONBD_N(x)	(x & 0x02)
+#define PPC40x_FLASH_SRAM_SEL(x) (x & 0x01)
+#define PPC40x_FLASH_LOW	0xFFF00000
+#define PPC40x_FLASH_HIGH	0xFFF80000
+#define PPC40x_FLASH_SIZE	0x80000
 
-#define PPC4xx_MACHINE_NAME     "IBM Bubinga"
+#define PPC4xx_MACHINE_NAME	"IBM Bubinga"
 
-#endif /* !__ASSEMBLY__ */
 #endif /* __BUBINGA_H__ */
 #endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/ebony.h b/arch/ppc/platforms/4xx/ebony.h
index d08faa4..b91ad42 100644
--- a/arch/ppc/platforms/4xx/ebony.h
+++ b/arch/ppc/platforms/4xx/ebony.h
@@ -24,8 +24,8 @@
 #define PPC44x_EMAC0_MR0	0xE0000800
 
 /* Where to find the MAC info */
-#define EBONY_OPENBIOS_MAC_BASE   0xfffffe0c
-#define EBONY_OPENBIOS_MAC_OFFSET 0x0c
+#define OPENBIOS_MAC_BASE	0xfffffe0c
+#define OPENBIOS_MAC_OFFSET	0x0c
 
 /* Default clock rates for Rev. B and Rev. C silicon */
 #define EBONY_440GP_RB_SYSCLK	33000000
diff --git a/arch/ppc/platforms/4xx/ppc440spe.c b/arch/ppc/platforms/4xx/ppc440spe.c
new file mode 100644
index 0000000..6139a0b
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ppc440spe.c
@@ -0,0 +1,148 @@
+/*
+ * arch/ppc/platforms/4xx/ppc440spe.c
+ *
+ * PPC440SPe I/O descriptions
+ *
+ * Roland Dreier <rolandd@cisco.com>
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ *
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2002-2005 MontaVista Software Inc.
+ *
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ * Copyright (c) 2003, 2004 Zultys Technologies
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <platforms/4xx/ppc440spe.h>
+#include <asm/ocp.h>
+#include <asm/ppc4xx_pic.h>
+
+static struct ocp_func_emac_data ppc440spe_emac0_def = {
+	.rgmii_idx	= -1,		/* No RGMII */
+	.rgmii_mux	= -1,		/* No RGMII */
+	.zmii_idx       = -1,           /* No ZMII */
+	.zmii_mux       = -1,           /* No ZMII */
+	.mal_idx        = 0,            /* MAL device index */
+	.mal_rx_chan    = 0,            /* MAL rx channel number */
+	.mal_tx_chan    = 0,            /* MAL tx channel number */
+	.wol_irq        = 61,  		/* WOL interrupt number */
+	.mdio_idx       = -1,           /* No shared MDIO */
+	.tah_idx	= -1,		/* No TAH */
+};
+OCP_SYSFS_EMAC_DATA()
+
+static struct ocp_func_mal_data ppc440spe_mal0_def = {
+	.num_tx_chans   = 1,    	/* Number of TX channels */
+	.num_rx_chans   = 1,    	/* Number of RX channels */
+	.txeob_irq	= 38,		/* TX End Of Buffer IRQ  */
+	.rxeob_irq	= 39,		/* RX End Of Buffer IRQ  */
+	.txde_irq	= 34,		/* TX Descriptor Error IRQ */
+	.rxde_irq	= 35,		/* RX Descriptor Error IRQ */
+	.serr_irq	= 33,		/* MAL System Error IRQ    */
+	.dcr_base	= DCRN_MAL_BASE /* MAL0_CFG DCR number */
+};
+OCP_SYSFS_MAL_DATA()
+
+static struct ocp_func_iic_data ppc440spe_iic0_def = {
+	.fast_mode	= 0,		/* Use standad mode (100Khz) */
+};
+
+static struct ocp_func_iic_data ppc440spe_iic1_def = {
+	.fast_mode	= 0,		/* Use standad mode (100Khz) */
+};
+OCP_SYSFS_IIC_DATA()
+
+struct ocp_def core_ocp[] = {
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_16550,
+	  .index	= 0,
+	  .paddr	= PPC440SPE_UART0_ADDR,
+	  .irq		= UART0_INT,
+	  .pm		= IBM_CPM_UART0,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_16550,
+	  .index	= 1,
+	  .paddr	= PPC440SPE_UART1_ADDR,
+	  .irq		= UART1_INT,
+	  .pm		= IBM_CPM_UART1,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_16550,
+	  .index	= 2,
+	  .paddr	= PPC440SPE_UART2_ADDR,
+	  .irq		= UART2_INT,
+	  .pm		= IBM_CPM_UART2,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_IIC,
+	  .index	= 0,
+	  .paddr	= 0x00000004f0000400ULL,
+	  .irq		= 2,
+	  .pm		= IBM_CPM_IIC0,
+	  .additions	= &ppc440spe_iic0_def,
+	  .show		= &ocp_show_iic_data
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_IIC,
+	  .index	= 1,
+	  .paddr	= 0x00000004f0000500ULL,
+	  .irq		= 3,
+	  .pm		= IBM_CPM_IIC1,
+	  .additions	= &ppc440spe_iic1_def,
+	  .show		= &ocp_show_iic_data
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_GPIO,
+	  .index	= 0,
+	  .paddr	= 0x00000004f0000700ULL,
+	  .irq		= OCP_IRQ_NA,
+	  .pm		= IBM_CPM_GPIO0,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_MAL,
+	  .paddr	= OCP_PADDR_NA,
+	  .irq		= OCP_IRQ_NA,
+	  .pm		= OCP_CPM_NA,
+	  .additions	= &ppc440spe_mal0_def,
+	  .show		= &ocp_show_mal_data,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_EMAC,
+	  .index	= 0,
+	  .paddr	= 0x00000004f0000800ULL,
+	  .irq		= 60,
+	  .pm		= OCP_CPM_NA,
+	  .additions	= &ppc440spe_emac0_def,
+	  .show		= &ocp_show_emac_data,
+	},
+	{ .vendor	= OCP_VENDOR_INVALID
+	}
+};
+
+/* Polarity and triggering settings for internal interrupt sources */
+struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[] __initdata = {
+	{ .polarity     = 0xffffffff,
+	  .triggering   = 0x010f0004,
+	  .ext_irq_mask = 0x00000000,
+	},
+	{ .polarity     = 0xffffffff,
+	  .triggering   = 0x001f8040,
+	  .ext_irq_mask = 0x00007c30,   /* IRQ6 - IRQ7, IRQ8 - IRQ12 */
+	},
+	{ .polarity     = 0xffffffff,
+	  .triggering   = 0x00000000,
+	  .ext_irq_mask = 0x000000fc,   /* IRQ0 - IRQ5 */
+	},
+	{ .polarity     = 0xffffffff,
+	  .triggering   = 0x00000000,
+	  .ext_irq_mask = 0x00000000,
+	},
+};
diff --git a/arch/ppc/platforms/4xx/ppc440spe.h b/arch/ppc/platforms/4xx/ppc440spe.h
new file mode 100644
index 0000000..2216846
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ppc440spe.h
@@ -0,0 +1,66 @@
+/*
+ * arch/ppc/platforms/4xx/ibm440spe.h
+ *
+ * PPC440SPe definitions
+ *
+ * Roland Dreier <rolandd@cisco.com>
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ *
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2004-2005 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifdef __KERNEL__
+#ifndef __PPC_PLATFORMS_PPC440SPE_H
+#define __PPC_PLATFORMS_PPC440SPE_H
+
+#include <linux/config.h>
+
+#include <asm/ibm44x.h>
+
+/* UART */
+#define PPC440SPE_UART0_ADDR	0x00000004f0000200ULL
+#define PPC440SPE_UART1_ADDR	0x00000004f0000300ULL
+#define PPC440SPE_UART2_ADDR	0x00000004f0000600ULL
+#define UART0_INT		0
+#define UART1_INT		1
+#define UART2_INT		37
+
+/* Clock and Power Management */
+#define IBM_CPM_IIC0		0x80000000	/* IIC interface */
+#define IBM_CPM_IIC1		0x40000000	/* IIC interface */
+#define IBM_CPM_PCI		0x20000000	/* PCI bridge */
+#define IBM_CPM_CPU		    0x02000000	/* processor core */
+#define IBM_CPM_DMA		    0x01000000	/* DMA controller */
+#define IBM_CPM_BGO		    0x00800000	/* PLB to OPB bus arbiter */
+#define IBM_CPM_BGI		    0x00400000	/* OPB to PLB bridge */
+#define IBM_CPM_EBC		    0x00200000	/* External Bux Controller */
+#define IBM_CPM_EBM		    0x00100000	/* Ext Bus Master Interface */
+#define IBM_CPM_DMC		    0x00080000	/* SDRAM peripheral controller */
+#define IBM_CPM_PLB		    0x00040000	/* PLB bus arbiter */
+#define IBM_CPM_SRAM		0x00020000	/* SRAM memory controller */
+#define IBM_CPM_PPM		    0x00002000	/* PLB Performance Monitor */
+#define IBM_CPM_UIC1		0x00001000	/* Universal Interrupt Controller */
+#define IBM_CPM_GPIO0		0x00000800	/* General Purpose IO (??) */
+#define IBM_CPM_GPT		    0x00000400	/* General Purpose Timers  */
+#define IBM_CPM_UART0		0x00000200	/* serial port 0 */
+#define IBM_CPM_UART1		0x00000100	/* serial port 1 */
+#define IBM_CPM_UART2		0x00000100	/* serial port 1 */
+#define IBM_CPM_UIC0		0x00000080	/* Universal Interrupt Controller */
+#define IBM_CPM_TMRCLK		0x00000040	/* CPU timers */
+#define IBM_CPM_EMAC0  		0x00000020	/* EMAC 0     */
+
+#define DFLT_IBM4xx_PM		~(IBM_CPM_UIC | IBM_CPM_UIC1 | IBM_CPM_CPU \
+				| IBM_CPM_EBC | IBM_CPM_SRAM | IBM_CPM_BGO \
+				| IBM_CPM_EBM | IBM_CPM_PLB | IBM_CPM_OPB \
+				| IBM_CPM_TMRCLK | IBM_CPM_DMA | IBM_CPM_PCI \
+				| IBM_CPM_TAHOE0 | IBM_CPM_TAHOE1 \
+				| IBM_CPM_EMAC0 | IBM_CPM_EMAC1 \
+			  	| IBM_CPM_EMAC2 | IBM_CPM_EMAC3 )
+#endif /* __PPC_PLATFORMS_PPC440SP_H */
+#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/sycamore.c b/arch/ppc/platforms/4xx/sycamore.c
index d8019ee..281b4a2 100644
--- a/arch/ppc/platforms/4xx/sycamore.c
+++ b/arch/ppc/platforms/4xx/sycamore.c
@@ -88,9 +88,6 @@
 void __init
 sycamore_setup_arch(void)
 {
-#define SYCAMORE_PS2_BASE	0xF0100000
-#define SYCAMORE_FPGA_BASE	0xF0300000
-
 	void *fpga_brdc;
 	unsigned char fpga_brdc_data;
 	void *fpga_enable;
@@ -100,7 +97,7 @@
 
 	ppc4xx_setup_arch();
 
-	ibm_ocp_set_emac(0, 1);
+	ibm_ocp_set_emac(0, 0);
 
 	kb_data = ioremap(SYCAMORE_PS2_BASE, 8);
 	if (!kb_data) {
@@ -111,7 +108,7 @@
 
 	kb_cs = kb_data + 1;
 
-	fpga_status = ioremap(SYCAMORE_FPGA_BASE, 8);
+	fpga_status = ioremap(PPC40x_FPGA_BASE, 8);
 	if (!fpga_status) {
 		printk(KERN_CRIT
 		       "sycamore_setup_arch() fpga_status ioremap failed\n");
diff --git a/arch/ppc/platforms/4xx/sycamore.h b/arch/ppc/platforms/4xx/sycamore.h
index 3e7b4e2..1cd6c82 100644
--- a/arch/ppc/platforms/4xx/sycamore.h
+++ b/arch/ppc/platforms/4xx/sycamore.h
@@ -1,67 +1,52 @@
 /*
  * arch/ppc/platforms/4xx/sycamore.h
  *
- * Macros, definitions, and data structures specific to the IBM PowerPC
- * 405GPr "Sycamore" evaluation board.
+ * Sycamore board definitions
  *
- * Author: Armin Kuster <akuster@mvista.com>
+ * Copyright (c) 2005 DENX Software Engineering
+ * Stefan Roese <sr@denx.de>
  *
- * 2000 (c) MontaVista, Software, Inc.  This file is licensed under
- * the terms of the GNU General Public License version 2.  This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
+ * Based on original work by
+ * 	Armin Kuster <akuster@mvista.com>
+ *	2000 (c) MontaVista, Software, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
  */
 
 #ifdef __KERNEL__
 #ifndef __ASM_SYCAMORE_H__
 #define __ASM_SYCAMORE_H__
 
+#include <linux/config.h>
 #include <platforms/4xx/ibm405gpr.h>
+#include <asm/ppcboot.h>
 
-#ifndef __ASSEMBLY__
-/*
- * Data structure defining board information maintained by the boot
- * ROM on IBM's "Sycamore" evaluation board. An effort has been made to
- * keep the field names consistent with the 8xx 'bd_t' board info
- * structures.
- */
-
-typedef struct board_info {
-	unsigned char	 bi_s_version[4];	/* Version of this structure */
-	unsigned char	 bi_r_version[30];	/* Version of the IBM ROM */
-	unsigned int	 bi_memsize;		/* DRAM installed, in bytes */
-	unsigned char	 bi_enetaddr[6];	/* Local Ethernet MAC address */
-	unsigned char	 bi_pci_enetaddr[6];	/* PCI Ethernet MAC address */
-	unsigned int	 bi_intfreq;		/* Processor speed, in Hz */
-	unsigned int	 bi_busfreq;		/* PLB Bus speed, in Hz */
-	unsigned int	 bi_pci_busfreq;	/* PCI Bus speed, in Hz */
-} bd_t;
-
-/* Some 4xx parts use a different timebase frequency from the internal clock.
-*/
-#define bi_tbfreq bi_intfreq
-
-
-/* Memory map for the IBM "Sycamore" 405GP evaluation board.
+/* Memory map for the IBM "Sycamore" 405GPr evaluation board.
  * Generic 4xx plus RTC.
  */
 
-extern void *sycamore_rtc_base;
 #define SYCAMORE_RTC_PADDR	((uint)0xf0000000)
 #define SYCAMORE_RTC_VADDR	SYCAMORE_RTC_PADDR
-#define SYCAMORE_RTC_SIZE		((uint)8*1024)
+#define SYCAMORE_RTC_SIZE	((uint)8*1024)
 
-#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK
-#define BASE_BAUD		201600
-#else
 #define BASE_BAUD		691200
-#endif
 
-#define SYCAMORE_PS2_BASE		0xF0100000
-#define SYCAMORE_FPGA_BASE	0xF0300000
+#define SYCAMORE_PS2_BASE	0xF0100000
+
+/* Flash */
+#define PPC40x_FPGA_BASE	0xF0300000
+#define PPC40x_FPGA_REG_OFFS	5	/* offset to flash map reg */
+#define PPC40x_FLASH_ONBD_N(x)	(x & 0x02)
+#define PPC40x_FLASH_SRAM_SEL(x) (x & 0x01)
+#define PPC40x_FLASH_LOW	0xFFF00000
+#define PPC40x_FLASH_HIGH	0xFFF80000
+#define PPC40x_FLASH_SIZE	0x80000
 
 #define PPC4xx_MACHINE_NAME	"IBM Sycamore"
 
-#endif /* !__ASSEMBLY__ */
 #endif /* __ASM_SYCAMORE_H__ */
 #endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/walnut.c b/arch/ppc/platforms/4xx/walnut.c
index a33eda4..74cb331 100644
--- a/arch/ppc/platforms/4xx/walnut.c
+++ b/arch/ppc/platforms/4xx/walnut.c
@@ -90,7 +90,7 @@
 
 	kb_cs = kb_data + 1;
 
-	fpga_status = ioremap(WALNUT_FPGA_BASE, 8);
+	fpga_status = ioremap(PPC40x_FPGA_BASE, 8);
 	if (!fpga_status) {
 		printk(KERN_CRIT
 		       "walnut_setup_arch() fpga_status ioremap failed\n");
diff --git a/arch/ppc/platforms/4xx/walnut.h b/arch/ppc/platforms/4xx/walnut.h
index 04cfbf3..dcf2691 100644
--- a/arch/ppc/platforms/4xx/walnut.h
+++ b/arch/ppc/platforms/4xx/walnut.h
@@ -1,72 +1,55 @@
 /*
  * arch/ppc/platforms/4xx/walnut.h
  *
- * Macros, definitions, and data structures specific to the IBM PowerPC
- * 405GP "Walnut" evaluation board.
+ * Walnut board definitions
  *
- * Authors: Grant Erickson <grant@lcse.umn.edu>, Frank Rowand
- * <frank_rowand@mvista.com>, Debbie Chu <debbie_chu@mvista.com> or
- * source@mvista.com
+ * Copyright (c) 2005 DENX Software Engineering
+ * Stefan Roese <sr@denx.de>
  *
- * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ * Based on original work by
+ * 	Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *	Frank Rowand <frank_rowand@mvista.com>
+ *	Debbie Chu <debbie_chu@mvista.com>
+ *	2000 (c) MontaVista, Software, Inc.
  *
- * 2000 (c) MontaVista, Software, Inc.  This file is licensed under
- * the terms of the GNU General Public License version 2.  This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
+ * 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.
+ *
  */
 
 #ifdef __KERNEL__
 #ifndef __ASM_WALNUT_H__
 #define __ASM_WALNUT_H__
 
-/* We have a 405GP core */
+#include <linux/config.h>
 #include <platforms/4xx/ibm405gp.h>
-
-#ifndef __ASSEMBLY__
-/*
- * Data structure defining board information maintained by the boot
- * ROM on IBM's "Walnut" evaluation board. An effort has been made to
- * keep the field names consistent with the 8xx 'bd_t' board info
- * structures.
- */
-
-typedef struct board_info {
-	unsigned char	 bi_s_version[4];	/* Version of this structure */
-	unsigned char	 bi_r_version[30];	/* Version of the IBM ROM */
-	unsigned int	 bi_memsize;		/* DRAM installed, in bytes */
-	unsigned char	 bi_enetaddr[6];	/* Local Ethernet MAC address */
-	unsigned char	 bi_pci_enetaddr[6];	/* PCI Ethernet MAC address */
-	unsigned int	 bi_intfreq;		/* Processor speed, in Hz */
-	unsigned int	 bi_busfreq;		/* PLB Bus speed, in Hz */
-	unsigned int	 bi_pci_busfreq;	/* PCI Bus speed, in Hz */
-} bd_t;
-
-/* Some 4xx parts use a different timebase frequency from the internal clock.
-*/
-#define bi_tbfreq bi_intfreq
-
+#include <asm/ppcboot.h>
 
 /* Memory map for the IBM "Walnut" 405GP evaluation board.
  * Generic 4xx plus RTC.
  */
 
-extern void *walnut_rtc_base;
 #define WALNUT_RTC_PADDR	((uint)0xf0000000)
 #define WALNUT_RTC_VADDR	WALNUT_RTC_PADDR
 #define WALNUT_RTC_SIZE		((uint)8*1024)
 
-#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK
-#define BASE_BAUD		201600
-#else
 #define BASE_BAUD		691200
-#endif
 
 #define WALNUT_PS2_BASE		0xF0100000
-#define WALNUT_FPGA_BASE	0xF0300000
+
+/* Flash */
+#define PPC40x_FPGA_BASE	0xF0300000
+#define PPC40x_FPGA_REG_OFFS	5	/* offset to flash map reg */
+#define PPC40x_FLASH_ONBD_N(x)	(x & 0x02)
+#define PPC40x_FLASH_SRAM_SEL(x) (x & 0x01)
+#define PPC40x_FLASH_LOW	0xFFF00000
+#define PPC40x_FLASH_HIGH	0xFFF80000
+#define PPC40x_FLASH_SIZE	0x80000
+#define WALNUT_FPGA_BASE	PPC40x_FPGA_BASE
 
 #define PPC4xx_MACHINE_NAME	"IBM Walnut"
 
-#endif /* !__ASSEMBLY__ */
 #endif /* __ASM_WALNUT_H__ */
 #endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/yucca.c b/arch/ppc/platforms/4xx/yucca.c
new file mode 100644
index 0000000..e60f4bd
--- /dev/null
+++ b/arch/ppc/platforms/4xx/yucca.c
@@ -0,0 +1,395 @@
+/*
+ * arch/ppc/platforms/4xx/yucca.c
+ *
+ * Yucca board specific routines
+ *
+ * Roland Dreier <rolandd@cisco.com> (based on luan.c by Matt Porter)
+ *
+ * Copyright 2004-2005 MontaVista Software Inc.
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/major.h>
+#include <linux/blkdev.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/ide.h>
+#include <linux/initrd.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/ocp.h>
+#include <asm/pci-bridge.h>
+#include <asm/time.h>
+#include <asm/todc.h>
+#include <asm/bootinfo.h>
+#include <asm/ppc4xx_pic.h>
+#include <asm/ppcboot.h>
+
+#include <syslib/ibm44x_common.h>
+#include <syslib/ibm440gx_common.h>
+#include <syslib/ibm440sp_common.h>
+#include <syslib/ppc440spe_pcie.h>
+
+extern bd_t __res;
+
+static struct ibm44x_clocks clocks __initdata;
+
+static void __init
+yucca_calibrate_decr(void)
+{
+	unsigned int freq;
+
+	if (mfspr(SPRN_CCR1) & CCR1_TCS)
+		freq = YUCCA_TMR_CLK;
+	else
+		freq = clocks.cpu;
+
+	ibm44x_calibrate_decr(freq);
+}
+
+static int
+yucca_show_cpuinfo(struct seq_file *m)
+{
+	seq_printf(m, "vendor\t\t: AMCC\n");
+	seq_printf(m, "machine\t\t: PPC440SPe EVB (Yucca)\n");
+
+	return 0;
+}
+
+static enum {
+	HOSE_UNKNOWN,
+	HOSE_PCIX,
+	HOSE_PCIE0,
+	HOSE_PCIE1,
+	HOSE_PCIE2
+} hose_type[4];
+
+static inline int
+yucca_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
+
+	if (hose_type[hose->index] == HOSE_PCIX) {
+		static char pci_irq_table[][4] =
+		/*
+		 *	PCI IDSEL/INTPIN->INTLINE
+		 *	  A   B   C   D
+		 */
+		{
+			{ 81, -1, -1, -1 },	/* IDSEL 1 - PCIX0 Slot 0 */
+		};
+		const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
+		return PCI_IRQ_TABLE_LOOKUP;
+	} else if (hose_type[hose->index] == HOSE_PCIE0) {
+		static char pci_irq_table[][4] =
+		/*
+		 *	PCI IDSEL/INTPIN->INTLINE
+		 *	  A   B   C   D
+		 */
+		{
+			{ 96, 97, 98, 99 },
+		};
+		const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
+		return PCI_IRQ_TABLE_LOOKUP;
+	} else if (hose_type[hose->index] == HOSE_PCIE1) {
+		static char pci_irq_table[][4] =
+		/*
+		 *	PCI IDSEL/INTPIN->INTLINE
+		 *	  A   B   C   D
+		 */
+		{
+			{ 100, 101, 102, 103 },
+		};
+		const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
+		return PCI_IRQ_TABLE_LOOKUP;
+	} else if (hose_type[hose->index] == HOSE_PCIE2) {
+		static char pci_irq_table[][4] =
+		/*
+		 *	PCI IDSEL/INTPIN->INTLINE
+		 *	  A   B   C   D
+		 */
+		{
+			{ 104, 105, 106, 107 },
+		};
+		const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
+		return PCI_IRQ_TABLE_LOOKUP;
+	}
+	return -1;
+}
+
+static void __init yucca_set_emacdata(void)
+{
+	struct ocp_def *def;
+	struct ocp_func_emac_data *emacdata;
+
+	/* Set phy_map, phy_mode, and mac_addr for the EMAC */
+	def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0);
+	emacdata = def->additions;
+	emacdata->phy_map = 0x00000001;	/* Skip 0x00 */
+	emacdata->phy_mode = PHY_MODE_GMII;
+	memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6);
+}
+
+static int __init yucca_pcie_card_present(int port)
+{
+   void __iomem *pcie_fpga_base;
+   u16 reg;
+
+   pcie_fpga_base = ioremap64(YUCCA_FPGA_REG_BASE, YUCCA_FPGA_REG_SIZE);
+   reg = in_be16(pcie_fpga_base + FPGA_REG1C);
+   iounmap(pcie_fpga_base);
+
+   switch(port) {
+   case 0: return !(reg & FPGA_REG1C_PE0_PRSNT);
+   case 1: return !(reg & FPGA_REG1C_PE1_PRSNT);
+   case 2: return !(reg & FPGA_REG1C_PE2_PRSNT);
+   default: return 0;
+   }
+}
+
+/*
+ * For the given slot, set rootpoint mode, send power to the slot,
+ * turn on the green LED and turn off the yellow LED, enable the clock
+ * and turn off reset.
+ */
+static void __init yucca_setup_pcie_fpga_rootpoint(int port)
+{
+	void __iomem *pcie_reg_fpga_base;
+	u16 power, clock, green_led, yellow_led, reset_off, rootpoint, endpoint;
+
+	pcie_reg_fpga_base = ioremap64(YUCCA_FPGA_REG_BASE, YUCCA_FPGA_REG_SIZE);
+
+	switch(port) {
+	case 0:
+		rootpoint   = FPGA_REG1C_PE0_ROOTPOINT;
+		endpoint    = 0;
+		power 	    = FPGA_REG1A_PE0_PWRON;
+		green_led   = FPGA_REG1A_PE0_GLED;
+		clock 	    = FPGA_REG1A_PE0_REFCLK_ENABLE;
+		yellow_led  = FPGA_REG1A_PE0_YLED;
+		reset_off   = FPGA_REG1C_PE0_PERST;
+		break;
+	case 1:
+		rootpoint   = 0;
+		endpoint    = FPGA_REG1C_PE1_ENDPOINT;
+		power 	    = FPGA_REG1A_PE1_PWRON;
+		green_led   = FPGA_REG1A_PE1_GLED;
+		clock 	    = FPGA_REG1A_PE1_REFCLK_ENABLE;
+		yellow_led  = FPGA_REG1A_PE1_YLED;
+		reset_off   = FPGA_REG1C_PE1_PERST;
+		break;
+	case 2:
+		rootpoint   = 0;
+		endpoint    = FPGA_REG1C_PE2_ENDPOINT;
+		power 	    = FPGA_REG1A_PE2_PWRON;
+		green_led   = FPGA_REG1A_PE2_GLED;
+		clock 	    = FPGA_REG1A_PE2_REFCLK_ENABLE;
+		yellow_led  = FPGA_REG1A_PE2_YLED;
+		reset_off   = FPGA_REG1C_PE2_PERST;
+		break;
+
+	default:
+		return;
+	}
+
+	out_be16(pcie_reg_fpga_base + FPGA_REG1A,
+		 ~(power | clock | green_led) &
+		 (yellow_led | in_be16(pcie_reg_fpga_base + FPGA_REG1A)));
+	out_be16(pcie_reg_fpga_base + FPGA_REG1C,
+		 ~(endpoint | reset_off) &
+		 (rootpoint | in_be16(pcie_reg_fpga_base + FPGA_REG1C)));
+
+	/*
+	 * Leave device in reset for a while after powering on the
+	 * slot to give it a chance to initialize.
+	 */
+	mdelay(250);
+
+	out_be16(pcie_reg_fpga_base + FPGA_REG1C,
+		 reset_off | in_be16(pcie_reg_fpga_base + FPGA_REG1C));
+
+	iounmap(pcie_reg_fpga_base);
+}
+
+static void __init
+yucca_setup_hoses(void)
+{
+	struct pci_controller *hose;
+	char name[20];
+	int i;
+
+	if (0 && ppc440spe_init_pcie()) {
+		printk(KERN_WARNING "PPC440SPe PCI Express initialization failed\n");
+		return;
+	}
+
+	for (i = 0; i <= 2; ++i) {
+		if (!yucca_pcie_card_present(i))
+			continue;
+
+		printk(KERN_INFO "PCIE%d: card present\n", i);
+		yucca_setup_pcie_fpga_rootpoint(i);
+		if (ppc440spe_init_pcie_rootport(i)) {
+			printk(KERN_WARNING "PCIE%d: initialization failed\n", i);
+			continue;
+		}
+
+		hose = pcibios_alloc_controller();
+		if (!hose)
+			return;
+
+		sprintf(name, "PCIE%d host bridge", i);
+		pci_init_resource(&hose->io_resource,
+				  YUCCA_PCIX_LOWER_IO,
+				  YUCCA_PCIX_UPPER_IO,
+				  IORESOURCE_IO,
+				  name);
+
+		hose->mem_space.start = YUCCA_PCIE_LOWER_MEM +
+			i * YUCCA_PCIE_MEM_SIZE;
+		hose->mem_space.end   = hose->mem_space.start +
+			YUCCA_PCIE_MEM_SIZE - 1;
+
+		pci_init_resource(&hose->mem_resources[0],
+				  hose->mem_space.start,
+				  hose->mem_space.end,
+				  IORESOURCE_MEM,
+				  name);
+
+		hose->first_busno = 0;
+		hose->last_busno  = 15;
+		hose_type[hose->index] = HOSE_PCIE0 + i;
+
+		ppc440spe_setup_pcie(hose, i);
+		hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
+	}
+
+	ppc_md.pci_swizzle = common_swizzle;
+	ppc_md.pci_map_irq = yucca_map_irq;
+}
+
+TODC_ALLOC();
+
+static void __init
+yucca_early_serial_map(void)
+{
+	struct uart_port port;
+
+	/* Setup ioremapped serial port access */
+	memset(&port, 0, sizeof(port));
+	port.membase = ioremap64(PPC440SPE_UART0_ADDR, 8);
+	port.irq = UART0_INT;
+	port.uartclk = clocks.uart0;
+	port.regshift = 0;
+	port.iotype = SERIAL_IO_MEM;
+	port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+	port.line = 0;
+
+	if (early_serial_setup(&port) != 0) {
+		printk("Early serial init of port 0 failed\n");
+	}
+
+	port.membase = ioremap64(PPC440SPE_UART1_ADDR, 8);
+	port.irq = UART1_INT;
+	port.uartclk = clocks.uart1;
+	port.line = 1;
+
+	if (early_serial_setup(&port) != 0) {
+		printk("Early serial init of port 1 failed\n");
+	}
+
+	port.membase = ioremap64(PPC440SPE_UART2_ADDR, 8);
+	port.irq = UART2_INT;
+	port.uartclk = BASE_BAUD;
+	port.line = 2;
+
+	if (early_serial_setup(&port) != 0) {
+		printk("Early serial init of port 2 failed\n");
+	}
+}
+
+static void __init
+yucca_setup_arch(void)
+{
+	yucca_set_emacdata();
+
+#if !defined(CONFIG_BDI_SWITCH)
+	/*
+	 * The Abatron BDI JTAG debugger does not tolerate others
+	 * mucking with the debug registers.
+	 */
+	mtspr(SPRN_DBCR0, (DBCR0_TDE | DBCR0_IDM));
+#endif
+
+	/*
+	 * Determine various clocks.
+	 * To be completely correct we should get SysClk
+	 * from FPGA, because it can be changed by on-board switches
+	 * --ebs
+	 */
+	/* 440GX and 440SPe clocking is the same - rd */
+	ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200);
+	ocp_sys_info.opb_bus_freq = clocks.opb;
+
+	/* init to some ~sane value until calibrate_delay() runs */
+	loops_per_jiffy = 50000000/HZ;
+
+	/* Setup PCIXn host bridges */
+	yucca_setup_hoses();
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (initrd_start)
+		ROOT_DEV = Root_RAM0;
+	else
+#endif
+#ifdef CONFIG_ROOT_NFS
+		ROOT_DEV = Root_NFS;
+#else
+		ROOT_DEV = Root_HDA1;
+#endif
+
+	yucca_early_serial_map();
+
+	/* Identify the system */
+	printk("Yucca port (Roland Dreier <rolandd@cisco.com>)\n");
+}
+
+void __init platform_init(unsigned long r3, unsigned long r4,
+		unsigned long r5, unsigned long r6, unsigned long r7)
+{
+	ibm44x_platform_init(r3, r4, r5, r6, r7);
+
+	ppc_md.setup_arch = yucca_setup_arch;
+	ppc_md.show_cpuinfo = yucca_show_cpuinfo;
+	ppc_md.find_end_of_memory = ibm440sp_find_end_of_memory;
+	ppc_md.get_irq = NULL;		/* Set in ppc4xx_pic_init() */
+
+	ppc_md.calibrate_decr = yucca_calibrate_decr;
+#ifdef CONFIG_KGDB
+	ppc_md.early_serial_map = yucca_early_serial_map;
+#endif
+}
diff --git a/arch/ppc/platforms/4xx/yucca.h b/arch/ppc/platforms/4xx/yucca.h
new file mode 100644
index 0000000..01a4afe
--- /dev/null
+++ b/arch/ppc/platforms/4xx/yucca.h
@@ -0,0 +1,111 @@
+/*
+ * arch/ppc/platforms/4xx/yucca.h
+ *
+ * Yucca board definitions
+ *
+ * Roland Dreier <rolandd@cisco.com> (based on luan.h by Matt Porter)
+ *
+ * Copyright 2004-2005 MontaVista Software Inc.
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_YUCCA_H__
+#define __ASM_YUCCA_H__
+
+#include <linux/config.h>
+#include <platforms/4xx/ppc440spe.h>
+
+/* F/W TLB mapping used in bootloader glue to reset EMAC */
+#define PPC44x_EMAC0_MR0	0xa0000800
+
+/* Location of MAC addresses in PIBS image */
+#define PIBS_FLASH_BASE		0xffe00000
+#define PIBS_MAC_BASE		(PIBS_FLASH_BASE+0x1b0400)
+
+/* External timer clock frequency */
+#define YUCCA_TMR_CLK		25000000
+
+/*
+ * FPGA registers
+ */
+#define YUCCA_FPGA_REG_BASE			0x00000004e2000000ULL
+#define YUCCA_FPGA_REG_SIZE			0x24
+
+#define FPGA_REG1A				0x1a
+
+#define FPGA_REG1A_PE0_GLED			0x8000
+#define FPGA_REG1A_PE1_GLED			0x4000
+#define FPGA_REG1A_PE2_GLED			0x2000
+#define FPGA_REG1A_PE0_YLED			0x1000
+#define FPGA_REG1A_PE1_YLED			0x0800
+#define FPGA_REG1A_PE2_YLED			0x0400
+#define FPGA_REG1A_PE0_PWRON			0x0200
+#define FPGA_REG1A_PE1_PWRON			0x0100
+#define FPGA_REG1A_PE2_PWRON			0x0080
+#define FPGA_REG1A_PE0_REFCLK_ENABLE		0x0040
+#define FPGA_REG1A_PE1_REFCLK_ENABLE		0x0020
+#define FPGA_REG1A_PE2_REFCLK_ENABLE		0x0010
+#define FPGA_REG1A_PE_SPREAD0			0x0008
+#define FPGA_REG1A_PE_SPREAD1			0x0004
+#define FPGA_REG1A_PE_SELSOURCE_0		0x0002
+#define FPGA_REG1A_PE_SELSOURCE_1		0x0001
+
+#define FPGA_REG1C				0x1c
+
+#define FPGA_REG1C_PE0_ROOTPOINT		0x8000
+#define FPGA_REG1C_PE1_ENDPOINT			0x4000
+#define FPGA_REG1C_PE2_ENDPOINT			0x2000
+#define FPGA_REG1C_PE0_PRSNT			0x1000
+#define FPGA_REG1C_PE1_PRSNT			0x0800
+#define FPGA_REG1C_PE2_PRSNT			0x0400
+#define FPGA_REG1C_PE0_WAKE			0x0080
+#define FPGA_REG1C_PE1_WAKE			0x0040
+#define FPGA_REG1C_PE2_WAKE			0x0020
+#define FPGA_REG1C_PE0_PERST			0x0010
+#define FPGA_REG1C_PE1_PERST			0x0008
+#define FPGA_REG1C_PE2_PERST			0x0004
+
+/*
+ * Serial port defines
+ */
+#define RS_TABLE_SIZE	3
+
+/* PIBS defined UART mappings, used before early_serial_setup */
+#define UART0_IO_BASE	0xa0000200
+#define UART1_IO_BASE	0xa0000300
+#define UART2_IO_BASE	0xa0000600
+
+#define BASE_BAUD	11059200
+#define STD_UART_OP(num)					\
+	{ 0, BASE_BAUD, 0, UART##num##_INT,			\
+		(ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST),	\
+		iomem_base: (void*)UART##num##_IO_BASE,		\
+		io_type: SERIAL_IO_MEM},
+
+#define SERIAL_PORT_DFNS	\
+	STD_UART_OP(0)		\
+	STD_UART_OP(1)		\
+	STD_UART_OP(2)
+
+/* PCI support */
+#define YUCCA_PCIX_LOWER_IO	0x00000000
+#define YUCCA_PCIX_UPPER_IO	0x0000ffff
+#define YUCCA_PCIX_LOWER_MEM	0x80000000
+#define YUCCA_PCIX_UPPER_MEM	0x8fffffff
+#define YUCCA_PCIE_LOWER_MEM	0x90000000
+#define YUCCA_PCIE_MEM_SIZE	0x10000000
+
+#define YUCCA_PCIX_MEM_SIZE	0x10000000
+#define YUCCA_PCIX_MEM_OFFSET	0x00000000
+#define YUCCA_PCIE_MEM_SIZE	0x10000000
+#define YUCCA_PCIE_MEM_OFFSET	0x00000000
+
+#endif				/* __ASM_YUCCA_H__ */
+#endif				/* __KERNEL__ */
diff --git a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
index bd3ac01..16ad092 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
@@ -45,6 +45,8 @@
 
 #include <mm/mmu_decl.h>
 
+#include <syslib/ppc85xx_rio.h>
+
 #include <platforms/85xx/mpc85xx_ads_common.h>
 
 #ifndef CONFIG_PCI
@@ -189,3 +191,11 @@
 }
 
 #endif /* CONFIG_PCI */
+
+#ifdef CONFIG_RAPIDIO
+void platform_rio_init(void)
+{
+	/* 512MB RIO LAW at 0xc0000000 */
+	mpc85xx_rio_setup(0xc0000000, 0x20000000);
+}
+#endif /* CONFIG_RAPIDIO */
diff --git a/arch/ppc/platforms/85xx/stx_gp3.c b/arch/ppc/platforms/85xx/stx_gp3.c
index 1e1b85f..15ce9d0 100644
--- a/arch/ppc/platforms/85xx/stx_gp3.c
+++ b/arch/ppc/platforms/85xx/stx_gp3.c
@@ -37,6 +37,7 @@
 #include <linux/module.h>
 #include <linux/fsl_devices.h>
 #include <linux/interrupt.h>
+#include <linux/rio.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -57,6 +58,7 @@
 
 #include <syslib/cpm2_pic.h>
 #include <syslib/ppc85xx_common.h>
+#include <syslib/ppc85xx_rio.h>
 
 
 unsigned char __res[sizeof(bd_t)];
@@ -273,6 +275,18 @@
 }
 #endif /* CONFIG_PCI */
 
+#ifdef CONFIG_RAPIDIO
+void
+platform_rio_init(void)
+{
+	/*
+	 * The STx firmware configures the RapidIO Local Access Window
+	 * at 0xc0000000 with a size of 512MB.
+	 */
+	mpc85xx_rio_setup(0xc0000000, 0x20000000);
+}
+#endif /* CONFIG_RAPIDIO */
+
 void __init
 platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
 	      unsigned long r6, unsigned long r7)
diff --git a/arch/ppc/platforms/ev64360.c b/arch/ppc/platforms/ev64360.c
index b132456..b9d844f 100644
--- a/arch/ppc/platforms/ev64360.c
+++ b/arch/ppc/platforms/ev64360.c
@@ -52,6 +52,8 @@
 
 unsigned char	__res[sizeof(bd_t)];
 
+TODC_ALLOC();
+
 static int __init
 ev64360_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
 {
@@ -182,6 +184,9 @@
 		 EV64360_RTC_WINDOW_BASE, EV64360_RTC_WINDOW_SIZE, 0);
 	bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN);
 
+	TODC_INIT(TODC_TYPE_DS1501, 0, 0,
+		ioremap(EV64360_RTC_WINDOW_BASE, EV64360_RTC_WINDOW_SIZE), 8);
+
 	mv64x60_set_32bit_window(&bh, MV64x60_CPU2SRAM_WIN,
 		 EV64360_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE, 0);
 	bh.ci->enable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN);
@@ -496,6 +501,13 @@
 	ppc_md.power_off = ev64360_power_off;
 	ppc_md.halt = ev64360_halt;
 	ppc_md.find_end_of_memory = ev64360_find_end_of_memory;
+	ppc_md.init = NULL;
+
+	ppc_md.time_init = todc_time_init;
+	ppc_md.set_rtc_time = todc_set_rtc_time;
+	ppc_md.get_rtc_time = todc_get_rtc_time;
+	ppc_md.nvram_read_val = todc_direct_read_val;
+	ppc_md.nvram_write_val = todc_direct_write_val;
 	ppc_md.calibrate_decr = ev64360_calibrate_decr;
 
 #if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE)
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
index b4ef15b..5bd33ba 100644
--- a/arch/ppc/syslib/Makefile
+++ b/arch/ppc/syslib/Makefile
@@ -15,6 +15,7 @@
 obj-$(CONFIG_440GP)		+= ibm440gp_common.o
 obj-$(CONFIG_440GX)		+= ibm440gx_common.o
 obj-$(CONFIG_440SP)		+= ibm440gx_common.o ibm440sp_common.o
+obj-$(CONFIG_440SPE)		+= ibm440gx_common.o ibm440sp_common.o ppc440spe_pcie.o
 ifeq ($(CONFIG_4xx),y)
 ifeq ($(CONFIG_VIRTEX_II_PRO),y)
 obj-$(CONFIG_40x)		+= xilinx_pic.o
@@ -32,6 +33,7 @@
 obj-$(CONFIG_PPC4xx_EDMA)	+= ppc4xx_sgdma.o
 ifeq ($(CONFIG_40x),y)
 obj-$(CONFIG_PCI)		+= pci_auto.o ppc405_pci.o
+obj-$(CONFIG_RAPIDIO)		+= ppc85xx_rio.o
 endif
 endif
 obj-$(CONFIG_8xx)		+= m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \
@@ -46,12 +48,14 @@
 obj-$(CONFIG_CPCI690)		+= todc_time.o pci_auto.o
 obj-$(CONFIG_EBONY)		+= pci_auto.o todc_time.o
 obj-$(CONFIG_EV64260)		+= todc_time.o pci_auto.o
+obj-$(CONFIG_EV64360)		+= todc_time.o
 obj-$(CONFIG_CHESTNUT)		+= mv64360_pic.o pci_auto.o
 obj-$(CONFIG_GEMINI)		+= open_pic.o
 obj-$(CONFIG_GT64260)		+= gt64260_pic.o
 obj-$(CONFIG_LOPEC)		+= pci_auto.o todc_time.o
 obj-$(CONFIG_HDPU)		+= pci_auto.o
 obj-$(CONFIG_LUAN)		+= pci_auto.o todc_time.o
+obj-$(CONFIG_YUCCA)		+= pci_auto.o todc_time.o
 obj-$(CONFIG_KATANA)		+= pci_auto.o
 obj-$(CONFIG_MV64360)		+= mv64360_pic.o
 obj-$(CONFIG_MV64X60)		+= mv64x60.o mv64x60_win.o
diff --git a/arch/ppc/syslib/ibm440sp_common.c b/arch/ppc/syslib/ibm440sp_common.c
index 417d4cf..cdafda1 100644
--- a/arch/ppc/syslib/ibm440sp_common.c
+++ b/arch/ppc/syslib/ibm440sp_common.c
@@ -1,7 +1,7 @@
 /*
  * arch/ppc/syslib/ibm440sp_common.c
  *
- * PPC440SP system library
+ * PPC440SP/PPC440SPe system library
  *
  * Matt Porter <mporter@kernel.crashing.org>
  * Copyright 2002-2005 MontaVista Software Inc.
@@ -35,7 +35,7 @@
 	u32 mem_size = 0;
 
 	/* Read two bank sizes and sum */
-	for (i=0; i<2; i++)
+	for (i=0; i< MQ0_NUM_BANKS; i++)
 		switch (mfdcr(DCRN_MQ0_BS0BAS + i) & MQ0_CONFIG_SIZE_MASK) {
 			case MQ0_CONFIG_SIZE_8M:
 				mem_size += PPC44x_MEM_SIZE_8M;
diff --git a/arch/ppc/syslib/ibm44x_common.c b/arch/ppc/syslib/ibm44x_common.c
index 5152c8e..71db11d 100644
--- a/arch/ppc/syslib/ibm44x_common.c
+++ b/arch/ppc/syslib/ibm44x_common.c
@@ -20,6 +20,7 @@
 #include <linux/types.h>
 #include <linux/serial.h>
 #include <linux/module.h>
+#include <linux/initrd.h>
 
 #include <asm/ibm44x.h>
 #include <asm/mmu.h>
@@ -214,9 +215,20 @@
 /* Called from machine_check_exception */
 void platform_machine_check(struct pt_regs *regs)
 {
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+	printk("PLB0: BEAR=0x%08x%08x ACR=  0x%08x BESR= 0x%08x%08x\n",
+	       mfdcr(DCRN_PLB0_BEARH), mfdcr(DCRN_PLB0_BEARL),
+	       mfdcr(DCRN_PLB0_ACR), mfdcr(DCRN_PLB0_BESRH),
+	       mfdcr(DCRN_PLB0_BESRL));
+	printk("PLB1: BEAR=0x%08x%08x ACR=  0x%08x BESR= 0x%08x%08x\n",
+	       mfdcr(DCRN_PLB1_BEARH), mfdcr(DCRN_PLB1_BEARL),
+	       mfdcr(DCRN_PLB1_ACR), mfdcr(DCRN_PLB1_BESRH),
+	       mfdcr(DCRN_PLB1_BESRL));
+#else
     	printk("PLB0: BEAR=0x%08x%08x ACR=  0x%08x BESR= 0x%08x\n",
 		mfdcr(DCRN_PLB0_BEARH), mfdcr(DCRN_PLB0_BEARL),
 		mfdcr(DCRN_PLB0_ACR),  mfdcr(DCRN_PLB0_BESR));
+#endif
 	printk("POB0: BEAR=0x%08x%08x BESR0=0x%08x BESR1=0x%08x\n",
 		mfdcr(DCRN_POB0_BEARH), mfdcr(DCRN_POB0_BEARL),
 		mfdcr(DCRN_POB0_BESR0), mfdcr(DCRN_POB0_BESR1));
diff --git a/arch/ppc/syslib/ppc405_pci.c b/arch/ppc/syslib/ppc405_pci.c
index 81c83bf..d6d838b 100644
--- a/arch/ppc/syslib/ppc405_pci.c
+++ b/arch/ppc/syslib/ppc405_pci.c
@@ -89,13 +89,6 @@
 	isa_mem_base = 0;
 	pci_dram_offset = 0;
 
-#if  (PSR_PCI_ARBIT_EN > 1)
-	/* Check if running in slave mode */
-	if ((mfdcr(DCRN_CHPSR) & PSR_PCI_ARBIT_EN) == 0) {
-		printk("Running as PCI slave, kernel PCI disabled !\n");
-		return;
-	}
-#endif
 	/* Setup PCI32 hose */
 	hose_a = pcibios_alloc_controller();
 	if (!hose_a)
diff --git a/arch/ppc/syslib/ppc440spe_pcie.c b/arch/ppc/syslib/ppc440spe_pcie.c
new file mode 100644
index 0000000..1509fc1
--- /dev/null
+++ b/arch/ppc/syslib/ppc440spe_pcie.c
@@ -0,0 +1,442 @@
+/*
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ * Roland Dreier <rolandd@cisco.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/reg.h>
+#include <asm/io.h>
+#include <asm/ibm44x.h>
+
+#include "ppc440spe_pcie.h"
+
+static int
+pcie_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+		     int len, u32 *val)
+{
+	struct pci_controller *hose = bus->sysdata;
+
+	if (PCI_SLOT(devfn) != 1)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	offset += devfn << 12;
+
+	/*
+	 * Note: the caller has already checked that offset is
+	 * suitably aligned and that len is 1, 2 or 4.
+	 */
+	switch (len) {
+	case 1:
+		*val = in_8(hose->cfg_data + offset);
+		break;
+	case 2:
+		*val = in_le16(hose->cfg_data + offset);
+		break;
+	default:
+		*val = in_le32(hose->cfg_data + offset);
+		break;
+	}
+
+	if (0) printk("%s: read %x(%d) @ %x\n", __func__, *val, len, offset);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+pcie_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+		      int len, u32 val)
+{
+	struct pci_controller *hose = bus->sysdata;
+
+	if (PCI_SLOT(devfn) != 1)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	offset += devfn << 12;
+
+	switch (len) {
+	case 1:
+		out_8(hose->cfg_data + offset, val);
+		break;
+	case 2:
+		out_le16(hose->cfg_data + offset, val);
+		break;
+	default:
+		out_le32(hose->cfg_data + offset, val);
+		break;
+	}
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pcie_pci_ops =
+{
+	.read  = pcie_read_config,
+	.write = pcie_write_config
+};
+
+enum {
+	PTYPE_ENDPOINT		= 0x0,
+	PTYPE_LEGACY_ENDPOINT	= 0x1,
+	PTYPE_ROOT_PORT		= 0x4,
+
+	LNKW_X1			= 0x1,
+	LNKW_X4			= 0x4,
+	LNKW_X8			= 0x8
+};
+
+static void check_error(void)
+{
+	u32 valPE0, valPE1, valPE2;
+
+	/* SDR0_PEGPLLLCT1 reset */
+	if (!(valPE0 = SDR_READ(PESDR0_PLLLCT1) & 0x01000000)) {
+		printk(KERN_INFO "PCIE: SDR0_PEGPLLLCT1 reset error 0x%8x\n", valPE0);
+	}
+
+	valPE0 = SDR_READ(PESDR0_RCSSET);
+	valPE1 = SDR_READ(PESDR1_RCSSET);
+	valPE2 = SDR_READ(PESDR2_RCSSET);
+
+	/* SDR0_PExRCSSET rstgu */
+	if ( !(valPE0 & 0x01000000) ||
+	     !(valPE1 & 0x01000000) ||
+	     !(valPE2 & 0x01000000)) {
+		printk(KERN_INFO "PCIE:  SDR0_PExRCSSET rstgu error\n");
+	}
+
+	/* SDR0_PExRCSSET rstdl */
+	if ( !(valPE0 & 0x00010000) ||
+	     !(valPE1 & 0x00010000) ||
+	     !(valPE2 & 0x00010000)) {
+		printk(KERN_INFO "PCIE:  SDR0_PExRCSSET rstdl error\n");
+	}
+
+	/* SDR0_PExRCSSET rstpyn */
+	if ( (valPE0 & 0x00001000) ||
+	     (valPE1 & 0x00001000) ||
+	     (valPE2 & 0x00001000)) {
+		printk(KERN_INFO "PCIE:  SDR0_PExRCSSET rstpyn error\n");
+	}
+
+	/* SDR0_PExRCSSET hldplb */
+	if ( (valPE0 & 0x10000000) ||
+	     (valPE1 & 0x10000000) ||
+	     (valPE2 & 0x10000000)) {
+		printk(KERN_INFO "PCIE:  SDR0_PExRCSSET hldplb error\n");
+	}
+
+	/* SDR0_PExRCSSET rdy */
+	if ( (valPE0 & 0x00100000) ||
+	     (valPE1 & 0x00100000) ||
+	     (valPE2 & 0x00100000)) {
+		printk(KERN_INFO "PCIE:  SDR0_PExRCSSET rdy error\n");
+	}
+
+	/* SDR0_PExRCSSET shutdown */
+	if ( (valPE0 & 0x00000100) ||
+	     (valPE1 & 0x00000100) ||
+	     (valPE2 & 0x00000100)) {
+		printk(KERN_INFO "PCIE:  SDR0_PExRCSSET shutdown error\n");
+	}
+}
+
+/*
+ * Initialize PCI Express core as described in User Manual section 27.12.1
+ */
+int ppc440spe_init_pcie(void)
+{
+	/* Set PLL clock receiver to LVPECL */
+	SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) | 1 << 28);
+
+	check_error();
+
+	printk(KERN_INFO "PCIE initialization OK\n");
+
+	if (!(SDR_READ(PESDR0_PLLLCT2) & 0x10000))
+		printk(KERN_INFO "PESDR_PLLCT2 resistance calibration failed (0x%08x)\n",
+		       SDR_READ(PESDR0_PLLLCT2));
+
+	/* De-assert reset of PCIe PLL, wait for lock */
+	SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) & ~(1 << 24));
+	udelay(3);
+
+	return 0;
+}
+
+int ppc440spe_init_pcie_rootport(int port)
+{
+	static int core_init;
+	void __iomem *utl_base;
+	u32 val = 0;
+	int i;
+
+	if (!core_init) {
+		++core_init;
+		i = ppc440spe_init_pcie();
+		if (i)
+			return i;
+	}
+
+	/*
+	 * Initialize various parts of the PCI Express core for our port:
+	 *
+	 * - Set as a root port and enable max width
+	 *   (PXIE0 -> X8, PCIE1 and PCIE2 -> X4).
+	 * - Set up UTL configuration.
+	 * - Increase SERDES drive strength to levels suggested by AMCC.
+	 * - De-assert RSTPYN, RSTDL and RSTGU.
+	 */
+	switch (port) {
+	case 0:
+		SDR_WRITE(PESDR0_DLPSET, PTYPE_ROOT_PORT << 20 | LNKW_X8 << 12);
+
+		SDR_WRITE(PESDR0_UTLSET1, 0x21222222);
+		SDR_WRITE(PESDR0_UTLSET2, 0x11000000);
+
+		SDR_WRITE(PESDR0_HSSL0SET1, 0x35000000);
+		SDR_WRITE(PESDR0_HSSL1SET1, 0x35000000);
+		SDR_WRITE(PESDR0_HSSL2SET1, 0x35000000);
+		SDR_WRITE(PESDR0_HSSL3SET1, 0x35000000);
+		SDR_WRITE(PESDR0_HSSL4SET1, 0x35000000);
+		SDR_WRITE(PESDR0_HSSL5SET1, 0x35000000);
+		SDR_WRITE(PESDR0_HSSL6SET1, 0x35000000);
+		SDR_WRITE(PESDR0_HSSL7SET1, 0x35000000);
+
+		SDR_WRITE(PESDR0_RCSSET,
+			  (SDR_READ(PESDR0_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+		break;
+
+	case 1:
+		SDR_WRITE(PESDR1_DLPSET, PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12);
+
+		SDR_WRITE(PESDR1_UTLSET1, 0x21222222);
+		SDR_WRITE(PESDR1_UTLSET2, 0x11000000);
+
+		SDR_WRITE(PESDR1_HSSL0SET1, 0x35000000);
+		SDR_WRITE(PESDR1_HSSL1SET1, 0x35000000);
+		SDR_WRITE(PESDR1_HSSL2SET1, 0x35000000);
+		SDR_WRITE(PESDR1_HSSL3SET1, 0x35000000);
+
+		SDR_WRITE(PESDR1_RCSSET,
+			  (SDR_READ(PESDR1_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+		break;
+
+	case 2:
+		SDR_WRITE(PESDR2_DLPSET, PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12);
+
+		SDR_WRITE(PESDR2_UTLSET1, 0x21222222);
+		SDR_WRITE(PESDR2_UTLSET2, 0x11000000);
+
+		SDR_WRITE(PESDR2_HSSL0SET1, 0x35000000);
+		SDR_WRITE(PESDR2_HSSL1SET1, 0x35000000);
+		SDR_WRITE(PESDR2_HSSL2SET1, 0x35000000);
+		SDR_WRITE(PESDR2_HSSL3SET1, 0x35000000);
+
+		SDR_WRITE(PESDR2_RCSSET,
+			  (SDR_READ(PESDR2_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+		break;
+	}
+
+	mdelay(1000);
+
+	switch (port) {
+	case 0: val = SDR_READ(PESDR0_RCSSTS); break;
+	case 1: val = SDR_READ(PESDR1_RCSSTS); break;
+	case 2: val = SDR_READ(PESDR2_RCSSTS); break;
+	}
+
+	if (!(val & (1 << 20)))
+		printk(KERN_INFO "PCIE%d: PGRST inactive\n", port);
+	else
+		printk(KERN_WARNING "PGRST for PCIE%d failed %08x\n", port, val);
+
+	switch (port) {
+	case 0: printk(KERN_INFO "PCIE0: LOOP %08x\n", SDR_READ(PESDR0_LOOP)); break;
+	case 1: printk(KERN_INFO "PCIE1: LOOP %08x\n", SDR_READ(PESDR1_LOOP)); break;
+	case 2: printk(KERN_INFO "PCIE2: LOOP %08x\n", SDR_READ(PESDR2_LOOP)); break;
+	}
+
+	/*
+	 * Map UTL registers at 0xc_1000_0n00
+	 */
+	switch (port) {
+	case 0:
+		mtdcr(DCRN_PEGPL_REGBAH(PCIE0), 0x0000000c);
+		mtdcr(DCRN_PEGPL_REGBAL(PCIE0), 0x10000000);
+		mtdcr(DCRN_PEGPL_REGMSK(PCIE0), 0x00007001);
+		mtdcr(DCRN_PEGPL_SPECIAL(PCIE0), 0x68782800);
+		break;
+
+	case 1:
+		mtdcr(DCRN_PEGPL_REGBAH(PCIE1), 0x0000000c);
+		mtdcr(DCRN_PEGPL_REGBAL(PCIE1), 0x10001000);
+		mtdcr(DCRN_PEGPL_REGMSK(PCIE1), 0x00007001);
+		mtdcr(DCRN_PEGPL_SPECIAL(PCIE1), 0x68782800);
+		break;
+
+	case 2:
+		mtdcr(DCRN_PEGPL_REGBAH(PCIE2), 0x0000000c);
+		mtdcr(DCRN_PEGPL_REGBAL(PCIE2), 0x10002000);
+		mtdcr(DCRN_PEGPL_REGMSK(PCIE2), 0x00007001);
+		mtdcr(DCRN_PEGPL_SPECIAL(PCIE2), 0x68782800);
+	}
+
+	utl_base = ioremap64(0xc10000000ull + 0x1000 * port, 0x100);
+
+	/*
+	 * Set buffer allocations and then assert VRB and TXE.
+	 */
+	out_be32(utl_base + PEUTL_OUTTR,   0x08000000);
+	out_be32(utl_base + PEUTL_INTR,    0x02000000);
+	out_be32(utl_base + PEUTL_OPDBSZ,  0x10000000);
+	out_be32(utl_base + PEUTL_PBBSZ,   0x53000000);
+	out_be32(utl_base + PEUTL_IPHBSZ,  0x08000000);
+	out_be32(utl_base + PEUTL_IPDBSZ,  0x10000000);
+	out_be32(utl_base + PEUTL_RCIRQEN, 0x00f00000);
+	out_be32(utl_base + PEUTL_PCTL,    0x80800066);
+
+	iounmap(utl_base);
+
+	/*
+	 * We map PCI Express configuration access into the 512MB regions
+	 *     PCIE0: 0xc_4000_0000
+	 *     PCIE1: 0xc_8000_0000
+	 *     PCIE2: 0xc_c000_0000
+	 */
+	switch (port) {
+	case 0:
+		mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c);
+		mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000);
+		mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */
+		break;
+
+	case 1:
+		mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c);
+		mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000);
+		mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */
+		break;
+
+	case 2:
+		mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c);
+		mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000);
+		mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */
+		break;
+	}
+
+	/*
+	 * Check for VC0 active and assert RDY.
+	 */
+	switch (port) {
+	case 0:
+		if (!(SDR_READ(PESDR0_RCSSTS) & (1 << 16)))
+			printk(KERN_WARNING "PCIE0: VC0 not active\n");
+		SDR_WRITE(PESDR0_RCSSET, SDR_READ(PESDR0_RCSSET) | 1 << 20);
+		break;
+	case 1:
+		if (!(SDR_READ(PESDR1_RCSSTS) & (1 << 16)))
+			printk(KERN_WARNING "PCIE0: VC0 not active\n");
+		SDR_WRITE(PESDR1_RCSSET, SDR_READ(PESDR1_RCSSET) | 1 << 20);
+		break;
+	case 2:
+		if (!(SDR_READ(PESDR2_RCSSTS) & (1 << 16)))
+			printk(KERN_WARNING "PCIE0: VC0 not active\n");
+		SDR_WRITE(PESDR2_RCSSET, SDR_READ(PESDR2_RCSSET) | 1 << 20);
+		break;
+	}
+
+#if 0
+	/* Dump all config regs */
+	for (i = 0x300; i <= 0x320; ++i)
+		printk("[%04x] 0x%08x\n", i, SDR_READ(i));
+	for (i = 0x340; i <= 0x353; ++i)
+		printk("[%04x] 0x%08x\n", i, SDR_READ(i));
+	for (i = 0x370; i <= 0x383; ++i)
+		printk("[%04x] 0x%08x\n", i, SDR_READ(i));
+	for (i = 0x3a0; i <= 0x3a2; ++i)
+		printk("[%04x] 0x%08x\n", i, SDR_READ(i));
+	for (i = 0x3c0; i <= 0x3c3; ++i)
+		printk("[%04x] 0x%08x\n", i, SDR_READ(i));
+#endif
+
+	mdelay(100);
+
+	return 0;
+}
+
+void ppc440spe_setup_pcie(struct pci_controller *hose, int port)
+{
+	void __iomem *mbase;
+
+	/*
+	 * Map 16MB, which is enough for 4 bits of bus #
+	 */
+	hose->cfg_data = ioremap64(0xc40000000ull + port * 0x40000000,
+				   1 << 24);
+	hose->ops = &pcie_pci_ops;
+
+	/*
+	 * Set bus numbers on our root port
+	 */
+	mbase = ioremap64(0xc50000000ull + port * 0x40000000, 4096);
+	out_8(mbase + PCI_PRIMARY_BUS, 0);
+	out_8(mbase + PCI_SECONDARY_BUS, 0);
+
+	/*
+	 * Set up outbound translation to hose->mem_space from PLB
+	 * addresses at an offset of 0xd_0000_0000.  We set the low
+	 * bits of the mask to 11 to turn off splitting into 8
+	 * subregions and to enable the outbound translation.
+	 */
+	out_le32(mbase + PECFG_POM0LAH, 0);
+	out_le32(mbase + PECFG_POM0LAL, hose->mem_space.start);
+
+	switch (port) {
+	case 0:
+		mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0),  0x0000000d);
+		mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0),  hose->mem_space.start);
+		mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
+		mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
+		      ~(hose->mem_space.end - hose->mem_space.start) | 3);
+		break;
+	case 1:
+		mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1),  0x0000000d);
+		mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1),  hose->mem_space.start);
+		mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
+		mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
+		      ~(hose->mem_space.end - hose->mem_space.start) | 3);
+
+		break;
+	case 2:
+		mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2),  0x0000000d);
+		mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2),  hose->mem_space.start);
+		mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
+		mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
+		      ~(hose->mem_space.end - hose->mem_space.start) | 3);
+		break;
+	}
+
+	/* Set up 16GB inbound memory window at 0 */
+	out_le32(mbase + PCI_BASE_ADDRESS_0, 0);
+	out_le32(mbase + PCI_BASE_ADDRESS_1, 0);
+	out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffc);
+	out_le32(mbase + PECFG_BAR0LMPA, 0);
+	out_le32(mbase + PECFG_PIM0LAL, 0);
+	out_le32(mbase + PECFG_PIM0LAH, 0);
+	out_le32(mbase + PECFG_PIMEN, 0x1);
+
+	/* Enable I/O, Mem, and Busmaster cycles */
+	out_le16(mbase + PCI_COMMAND,
+		 in_le16(mbase + PCI_COMMAND) |
+		 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+
+	iounmap(mbase);
+}
diff --git a/arch/ppc/syslib/ppc440spe_pcie.h b/arch/ppc/syslib/ppc440spe_pcie.h
new file mode 100644
index 0000000..55b765a
--- /dev/null
+++ b/arch/ppc/syslib/ppc440spe_pcie.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ * Roland Dreier <rolandd@cisco.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __PPC_SYSLIB_PPC440SPE_PCIE_H
+#define __PPC_SYSLIB_PPC440SPE_PCIE_H
+
+#define DCRN_SDR0_CFGADDR	0x00e
+#define DCRN_SDR0_CFGDATA	0x00f
+
+#define DCRN_PCIE0_BASE		0x100
+#define DCRN_PCIE1_BASE		0x120
+#define DCRN_PCIE2_BASE		0x140
+#define PCIE0			DCRN_PCIE0_BASE
+#define PCIE1			DCRN_PCIE1_BASE
+#define PCIE2			DCRN_PCIE2_BASE
+
+#define DCRN_PEGPL_CFGBAH(base)		(base + 0x00)
+#define DCRN_PEGPL_CFGBAL(base)		(base + 0x01)
+#define DCRN_PEGPL_CFGMSK(base)		(base + 0x02)
+#define DCRN_PEGPL_MSGBAH(base)		(base + 0x03)
+#define DCRN_PEGPL_MSGBAL(base)		(base + 0x04)
+#define DCRN_PEGPL_MSGMSK(base)		(base + 0x05)
+#define DCRN_PEGPL_OMR1BAH(base)	(base + 0x06)
+#define DCRN_PEGPL_OMR1BAL(base)	(base + 0x07)
+#define DCRN_PEGPL_OMR1MSKH(base)	(base + 0x08)
+#define DCRN_PEGPL_OMR1MSKL(base)	(base + 0x09)
+#define DCRN_PEGPL_REGBAH(base)		(base + 0x12)
+#define DCRN_PEGPL_REGBAL(base)		(base + 0x13)
+#define DCRN_PEGPL_REGMSK(base)		(base + 0x14)
+#define DCRN_PEGPL_SPECIAL(base)	(base + 0x15)
+
+/*
+ * System DCRs (SDRs)
+ */
+#define PESDR0_PLLLCT1		0x03a0
+#define PESDR0_PLLLCT2		0x03a1
+#define PESDR0_PLLLCT3		0x03a2
+
+#define PESDR0_UTLSET1		0x0300
+#define PESDR0_UTLSET2		0x0301
+#define PESDR0_DLPSET		0x0302
+#define PESDR0_LOOP		0x0303
+#define PESDR0_RCSSET		0x0304
+#define PESDR0_RCSSTS		0x0305
+#define PESDR0_HSSL0SET1	0x0306
+#define PESDR0_HSSL0SET2	0x0307
+#define PESDR0_HSSL0STS		0x0308
+#define PESDR0_HSSL1SET1	0x0309
+#define PESDR0_HSSL1SET2	0x030a
+#define PESDR0_HSSL1STS		0x030b
+#define PESDR0_HSSL2SET1	0x030c
+#define PESDR0_HSSL2SET2	0x030d
+#define PESDR0_HSSL2STS		0x030e
+#define PESDR0_HSSL3SET1	0x030f
+#define PESDR0_HSSL3SET2	0x0310
+#define PESDR0_HSSL3STS		0x0311
+#define PESDR0_HSSL4SET1	0x0312
+#define PESDR0_HSSL4SET2	0x0313
+#define PESDR0_HSSL4STS		0x0314
+#define PESDR0_HSSL5SET1	0x0315
+#define PESDR0_HSSL5SET2	0x0316
+#define PESDR0_HSSL5STS		0x0317
+#define PESDR0_HSSL6SET1	0x0318
+#define PESDR0_HSSL6SET2	0x0319
+#define PESDR0_HSSL6STS		0x031a
+#define PESDR0_HSSL7SET1	0x031b
+#define PESDR0_HSSL7SET2	0x031c
+#define PESDR0_HSSL7STS		0x031d
+#define PESDR0_HSSCTLSET	0x031e
+#define PESDR0_LANE_ABCD	0x031f
+#define PESDR0_LANE_EFGH	0x0320
+
+#define PESDR1_UTLSET1		0x0340
+#define PESDR1_UTLSET2		0x0341
+#define PESDR1_DLPSET		0x0342
+#define PESDR1_LOOP		0x0343
+#define PESDR1_RCSSET		0x0344
+#define PESDR1_RCSSTS		0x0345
+#define PESDR1_HSSL0SET1	0x0346
+#define PESDR1_HSSL0SET2	0x0347
+#define PESDR1_HSSL0STS		0x0348
+#define PESDR1_HSSL1SET1	0x0349
+#define PESDR1_HSSL1SET2	0x034a
+#define PESDR1_HSSL1STS		0x034b
+#define PESDR1_HSSL2SET1	0x034c
+#define PESDR1_HSSL2SET2	0x034d
+#define PESDR1_HSSL2STS		0x034e
+#define PESDR1_HSSL3SET1	0x034f
+#define PESDR1_HSSL3SET2	0x0350
+#define PESDR1_HSSL3STS		0x0351
+#define PESDR1_HSSCTLSET	0x0352
+#define PESDR1_LANE_ABCD	0x0353
+
+#define PESDR2_UTLSET1		0x0370
+#define PESDR2_UTLSET2		0x0371
+#define PESDR2_DLPSET		0x0372
+#define PESDR2_LOOP		0x0373
+#define PESDR2_RCSSET		0x0374
+#define PESDR2_RCSSTS		0x0375
+#define PESDR2_HSSL0SET1	0x0376
+#define PESDR2_HSSL0SET2	0x0377
+#define PESDR2_HSSL0STS		0x0378
+#define PESDR2_HSSL1SET1	0x0379
+#define PESDR2_HSSL1SET2	0x037a
+#define PESDR2_HSSL1STS		0x037b
+#define PESDR2_HSSL2SET1	0x037c
+#define PESDR2_HSSL2SET2	0x037d
+#define PESDR2_HSSL2STS		0x037e
+#define PESDR2_HSSL3SET1	0x037f
+#define PESDR2_HSSL3SET2	0x0380
+#define PESDR2_HSSL3STS		0x0381
+#define PESDR2_HSSCTLSET	0x0382
+#define PESDR2_LANE_ABCD	0x0383
+
+/*
+ * UTL register offsets
+ */
+#define PEUTL_PBBSZ		0x20
+#define PEUTL_OPDBSZ		0x68
+#define PEUTL_IPHBSZ		0x70
+#define PEUTL_IPDBSZ		0x78
+#define PEUTL_OUTTR		0x90
+#define PEUTL_INTR		0x98
+#define PEUTL_PCTL		0xa0
+#define PEUTL_RCIRQEN		0xb8
+
+/*
+ * Config space register offsets
+ */
+#define PECFG_BAR0LMPA		0x210
+#define PECFG_BAR0HMPA		0x214
+#define PECFG_PIMEN		0x33c
+#define PECFG_PIM0LAL		0x340
+#define PECFG_PIM0LAH		0x344
+#define PECFG_POM0LAL		0x380
+#define PECFG_POM0LAH		0x384
+
+int ppc440spe_init_pcie(void);
+int ppc440spe_init_pcie_rootport(int port);
+void ppc440spe_setup_pcie(struct pci_controller *hose, int port);
+
+#endif /* __PPC_SYSLIB_PPC440SPE_PCIE_H */
diff --git a/arch/ppc/syslib/ppc4xx_pic.c b/arch/ppc/syslib/ppc4xx_pic.c
index 0b43563..aa41651 100644
--- a/arch/ppc/syslib/ppc4xx_pic.c
+++ b/arch/ppc/syslib/ppc4xx_pic.c
@@ -38,6 +38,7 @@
 #define IRQ_MASK_UICx(irq)		(1 << (31 - ((irq) & 0x1f)))
 #define IRQ_MASK_UIC1(irq)		IRQ_MASK_UICx(irq)
 #define IRQ_MASK_UIC2(irq)		IRQ_MASK_UICx(irq)
+#define IRQ_MASK_UIC3(irq)		IRQ_MASK_UICx(irq)
 
 #define UIC_HANDLERS(n)							\
 static void ppc4xx_uic##n##_enable(unsigned int irq)			\
@@ -88,7 +89,38 @@
 	.end 		= ppc4xx_uic##n##_end,				\
 }									\
 
-#if NR_UICS == 3
+#if NR_UICS == 4
+#define ACK_UIC0_PARENT
+#define ACK_UIC1_PARENT	mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC1NC);
+#define ACK_UIC2_PARENT	mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC2NC);
+#define ACK_UIC3_PARENT	mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC3NC);
+UIC_HANDLERS(0);
+UIC_HANDLERS(1);
+UIC_HANDLERS(2);
+UIC_HANDLERS(3);
+
+static int ppc4xx_pic_get_irq(struct pt_regs *regs)
+{
+	u32 uic0 = mfdcr(DCRN_UIC_MSR(UIC0));
+	if (uic0 & UIC0_UIC1NC)
+		return 64 - ffs(mfdcr(DCRN_UIC_MSR(UIC1)));
+	else if (uic0 & UIC0_UIC2NC)
+		return 96 - ffs(mfdcr(DCRN_UIC_MSR(UIC2)));
+	else if (uic0 & UIC0_UIC3NC)
+		return 128 - ffs(mfdcr(DCRN_UIC_MSR(UIC3)));
+	else
+		return uic0 ? 32 - ffs(uic0) : -1;
+}
+
+static void __init ppc4xx_pic_impl_init(void)
+{
+	/* Enable cascade interrupts in UIC0 */
+	ppc_cached_irq_mask[0] |= UIC0_UIC1NC | UIC0_UIC2NC | UIC0_UIC3NC;
+	mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC1NC | UIC0_UIC2NC | UIC0_UIC3NC);
+	mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[0]);
+}
+
+#elif NR_UICS == 3
 #define ACK_UIC0_PARENT	mtdcr(DCRN_UIC_SR(UICB), UICB_UIC0NC);
 #define ACK_UIC1_PARENT	mtdcr(DCRN_UIC_SR(UICB), UICB_UIC1NC);
 #define ACK_UIC2_PARENT	mtdcr(DCRN_UIC_SR(UICB), UICB_UIC2NC);
@@ -170,6 +202,9 @@
 	{ .decl = DECLARE_UIC(1), .base = UIC1 },
 #if NR_UICS > 2
 	{ .decl = DECLARE_UIC(2), .base = UIC2 },
+#if NR_UICS > 3
+	{ .decl = DECLARE_UIC(3), .base = UIC3 },
+#endif
 #endif
 #endif
 };
diff --git a/arch/ppc/syslib/ppc85xx_rio.c b/arch/ppc/syslib/ppc85xx_rio.c
new file mode 100644
index 0000000..297f3b5
--- /dev/null
+++ b/arch/ppc/syslib/ppc85xx_rio.c
@@ -0,0 +1,938 @@
+/*
+ * MPC85xx RapidIO support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/rio.h>
+#include <linux/rio_drv.h>
+
+#include <asm/io.h>
+
+#define RIO_REGS_BASE		(CCSRBAR + 0xc0000)
+#define RIO_ATMU_REGS_OFFSET	0x10c00
+#define RIO_MSG_REGS_OFFSET	0x11000
+#define RIO_MAINT_WIN_SIZE	0x400000
+#define RIO_DBELL_WIN_SIZE	0x1000
+
+#define RIO_MSG_OMR_MUI		0x00000002
+#define RIO_MSG_OSR_TE		0x00000080
+#define RIO_MSG_OSR_QOI		0x00000020
+#define RIO_MSG_OSR_QFI		0x00000010
+#define RIO_MSG_OSR_MUB		0x00000004
+#define RIO_MSG_OSR_EOMI	0x00000002
+#define RIO_MSG_OSR_QEI		0x00000001
+
+#define RIO_MSG_IMR_MI		0x00000002
+#define RIO_MSG_ISR_TE		0x00000080
+#define RIO_MSG_ISR_QFI		0x00000010
+#define RIO_MSG_ISR_DIQI	0x00000001
+
+#define RIO_MSG_DESC_SIZE	32
+#define RIO_MSG_BUFFER_SIZE	4096
+#define RIO_MIN_TX_RING_SIZE	2
+#define RIO_MAX_TX_RING_SIZE	2048
+#define RIO_MIN_RX_RING_SIZE	2
+#define RIO_MAX_RX_RING_SIZE	2048
+
+#define DOORBELL_DMR_DI		0x00000002
+#define DOORBELL_DSR_TE		0x00000080
+#define DOORBELL_DSR_QFI	0x00000010
+#define DOORBELL_DSR_DIQI	0x00000001
+#define DOORBELL_TID_OFFSET	0x03
+#define DOORBELL_SID_OFFSET	0x05
+#define DOORBELL_INFO_OFFSET	0x06
+
+#define DOORBELL_MESSAGE_SIZE	0x08
+#define DBELL_SID(x)		(*(u8 *)(x + DOORBELL_SID_OFFSET))
+#define DBELL_TID(x)		(*(u8 *)(x + DOORBELL_TID_OFFSET))
+#define DBELL_INF(x)		(*(u16 *)(x + DOORBELL_INFO_OFFSET))
+
+#define is_power_of_2(x)	(((x) & ((x) - 1)) == 0)
+
+struct rio_atmu_regs {
+	u32 rowtar;
+	u32 pad1;
+	u32 rowbar;
+	u32 pad2;
+	u32 rowar;
+	u32 pad3[3];
+};
+
+struct rio_msg_regs {
+	u32 omr;
+	u32 osr;
+	u32 pad1;
+	u32 odqdpar;
+	u32 pad2;
+	u32 osar;
+	u32 odpr;
+	u32 odatr;
+	u32 odcr;
+	u32 pad3;
+	u32 odqepar;
+	u32 pad4[13];
+	u32 imr;
+	u32 isr;
+	u32 pad5;
+	u32 ifqdpar;
+	u32 pad6;
+	u32 ifqepar;
+	u32 pad7[250];
+	u32 dmr;
+	u32 dsr;
+	u32 pad8;
+	u32 dqdpar;
+	u32 pad9;
+	u32 dqepar;
+	u32 pad10[26];
+	u32 pwmr;
+	u32 pwsr;
+	u32 pad11;
+	u32 pwqbar;
+};
+
+struct rio_tx_desc {
+	u32 res1;
+	u32 saddr;
+	u32 dport;
+	u32 dattr;
+	u32 res2;
+	u32 res3;
+	u32 dwcnt;
+	u32 res4;
+};
+
+static u32 regs_win;
+static struct rio_atmu_regs *atmu_regs;
+static struct rio_atmu_regs *maint_atmu_regs;
+static struct rio_atmu_regs *dbell_atmu_regs;
+static u32 dbell_win;
+static u32 maint_win;
+static struct rio_msg_regs *msg_regs;
+
+static struct rio_dbell_ring {
+	void *virt;
+	dma_addr_t phys;
+} dbell_ring;
+
+static struct rio_msg_tx_ring {
+	void *virt;
+	dma_addr_t phys;
+	void *virt_buffer[RIO_MAX_TX_RING_SIZE];
+	dma_addr_t phys_buffer[RIO_MAX_TX_RING_SIZE];
+	int tx_slot;
+	int size;
+	void *dev_id;
+} msg_tx_ring;
+
+static struct rio_msg_rx_ring {
+	void *virt;
+	dma_addr_t phys;
+	void *virt_buffer[RIO_MAX_RX_RING_SIZE];
+	int rx_slot;
+	int size;
+	void *dev_id;
+} msg_rx_ring;
+
+/**
+ * mpc85xx_rio_doorbell_send - Send a MPC85xx doorbell message
+ * @index: ID of RapidIO interface
+ * @destid: Destination ID of target device
+ * @data: 16-bit info field of RapidIO doorbell message
+ *
+ * Sends a MPC85xx doorbell message. Returns %0 on success or
+ * %-EINVAL on failure.
+ */
+static int mpc85xx_rio_doorbell_send(int index, u16 destid, u16 data)
+{
+	pr_debug("mpc85xx_doorbell_send: index %d destid %4.4x data %4.4x\n",
+		 index, destid, data);
+	out_be32((void *)&dbell_atmu_regs->rowtar, destid << 22);
+	out_be16((void *)(dbell_win), data);
+
+	return 0;
+}
+
+/**
+ * mpc85xx_local_config_read - Generate a MPC85xx local config space read
+ * @index: ID of RapdiIO interface
+ * @offset: Offset into configuration space
+ * @len: Length (in bytes) of the maintenance transaction
+ * @data: Value to be read into
+ *
+ * Generates a MPC85xx local configuration space read. Returns %0 on
+ * success or %-EINVAL on failure.
+ */
+static int mpc85xx_local_config_read(int index, u32 offset, int len, u32 * data)
+{
+	pr_debug("mpc85xx_local_config_read: index %d offset %8.8x\n", index,
+		 offset);
+	*data = in_be32((void *)(regs_win + offset));
+
+	return 0;
+}
+
+/**
+ * mpc85xx_local_config_write - Generate a MPC85xx local config space write
+ * @index: ID of RapdiIO interface
+ * @offset: Offset into configuration space
+ * @len: Length (in bytes) of the maintenance transaction
+ * @data: Value to be written
+ *
+ * Generates a MPC85xx local configuration space write. Returns %0 on
+ * success or %-EINVAL on failure.
+ */
+static int mpc85xx_local_config_write(int index, u32 offset, int len, u32 data)
+{
+	pr_debug
+	    ("mpc85xx_local_config_write: index %d offset %8.8x data %8.8x\n",
+	     index, offset, data);
+	out_be32((void *)(regs_win + offset), data);
+
+	return 0;
+}
+
+/**
+ * mpc85xx_rio_config_read - Generate a MPC85xx read maintenance transaction
+ * @index: ID of RapdiIO interface
+ * @destid: Destination ID of transaction
+ * @hopcount: Number of hops to target device
+ * @offset: Offset into configuration space
+ * @len: Length (in bytes) of the maintenance transaction
+ * @val: Location to be read into
+ *
+ * Generates a MPC85xx read maintenance transaction. Returns %0 on
+ * success or %-EINVAL on failure.
+ */
+static int
+mpc85xx_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len,
+			u32 * val)
+{
+	u8 *data;
+
+	pr_debug
+	    ("mpc85xx_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n",
+	     index, destid, hopcount, offset, len);
+	out_be32((void *)&maint_atmu_regs->rowtar,
+		 (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
+
+	data = (u8 *) maint_win + offset;
+	switch (len) {
+	case 1:
+		*val = in_8((u8 *) data);
+		break;
+	case 2:
+		*val = in_be16((u16 *) data);
+		break;
+	default:
+		*val = in_be32((u32 *) data);
+		break;
+	}
+
+	return 0;
+}
+
+/**
+ * mpc85xx_rio_config_write - Generate a MPC85xx write maintenance transaction
+ * @index: ID of RapdiIO interface
+ * @destid: Destination ID of transaction
+ * @hopcount: Number of hops to target device
+ * @offset: Offset into configuration space
+ * @len: Length (in bytes) of the maintenance transaction
+ * @val: Value to be written
+ *
+ * Generates an MPC85xx write maintenance transaction. Returns %0 on
+ * success or %-EINVAL on failure.
+ */
+static int
+mpc85xx_rio_config_write(int index, u16 destid, u8 hopcount, u32 offset,
+			 int len, u32 val)
+{
+	u8 *data;
+	pr_debug
+	    ("mpc85xx_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n",
+	     index, destid, hopcount, offset, len, val);
+	out_be32((void *)&maint_atmu_regs->rowtar,
+		 (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
+
+	data = (u8 *) maint_win + offset;
+	switch (len) {
+	case 1:
+		out_8((u8 *) data, val);
+		break;
+	case 2:
+		out_be16((u16 *) data, val);
+		break;
+	default:
+		out_be32((u32 *) data, val);
+		break;
+	}
+
+	return 0;
+}
+
+/**
+ * rio_hw_add_outb_message - Add message to the MPC85xx outbound message queue
+ * @mport: Master port with outbound message queue
+ * @rdev: Target of outbound message
+ * @mbox: Outbound mailbox
+ * @buffer: Message to add to outbound queue
+ * @len: Length of message
+ *
+ * Adds the @buffer message to the MPC85xx outbound message queue. Returns
+ * %0 on success or %-EINVAL on failure.
+ */
+int
+rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
+			void *buffer, size_t len)
+{
+	u32 omr;
+	struct rio_tx_desc *desc =
+	    (struct rio_tx_desc *)msg_tx_ring.virt + msg_tx_ring.tx_slot;
+	int ret = 0;
+
+	pr_debug
+	    ("RIO: rio_hw_add_outb_message(): destid %4.4x mbox %d buffer %8.8x len %8.8x\n",
+	     rdev->destid, mbox, (int)buffer, len);
+
+	if ((len < 8) || (len > RIO_MAX_MSG_SIZE)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* Copy and clear rest of buffer */
+	memcpy(msg_tx_ring.virt_buffer[msg_tx_ring.tx_slot], buffer, len);
+	if (len < (RIO_MAX_MSG_SIZE - 4))
+		memset((void *)((u32) msg_tx_ring.
+				virt_buffer[msg_tx_ring.tx_slot] + len), 0,
+		       RIO_MAX_MSG_SIZE - len);
+
+	/* Set mbox field for message */
+	desc->dport = mbox & 0x3;
+
+	/* Enable EOMI interrupt, set priority, and set destid */
+	desc->dattr = 0x28000000 | (rdev->destid << 2);
+
+	/* Set transfer size aligned to next power of 2 (in double words) */
+	desc->dwcnt = is_power_of_2(len) ? len : 1 << get_bitmask_order(len);
+
+	/* Set snooping and source buffer address */
+	desc->saddr = 0x00000004 | msg_tx_ring.phys_buffer[msg_tx_ring.tx_slot];
+
+	/* Increment enqueue pointer */
+	omr = in_be32((void *)&msg_regs->omr);
+	out_be32((void *)&msg_regs->omr, omr | RIO_MSG_OMR_MUI);
+
+	/* Go to next descriptor */
+	if (++msg_tx_ring.tx_slot == msg_tx_ring.size)
+		msg_tx_ring.tx_slot = 0;
+
+      out:
+	return ret;
+}
+
+EXPORT_SYMBOL_GPL(rio_hw_add_outb_message);
+
+/**
+ * mpc85xx_rio_tx_handler - MPC85xx outbound message interrupt handler
+ * @irq: Linux interrupt number
+ * @dev_instance: Pointer to interrupt-specific data
+ * @regs: Register context
+ *
+ * Handles outbound message interrupts. Executes a register outbound
+ * mailbox event handler and acks the interrupt occurence.
+ */
+static irqreturn_t
+mpc85xx_rio_tx_handler(int irq, void *dev_instance, struct pt_regs *regs)
+{
+	int osr;
+	struct rio_mport *port = (struct rio_mport *)dev_instance;
+
+	osr = in_be32((void *)&msg_regs->osr);
+
+	if (osr & RIO_MSG_OSR_TE) {
+		pr_info("RIO: outbound message transmission error\n");
+		out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_TE);
+		goto out;
+	}
+
+	if (osr & RIO_MSG_OSR_QOI) {
+		pr_info("RIO: outbound message queue overflow\n");
+		out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_QOI);
+		goto out;
+	}
+
+	if (osr & RIO_MSG_OSR_EOMI) {
+		u32 dqp = in_be32((void *)&msg_regs->odqdpar);
+		int slot = (dqp - msg_tx_ring.phys) >> 5;
+		port->outb_msg[0].mcback(port, msg_tx_ring.dev_id, -1, slot);
+
+		/* Ack the end-of-message interrupt */
+		out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_EOMI);
+	}
+
+      out:
+	return IRQ_HANDLED;
+}
+
+/**
+ * rio_open_outb_mbox - Initialize MPC85xx outbound mailbox
+ * @mport: Master port implementing the outbound message unit
+ * @dev_id: Device specific pointer to pass on event
+ * @mbox: Mailbox to open
+ * @entries: Number of entries in the outbound mailbox ring
+ *
+ * Initializes buffer ring, request the outbound message interrupt,
+ * and enables the outbound message unit. Returns %0 on success and
+ * %-EINVAL or %-ENOMEM on failure.
+ */
+int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
+{
+	int i, j, rc = 0;
+
+	if ((entries < RIO_MIN_TX_RING_SIZE) ||
+	    (entries > RIO_MAX_TX_RING_SIZE) || (!is_power_of_2(entries))) {
+		rc = -EINVAL;
+		goto out;
+	}
+
+	/* Initialize shadow copy ring */
+	msg_tx_ring.dev_id = dev_id;
+	msg_tx_ring.size = entries;
+
+	for (i = 0; i < msg_tx_ring.size; i++) {
+		if (!
+		    (msg_tx_ring.virt_buffer[i] =
+		     dma_alloc_coherent(NULL, RIO_MSG_BUFFER_SIZE,
+					&msg_tx_ring.phys_buffer[i],
+					GFP_KERNEL))) {
+			rc = -ENOMEM;
+			for (j = 0; j < msg_tx_ring.size; j++)
+				if (msg_tx_ring.virt_buffer[j])
+					dma_free_coherent(NULL,
+							  RIO_MSG_BUFFER_SIZE,
+							  msg_tx_ring.
+							  virt_buffer[j],
+							  msg_tx_ring.
+							  phys_buffer[j]);
+			goto out;
+		}
+	}
+
+	/* Initialize outbound message descriptor ring */
+	if (!(msg_tx_ring.virt = dma_alloc_coherent(NULL,
+						    msg_tx_ring.size *
+						    RIO_MSG_DESC_SIZE,
+						    &msg_tx_ring.phys,
+						    GFP_KERNEL))) {
+		rc = -ENOMEM;
+		goto out_dma;
+	}
+	memset(msg_tx_ring.virt, 0, msg_tx_ring.size * RIO_MSG_DESC_SIZE);
+	msg_tx_ring.tx_slot = 0;
+
+	/* Point dequeue/enqueue pointers at first entry in ring */
+	out_be32((void *)&msg_regs->odqdpar, msg_tx_ring.phys);
+	out_be32((void *)&msg_regs->odqepar, msg_tx_ring.phys);
+
+	/* Configure for snooping */
+	out_be32((void *)&msg_regs->osar, 0x00000004);
+
+	/* Clear interrupt status */
+	out_be32((void *)&msg_regs->osr, 0x000000b3);
+
+	/* Hook up outbound message handler */
+	if ((rc =
+	     request_irq(MPC85xx_IRQ_RIO_TX, mpc85xx_rio_tx_handler, 0,
+			 "msg_tx", (void *)mport)) < 0)
+		goto out_irq;
+
+	/*
+	 * Configure outbound message unit
+	 *      Snooping
+	 *      Interrupts (all enabled, except QEIE)
+	 *      Chaining mode
+	 *      Disable
+	 */
+	out_be32((void *)&msg_regs->omr, 0x00100220);
+
+	/* Set number of entries */
+	out_be32((void *)&msg_regs->omr,
+		 in_be32((void *)&msg_regs->omr) |
+		 ((get_bitmask_order(entries) - 2) << 12));
+
+	/* Now enable the unit */
+	out_be32((void *)&msg_regs->omr, in_be32((void *)&msg_regs->omr) | 0x1);
+
+      out:
+	return rc;
+
+      out_irq:
+	dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE,
+			  msg_tx_ring.virt, msg_tx_ring.phys);
+
+      out_dma:
+	for (i = 0; i < msg_tx_ring.size; i++)
+		dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
+				  msg_tx_ring.virt_buffer[i],
+				  msg_tx_ring.phys_buffer[i]);
+
+	return rc;
+}
+
+/**
+ * rio_close_outb_mbox - Shut down MPC85xx outbound mailbox
+ * @mport: Master port implementing the outbound message unit
+ * @mbox: Mailbox to close
+ *
+ * Disables the outbound message unit, free all buffers, and
+ * frees the outbound message interrupt.
+ */
+void rio_close_outb_mbox(struct rio_mport *mport, int mbox)
+{
+	/* Disable inbound message unit */
+	out_be32((void *)&msg_regs->omr, 0);
+
+	/* Free ring */
+	dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE,
+			  msg_tx_ring.virt, msg_tx_ring.phys);
+
+	/* Free interrupt */
+	free_irq(MPC85xx_IRQ_RIO_TX, (void *)mport);
+}
+
+/**
+ * mpc85xx_rio_rx_handler - MPC85xx inbound message interrupt handler
+ * @irq: Linux interrupt number
+ * @dev_instance: Pointer to interrupt-specific data
+ * @regs: Register context
+ *
+ * Handles inbound message interrupts. Executes a registered inbound
+ * mailbox event handler and acks the interrupt occurence.
+ */
+static irqreturn_t
+mpc85xx_rio_rx_handler(int irq, void *dev_instance, struct pt_regs *regs)
+{
+	int isr;
+	struct rio_mport *port = (struct rio_mport *)dev_instance;
+
+	isr = in_be32((void *)&msg_regs->isr);
+
+	if (isr & RIO_MSG_ISR_TE) {
+		pr_info("RIO: inbound message reception error\n");
+		out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_TE);
+		goto out;
+	}
+
+	/* XXX Need to check/dispatch until queue empty */
+	if (isr & RIO_MSG_ISR_DIQI) {
+		/*
+		 * We implement *only* mailbox 0, but can receive messages
+		 * for any mailbox/letter to that mailbox destination. So,
+		 * make the callback with an unknown/invalid mailbox number
+		 * argument.
+		 */
+		port->inb_msg[0].mcback(port, msg_rx_ring.dev_id, -1, -1);
+
+		/* Ack the queueing interrupt */
+		out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_DIQI);
+	}
+
+      out:
+	return IRQ_HANDLED;
+}
+
+/**
+ * rio_open_inb_mbox - Initialize MPC85xx inbound mailbox
+ * @mport: Master port implementing the inbound message unit
+ * @dev_id: Device specific pointer to pass on event
+ * @mbox: Mailbox to open
+ * @entries: Number of entries in the inbound mailbox ring
+ *
+ * Initializes buffer ring, request the inbound message interrupt,
+ * and enables the inbound message unit. Returns %0 on success
+ * and %-EINVAL or %-ENOMEM on failure.
+ */
+int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
+{
+	int i, rc = 0;
+
+	if ((entries < RIO_MIN_RX_RING_SIZE) ||
+	    (entries > RIO_MAX_RX_RING_SIZE) || (!is_power_of_2(entries))) {
+		rc = -EINVAL;
+		goto out;
+	}
+
+	/* Initialize client buffer ring */
+	msg_rx_ring.dev_id = dev_id;
+	msg_rx_ring.size = entries;
+	msg_rx_ring.rx_slot = 0;
+	for (i = 0; i < msg_rx_ring.size; i++)
+		msg_rx_ring.virt_buffer[i] = NULL;
+
+	/* Initialize inbound message ring */
+	if (!(msg_rx_ring.virt = dma_alloc_coherent(NULL,
+						    msg_rx_ring.size *
+						    RIO_MAX_MSG_SIZE,
+						    &msg_rx_ring.phys,
+						    GFP_KERNEL))) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	/* Point dequeue/enqueue pointers at first entry in ring */
+	out_be32((void *)&msg_regs->ifqdpar, (u32) msg_rx_ring.phys);
+	out_be32((void *)&msg_regs->ifqepar, (u32) msg_rx_ring.phys);
+
+	/* Clear interrupt status */
+	out_be32((void *)&msg_regs->isr, 0x00000091);
+
+	/* Hook up inbound message handler */
+	if ((rc =
+	     request_irq(MPC85xx_IRQ_RIO_RX, mpc85xx_rio_rx_handler, 0,
+			 "msg_rx", (void *)mport)) < 0) {
+		dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
+				  msg_tx_ring.virt_buffer[i],
+				  msg_tx_ring.phys_buffer[i]);
+		goto out;
+	}
+
+	/*
+	 * Configure inbound message unit:
+	 *      Snooping
+	 *      4KB max message size
+	 *      Unmask all interrupt sources
+	 *      Disable
+	 */
+	out_be32((void *)&msg_regs->imr, 0x001b0060);
+
+	/* Set number of queue entries */
+	out_be32((void *)&msg_regs->imr,
+		 in_be32((void *)&msg_regs->imr) |
+		 ((get_bitmask_order(entries) - 2) << 12));
+
+	/* Now enable the unit */
+	out_be32((void *)&msg_regs->imr, in_be32((void *)&msg_regs->imr) | 0x1);
+
+      out:
+	return rc;
+}
+
+/**
+ * rio_close_inb_mbox - Shut down MPC85xx inbound mailbox
+ * @mport: Master port implementing the inbound message unit
+ * @mbox: Mailbox to close
+ *
+ * Disables the inbound message unit, free all buffers, and
+ * frees the inbound message interrupt.
+ */
+void rio_close_inb_mbox(struct rio_mport *mport, int mbox)
+{
+	/* Disable inbound message unit */
+	out_be32((void *)&msg_regs->imr, 0);
+
+	/* Free ring */
+	dma_free_coherent(NULL, msg_rx_ring.size * RIO_MAX_MSG_SIZE,
+			  msg_rx_ring.virt, msg_rx_ring.phys);
+
+	/* Free interrupt */
+	free_irq(MPC85xx_IRQ_RIO_RX, (void *)mport);
+}
+
+/**
+ * rio_hw_add_inb_buffer - Add buffer to the MPC85xx inbound message queue
+ * @mport: Master port implementing the inbound message unit
+ * @mbox: Inbound mailbox number
+ * @buf: Buffer to add to inbound queue
+ *
+ * Adds the @buf buffer to the MPC85xx inbound message queue. Returns
+ * %0 on success or %-EINVAL on failure.
+ */
+int rio_hw_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf)
+{
+	int rc = 0;
+
+	pr_debug("RIO: rio_hw_add_inb_buffer(), msg_rx_ring.rx_slot %d\n",
+		 msg_rx_ring.rx_slot);
+
+	if (msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot]) {
+		printk(KERN_ERR
+		       "RIO: error adding inbound buffer %d, buffer exists\n",
+		       msg_rx_ring.rx_slot);
+		rc = -EINVAL;
+		goto out;
+	}
+
+	msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot] = buf;
+	if (++msg_rx_ring.rx_slot == msg_rx_ring.size)
+		msg_rx_ring.rx_slot = 0;
+
+      out:
+	return rc;
+}
+
+EXPORT_SYMBOL_GPL(rio_hw_add_inb_buffer);
+
+/**
+ * rio_hw_get_inb_message - Fetch inbound message from the MPC85xx message unit
+ * @mport: Master port implementing the inbound message unit
+ * @mbox: Inbound mailbox number
+ *
+ * Gets the next available inbound message from the inbound message queue.
+ * A pointer to the message is returned on success or NULL on failure.
+ */
+void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox)
+{
+	u32 imr;
+	u32 phys_buf, virt_buf;
+	void *buf = NULL;
+	int buf_idx;
+
+	phys_buf = in_be32((void *)&msg_regs->ifqdpar);
+
+	/* If no more messages, then bail out */
+	if (phys_buf == in_be32((void *)&msg_regs->ifqepar))
+		goto out2;
+
+	virt_buf = (u32) msg_rx_ring.virt + (phys_buf - msg_rx_ring.phys);
+	buf_idx = (phys_buf - msg_rx_ring.phys) / RIO_MAX_MSG_SIZE;
+	buf = msg_rx_ring.virt_buffer[buf_idx];
+
+	if (!buf) {
+		printk(KERN_ERR
+		       "RIO: inbound message copy failed, no buffers\n");
+		goto out1;
+	}
+
+	/* Copy max message size, caller is expected to allocate that big */
+	memcpy(buf, (void *)virt_buf, RIO_MAX_MSG_SIZE);
+
+	/* Clear the available buffer */
+	msg_rx_ring.virt_buffer[buf_idx] = NULL;
+
+      out1:
+	imr = in_be32((void *)&msg_regs->imr);
+	out_be32((void *)&msg_regs->imr, imr | RIO_MSG_IMR_MI);
+
+      out2:
+	return buf;
+}
+
+EXPORT_SYMBOL_GPL(rio_hw_get_inb_message);
+
+/**
+ * mpc85xx_rio_dbell_handler - MPC85xx doorbell interrupt handler
+ * @irq: Linux interrupt number
+ * @dev_instance: Pointer to interrupt-specific data
+ * @regs: Register context
+ *
+ * Handles doorbell interrupts. Parses a list of registered
+ * doorbell event handlers and executes a matching event handler.
+ */
+static irqreturn_t
+mpc85xx_rio_dbell_handler(int irq, void *dev_instance, struct pt_regs *regs)
+{
+	int dsr;
+	struct rio_mport *port = (struct rio_mport *)dev_instance;
+
+	dsr = in_be32((void *)&msg_regs->dsr);
+
+	if (dsr & DOORBELL_DSR_TE) {
+		pr_info("RIO: doorbell reception error\n");
+		out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_TE);
+		goto out;
+	}
+
+	if (dsr & DOORBELL_DSR_QFI) {
+		pr_info("RIO: doorbell queue full\n");
+		out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_QFI);
+		goto out;
+	}
+
+	/* XXX Need to check/dispatch until queue empty */
+	if (dsr & DOORBELL_DSR_DIQI) {
+		u32 dmsg =
+		    (u32) dbell_ring.virt +
+		    (in_be32((void *)&msg_regs->dqdpar) & 0xfff);
+		u32 dmr;
+		struct rio_dbell *dbell;
+		int found = 0;
+
+		pr_debug
+		    ("RIO: processing doorbell, sid %2.2x tid %2.2x info %4.4x\n",
+		     DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg));
+
+		list_for_each_entry(dbell, &port->dbells, node) {
+			if ((dbell->res->start <= DBELL_INF(dmsg)) &&
+			    (dbell->res->end >= DBELL_INF(dmsg))) {
+				found = 1;
+				break;
+			}
+		}
+		if (found) {
+			dbell->dinb(port, dbell->dev_id, DBELL_SID(dmsg), DBELL_TID(dmsg),
+				    DBELL_INF(dmsg));
+		} else {
+			pr_debug
+			    ("RIO: spurious doorbell, sid %2.2x tid %2.2x info %4.4x\n",
+			     DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg));
+		}
+		dmr = in_be32((void *)&msg_regs->dmr);
+		out_be32((void *)&msg_regs->dmr, dmr | DOORBELL_DMR_DI);
+		out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_DIQI);
+	}
+
+      out:
+	return IRQ_HANDLED;
+}
+
+/**
+ * mpc85xx_rio_doorbell_init - MPC85xx doorbell interface init
+ * @mport: Master port implementing the inbound doorbell unit
+ *
+ * Initializes doorbell unit hardware and inbound DMA buffer
+ * ring. Called from mpc85xx_rio_setup(). Returns %0 on success
+ * or %-ENOMEM on failure.
+ */
+static int mpc85xx_rio_doorbell_init(struct rio_mport *mport)
+{
+	int rc = 0;
+
+	/* Map outbound doorbell window immediately after maintenance window */
+	if (!(dbell_win =
+	      (u32) ioremap(mport->iores.start + RIO_MAINT_WIN_SIZE,
+			    RIO_DBELL_WIN_SIZE))) {
+		printk(KERN_ERR
+		       "RIO: unable to map outbound doorbell window\n");
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	/* Initialize inbound doorbells */
+	if (!(dbell_ring.virt = dma_alloc_coherent(NULL,
+						   512 * DOORBELL_MESSAGE_SIZE,
+						   &dbell_ring.phys,
+						   GFP_KERNEL))) {
+		printk(KERN_ERR "RIO: unable allocate inbound doorbell ring\n");
+		rc = -ENOMEM;
+		iounmap((void *)dbell_win);
+		goto out;
+	}
+
+	/* Point dequeue/enqueue pointers at first entry in ring */
+	out_be32((void *)&msg_regs->dqdpar, (u32) dbell_ring.phys);
+	out_be32((void *)&msg_regs->dqepar, (u32) dbell_ring.phys);
+
+	/* Clear interrupt status */
+	out_be32((void *)&msg_regs->dsr, 0x00000091);
+
+	/* Hook up doorbell handler */
+	if ((rc =
+	     request_irq(MPC85xx_IRQ_RIO_BELL, mpc85xx_rio_dbell_handler, 0,
+			 "dbell_rx", (void *)mport) < 0)) {
+		iounmap((void *)dbell_win);
+		dma_free_coherent(NULL, 512 * DOORBELL_MESSAGE_SIZE,
+				  dbell_ring.virt, dbell_ring.phys);
+		printk(KERN_ERR
+		       "MPC85xx RIO: unable to request inbound doorbell irq");
+		goto out;
+	}
+
+	/* Configure doorbells for snooping, 512 entries, and enable */
+	out_be32((void *)&msg_regs->dmr, 0x00108161);
+
+      out:
+	return rc;
+}
+
+static char *cmdline = NULL;
+
+static int mpc85xx_rio_get_hdid(int index)
+{
+	/* XXX Need to parse multiple entries in some format */
+	if (!cmdline)
+		return -1;
+
+	return simple_strtol(cmdline, NULL, 0);
+}
+
+static int mpc85xx_rio_get_cmdline(char *s)
+{
+	if (!s)
+		return 0;
+
+	cmdline = s;
+	return 1;
+}
+
+__setup("riohdid=", mpc85xx_rio_get_cmdline);
+
+/**
+ * mpc85xx_rio_setup - Setup MPC85xx RapidIO interface
+ * @law_start: Starting physical address of RapidIO LAW
+ * @law_size: Size of RapidIO LAW
+ *
+ * Initializes MPC85xx RapidIO hardware interface, configures
+ * master port with system-specific info, and registers the
+ * master port with the RapidIO subsystem.
+ */
+void mpc85xx_rio_setup(int law_start, int law_size)
+{
+	struct rio_ops *ops;
+	struct rio_mport *port;
+
+	ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL);
+	ops->lcread = mpc85xx_local_config_read;
+	ops->lcwrite = mpc85xx_local_config_write;
+	ops->cread = mpc85xx_rio_config_read;
+	ops->cwrite = mpc85xx_rio_config_write;
+	ops->dsend = mpc85xx_rio_doorbell_send;
+
+	port = kmalloc(sizeof(struct rio_mport), GFP_KERNEL);
+	port->id = 0;
+	port->index = 0;
+	INIT_LIST_HEAD(&port->dbells);
+	port->iores.start = law_start;
+	port->iores.end = law_start + law_size;
+	port->iores.flags = IORESOURCE_MEM;
+
+	rio_init_dbell_res(&port->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff);
+	rio_init_mbox_res(&port->riores[RIO_INB_MBOX_RESOURCE], 0, 0);
+	rio_init_mbox_res(&port->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0);
+	strcpy(port->name, "RIO0 mport");
+
+	port->ops = ops;
+	port->host_deviceid = mpc85xx_rio_get_hdid(port->id);
+
+	rio_register_mport(port);
+
+	regs_win = (u32) ioremap(RIO_REGS_BASE, 0x20000);
+	atmu_regs = (struct rio_atmu_regs *)(regs_win + RIO_ATMU_REGS_OFFSET);
+	maint_atmu_regs = atmu_regs + 1;
+	dbell_atmu_regs = atmu_regs + 2;
+	msg_regs = (struct rio_msg_regs *)(regs_win + RIO_MSG_REGS_OFFSET);
+
+	/* Configure maintenance transaction window */
+	out_be32((void *)&maint_atmu_regs->rowbar, 0x000c0000);
+	out_be32((void *)&maint_atmu_regs->rowar, 0x80077015);
+
+	maint_win = (u32) ioremap(law_start, RIO_MAINT_WIN_SIZE);
+
+	/* Configure outbound doorbell window */
+	out_be32((void *)&dbell_atmu_regs->rowbar, 0x000c0400);
+	out_be32((void *)&dbell_atmu_regs->rowar, 0x8004200b);
+	mpc85xx_rio_doorbell_init(port);
+}
diff --git a/arch/ppc/syslib/ppc85xx_rio.h b/arch/ppc/syslib/ppc85xx_rio.h
new file mode 100644
index 0000000..c0827a2
--- /dev/null
+++ b/arch/ppc/syslib/ppc85xx_rio.h
@@ -0,0 +1,21 @@
+/*
+ * MPC85xx RapidIO definitions
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __PPC_SYSLIB_PPC85XX_RIO_H
+#define __PPC_SYSLIB_PPC85XX_RIO_H
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+extern void mpc85xx_rio_setup(int law_start, int law_size);
+
+#endif				/* __PPC_SYSLIB_PPC85XX_RIO_H */
diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c
index 62ee86e..603f011 100644
--- a/arch/ppc/syslib/ppc_sys.c
+++ b/arch/ppc/syslib/ppc_sys.c
@@ -14,6 +14,7 @@
  * option) any later version.
  */
 
+#include <linux/string.h>
 #include <asm/ppc_sys.h>
 
 int (*ppc_sys_device_fixup) (struct platform_device * pdev);
diff --git a/arch/ppc/syslib/prom.c b/arch/ppc/syslib/prom.c
index 278da6e..1b9aa0d 100644
--- a/arch/ppc/syslib/prom.c
+++ b/arch/ppc/syslib/prom.c
@@ -1335,10 +1335,8 @@
 	if (!res)
 		return -ENODEV;
 
-	if (res->name) {
-		kfree(res->name);
-		res->name = NULL;
-	}
+	kfree(res->name);
+	res->name = NULL;
 	release_resource(res);
 	kfree(res);
 
diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c
index c1dc876..e0dde24 100644
--- a/arch/ppc64/boot/main.c
+++ b/arch/ppc64/boot/main.c
@@ -203,8 +203,15 @@
 		if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0)
 			break;
 	}
-	vmlinux.size = (unsigned long)elf64ph->p_filesz;
-	vmlinux.memsize = (unsigned long)elf64ph->p_memsz;
+	vmlinux.size = (unsigned long)elf64ph->p_filesz +
+		(unsigned long)elf64ph->p_offset;
+	/* We need to claim the memsize plus the file offset since gzip
+	 * will expand the header (file offset), then the kernel, then
+	 * possible rubbish we don't care about. But the kernel bss must
+	 * be claimed (it will be zero'd by the kernel itself)
+	 */
+	vmlinux.memsize = (unsigned long)elf64ph->p_memsz +
+		(unsigned long)elf64ph->p_offset;
 	printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize);
 	vmlinux.addr = try_claim(vmlinux.memsize);
 	if (vmlinux.addr == 0) {
diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c
index ed876a5..511af54 100644
--- a/arch/ppc64/kernel/kprobes.c
+++ b/arch/ppc64/kernel/kprobes.c
@@ -30,19 +30,14 @@
 #include <linux/config.h>
 #include <linux/kprobes.h>
 #include <linux/ptrace.h>
-#include <linux/spinlock.h>
 #include <linux/preempt.h>
 #include <asm/cacheflush.h>
 #include <asm/kdebug.h>
 #include <asm/sstep.h>
 
 static DECLARE_MUTEX(kprobe_mutex);
-
-static struct kprobe *current_kprobe;
-static unsigned long kprobe_status, kprobe_saved_msr;
-static struct kprobe *kprobe_prev;
-static unsigned long kprobe_status_prev, kprobe_saved_msr_prev;
-static struct pt_regs jprobe_saved_regs;
+DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
 int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
@@ -108,20 +103,28 @@
 		regs->nip = (unsigned long)p->ainsn.insn;
 }
 
-static inline void save_previous_kprobe(void)
+static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-	kprobe_prev = current_kprobe;
-	kprobe_status_prev = kprobe_status;
-	kprobe_saved_msr_prev = kprobe_saved_msr;
+	kcb->prev_kprobe.kp = kprobe_running();
+	kcb->prev_kprobe.status = kcb->kprobe_status;
+	kcb->prev_kprobe.saved_msr = kcb->kprobe_saved_msr;
 }
 
-static inline void restore_previous_kprobe(void)
+static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-	current_kprobe = kprobe_prev;
-	kprobe_status = kprobe_status_prev;
-	kprobe_saved_msr = kprobe_saved_msr_prev;
+	__get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+	kcb->kprobe_status = kcb->prev_kprobe.status;
+	kcb->kprobe_saved_msr = kcb->prev_kprobe.saved_msr;
 }
 
+static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
+				struct kprobe_ctlblk *kcb)
+{
+	__get_cpu_var(current_kprobe) = p;
+	kcb->kprobe_saved_msr = regs->msr;
+}
+
+/* Called with kretprobe_lock held */
 void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
 				      struct pt_regs *regs)
 {
@@ -145,19 +148,24 @@
 	struct kprobe *p;
 	int ret = 0;
 	unsigned int *addr = (unsigned int *)regs->nip;
+	struct kprobe_ctlblk *kcb;
+
+	/*
+	 * We don't want to be preempted for the entire
+	 * duration of kprobe processing
+	 */
+	preempt_disable();
+	kcb = get_kprobe_ctlblk();
 
 	/* Check we're not actually recursing */
 	if (kprobe_running()) {
-		/* We *are* holding lock here, so this is safe.
-		   Disarm the probe we just hit, and ignore it. */
 		p = get_kprobe(addr);
 		if (p) {
 			kprobe_opcode_t insn = *p->ainsn.insn;
-			if (kprobe_status == KPROBE_HIT_SS &&
+			if (kcb->kprobe_status == KPROBE_HIT_SS &&
 					is_trap(insn)) {
 				regs->msr &= ~MSR_SE;
-				regs->msr |= kprobe_saved_msr;
-				unlock_kprobes();
+				regs->msr |= kcb->kprobe_saved_msr;
 				goto no_kprobe;
 			}
 			/* We have reentered the kprobe_handler(), since
@@ -166,27 +174,24 @@
 			 * just single step on the instruction of the new probe
 			 * without calling any user handlers.
 			 */
-			save_previous_kprobe();
-			current_kprobe = p;
-			kprobe_saved_msr = regs->msr;
+			save_previous_kprobe(kcb);
+			set_current_kprobe(p, regs, kcb);
+			kcb->kprobe_saved_msr = regs->msr;
 			p->nmissed++;
 			prepare_singlestep(p, regs);
-			kprobe_status = KPROBE_REENTER;
+			kcb->kprobe_status = KPROBE_REENTER;
 			return 1;
 		} else {
-			p = current_kprobe;
+			p = __get_cpu_var(current_kprobe);
 			if (p->break_handler && p->break_handler(p, regs)) {
 				goto ss_probe;
 			}
 		}
-		/* If it's not ours, can't be delete race, (we hold lock). */
 		goto no_kprobe;
 	}
 
-	lock_kprobes();
 	p = get_kprobe(addr);
 	if (!p) {
-		unlock_kprobes();
 		if (*addr != BREAKPOINT_INSTRUCTION) {
 			/*
 			 * PowerPC has multiple variants of the "trap"
@@ -209,24 +214,19 @@
 		goto no_kprobe;
 	}
 
-	kprobe_status = KPROBE_HIT_ACTIVE;
-	current_kprobe = p;
-	kprobe_saved_msr = regs->msr;
+	kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+	set_current_kprobe(p, regs, kcb);
 	if (p->pre_handler && p->pre_handler(p, regs))
 		/* handler has already set things up, so skip ss setup */
 		return 1;
 
 ss_probe:
 	prepare_singlestep(p, regs);
-	kprobe_status = KPROBE_HIT_SS;
-	/*
-	 * This preempt_disable() matches the preempt_enable_no_resched()
-	 * in post_kprobe_handler().
-	 */
-	preempt_disable();
+	kcb->kprobe_status = KPROBE_HIT_SS;
 	return 1;
 
 no_kprobe:
+	preempt_enable_no_resched();
 	return ret;
 }
 
@@ -251,9 +251,10 @@
         struct kretprobe_instance *ri = NULL;
         struct hlist_head *head;
         struct hlist_node *node, *tmp;
-	unsigned long orig_ret_address = 0;
+	unsigned long flags, orig_ret_address = 0;
 	unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
 
+	spin_lock_irqsave(&kretprobe_lock, flags);
         head = kretprobe_inst_table_head(current);
 
 	/*
@@ -292,12 +293,14 @@
 	BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
 	regs->nip = orig_ret_address;
 
-	unlock_kprobes();
+	reset_current_kprobe();
+	spin_unlock_irqrestore(&kretprobe_lock, flags);
+	preempt_enable_no_resched();
 
         /*
          * By returning a non-zero value, we are telling
-         * kprobe_handler() that we have handled unlocking
-         * and re-enabling preemption.
+         * kprobe_handler() that we don't want the post_handler
+         * to run (and have re-enabled preemption)
          */
         return 1;
 }
@@ -323,23 +326,26 @@
 
 static inline int post_kprobe_handler(struct pt_regs *regs)
 {
-	if (!kprobe_running())
+	struct kprobe *cur = kprobe_running();
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	if (!cur)
 		return 0;
 
-	if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
-		kprobe_status = KPROBE_HIT_SSDONE;
-		current_kprobe->post_handler(current_kprobe, regs, 0);
+	if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
+		kcb->kprobe_status = KPROBE_HIT_SSDONE;
+		cur->post_handler(cur, regs, 0);
 	}
 
-	resume_execution(current_kprobe, regs);
-	regs->msr |= kprobe_saved_msr;
+	resume_execution(cur, regs);
+	regs->msr |= kcb->kprobe_saved_msr;
 
 	/*Restore back the original saved kprobes variables and continue. */
-	if (kprobe_status == KPROBE_REENTER) {
-		restore_previous_kprobe();
+	if (kcb->kprobe_status == KPROBE_REENTER) {
+		restore_previous_kprobe(kcb);
 		goto out;
 	}
-	unlock_kprobes();
+	reset_current_kprobe();
 out:
 	preempt_enable_no_resched();
 
@@ -354,19 +360,20 @@
 	return 1;
 }
 
-/* Interrupts disabled, kprobe_lock held. */
 static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 {
-	if (current_kprobe->fault_handler
-	    && current_kprobe->fault_handler(current_kprobe, regs, trapnr))
+	struct kprobe *cur = kprobe_running();
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
 		return 1;
 
-	if (kprobe_status & KPROBE_HIT_SS) {
-		resume_execution(current_kprobe, regs);
+	if (kcb->kprobe_status & KPROBE_HIT_SS) {
+		resume_execution(cur, regs);
 		regs->msr &= ~MSR_SE;
-		regs->msr |= kprobe_saved_msr;
+		regs->msr |= kcb->kprobe_saved_msr;
 
-		unlock_kprobes();
+		reset_current_kprobe();
 		preempt_enable_no_resched();
 	}
 	return 0;
@@ -381,11 +388,6 @@
 	struct die_args *args = (struct die_args *)data;
 	int ret = NOTIFY_DONE;
 
-	/*
-	 * Interrupts are not disabled here.  We need to disable
-	 * preemption, because kprobe_running() uses smp_processor_id().
-	 */
-	preempt_disable();
 	switch (val) {
 	case DIE_BPT:
 		if (kprobe_handler(args->regs))
@@ -396,22 +398,25 @@
 			ret = NOTIFY_STOP;
 		break;
 	case DIE_PAGE_FAULT:
+		/* kprobe_running() needs smp_processor_id() */
+		preempt_disable();
 		if (kprobe_running() &&
 		    kprobe_fault_handler(args->regs, args->trapnr))
 			ret = NOTIFY_STOP;
+		preempt_enable();
 		break;
 	default:
 		break;
 	}
-	preempt_enable_no_resched();
 	return ret;
 }
 
 int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct jprobe *jp = container_of(p, struct jprobe, kp);
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 
-	memcpy(&jprobe_saved_regs, regs, sizeof(struct pt_regs));
+	memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs));
 
 	/* setup return addr to the jprobe handler routine */
 	regs->nip = (unsigned long)(((func_descr_t *)jp->entry)->entry);
@@ -431,12 +436,15 @@
 
 int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
 	/*
 	 * FIXME - we should ideally be validating that we got here 'cos
 	 * of the "trap" in jprobe_return() above, before restoring the
 	 * saved regs...
 	 */
-	memcpy(regs, &jprobe_saved_regs, sizeof(struct pt_regs));
+	memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs));
+	preempt_enable_no_resched();
 	return 1;
 }
 
diff --git a/arch/ppc64/kernel/lparcfg.c b/arch/ppc64/kernel/lparcfg.c
index e861557..3e7b2f2 100644
--- a/arch/ppc64/kernel/lparcfg.c
+++ b/arch/ppc64/kernel/lparcfg.c
@@ -599,9 +599,7 @@
 void __exit lparcfg_cleanup(void)
 {
 	if (proc_ppc64_lparcfg) {
-		if (proc_ppc64_lparcfg->data) {
-			kfree(proc_ppc64_lparcfg->data);
-		}
+		kfree(proc_ppc64_lparcfg->data);
 		remove_proc_entry("lparcfg", proc_ppc64_lparcfg->parent);
 	}
 }
diff --git a/arch/ppc64/kernel/scanlog.c b/arch/ppc64/kernel/scanlog.c
index 215bf89..2edc947 100644
--- a/arch/ppc64/kernel/scanlog.c
+++ b/arch/ppc64/kernel/scanlog.c
@@ -225,8 +225,7 @@
 void __exit scanlog_cleanup(void)
 {
 	if (proc_ppc64_scan_log_dump) {
-		if (proc_ppc64_scan_log_dump->data)
-			kfree(proc_ppc64_scan_log_dump->data);
+		kfree(proc_ppc64_scan_log_dump->data);
 		remove_proc_entry("scan-log-dump", proc_ppc64_scan_log_dump->parent);
 	}
 }
diff --git a/arch/ppc64/kernel/sysfs.c b/arch/ppc64/kernel/sysfs.c
index 6654b35..e99ec62 100644
--- a/arch/ppc64/kernel/sysfs.c
+++ b/arch/ppc64/kernel/sysfs.c
@@ -20,6 +20,7 @@
 #include <asm/paca.h>
 #include <asm/lppaca.h>
 #include <asm/machdep.h>
+#include <asm/smp.h>
 
 static DEFINE_PER_CPU(struct cpu, cpu_devices);
 
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index 98db304..73a09a6 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -76,9 +76,7 @@
 OBJCOPYFLAGS	:= -O binary
 LDFLAGS_vmlinux := -e start
 
-head-$(CONFIG_ARCH_S390_31)	+= arch/$(ARCH)/kernel/head.o
-head-$(CONFIG_ARCH_S390X)	+= arch/$(ARCH)/kernel/head64.o
-head-y				+= arch/$(ARCH)/kernel/init_task.o
+head-y		:= arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o
 
 core-y		+= arch/$(ARCH)/mm/ arch/$(ARCH)/kernel/ arch/$(ARCH)/crypto/ \
 		   arch/$(ARCH)/appldata/
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index 8584dd8..7434c32 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -8,9 +8,7 @@
             setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
             semaphore.o s390_ext.o debug.o profile.o irq.o reipl_diag.o
 
-extra-$(CONFIG_ARCH_S390_31)	+= head.o 
-extra-$(CONFIG_ARCH_S390X)	+= head64.o 
-extra-y				+= init_task.o vmlinux.lds
+extra-y				+= head.o init_task.o vmlinux.lds
 
 obj-$(CONFIG_MODULES)		+= s390_ksyms.o module.o
 obj-$(CONFIG_SMP)		+= smp.o
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 9b30f4c..27b0773 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -288,7 +288,7 @@
 	bo	BASED(sysc_restart)
 	tm	__TI_flags+3(%r9),_TIF_SINGLE_STEP
 	bo	BASED(sysc_singlestep)
-	b	BASED(sysc_leave)      # out of here, do NOT recheck
+	b	BASED(sysc_work_loop)
 
 #
 # _TIF_RESTART_SVC is set, set up registers and restart svc
@@ -645,7 +645,7 @@
         l       %r1,BASED(.Ldo_signal)
 	basr    %r14,%r1	       # call do_signal
         stnsm   __SF_EMPTY(%r15),0xfc  # disable I/O and ext. interrupts
-	b	BASED(io_leave)        # out of here, do NOT recheck
+	b	BASED(io_work_loop)
 
 /*
  * External interrupt handler routine
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 7b9b4a2..4eb71ff 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -283,7 +283,7 @@
 	jo	sysc_restart
 	tm	__TI_flags+7(%r9),_TIF_SINGLE_STEP
 	jo	sysc_singlestep
-	j	sysc_leave        # out of here, do NOT recheck
+	j	sysc_work_loop
 
 #
 # _TIF_RESTART_SVC is set, set up registers and restart svc
@@ -684,7 +684,7 @@
 	slgr    %r3,%r3			# clear *oldset
 	brasl	%r14,do_signal		# call do_signal
 	stnsm   __SF_EMPTY(%r15),0xfc	# disable I/O and ext. interrupts
-	j	sysc_leave		# out of here, do NOT recheck
+	j	io_work_loop
 
 /*
  * External interrupt handler routine
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index 039354d..d31a97c 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -1,11 +1,12 @@
 /*
  *  arch/s390/kernel/head.S
  *
- *  S390 version
- *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Hartmut Penner (hp@de.ibm.com),
- *               Martin Schwidefsky (schwidefsky@de.ibm.com),
- *               Rob van der Heij (rvdhei@iae.nl)
+ * (C) Copyright IBM Corp. 1999, 2005
+ *
+ *    Author(s): Hartmut Penner <hp@de.ibm.com>
+ *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
+ *		 Rob van der Heij <rvdhei@iae.nl>
+ *		 Heiko Carstens <heiko.carstens@de.ibm.com>
  *
  * There are 5 different IPL methods
  *  1) load the image directly into ram at address 0 and do an PSW restart
@@ -19,12 +20,7 @@
  *  5) direct call of start by the SALIPL loader
  *  We use the cpuid to distinguish between VM and native ipl
  *  params for kernel are pushed to 0x10400 (see setup.h)
-
-    Changes: 
-    Okt 25 2000 <rvdheij@iae.nl>
-	added code to skip HDR and EOF to allow SL tape IPL (5 retries)
-	changed first CCW from rewind to backspace block
-
+ *
  */
 
 #include <linux/config.h>
@@ -34,6 +30,12 @@
 #include <asm/thread_info.h>
 #include <asm/page.h>
 
+#ifdef CONFIG_ARCH_S390X
+#define ARCH_OFFSET	4
+#else
+#define ARCH_OFFSET	0
+#endif
+
 #ifndef CONFIG_IPL
         .org   0
         .long  0x00080000,0x80000000+startup   # Just a restart PSW
@@ -201,7 +203,7 @@
         ssch  0(%r3)                           # load chunk of 1600 bytes
         bnz   .Llderr
 .Lwait4irq:
-        mvc   __LC_IO_NEW_PSW(8),.Lnewpsw      # set up IO interrupt psw
+        mvc   0x78(8),.Lnewpsw                 # set up IO interrupt psw
         lpsw  .Lwaitpsw              
 .Lioint:
         c     %r1,0xb8                         # compare subchannel number
@@ -265,13 +267,13 @@
         la    %r2,IPL_BS                       # load start address
         bas   %r14,.Lloader                    # load rest of ipl image
         l     %r12,.Lparm                      # pointer to parameter area
-        st    %r1,IPL_DEVICE-PARMAREA(%r12)    # store ipl device number
+        st    %r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number
 
 #
 # load parameter file from ipl device
 #
 .Lagain1:
- 	l     %r2,INITRD_START-PARMAREA(%r12)  # use ramdisk location as temp
+ 	l     %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # ramdisk loc. is temp
         bas   %r14,.Lloader                    # load parameter file
         ltr   %r2,%r2                          # got anything ?
         bz    .Lnopf
@@ -279,7 +281,7 @@
 	bnh   .Lnotrunc
 	la    %r2,895
 .Lnotrunc:
-	l     %r4,INITRD_START-PARMAREA(%r12)
+	l     %r4,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
 	clc   0(3,%r4),.L_hdr		       # if it is HDRx
 	bz    .Lagain1			       # skip dataset header
 	clc   0(3,%r4),.L_eof		       # if it is EOFx
@@ -322,14 +324,14 @@
 # load ramdisk from ipl device
 #	
 .Lagain2:
- 	l     %r2,INITRD_START-PARMAREA(%r12)  # load adr. of ramdisk
+ 	l     %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # addr of ramdisk
         bas   %r14,.Lloader                    # load ramdisk
- 	st    %r2,INITRD_SIZE-PARMAREA(%r12)   # store size of ramdisk
+ 	st    %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of ramdisk
         ltr   %r2,%r2
         bnz   .Lrdcont
-        st    %r2,INITRD_START-PARMAREA(%r12)  # no ramdisk found, null it
+        st    %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found
 .Lrdcont:
-	l     %r2,INITRD_START-PARMAREA(%r12)
+	l     %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
 
 	clc   0(3,%r2),.L_hdr		       # skip HDRx and EOFx 
 	bz    .Lagain2
@@ -432,10 +434,10 @@
 	la    %r3,1(%r3)
 .done:
         l     %r1,.memsize
-	st    %r3,0(%r1)
+	st    %r3,ARCH_OFFSET(%r1)
 	slr   %r0,%r0
-	st    %r0,INITRD_SIZE-PARMAREA(%r11)
-	st    %r0,INITRD_START-PARMAREA(%r11)
+	st    %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11)
+	st    %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11)
 	j     startup                   # continue with startup
 .tbl:	.long _ebcasc			# translate table
 .cmd:	.long COMMAND_LINE		# address of command line buffer
@@ -478,304 +480,23 @@
 	.byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7 
 	.byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
 
-#
-# startup-code at 0x10000, running in real mode
-# this is called either by the ipl loader or directly by PSW restart
-# or linload or SALIPL
-#
-        .org  0x10000
-startup:basr  %r13,0                     # get base
-.LPG1:	l     %r1, .Lget_ipl_device_addr-.LPG1(%r13)
-	basr  %r14, %r1
-	lctl  %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
-	la    %r12,_pstart-.LPG1(%r13)   # pointer to parameter area
-					 # move IPL device to lowcore
-        mvc   __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
-	
-#
-# clear bss memory
-#
-        l     %r2,.Lbss_bgn-.LPG1(%r13) # start of bss
-        l     %r3,.Lbss_end-.LPG1(%r13) # end of bss
-        sr    %r3,%r2                   # length of bss
-        sr    %r4,%r4                   #
-        sr    %r5,%r5                   # set src,length and pad to zero
-        sr    %r0,%r0                   #
-        mvcle %r2,%r4,0                 # clear mem
-        jo    .-4                       # branch back, if not finish
-
-	l     %r2,.Lrcp-.LPG1(%r13)	# Read SCP forced command word
-.Lservicecall:
-	stosm .Lpmask-.LPG1(%r13),0x01	# authorize ext interrupts
-
-	stctl %r0, %r0,.Lcr-.LPG1(%r13)	# get cr0
-	la    %r1,0x200			# set bit 22
-	o     %r1,.Lcr-.LPG1(%r13)	# or old cr0 with r1
-	st    %r1,.Lcr-.LPG1(%r13)
-	lctl  %r0, %r0,.Lcr-.LPG1(%r13)	# load modified cr0
-
-	mvc   __LC_EXT_NEW_PSW(8),.Lpcext-.LPG1(%r13) # set postcall psw
-	la    %r1, .Lsclph-.LPG1(%r13)
-	a     %r1,__LC_EXT_NEW_PSW+4	# set handler
-	st    %r1,__LC_EXT_NEW_PSW+4
-
-	la    %r4,_pstart-.LPG1(%r13)	# %r4 is our index for sccb stuff
-	la    %r1, .Lsccb-PARMAREA(%r4)	# our sccb
-	.insn rre,0xb2200000,%r2,%r1	# service call
-	ipm   %r1
-	srl   %r1,28			# get cc code
-	xr    %r3, %r3
-	chi   %r1,3
-	be    .Lfchunk-.LPG1(%r13)	# leave
-	chi   %r1,2
-	be    .Lservicecall-.LPG1(%r13)
-	lpsw  .Lwaitsclp-.LPG1(%r13)
-.Lsclph:
-	lh    %r1,.Lsccbr-PARMAREA(%r4)
-	chi   %r1,0x10			# 0x0010 is the sucess code
-	je    .Lprocsccb		# let's process the sccb
-	chi   %r1,0x1f0
-	bne   .Lfchunk-.LPG1(%r13)	# unhandled error code
-	c     %r2, .Lrcp-.LPG1(%r13)	# Did we try Read SCP forced
-	bne   .Lfchunk-.LPG1(%r13)	# if no, give up
-	l     %r2, .Lrcp2-.LPG1(%r13)	# try with Read SCP
-	b     .Lservicecall-.LPG1(%r13)
-.Lprocsccb:
-	lhi   %r1,0
-	icm   %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0
-	jnz   .Lscnd
-	lhi   %r1,0x800			# otherwise report 2GB
-.Lscnd:
-	lhi   %r3,0x800			# limit reported memory size to 2GB
-	cr    %r1,%r3
-	jl    .Lno2gb
-	lr    %r1,%r3
-.Lno2gb:
-	xr    %r3,%r3			# same logic
-	ic    %r3,.Lscpa1-PARMAREA(%r4)
-	chi   %r3,0x00
-	jne   .Lcompmem
-	l     %r3,.Lscpa2-PARMAREA(%r13)
-.Lcompmem:
-	mr    %r2,%r1			# mem in MB on 128-bit
-	l     %r1,.Lonemb-.LPG1(%r13)
-	mr    %r2,%r1			# mem size in bytes in %r3
-	b     .Lfchunk-.LPG1(%r13)
-
-	.align 4
-.Lget_ipl_device_addr:
-	.long .Lget_ipl_device
-.Lpmask:
-	.byte 0
-.align 8
-.Lpcext:.long  0x00080000,0x80000000
-.Lcr:
-	.long 0x00			# place holder for cr0
-.Lwaitsclp:
-	.long 0x020A0000
-	.long .Lsclph
-.Lrcp:
-	.int 0x00120001			# Read SCP forced code
-.Lrcp2:
-	.int 0x00020001			# Read SCP code
-.Lonemb:
-	.int 0x100000
-.Lfchunk:
-
-#
-# find memory chunks.
-#
-	lr    %r9,%r3			 # end of mem
-	mvc   __LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13)
-	la    %r1,1                      # test in increments of 128KB
-	sll   %r1,17
-	l     %r3,.Lmchunk-.LPG1(%r13)   # get pointer to memory_chunk array
-	slr   %r4,%r4                    # set start of chunk to zero
-	slr   %r5,%r5                    # set end of chunk to zero
-	slr   %r6,%r6			 # set access code to zero
-	la    %r10, MEMORY_CHUNKS	 # number of chunks
-.Lloop:
-	tprot 0(%r5),0			 # test protection of first byte
-	ipm   %r7
-	srl   %r7,28
-	clr   %r6,%r7			 # compare cc with last access code
-	be    .Lsame-.LPG1(%r13)
-	b     .Lchkmem-.LPG1(%r13)
-.Lsame:
-	ar    %r5,%r1			 # add 128KB to end of chunk
-	bno   .Lloop-.LPG1(%r13)	 # r1 < 0x80000000 -> loop
-.Lchkmem:				 # > 2GB or tprot got a program check
-	clr   %r4,%r5			 # chunk size > 0?
-	be    .Lchkloop-.LPG1(%r13)
-	st    %r4,0(%r3)		 # store start address of chunk
-	lr    %r0,%r5
-	slr   %r0,%r4
-	st    %r0,4(%r3)		 # store size of chunk
-	st    %r6,8(%r3)		 # store type of chunk
-	la    %r3,12(%r3)
-	l     %r4,.Lmemsize-.LPG1(%r13)	 # address of variable memory_size
-	st    %r5,0(%r4)		 # store last end to memory size
-	ahi   %r10,-1			 # update chunk number
-.Lchkloop:
-	lr    %r6,%r7			 # set access code to last cc
-	# we got an exception or we're starting a new
-	# chunk , we must check if we should
-	# still try to find valid memory (if we detected
-	# the amount of available storage), and if we
-	# have chunks left
-	xr    %r0,%r0
-	clr   %r0,%r9			 # did we detect memory?
-	je    .Ldonemem			 # if not, leave
-	chi   %r10,0			 # do we have chunks left?
-	je    .Ldonemem
-	alr   %r5,%r1			 # add 128KB to end of chunk
-	lr    %r4,%r5			 # potential new chunk
-	clr    %r5,%r9			 # should we go on?
-	jl     .Lloop
-.Ldonemem:		
-        l      %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags
-#
-# find out if we are running under VM
-#
-        stidp  __LC_CPUID               # store cpuid
-	tm     __LC_CPUID,0xff          # running under VM ?
-	bno    .Lnovm-.LPG1(%r13)
-        oi     3(%r12),1                # set VM flag
-.Lnovm:
-        lh     %r0,__LC_CPUID+4         # get cpu version
-        chi    %r0,0x7490               # running on a P/390 ?
-        bne    .Lnop390-.LPG1(%r13)
-        oi     3(%r12),4                # set P/390 flag
-.Lnop390:
-
-#
-# find out if we have an IEEE fpu
-#
-        mvc    __LC_PGM_NEW_PSW(8),.Lpcfpu-.LPG1(%r13)
-	efpc   %r0,0                    # test IEEE extract fpc instruction
-        oi     3(%r12),2                # set IEEE fpu flag
-.Lchkfpu:
-
-#
-# find out if we have the CSP instruction
-#
-       mvc    __LC_PGM_NEW_PSW(8),.Lpccsp-.LPG1(%r13)
-       la     %r0,0
-       lr     %r1,%r0
-       la     %r2,4
-       csp    %r0,%r2                   # Test CSP instruction
-       oi     3(%r12),8                 # set CSP flag
-.Lchkcsp:
-
-#
-# find out if we have the MVPG instruction
-#
-       mvc    __LC_PGM_NEW_PSW(8),.Lpcmvpg-.LPG1(%r13)
-       sr     %r0,%r0
-       la     %r1,0
-       la     %r2,0
-       mvpg   %r1,%r2                   # Test CSP instruction
-       oi     3(%r12),16                # set MVPG flag
-.Lchkmvpg:
-
-#
-# find out if we have the IDTE instruction
-#
-	mvc	__LC_PGM_NEW_PSW(8),.Lpcidte-.LPG1(%r13)
-	.long	0xb2b10000		# store facility list
-	tm	0xc8,0x08		# check bit for clearing-by-ASCE
-	bno	.Lchkidte-.LPG1(%r13)
-	lhi	%r1,2094
-	lhi	%r2,0
-	.long	0xb98e2001
-	oi	3(%r12),0x80		# set IDTE flag
-.Lchkidte:
-
-        lpsw  .Lentry-.LPG1(13)         # jump to _stext in primary-space,
-                                        # virtual and never return ...
-        .align 8
-.Lentry:.long  0x00080000,0x80000000 + _stext
-.Lctl:  .long  0x04b50002               # cr0: various things
-        .long  0                        # cr1: primary space segment table
-        .long  .Lduct                   # cr2: dispatchable unit control table
-        .long  0                        # cr3: instruction authorization
-        .long  0                        # cr4: instruction authorization
-        .long  0xffffffff               # cr5: primary-aste origin
-        .long  0                        # cr6:  I/O interrupts
-        .long  0                        # cr7:  secondary space segment table
-        .long  0                        # cr8:  access registers translation
-        .long  0                        # cr9:  tracing off
-        .long  0                        # cr10: tracing off
-        .long  0                        # cr11: tracing off
-        .long  0                        # cr12: tracing off
-        .long  0                        # cr13: home space segment table
-        .long  0xc0000000               # cr14: machine check handling off
-        .long  0                        # cr15: linkage stack operations
-.Lpcmem:.long  0x00080000,0x80000000 + .Lchkmem
-.Lpcfpu:.long  0x00080000,0x80000000 + .Lchkfpu
-.Lpccsp:.long  0x00080000,0x80000000 + .Lchkcsp
-.Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg
-.Lpcidte:.long 0x00080000,0x80000000 + .Lchkidte
-.Lmemsize:.long memory_size
-.Lmchunk:.long memory_chunk
-.Lmflags:.long machine_flags
-.Lbss_bgn:  .long  __bss_start
-.Lbss_end:  .long  _end
-
-	.org PARMAREA-64
-.Lduct:	.long 0,0,0,0,0,0,0,0
-	.long 0,0,0,0,0,0,0,0
-
-#
-# params at 10400 (setup.h)
-#
-	.org   PARMAREA
-	.global _pstart
-_pstart:	
-        .long  0,0                      # IPL_DEVICE
-        .long  0,RAMDISK_ORIGIN         # INITRD_START
-        .long  0,RAMDISK_SIZE           # INITRD_SIZE
-
-        .org   COMMAND_LINE
-    	.byte  "root=/dev/ram0 ro"
-        .byte  0
-	.org   0x11000
-.Lsccb:
-	.hword 0x1000			# length, one page
-	.byte 0x00,0x00,0x00
-	.byte 0x80			# variable response bit set
-.Lsccbr:
-	.hword 0x00			# response code
-.Lscpincr1:
-	.hword 0x00
-.Lscpa1:
-	.byte 0x00
-	.fill 89,1,0
-.Lscpa2:
-	.int 0x00
-.Lscpincr2:
-	.quad 0x00
-	.fill 3984,1,0
-	.org 0x12000
-	.global _pend
-_pend:	
-
+.macro GET_IPL_DEVICE
 .Lget_ipl_device:
 	basr  %r12,0
-.LPG2:	l     %r1,0xb8			# get sid
+.LGID:	l     %r1,0xb8			# get sid
 	sll   %r1,15			# test if subchannel is enabled
 	srl   %r1,31
 	ltr   %r1,%r1
 	bz    0(%r14)			# subchannel disabled
 	l     %r1,0xb8
-	la    %r5,.Lipl_schib-.LPG2(%r12)
+	la    %r5,.Lipl_schib-.LGID(%r12)
 	stsch 0(%r5)		        # get schib of subchannel
 	bnz   0(%r14)			# schib not available
 	tm    5(%r5),0x01		# devno valid?
 	bno   0(%r14)
-	la    %r6,ipl_parameter_flags-.LPG2(%r12)
+	la    %r6,ipl_parameter_flags-.LGID(%r12)
 	oi    3(%r6),0x01		# set flag
-	la    %r2,ipl_devno-.LPG2(%r12)
+	la    %r2,ipl_devno-.LGID(%r12)
 	mvc   0(2,%r2),6(%r5)		# store devno
 	tm    4(%r5),0x80		# qdio capable device?
 	bno   0(%r14)
@@ -816,46 +537,10 @@
 	.globl ipl_devno
 ipl_devno:
 	.word 0
+.endm
 
-#ifdef CONFIG_SHARED_KERNEL
-	.org   0x100000
+#ifdef CONFIG_ARCH_S390X
+#include "head64.S"
+#else
+#include "head31.S"
 #endif
-
-#
-# startup-code, running in virtual mode
-#
-        .globl _stext
-_stext:	basr  %r13,0                    # get base
-.LPG3:
-#
-# Setup stack
-#
-        l     %r15,.Linittu-.LPG3(%r13)
-	mvc   __LC_CURRENT(4),__TI_task(%r15)
-        ahi   %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE
-        st    %r15,__LC_KERNEL_STACK    # set end of kernel stack
-        ahi   %r15,-96
-        xc    __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
-
-# check control registers
-        stctl  %c0,%c15,0(%r15)
-	oi     2(%r15),0x40             # enable sigp emergency signal
-	oi     0(%r15),0x10             # switch on low address protection
-        lctl   %c0,%c15,0(%r15)
-
-#
-        lam    0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
-        l      %r14,.Lstart-.LPG3(%r13)
-        basr   %r14,%r14                # call start_kernel
-#
-# We returned from start_kernel ?!? PANIK
-#
-        basr  %r13,0
-	lpsw  .Ldw-.(%r13)           # load disabled wait psw
-#
-            .align 8
-.Ldw:	    .long  0x000a0000,0x00000000
-.Linittu:   .long  init_thread_union
-.Lstart:    .long  start_kernel
-.Laregs:    .long  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S
new file mode 100644
index 0000000..2d3b089
--- /dev/null
+++ b/arch/s390/kernel/head31.S
@@ -0,0 +1,336 @@
+/*
+ * arch/s390/kernel/head31.S
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ *   Author(s):	Hartmut Penner <hp@de.ibm.com>
+ *		Martin Schwidefsky <schwidefsky@de.ibm.com>
+ *		Rob van der Heij <rvdhei@iae.nl>
+ *		Heiko Carstens <heiko.carstens@de.ibm.com>
+ *
+ */
+
+#
+# startup-code at 0x10000, running in absolute addressing mode
+# this is called either by the ipl loader or directly by PSW restart
+# or linload or SALIPL
+#
+	.org	0x10000
+startup:basr	%r13,0			 # get base
+.LPG1:	l	%r1, .Lget_ipl_device_addr-.LPG1(%r13)
+	basr	%r14, %r1
+	lctl	%c0,%c15,.Lctl-.LPG1(%r13) # load control registers
+	la	%r12,_pstart-.LPG1(%r13) # pointer to parameter area
+					 # move IPL device to lowcore
+	mvc	__LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
+
+#
+# clear bss memory
+#
+	l	%r2,.Lbss_bgn-.LPG1(%r13) # start of bss
+	l	%r3,.Lbss_end-.LPG1(%r13) # end of bss
+	sr	%r3,%r2			# length of bss
+	sr	%r4,%r4
+	sr	%r5,%r5			# set src,length and pad to zero
+	sr	%r0,%r0
+	mvcle	%r2,%r4,0		# clear mem
+	jo	.-4			# branch back, if not finish
+
+	l	%r2,.Lrcp-.LPG1(%r13)	# Read SCP forced command word
+.Lservicecall:
+	stosm	.Lpmask-.LPG1(%r13),0x01	# authorize ext interrupts
+
+	stctl	%r0, %r0,.Lcr-.LPG1(%r13)	# get cr0
+	la	%r1,0x200		# set bit 22
+	o	%r1,.Lcr-.LPG1(%r13)	# or old cr0 with r1
+	st	%r1,.Lcr-.LPG1(%r13)
+	lctl	%r0, %r0,.Lcr-.LPG1(%r13)	# load modified cr0
+
+	mvc	__LC_EXT_NEW_PSW(8),.Lpcext-.LPG1(%r13) # set postcall psw
+	la	%r1, .Lsclph-.LPG1(%r13)
+	a	%r1,__LC_EXT_NEW_PSW+4	# set handler
+	st	%r1,__LC_EXT_NEW_PSW+4
+
+	la	%r4,_pstart-.LPG1(%r13)	# %r4 is our index for sccb stuff
+	la	%r1, .Lsccb-PARMAREA(%r4)	# our sccb
+	.insn	rre,0xb2200000,%r2,%r1	# service call
+	ipm	%r1
+	srl	%r1,28			# get cc code
+	xr	%r3, %r3
+	chi	%r1,3
+	be	.Lfchunk-.LPG1(%r13)	# leave
+	chi	%r1,2
+	be	.Lservicecall-.LPG1(%r13)
+	lpsw	.Lwaitsclp-.LPG1(%r13)
+.Lsclph:
+	lh	%r1,.Lsccbr-PARMAREA(%r4)
+	chi	%r1,0x10		# 0x0010 is the sucess code
+	je	.Lprocsccb		# let's process the sccb
+	chi	%r1,0x1f0
+	bne	.Lfchunk-.LPG1(%r13)	# unhandled error code
+	c	%r2, .Lrcp-.LPG1(%r13)	# Did we try Read SCP forced
+	bne	.Lfchunk-.LPG1(%r13)	# if no, give up
+	l	%r2, .Lrcp2-.LPG1(%r13)	# try with Read SCP
+	b	.Lservicecall-.LPG1(%r13)
+.Lprocsccb:
+	lhi	%r1,0
+	icm	%r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0
+	jnz	.Lscnd
+	lhi	%r1,0x800		# otherwise report 2GB
+.Lscnd:
+	lhi	%r3,0x800		# limit reported memory size to 2GB
+	cr	%r1,%r3
+	jl	.Lno2gb
+	lr	%r1,%r3
+.Lno2gb:
+	xr	%r3,%r3			# same logic
+	ic	%r3,.Lscpa1-PARMAREA(%r4)
+	chi	%r3,0x00
+	jne	.Lcompmem
+	l	%r3,.Lscpa2-PARMAREA(%r13)
+.Lcompmem:
+	mr	%r2,%r1			# mem in MB on 128-bit
+	l	%r1,.Lonemb-.LPG1(%r13)
+	mr	%r2,%r1			# mem size in bytes in %r3
+	b	.Lfchunk-.LPG1(%r13)
+
+	.align 4
+.Lget_ipl_device_addr:
+	.long	.Lget_ipl_device
+.Lpmask:
+	.byte	0
+.align 8
+.Lpcext:.long	0x00080000,0x80000000
+.Lcr:
+	.long	0x00			# place holder for cr0
+.Lwaitsclp:
+	.long 0x010a0000,0x80000000 + .Lsclph
+.Lrcp:
+	.int	0x00120001		# Read SCP forced code
+.Lrcp2:
+	.int	0x00020001		# Read SCP code
+.Lonemb:
+	.int	0x100000
+.Lfchunk:
+
+#
+# find memory chunks.
+#
+	lr	%r9,%r3			# end of mem
+	mvc	__LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13)
+	la	%r1,1			# test in increments of 128KB
+	sll	%r1,17
+	l	%r3,.Lmchunk-.LPG1(%r13) # get pointer to memory_chunk array
+	slr	%r4,%r4			# set start of chunk to zero
+	slr	%r5,%r5			# set end of chunk to zero
+	slr	%r6,%r6			# set access code to zero
+	la	%r10, MEMORY_CHUNKS	# number of chunks
+.Lloop:
+	tprot	0(%r5),0		# test protection of first byte
+	ipm	%r7
+	srl	%r7,28
+	clr	%r6,%r7			# compare cc with last access code
+	be	.Lsame-.LPG1(%r13)
+	b	.Lchkmem-.LPG1(%r13)
+.Lsame:
+	ar	%r5,%r1			# add 128KB to end of chunk
+	bno	.Lloop-.LPG1(%r13)	# r1 < 0x80000000 -> loop
+.Lchkmem:				# > 2GB or tprot got a program check
+	clr	%r4,%r5			# chunk size > 0?
+	be	.Lchkloop-.LPG1(%r13)
+	st	%r4,0(%r3)		# store start address of chunk
+	lr	%r0,%r5
+	slr	%r0,%r4
+	st	%r0,4(%r3)		# store size of chunk
+	st	%r6,8(%r3)		# store type of chunk
+	la	%r3,12(%r3)
+	l	%r4,.Lmemsize-.LPG1(%r13)	 # address of variable memory_size
+	st	%r5,0(%r4)		# store last end to memory size
+	ahi	%r10,-1			# update chunk number
+.Lchkloop:
+	lr	%r6,%r7			# set access code to last cc
+	# we got an exception or we're starting a new
+	# chunk , we must check if we should
+	# still try to find valid memory (if we detected
+	# the amount of available storage), and if we
+	# have chunks left
+	xr	%r0,%r0
+	clr	%r0,%r9			# did we detect memory?
+	je	.Ldonemem		# if not, leave
+	chi	%r10,0			# do we have chunks left?
+	je	.Ldonemem
+	alr	%r5,%r1			# add 128KB to end of chunk
+	lr	%r4,%r5			# potential new chunk
+	clr	%r5,%r9			# should we go on?
+	jl	.Lloop
+.Ldonemem:
+	l	%r12,.Lmflags-.LPG1(%r13) # get address of machine_flags
+#
+# find out if we are running under VM
+#
+	stidp	__LC_CPUID		# store cpuid
+	tm	__LC_CPUID,0xff		# running under VM ?
+	bno	.Lnovm-.LPG1(%r13)
+	oi	3(%r12),1		# set VM flag
+.Lnovm:
+	lh	%r0,__LC_CPUID+4	# get cpu version
+	chi	%r0,0x7490		# running on a P/390 ?
+	bne	.Lnop390-.LPG1(%r13)
+	oi	3(%r12),4		# set P/390 flag
+.Lnop390:
+
+#
+# find out if we have an IEEE fpu
+#
+	mvc	__LC_PGM_NEW_PSW(8),.Lpcfpu-.LPG1(%r13)
+	efpc	%r0,0			# test IEEE extract fpc instruction
+	oi	3(%r12),2		# set IEEE fpu flag
+.Lchkfpu:
+
+#
+# find out if we have the CSP instruction
+#
+       mvc	 __LC_PGM_NEW_PSW(8),.Lpccsp-.LPG1(%r13)
+       la	 %r0,0
+       lr	%r1,%r0
+       la	%r2,4
+       csp	%r0,%r2			# Test CSP instruction
+       oi	3(%r12),8		# set CSP flag
+.Lchkcsp:
+
+#
+# find out if we have the MVPG instruction
+#
+       mvc	__LC_PGM_NEW_PSW(8),.Lpcmvpg-.LPG1(%r13)
+       sr	%r0,%r0
+       la	%r1,0
+       la	%r2,0
+       mvpg	%r1,%r2			# Test CSP instruction
+       oi	3(%r12),16		# set MVPG flag
+.Lchkmvpg:
+
+#
+# find out if we have the IDTE instruction
+#
+	mvc	__LC_PGM_NEW_PSW(8),.Lpcidte-.LPG1(%r13)
+	.long	0xb2b10000		# store facility list
+	tm	0xc8,0x08		# check bit for clearing-by-ASCE
+	bno	.Lchkidte-.LPG1(%r13)
+	lhi	%r1,2094
+	lhi	%r2,0
+	.long	0xb98e2001
+	oi	3(%r12),0x80		# set IDTE flag
+.Lchkidte:
+
+	lpsw  .Lentry-.LPG1(13)		# jump to _stext in primary-space,
+					# virtual and never return ...
+	.align	8
+.Lentry:.long	0x00080000,0x80000000 + _stext
+.Lctl:	.long	0x04b50002		# cr0: various things
+	.long	0			# cr1: primary space segment table
+	.long	.Lduct			# cr2: dispatchable unit control table
+	.long	0			# cr3: instruction authorization
+	.long	0			# cr4: instruction authorization
+	.long	0xffffffff		# cr5: primary-aste origin
+	.long	0			# cr6:	I/O interrupts
+	.long	0			# cr7:	secondary space segment table
+	.long	0			# cr8:	access registers translation
+	.long	0			# cr9:	tracing off
+	.long	0			# cr10: tracing off
+	.long	0			# cr11: tracing off
+	.long	0			# cr12: tracing off
+	.long	0			# cr13: home space segment table
+	.long	0xc0000000		# cr14: machine check handling off
+	.long	0			# cr15: linkage stack operations
+.Lpcmem:.long	0x00080000,0x80000000 + .Lchkmem
+.Lpcfpu:.long	0x00080000,0x80000000 + .Lchkfpu
+.Lpccsp:.long	0x00080000,0x80000000 + .Lchkcsp
+.Lpcmvpg:.long	0x00080000,0x80000000 + .Lchkmvpg
+.Lpcidte:.long	0x00080000,0x80000000 + .Lchkidte
+.Lmemsize:.long memory_size
+.Lmchunk:.long	memory_chunk
+.Lmflags:.long	machine_flags
+.Lbss_bgn:  .long __bss_start
+.Lbss_end:  .long _end
+
+	.org	PARMAREA-64
+.Lduct:	.long	0,0,0,0,0,0,0,0
+	.long	0,0,0,0,0,0,0,0
+
+#
+# params at 10400 (setup.h)
+#
+	.org	PARMAREA
+	.global _pstart
+_pstart:
+	.long	0,0			# IPL_DEVICE
+	.long	0,RAMDISK_ORIGIN	# INITRD_START
+	.long	0,RAMDISK_SIZE		# INITRD_SIZE
+
+	.org	COMMAND_LINE
+	.byte	"root=/dev/ram0 ro"
+	.byte	0
+	.org	0x11000
+.Lsccb:
+	.hword	0x1000			# length, one page
+	.byte	0x00,0x00,0x00
+	.byte	0x80			# variable response bit set
+.Lsccbr:
+	.hword	0x00			# response code
+.Lscpincr1:
+	.hword	0x00
+.Lscpa1:
+	.byte	0x00
+	.fill	89,1,0
+.Lscpa2:
+	.int	0x00
+.Lscpincr2:
+	.quad	0x00
+	.fill	3984,1,0
+	.org	0x12000
+	.global	_pend
+_pend:
+
+	GET_IPL_DEVICE
+
+#ifdef CONFIG_SHARED_KERNEL
+	.org	0x100000
+#endif
+
+#
+# startup-code, running in virtual mode
+#
+	.globl	_stext
+_stext:	basr	%r13,0			# get base
+.LPG3:
+#
+# Setup stack
+#
+	l	%r15,.Linittu-.LPG3(%r13)
+	mvc	__LC_CURRENT(4),__TI_task(%r15)
+	ahi	%r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE
+	st	%r15,__LC_KERNEL_STACK	# set end of kernel stack
+	ahi	%r15,-96
+	xc	__SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
+
+# check control registers
+	stctl	%c0,%c15,0(%r15)
+	oi	2(%r15),0x40		# enable sigp emergency signal
+	oi	0(%r15),0x10		# switch on low address protection
+	lctl	%c0,%c15,0(%r15)
+
+#
+	lam	0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
+	l	%r14,.Lstart-.LPG3(%r13)
+	basr	%r14,%r14		# call start_kernel
+#
+# We returned from start_kernel ?!? PANIK
+#
+	basr	%r13,0
+	lpsw	.Ldw-.(%r13)		# load disabled wait psw
+#
+	.align	8
+.Ldw:	.long	0x000a0000,0x00000000
+.Linittu:.long	init_thread_union
+.Lstart:.long	start_kernel
+.Laregs:.long	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index 193aafa..f08c06f 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -1,482 +1,17 @@
 /*
- *  arch/s390/kernel/head.S
+ * arch/s390/kernel/head64.S
  *
- *  S390 version
- *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Hartmut Penner (hp@de.ibm.com),
- *               Martin Schwidefsky (schwidefsky@de.ibm.com),
- *               Rob van der Heij (rvdhei@iae.nl)
+ * (C) Copyright IBM Corp. 1999,2005
  *
- * There are 5 different IPL methods
- *  1) load the image directly into ram at address 0 and do an PSW restart
- *  2) linload will load the image from address 0x10000 to memory 0x10000
- *     and start the code thru LPSW 0x0008000080010000 (VM only, deprecated)
- *  3) generate the tape ipl header, store the generated image on a tape
- *     and ipl from it
- *     In case of SL tape you need to IPL 5 times to get past VOL1 etc
- *  4) generate the vm reader ipl header, move the generated image to the
- *     VM reader (use option NOH!) and do a ipl from reader (VM only)
- *  5) direct call of start by the SALIPL loader
- *  We use the cpuid to distinguish between VM and native ipl
- *  params for kernel are pushed to 0x10400 (see setup.h)
-
-    Changes: 
-    Okt 25 2000 <rvdheij@iae.nl>
-	added code to skip HDR and EOF to allow SL tape IPL (5 retries)
-	changed first CCW from rewind to backspace block
-
+ *   Author(s):	Hartmut Penner <hp@de.ibm.com>
+ *		Martin Schwidefsky <schwidefsky@de.ibm.com>
+ *		Rob van der Heij <rvdhei@iae.nl>
+ *		Heiko Carstens <heiko.carstens@de.ibm.com>
+ *
  */
 
-#include <linux/config.h>
-#include <asm/setup.h>
-#include <asm/lowcore.h>
-#include <asm/asm-offsets.h>
-#include <asm/thread_info.h>
-#include <asm/page.h>
-
-#ifndef CONFIG_IPL
-        .org   0
-        .long  0x00080000,0x80000000+startup   # Just a restart PSW
-#else
-#ifdef CONFIG_IPL_TAPE
-#define IPL_BS 1024
-        .org   0
-        .long  0x00080000,0x80000000+iplstart  # The first 24 bytes are loaded
-        .long  0x27000000,0x60000001           # by ipl to addresses 0-23.
-        .long  0x02000000,0x20000000+IPL_BS    # (a PSW and two CCWs).
-        .long  0x00000000,0x00000000           # external old psw
-        .long  0x00000000,0x00000000           # svc old psw
-        .long  0x00000000,0x00000000           # program check old psw
-        .long  0x00000000,0x00000000           # machine check old psw
-        .long  0x00000000,0x00000000           # io old psw
-        .long  0x00000000,0x00000000
-        .long  0x00000000,0x00000000
-        .long  0x00000000,0x00000000
-        .long  0x000a0000,0x00000058           # external new psw
-        .long  0x000a0000,0x00000060           # svc new psw
-        .long  0x000a0000,0x00000068           # program check new psw
-        .long  0x000a0000,0x00000070           # machine check new psw
-        .long  0x00080000,0x80000000+.Lioint   # io new psw
-
-        .org   0x100
 #
-# subroutine for loading from tape
-# Paramters:	
-#  R1 = device number
-#  R2 = load address
-.Lloader:	
-        st    %r14,.Lldret
-        la    %r3,.Lorbread                    # r3 = address of orb 
-	la    %r5,.Lirb                        # r5 = address of irb
-        st    %r2,.Lccwread+4                  # initialize CCW data addresses
-        lctl  %c6,%c6,.Lcr6               
-        slr   %r2,%r2
-.Lldlp:
-        la    %r6,3                            # 3 retries
-.Lssch:
-        ssch  0(%r3)                           # load chunk of IPL_BS bytes
-        bnz   .Llderr
-.Lw4end:
-        bas   %r14,.Lwait4io
-        tm    8(%r5),0x82                      # do we have a problem ?
-        bnz   .Lrecov
-        slr   %r7,%r7
-        icm   %r7,3,10(%r5)                    # get residual count
-        lcr   %r7,%r7
-        la    %r7,IPL_BS(%r7)                  # IPL_BS-residual=#bytes read
-        ar    %r2,%r7                          # add to total size
-        tm    8(%r5),0x01                      # found a tape mark ?
-        bnz   .Ldone
-        l     %r0,.Lccwread+4                  # update CCW data addresses
-        ar    %r0,%r7
-        st    %r0,.Lccwread+4                
-        b     .Lldlp
-.Ldone:
-        l     %r14,.Lldret
-        br    %r14                             # r2 contains the total size
-.Lrecov:
-        bas   %r14,.Lsense                     # do the sensing
-        bct   %r6,.Lssch                       # dec. retry count & branch
-        b     .Llderr
-#
-# Sense subroutine
-#
-.Lsense:
-        st    %r14,.Lsnsret
-        la    %r7,.Lorbsense              
-        ssch  0(%r7)                           # start sense command
-        bnz   .Llderr
-        bas   %r14,.Lwait4io
-        l     %r14,.Lsnsret
-        tm    8(%r5),0x82                      # do we have a problem ?
-        bnz   .Llderr
-        br    %r14
-#
-# Wait for interrupt subroutine
-#
-.Lwait4io:
-        lpsw  .Lwaitpsw                 
-.Lioint:
-        c     %r1,0xb8                         # compare subchannel number
-        bne   .Lwait4io
-        tsch  0(%r5)
-        slr   %r0,%r0
-        tm    8(%r5),0x82                      # do we have a problem ?
-        bnz   .Lwtexit
-        tm    8(%r5),0x04                      # got device end ?
-        bz    .Lwait4io
-.Lwtexit:
-        br    %r14
-.Llderr:
-        lpsw  .Lcrash              
-
-        .align 8
-.Lorbread:
-	.long  0x00000000,0x0080ff00,.Lccwread
-        .align 8
-.Lorbsense:
-        .long  0x00000000,0x0080ff00,.Lccwsense
-        .align 8
-.Lccwread:
-        .long  0x02200000+IPL_BS,0x00000000
-.Lccwsense:
-        .long  0x04200001,0x00000000
-.Lwaitpsw:
-	.long  0x020a0000,0x80000000+.Lioint
-
-.Lirb:	.long  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-.Lcr6:  .long  0xff000000
-        .align 8
-.Lcrash:.long  0x000a0000,0x00000000
-.Lldret:.long  0
-.Lsnsret: .long 0
-#endif  /* CONFIG_IPL_TAPE */
-
-#ifdef CONFIG_IPL_VM
-#define IPL_BS 0x730
-        .org   0
-        .long  0x00080000,0x80000000+iplstart  # The first 24 bytes are loaded
-        .long  0x02000018,0x60000050           # by ipl to addresses 0-23.
-        .long  0x02000068,0x60000050           # (a PSW and two CCWs).
-        .fill  80-24,1,0x40                    # bytes 24-79 are discarded !!
-        .long  0x020000f0,0x60000050           # The next 160 byte are loaded
-        .long  0x02000140,0x60000050           # to addresses 0x18-0xb7
-        .long  0x02000190,0x60000050           # They form the continuation
-        .long  0x020001e0,0x60000050           # of the CCW program started
-        .long  0x02000230,0x60000050           # by ipl and load the range
-        .long  0x02000280,0x60000050           # 0x0f0-0x730 from the image
-        .long  0x020002d0,0x60000050           # to the range 0x0f0-0x730
-        .long  0x02000320,0x60000050           # in memory. At the end of
-        .long  0x02000370,0x60000050           # the channel program the PSW
-        .long  0x020003c0,0x60000050           # at location 0 is loaded.
-        .long  0x02000410,0x60000050           # Initial processing starts
-        .long  0x02000460,0x60000050           # at 0xf0 = iplstart.
-        .long  0x020004b0,0x60000050
-        .long  0x02000500,0x60000050
-        .long  0x02000550,0x60000050
-        .long  0x020005a0,0x60000050
-        .long  0x020005f0,0x60000050
-        .long  0x02000640,0x60000050
-        .long  0x02000690,0x60000050
-        .long  0x020006e0,0x20000050
-
-        .org   0xf0
-#
-# subroutine for loading cards from the reader
-#
-.Lloader:	
-	la    %r3,.Lorb                        # r2 = address of orb into r2
-	la    %r5,.Lirb                        # r4 = address of irb
-        la    %r6,.Lccws              
-        la    %r7,20
-.Linit:
-        st    %r2,4(%r6)                       # initialize CCW data addresses
-        la    %r2,0x50(%r2)
-        la    %r6,8(%r6)
-        bct   7,.Linit
-
-        lctl  %c6,%c6,.Lcr6                    # set IO subclass mask
-	slr   %r2,%r2
-.Lldlp:
-        ssch  0(%r3)                           # load chunk of 1600 bytes
-        bnz   .Llderr
-.Lwait4irq:
-        mvc   0x78(8),.Lnewpsw                 # set up IO interrupt psw
-        lpsw  .Lwaitpsw              
-.Lioint:
-        c     %r1,0xb8                         # compare subchannel number
-	bne   .Lwait4irq
-	tsch  0(%r5)
-
-	slr   %r0,%r0
-	ic    %r0,8(%r5)                       # get device status
-	chi   %r0,8                            # channel end ?
-	be    .Lcont
-	chi   %r0,12                           # channel end + device end ?
-	be    .Lcont
-
-        l     %r0,4(%r5)
-        s     %r0,8(%r3)                       # r0/8 = number of ccws executed
-        mhi   %r0,10                           # *10 = number of bytes in ccws
-        lh    %r3,10(%r5)                      # get residual count
-        sr    %r0,%r3                          # #ccws*80-residual=#bytes read
-	ar    %r2,%r0
-	
-        br    %r14                             # r2 contains the total size
-
-.Lcont:
-	ahi   %r2,0x640                        # add 0x640 to total size
-        la    %r6,.Lccws             
-        la    %r7,20
-.Lincr:
-        l     %r0,4(%r6)                       # update CCW data addresses
-        ahi   %r0,0x640
-        st    %r0,4(%r6)
-        ahi   %r6,8
-        bct   7,.Lincr
-
-        b     .Lldlp
-.Llderr:
-        lpsw  .Lcrash              
-
-        .align 8
-.Lorb:	.long  0x00000000,0x0080ff00,.Lccws
-.Lirb:	.long  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-.Lcr6:  .long  0xff000000
-.Lloadp:.long  0,0
-        .align 8
-.Lcrash:.long  0x000a0000,0x00000000
-.Lnewpsw:
-        .long  0x00080000,0x80000000+.Lioint
-.Lwaitpsw:
-        .long  0x020a0000,0x80000000+.Lioint
-
-        .align 8
-.Lccws: .rept  19
-        .long  0x02600050,0x00000000
-        .endr
-        .long  0x02200050,0x00000000
-#endif  /* CONFIG_IPL_VM */
-
-iplstart:
-        lh    %r1,0xb8                         # test if subchannel number
-        bct   %r1,.Lnoload                     #  is valid
-	l     %r1,0xb8                         # load ipl subchannel number
-        la    %r2,IPL_BS                       # load start address
-        bas   %r14,.Lloader                    # load rest of ipl image
-        larl  %r12,_pstart                     # pointer to parameter area
-        st    %r1,IPL_DEVICE+4-PARMAREA(%r12)  # store ipl device number
-
-#
-# load parameter file from ipl device
-#
-.Lagain1:
- 	l     %r2,INITRD_START+4-PARMAREA(%r12)# use ramdisk location as temp
-        bas   %r14,.Lloader                    # load parameter file
-        ltr   %r2,%r2                          # got anything ?
-        bz    .Lnopf
-	chi   %r2,895
-	bnh   .Lnotrunc
-	la    %r2,895
-.Lnotrunc:
-	l     %r4,INITRD_START+4-PARMAREA(%r12)
- 	clc   0(3,%r4),.L_hdr		       # if it is HDRx
- 	bz    .Lagain1			       # skip dataset header
- 	clc   0(3,%r4),.L_eof		       # if it is EOFx
- 	bz    .Lagain1			       # skip dateset trailer
-        la    %r5,0(%r4,%r2)
-        lr    %r3,%r2
-.Lidebc:
-        tm    0(%r5),0x80                      # high order bit set ?
-        bo    .Ldocv                           #  yes -> convert from EBCDIC
-        ahi   %r5,-1
-        bct   %r3,.Lidebc
-        b     .Lnocv
-.Ldocv:
-        l     %r3,.Lcvtab
-        tr    0(256,%r4),0(%r3)                # convert parameters to ascii
-        tr    256(256,%r4),0(%r3)
-        tr    512(256,%r4),0(%r3)
-        tr    768(122,%r4),0(%r3)
-.Lnocv: la    %r3,COMMAND_LINE-PARMAREA(%r12)  # load adr. of command line
-	mvc   0(256,%r3),0(%r4)
-	mvc   256(256,%r3),256(%r4)
-	mvc   512(256,%r3),512(%r4)
-	mvc   768(122,%r3),768(%r4)
-        slr   %r0,%r0
-        b     .Lcntlp
-.Ldelspc:
-        ic    %r0,0(%r2,%r3)
-        chi   %r0,0x20                         # is it a space ?
-        be    .Lcntlp
-        ahi   %r2,1
-        b     .Leolp
-.Lcntlp:
-        brct  %r2,.Ldelspc
-.Leolp:
-        slr   %r0,%r0
-        stc   %r0,0(%r2,%r3)                   # terminate buffer
-.Lnopf:
-
-#
-# load ramdisk from ipl device
-#
-.Lagain2:
- 	l     %r2,INITRD_START+4-PARMAREA(%r12)# load adr. of ramdisk
-        bas   %r14,.Lloader                    # load ramdisk
- 	st    %r2,INITRD_SIZE+4-PARMAREA(%r12) # store size of ramdisk
-        ltr   %r2,%r2
-        bnz   .Lrdcont
-        st    %r2,INITRD_START+4-PARMAREA(%r12)# no ramdisk found, null it
-.Lrdcont:
-	l     %r2,INITRD_START+4-PARMAREA(%r12)
-	clc   0(3,%r2),.L_hdr		       # skip HDRx and EOFx 
-	bz    .Lagain2
-	clc   0(3,%r2),.L_eof
-	bz    .Lagain2
-
-#ifdef CONFIG_IPL_VM
-#
-# reset files in VM reader
-#
-        stidp __LC_CPUID                       # store cpuid
-	tm    __LC_CPUID,0xff                  # running VM ?
-	bno   .Lnoreset
-        la    %r2,.Lreset              
-        lhi   %r3,26
-	diag  %r2,%r3,8
-	la    %r5,.Lirb
-	stsch 0(%r5)			       # check if irq is pending
-	tm    30(%r5),0x0f		       # by verifying if any of the
-	bnz   .Lwaitforirq		       # activity or status control
-	tm    31(%r5),0xff		       # bits is set in the schib
-	bz    .Lnoreset
-.Lwaitforirq:
-	mvc   0x78(8),.Lrdrnewpsw	       # set up IO interrupt psw
-.Lwaitrdrirq:
-	lpsw  .Lrdrwaitpsw
-.Lrdrint:
-	c     %r1,0xb8			       # compare subchannel number
-	bne   .Lwaitrdrirq
-	la    %r5,.Lirb
-	tsch  0(%r5)
-.Lnoreset:
-	b     .Lnoload
-
-	.align 8
-.Lrdrnewpsw:
-	.long  0x00080000,0x80000000+.Lrdrint
-.Lrdrwaitpsw:
-	.long  0x020a0000,0x80000000+.Lrdrint
-#endif
-
-#
-# everything loaded, go for it
-#
-.Lnoload:
-        l     %r1,.Lstartup
-        br    %r1
-
-.Lstartup: .long startup
-.Lcvtab:.long  _ebcasc                         # ebcdic to ascii table
-.Lreset:.byte  0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
-        .byte  0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
-        .byte  0xc8,0xd6,0xd3,0xc4             # "change rdr all keep nohold"
-.L_eof: .long  0xc5d6c600       /* C'EOF' */
-.L_hdr: .long  0xc8c4d900       /* C'HDR' */
-#endif  /* CONFIG_IPL */
-
-#
-# SALIPL loader support. Based on a patch by Rob van der Heij.
-# This entry point is called directly from the SALIPL loader and
-# doesn't need a builtin ipl record.
-#
-        .org  0x800
-	.globl start
-start:
-	stm   %r0,%r15,0x07b0		# store registers
-	basr  %r12,%r0
-.base:
-	l     %r11,.parm
-	l     %r8,.cmd			# pointer to command buffer
-
-	ltr   %r9,%r9			# do we have SALIPL parameters?
-	bp    .sk8x8
-
-	mvc   0(64,%r8),0x00b0		# copy saved registers
-	xc    64(240-64,%r8),0(%r8)	# remainder of buffer
-	tr    0(64,%r8),.lowcase	
-	b     .gotr
-.sk8x8:
-	mvc   0(240,%r8),0(%r9)		# copy iplparms into buffer
-.gotr:
-	l     %r10,.tbl			# EBCDIC to ASCII table
-	tr    0(240,%r8),0(%r10)
-	stidp __LC_CPUID		# Are we running on VM maybe
-	cli   __LC_CPUID,0xff
-	bnz   .test
-	.long 0x83300060		# diag 3,0,x'0060' - storage size
-	b     .done
-.test:
-	mvc   0x68(8),.pgmnw		# set up pgm check handler
-	l     %r2,.fourmeg
-	lr    %r3,%r2
-	bctr  %r3,%r0			# 4M-1
-.loop:  iske  %r0,%r3
-	ar    %r3,%r2
-.pgmx:
-	sr    %r3,%r2
-	la    %r3,1(%r3)
-.done:
-	l     %r1,.memsize
-	st    %r3,4(%r1)
-	slr   %r0,%r0
-	st    %r0,INITRD_SIZE+4-PARMAREA(%r11)
-	st    %r0,INITRD_START+4-PARMAREA(%r11)
-	j     startup                   # continue with startup
-.tbl:	.long _ebcasc			# translate table
-.cmd:	.long COMMAND_LINE		# address of command line buffer
-.parm:	.long PARMAREA
-.fourmeg: .long 0x00400000      	# 4M
-.pgmnw:	.long 0x00080000,.pgmx
-.memsize: .long memory_size
-.lowcase:
-	.byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 
-	.byte 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
-	.byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17 
-	.byte 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
-	.byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 
-	.byte 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f
-	.byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37 
-	.byte 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f
-	.byte 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47 
-	.byte 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f
-	.byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57 
-	.byte 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f
-	.byte 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67 
-	.byte 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f
-	.byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77 
-	.byte 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f
-
-	.byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87 
-	.byte 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f
-	.byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97 
-	.byte 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f
-	.byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7 
-	.byte 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf
-	.byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7 
-	.byte 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf
-	.byte 0xc0,0x81,0x82,0x83,0x84,0x85,0x86,0x87	# .abcdefg 
-	.byte 0x88,0x89,0xca,0xcb,0xcc,0xcd,0xce,0xcf	# hi
-	.byte 0xd0,0x91,0x92,0x93,0x94,0x95,0x96,0x97 	# .jklmnop
-	.byte 0x98,0x99,0xda,0xdb,0xdc,0xdd,0xde,0xdf	# qr
-	.byte 0xe0,0xe1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7	# ..stuvwx
-	.byte 0xa8,0xa9,0xea,0xeb,0xec,0xed,0xee,0xef	# yz
-	.byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7 
-	.byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
-
-#
-# startup-code at 0x10000, running in real mode
+# startup-code at 0x10000, running in absolute addressing mode
 # this is called either by the ipl loader or directly by PSW restart
 # or linload or SALIPL
 #
@@ -530,7 +65,7 @@
 	be    .Lfchunk-.LPG1(%r13)	# leave
 	chi   %r1,2
 	be    .Lservicecall-.LPG1(%r13)
-	lpsw  .Lwaitsclp-.LPG1(%r13)
+	lpswe .Lwaitsclp-.LPG1(%r13)
 .Lsclph:
 	lh    %r1,.Lsccbr-PARMAREA(%r4)
 	chi   %r1,0x10			# 0x0010 is the sucess code
@@ -567,8 +102,7 @@
 .Lcr:
 	.quad 0x00  # place holder for cr0
 .Lwaitsclp:
-	.long 0x020A0000
-	.quad .Lsclph
+	.quad  0x0102000180000000,.Lsclph
 .Lrcp:
 	.int 0x00120001 # Read SCP forced code
 .Lrcp2:
@@ -751,62 +285,7 @@
 	.global _pend
 _pend:	
 
-.Lget_ipl_device:
-	basr  %r12,0
-.LPG2:	l     %r1,0xb8			# get sid
-	sll   %r1,15			# test if subchannel is enabled
-	srl   %r1,31
-	ltr   %r1,%r1
-	bz    0(%r14)			# subchannel disabled
-	l     %r1,0xb8
-	la    %r5,.Lipl_schib-.LPG2(%r12)
-	stsch 0(%r5)		        # get schib of subchannel
-	bnz   0(%r14)			# schib not available
-	tm    5(%r5),0x01		# devno valid?
-	bno   0(%r14)
-	la    %r6,ipl_parameter_flags-.LPG2(%r12)
-	oi    3(%r6),0x01		# set flag
-	la    %r2,ipl_devno-.LPG2(%r12)
-	mvc   0(2,%r2),6(%r5)		# store devno
-	tm    4(%r5),0x80		# qdio capable device?
-	bno   0(%r14)
-	oi    3(%r6),0x02		# set flag
-
-	# copy ipl parameters
-
-	lhi   %r0,4096
-	l     %r2,20(%r0)		# get address of parameter list
-	lhi   %r3,IPL_PARMBLOCK_ORIGIN
-	st    %r3,20(%r0)
-	lhi   %r4,1
-	cr    %r2,%r3			# start parameters < destination ?
-	jl    0f
-	lhi   %r1,1			# copy direction is upwards
-	j     1f
-0:	lhi   %r1,-1			# copy direction is downwards
-	ar    %r2,%r0
-	ar    %r3,%r0
-	ar    %r2,%r1
-	ar    %r3,%r1
-1:	mvc   0(1,%r3),0(%r2)		# finally copy ipl parameters
-	ar    %r3,%r1
-	ar    %r2,%r1
-	sr    %r0,%r4
-	jne   1b
-	b     0(%r14)
-
-	.align 4
-.Lipl_schib:
-	.rept 13
-	.long 0
-	.endr
-
-	.globl ipl_parameter_flags
-ipl_parameter_flags:
-	.long 0
-	.globl ipl_devno
-ipl_devno:
-	.word 0
+	GET_IPL_DEVICE
 
 #ifdef CONFIG_SHARED_KERNEL
 	.org   0x100000
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 9a1d958..c36353e 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -237,6 +237,8 @@
  */
 static inline void stop_hz_timer(void)
 {
+	unsigned long flags;
+	unsigned long seq, next;
 	__u64 timer, todval;
 
 	if (sysctl_hz_timer != 0)
@@ -257,7 +259,11 @@
 	 * This cpu is going really idle. Set up the clock comparator
 	 * for the next event.
 	 */
-	timer = (__u64) (next_timer_interrupt() - jiffies) + jiffies_64;
+	next = next_timer_interrupt();
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
+		timer = (__u64)(next - jiffies) + jiffies_64;
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 	todval = -1ULL;
 	/* Be careful about overflows. */
 	if (timer < (-1ULL / CLK_TICKS_PER_JIFFY)) {
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 6b8703e..c5bd36f 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -57,7 +57,6 @@
 
 extern pgm_check_handler_t do_protection_exception;
 extern pgm_check_handler_t do_dat_exception;
-extern pgm_check_handler_t do_pseudo_page_fault;
 #ifdef CONFIG_PFAULT
 extern int pfault_init(void);
 extern void pfault_fini(void);
@@ -676,20 +675,6 @@
 	panic("Corrupt kernel stack, can't continue.");
 }
 
-#ifndef CONFIG_ARCH_S390X
-static int
-pagex_reboot_event(struct notifier_block *this, unsigned long event, void *ptr)
-{
-	if (MACHINE_IS_VM)
-		cpcmd("SET PAGEX OFF", NULL, 0, NULL);
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block pagex_reboot_notifier = {
-	.notifier_call = &pagex_reboot_event,
-};
-#endif
-
 /* init is done in lowcore.S and head.S */
 
 void __init trap_init(void)
@@ -717,9 +702,7 @@
         pgm_check_table[0x11] = &do_dat_exception;
         pgm_check_table[0x12] = &translation_exception;
         pgm_check_table[0x13] = &special_op_exception;
-#ifndef CONFIG_ARCH_S390X
- 	pgm_check_table[0x14] = &do_pseudo_page_fault;
-#else /* CONFIG_ARCH_S390X */
+#ifdef CONFIG_ARCH_S390X
         pgm_check_table[0x38] = &do_dat_exception;
 	pgm_check_table[0x39] = &do_dat_exception;
 	pgm_check_table[0x3A] = &do_dat_exception;
@@ -731,12 +714,10 @@
 	pgm_check_table[0x40] = &do_monitor_call;
 
 	if (MACHINE_IS_VM) {
-		/*
-		 * First try to get pfault pseudo page faults going.
-		 * If this isn't available turn on pagex page faults.
-		 */
 #ifdef CONFIG_PFAULT
-		/* request the 0x2603 external interrupt */
+		/*
+		 * Try to get pfault pseudo page faults going.
+		 */
 		if (register_early_external_interrupt(0x2603, pfault_interrupt,
 						      &ext_int_pfault) != 0)
 			panic("Couldn't request external interrupt 0x2603");
@@ -748,9 +729,5 @@
 		unregister_early_external_interrupt(0x2603, pfault_interrupt,
 						    &ext_int_pfault);
 #endif
-#ifndef CONFIG_ARCH_S390X
-		register_reboot_notifier(&pagex_reboot_notifier);
-		cpcmd("SET PAGEX ON", NULL, 0, NULL);
-#endif
 	}
 }
diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c
index c534810..506a33b 100644
--- a/arch/s390/mm/extmem.c
+++ b/arch/s390/mm/extmem.c
@@ -234,8 +234,8 @@
 	rc = 0;
 
  out_free:
-	if (qin) kfree(qin);
-	if (qout) kfree(qout);
+	kfree(qin);
+	kfree(qout);
 	return rc;
 }
 
@@ -394,7 +394,7 @@
 				segtype_string[seg->vm_segtype]);
 	goto out;
  out_free:
-	kfree (seg);
+	kfree(seg);
  out:
 	return rc;
 }
@@ -505,7 +505,7 @@
 	list_del(&seg->list);
 	dcss_diag(DCSS_PURGESEG, seg->dcss_name,
 		  &dummy, &dummy);
-	kfree (seg);
+	kfree(seg);
  out_unlock:
 	spin_unlock(&dcss_lock);
 	return rc;
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 856a971..64e32da 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -352,115 +352,6 @@
 	do_exception(regs, error_code & 0xff, 0);
 }
 
-#ifndef CONFIG_ARCH_S390X
-
-typedef struct _pseudo_wait_t {
-       struct _pseudo_wait_t *next;
-       wait_queue_head_t queue;
-       unsigned long address;
-       int resolved;
-} pseudo_wait_t;
-
-static pseudo_wait_t *pseudo_lock_queue = NULL;
-static spinlock_t pseudo_wait_spinlock; /* spinlock to protect lock queue */
-
-/*
- * This routine handles 'pagex' pseudo page faults.
- */
-asmlinkage void
-do_pseudo_page_fault(struct pt_regs *regs, unsigned long error_code)
-{
-        pseudo_wait_t wait_struct;
-        pseudo_wait_t *ptr, *last, *next;
-        unsigned long address;
-
-        /*
-         * get the failing address
-         * more specific the segment and page table portion of
-         * the address
-         */
-        address = S390_lowcore.trans_exc_code & 0xfffff000;
-
-        if (address & 0x80000000) {
-                /* high bit set -> a page has been swapped in by VM */
-                address &= 0x7fffffff;
-                spin_lock(&pseudo_wait_spinlock);
-                last = NULL;
-                ptr = pseudo_lock_queue;
-                while (ptr != NULL) {
-                        next = ptr->next;
-                        if (address == ptr->address) {
-				 /*
-                                 * This is one of the processes waiting
-                                 * for the page. Unchain from the queue.
-                                 * There can be more than one process
-                                 * waiting for the same page. VM presents
-                                 * an initial and a completion interrupt for
-                                 * every process that tries to access a 
-                                 * page swapped out by VM. 
-                                 */
-                                if (last == NULL)
-                                        pseudo_lock_queue = next;
-                                else
-                                        last->next = next;
-                                /* now wake up the process */
-                                ptr->resolved = 1;
-                                wake_up(&ptr->queue);
-                        } else
-                                last = ptr;
-                        ptr = next;
-                }
-                spin_unlock(&pseudo_wait_spinlock);
-        } else {
-                /* Pseudo page faults in kernel mode is a bad idea */
-                if (!(regs->psw.mask & PSW_MASK_PSTATE)) {
-                        /*
-			 * VM presents pseudo page faults if the interrupted
-			 * state was not disabled for interrupts. So we can
-			 * get pseudo page fault interrupts while running
-			 * in kernel mode. We simply access the page here
-			 * while we are running disabled. VM will then swap
-			 * in the page synchronously.
-                         */
-                         if (check_user_space(regs, error_code) == 0)
-                                 /* dereference a virtual kernel address */
-                                 __asm__ __volatile__ (
-                                         "  ic 0,0(%0)"
-                                         : : "a" (address) : "0");
-                         else
-                                 /* dereference a virtual user address */
-                                 __asm__ __volatile__ (
-                                         "  la   2,0(%0)\n"
-                                         "  sacf 512\n"
-                                         "  ic   2,0(2)\n"
-					 "0:sacf 0\n"
-					 ".section __ex_table,\"a\"\n"
-					 "  .align 4\n"
-					 "  .long  0b,0b\n"
-					 ".previous"
-                                         : : "a" (address) : "2" );
-
-                        return;
-                }
-		/* initialize and add element to pseudo_lock_queue */
-                init_waitqueue_head (&wait_struct.queue);
-                wait_struct.address = address;
-                wait_struct.resolved = 0;
-                spin_lock(&pseudo_wait_spinlock);
-                wait_struct.next = pseudo_lock_queue;
-                pseudo_lock_queue = &wait_struct;
-                spin_unlock(&pseudo_wait_spinlock);
-		/*
-		 * The instruction that caused the program check will
-		 * be repeated. Don't signal single step via SIGTRAP.
-		 */
-		clear_tsk_thread_flag(current, TIF_SINGLE_STEP);
-                /* go to sleep */
-                wait_event(wait_struct.queue, wait_struct.resolved);
-        }
-}
-#endif /* CONFIG_ARCH_S390X */
-
 #ifdef CONFIG_PFAULT 
 /*
  * 'pfault' pseudo page faults routines.
@@ -508,7 +399,7 @@
 		"   .quad  0b,1b\n"
 #endif /* CONFIG_ARCH_S390X */
 		".previous"
-                : "=d" (rc) : "a" (&refbk) : "cc" );
+                : "=d" (rc) : "a" (&refbk), "m" (refbk) : "cc" );
         __ctl_set_bit(0, 9);
         return rc;
 }
@@ -532,7 +423,7 @@
 		"   .quad  0b,0b\n"
 #endif /* CONFIG_ARCH_S390X */
 		".previous"
-		: : "a" (&refbk) : "cc" );
+		: : "a" (&refbk), "m" (refbk) : "cc" );
 }
 
 asmlinkage void
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 3e804c7..64f5ae0 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -490,16 +490,6 @@
        depends on CPU_SUBTYPE_ST40STB1 || CPU_SUBTYPE_ST40GX1
        default y
 
-config ARCH_DISCONTIGMEM_ENABLE
-	bool
-	depends on SH_HP690
-	default y
-	help
-	  Say Y to upport efficient handling of discontiguous physical memory,
-	  for architectures which are either NUMA (Non-Uniform Memory Access)
-	  or have huge holes in the physical address space for other reasons.
-	  See <file:Documentation/vm/numa> for more.
-
 source "mm/Kconfig"
 
 config ZERO_PAGE_OFFSET
@@ -770,24 +760,6 @@
 
 endmenu
 
-menu "SH initrd options"
-	depends on BLK_DEV_INITRD
-
-config EMBEDDED_RAMDISK
-	bool "Embed root filesystem ramdisk into the kernel"
-
-config EMBEDDED_RAMDISK_IMAGE
-	string "Filename of gziped ramdisk image"
-	depends on EMBEDDED_RAMDISK
-	default "ramdisk.gz"
-	help
-	  This is the filename of the ramdisk image to be built into the
-	  kernel.  Relative pathnames are relative to arch/sh/ramdisk/.
-	  The ramdisk image is not part of the kernel distribution; you must
-	  provide one yourself.
-
-endmenu
-
 source "net/Kconfig"
 
 source "drivers/Kconfig"
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index 4a30490..67192d6 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -60,14 +60,6 @@
 
 core-y				+= arch/sh/kernel/ arch/sh/mm/
 
-#
-# ramdisk/initrd support
-# You need a compressed ramdisk image, named
-# CONFIG_EMBEDDED_RAMDISK_IMAGE. Relative pathnames
-# are relative to arch/sh/ramdisk/.
-#
-core-$(CONFIG_EMBEDDED_RAMDISK)	+= arch/sh/ramdisk/
-
 # Boards
 machdir-$(CONFIG_SH_SOLUTION_ENGINE)		:= se/770x
 machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE)	:= se/7751
diff --git a/arch/sh/drivers/Makefile b/arch/sh/drivers/Makefile
index bd6726c..338c372 100644
--- a/arch/sh/drivers/Makefile
+++ b/arch/sh/drivers/Makefile
@@ -2,6 +2,7 @@
 # Makefile for the Linux SuperH-specific device drivers.
 #
 
-obj-$(CONFIG_PCI)	+= pci/
-obj-$(CONFIG_SH_DMA)	+= dma/
+obj-$(CONFIG_PCI)		+= pci/
+obj-$(CONFIG_SH_DMA)		+= dma/
+obj-$(CONFIG_SUPERHYWAY)	+= superhyway/
 
diff --git a/arch/sh/drivers/superhyway/Makefile b/arch/sh/drivers/superhyway/Makefile
new file mode 100644
index 0000000..5b8e0c7
--- /dev/null
+++ b/arch/sh/drivers/superhyway/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for the SuperHyway specific kernel interface routines under Linux.
+#
+
+obj-$(CONFIG_CPU_SUBTYPE_SH4_202)	+= ops-sh4-202.o
+
diff --git a/arch/sh/drivers/superhyway/ops-sh4-202.c b/arch/sh/drivers/superhyway/ops-sh4-202.c
new file mode 100644
index 0000000..a55c98a
--- /dev/null
+++ b/arch/sh/drivers/superhyway/ops-sh4-202.c
@@ -0,0 +1,171 @@
+/*
+ * arch/sh/drivers/superhyway/ops-sh4-202.c
+ *
+ * SuperHyway bus support for SH4-202
+ *
+ * Copyright (C) 2005  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.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/superhyway.h>
+#include <linux/string.h>
+#include <asm/addrspace.h>
+#include <asm/io.h>
+
+#define PHYS_EMI_CBLOCK		P4SEGADDR(0x1ec00000)
+#define PHYS_EMI_DBLOCK		P4SEGADDR(0x08000000)
+#define PHYS_FEMI_CBLOCK	P4SEGADDR(0x1f800000)
+#define PHYS_FEMI_DBLOCK	P4SEGADDR(0x00000000)
+
+#define PHYS_EPBR_BLOCK		P4SEGADDR(0x1de00000)
+#define PHYS_DMAC_BLOCK		P4SEGADDR(0x1fa00000)
+#define PHYS_PBR_BLOCK		P4SEGADDR(0x1fc00000)
+
+static struct resource emi_resources[] = {
+	[0] = {
+		.start	= PHYS_EMI_CBLOCK,
+		.end	= PHYS_EMI_CBLOCK + 0x00300000 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= PHYS_EMI_DBLOCK,
+		.end	= PHYS_EMI_DBLOCK + 0x08000000 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct superhyway_device emi_device = {
+	.name		= "emi",
+	.num_resources	= ARRAY_SIZE(emi_resources),
+	.resource	= emi_resources,
+};
+
+static struct resource femi_resources[] = {
+	[0] = {
+		.start	= PHYS_FEMI_CBLOCK,
+		.end	= PHYS_FEMI_CBLOCK + 0x00100000 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= PHYS_FEMI_DBLOCK,
+		.end	= PHYS_FEMI_DBLOCK + 0x08000000 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct superhyway_device femi_device = {
+	.name		= "femi",
+	.num_resources	= ARRAY_SIZE(femi_resources),
+	.resource	= femi_resources,
+};
+
+static struct resource epbr_resources[] = {
+	[0] = {
+		.start	= P4SEGADDR(0x1e7ffff8),
+		.end	= P4SEGADDR(0x1e7ffff8 + (sizeof(u32) * 2) - 1),
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= PHYS_EPBR_BLOCK,
+		.end	= PHYS_EPBR_BLOCK + 0x00a00000 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct superhyway_device epbr_device = {
+	.name		= "epbr",
+	.num_resources	= ARRAY_SIZE(epbr_resources),
+	.resource	= epbr_resources,
+};
+
+static struct resource dmac_resource = {
+	.start	= PHYS_DMAC_BLOCK,
+	.end	= PHYS_DMAC_BLOCK + 0x00100000 - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct superhyway_device dmac_device = {
+	.name		= "dmac",
+	.num_resources	= 1,
+	.resource	= &dmac_resource,
+};
+
+static struct resource pbr_resources[] = {
+	[0] = {
+		.start	= P4SEGADDR(0x1ffffff8),
+		.end	= P4SEGADDR(0x1ffffff8 + (sizeof(u32) * 2) - 1),
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= PHYS_PBR_BLOCK,
+		.end	= PHYS_PBR_BLOCK + 0x00400000 - (sizeof(u32) * 2) - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct superhyway_device pbr_device = {
+	.name		= "pbr",
+	.num_resources	= ARRAY_SIZE(pbr_resources),
+	.resource	= pbr_resources,
+};
+
+static struct superhyway_device *sh4202_devices[] __initdata = {
+	&emi_device, &femi_device, &epbr_device, &dmac_device, &pbr_device,
+};
+
+static int sh4202_read_vcr(unsigned long base, struct superhyway_vcr_info *vcr)
+{
+	u32 vcrh, vcrl;
+	u64 tmp;
+
+	/*
+	 * XXX: Even though the SH4-202 Evaluation Device documentation
+	 * indicates that VCRL is mapped first with VCRH at a + 0x04
+	 * offset, the opposite seems to be true.
+	 *
+	 * Some modules (PBR and ePBR for instance) also appear to have
+	 * VCRL/VCRH flipped in the documentation, but on the SH4-202
+	 * itself it appears that these are all consistently mapped with
+	 * VCRH preceeding VCRL.
+	 *
+	 * Do not trust the documentation, for it is evil.
+	 */
+	vcrh = ctrl_inl(base);
+	vcrl = ctrl_inl(base + sizeof(u32));
+
+	tmp = ((u64)vcrh << 32) | vcrl;
+	memcpy(vcr, &tmp, sizeof(u64));
+
+	return 0;
+}
+
+static int sh4202_write_vcr(unsigned long base, struct superhyway_vcr_info vcr)
+{
+	u64 tmp = *(u64 *)&vcr;
+
+	ctrl_outl((tmp >> 32) & 0xffffffff, base);
+	ctrl_outl(tmp & 0xffffffff, base + sizeof(u32));
+
+	return 0;
+}
+
+static struct superhyway_ops sh4202_superhyway_ops = {
+	.read_vcr	= sh4202_read_vcr,
+	.write_vcr	= sh4202_write_vcr,
+};
+
+struct superhyway_bus superhyway_channels[] = {
+	{ &sh4202_superhyway_ops, },
+	{ 0, },
+};
+
+int __init superhyway_scan_bus(struct superhyway_bus *bus)
+{
+	return superhyway_add_devices(bus, sh4202_devices,
+				      ARRAY_SIZE(sh4202_devices));
+}
+
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
index 1fbe5a4..1a8be06 100644
--- a/arch/sh/kernel/ptrace.c
+++ b/arch/sh/kernel/ptrace.c
@@ -80,48 +80,11 @@
 	/* nothing to do.. */
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-	struct task_struct *child;
 	struct user * dummy = NULL;
 	int ret;
 
-	lock_kernel();
-	ret = -EPERM;
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-		ret = security_ptrace(current->parent, current);
-		if (ret)
-			goto out;
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
-		goto out;
-	}
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (!child)
-		goto out;
-
-	ret = -EPERM;
-	if (pid == 1)		/* you may not mess with init */
-		goto out_tsk;
-
-	if (request == PTRACE_ATTACH) {
-		ret = ptrace_attach(child);
-		goto out_tsk;
-	}
-
-	ret = ptrace_check_attach(child, request == PTRACE_KILL);
-	if (ret < 0)
-		goto out_tsk;
-
 	switch (request) {
 	/* when I and D space are separate, these will need to be fixed. */
 	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
@@ -289,10 +252,7 @@
 		ret = ptrace_request(child, request, addr, data);
 		break;
 	}
-out_tsk:
-	put_task_struct(child);
-out:
-	unlock_kernel();
+
 	return ret;
 }
 
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 25b9d9e..036050b 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -83,9 +83,9 @@
 /* ... */
 #define COMMAND_LINE ((char *) (PARAM+0x100))
 
-#define RAMDISK_IMAGE_START_MASK  	0x07FF
+#define RAMDISK_IMAGE_START_MASK	0x07FF
 #define RAMDISK_PROMPT_FLAG		0x8000
-#define RAMDISK_LOAD_FLAG		0x4000	
+#define RAMDISK_LOAD_FLAG		0x4000
 
 static char command_line[COMMAND_LINE_SIZE] = { 0, };
 
@@ -284,18 +284,6 @@
 #define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
 #define PFN_PHYS(x)	((x) << PAGE_SHIFT)
 
-#ifdef CONFIG_DISCONTIGMEM
-	NODE_DATA(0)->bdata = &discontig_node_bdata[0];
-	NODE_DATA(1)->bdata = &discontig_node_bdata[1];
-
-	bootmap_size = init_bootmem_node(NODE_DATA(1), 
-					 PFN_UP(__MEMORY_START_2ND),
-					 PFN_UP(__MEMORY_START_2ND),
-					 PFN_DOWN(__MEMORY_START_2ND+__MEMORY_SIZE_2ND));
-	free_bootmem_node(NODE_DATA(1), __MEMORY_START_2ND, __MEMORY_SIZE_2ND);
-	reserve_bootmem_node(NODE_DATA(1), __MEMORY_START_2ND, bootmap_size);
-#endif
-
 	/*
 	 * Find the highest page frame number we have available
 	 */
@@ -306,10 +294,10 @@
 	 */
 	max_low_pfn = max_pfn;
 
- 	/*
+	/*
 	 * Partially used pages are not usable - thus
 	 * we are rounding upwards:
- 	 */
+	 */
 	start_pfn = PFN_UP(__pa(_end));
 
 	/*
@@ -360,12 +348,12 @@
 	reserve_bootmem_node(NODE_DATA(0), __MEMORY_START, PAGE_SIZE);
 
 #ifdef CONFIG_BLK_DEV_INITRD
- 	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
- 	if (&__rd_start != &__rd_end) {
+	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+	if (&__rd_start != &__rd_end) {
 		LOADER_TYPE = 1;
 		INITRD_START = PHYSADDR((unsigned long)&__rd_start) - __MEMORY_START;
 		INITRD_SIZE = (unsigned long)&__rd_end - (unsigned long)&__rd_start;
- 	}
+	}
 
 	if (LOADER_TYPE && INITRD_START) {
 		if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 4e9c854..e342565f 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -51,11 +51,6 @@
 #define MAX_LOW_PFN	(NODE_DATA(0)->bdata->node_low_pfn)
 #endif
 
-#ifdef CONFIG_DISCONTIGMEM
-pg_data_t discontig_page_data[MAX_NUMNODES];
-bootmem_data_t discontig_node_bdata[MAX_NUMNODES];
-#endif
-
 void (*copy_page)(void *from, void *to);
 void (*clear_page)(void *to);
 
@@ -216,15 +211,6 @@
 #endif
 	NODE_DATA(0)->node_mem_map = NULL;
 	free_area_init_node(0, NODE_DATA(0), zones_size, __MEMORY_START >> PAGE_SHIFT, 0);
-
-#ifdef CONFIG_DISCONTIGMEM
-	/*
-	 * And for discontig, do some more fixups on the zone sizes..
-	 */
-	zones_size[ZONE_DMA] = __MEMORY_SIZE_2ND >> PAGE_SHIFT;
-	zones_size[ZONE_NORMAL] = 0;
-	free_area_init_node(1, NODE_DATA(1), zones_size, __MEMORY_START_2ND >> PAGE_SHIFT, 0);
-#endif
 }
 
 void __init mem_init(void)
@@ -248,7 +234,7 @@
 	memset(empty_zero_page, 0, PAGE_SIZE);
 	__flush_wback_region(empty_zero_page, PAGE_SIZE);
 
-	/* 
+	/*
 	 * Setup wrappers for copy/clear_page(), these will get overridden
 	 * later in the boot process if a better method is available.
 	 */
@@ -257,9 +243,6 @@
 
 	/* this will put all low memory onto the freelists */
 	totalram_pages += free_all_bootmem_node(NODE_DATA(0));
-#ifdef CONFIG_DISCONTIGMEM
-	totalram_pages += free_all_bootmem_node(NODE_DATA(1));
-#endif
 	reservedpages = 0;
 	for (tmp = 0; tmp < num_physpages; tmp++)
 		/*
@@ -286,7 +269,7 @@
 void free_initmem(void)
 {
 	unsigned long addr;
-	
+
 	addr = (unsigned long)(&__init_begin);
 	for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
 		ClearPageReserved(virt_to_page(addr));
diff --git a/arch/sh/mm/tlb-sh3.c b/arch/sh/mm/tlb-sh3.c
index 7a0d5c1..46b09e2 100644
--- a/arch/sh/mm/tlb-sh3.c
+++ b/arch/sh/mm/tlb-sh3.c
@@ -40,12 +40,17 @@
 		return;
 
 #if defined(CONFIG_SH7705_CACHE_32KB)
-	struct page *page;
-	page = pte_page(pte);
-	if (VALID_PAGE(page) && !test_bit(PG_mapped, &page->flags)) {
-		unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
-		__flush_wback_region((void *)P1SEGADDR(phys), PAGE_SIZE);
-		__set_bit(PG_mapped, &page->flags);
+	{
+		struct page *page = pte_page(pte);
+		unsigned long pfn = pte_pfn(pte);
+
+		if (pfn_valid(pfn) && !test_bit(PG_mapped, &page->flags)) {
+			unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
+
+			__flush_wback_region((void *)P1SEGADDR(phys),
+					     PAGE_SIZE);
+			__set_bit(PG_mapped, &page->flags);
+		}
 	}
 #endif
 
@@ -80,7 +85,7 @@
 	 */
 	addr = MMU_TLB_ADDRESS_ARRAY | (page & 0x1F000);
 	data = (page & 0xfffe0000) | asid; /* VALID bit is off */
-	
+
 	if ((cpu_data->flags & CPU_HAS_MMU_PAGE_ASSOC)) {
 		addr |= MMU_PAGE_ASSOC_BIT;
 		ways = 1;	/* we already know the way .. */
diff --git a/arch/sh/ramdisk/Makefile b/arch/sh/ramdisk/Makefile
deleted file mode 100644
index 99e1c68..0000000
--- a/arch/sh/ramdisk/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Makefile for a ramdisk image
-#
-
-obj-y += ramdisk.o
-
-
-O_FORMAT = $(shell $(OBJDUMP) -i | head -n 2 | grep elf32)
-img := $(subst ",,$(CONFIG_EMBEDDED_RAMDISK_IMAGE))
-# add $(src) when $(img) is relative
-img := $(subst $(src)//,/,$(src)/$(img))
-
-quiet_cmd_ramdisk = LD      $@
-define cmd_ramdisk
-	$(LD) -T $(srctree)/$(src)/ld.script -b binary --oformat $(O_FORMAT) \
-		-o $@ $(img)
-endef
-
-$(obj)/ramdisk.o: $(img) $(srctree)/$(src)/ld.script
-	$(call cmd,ramdisk)
diff --git a/arch/sh/ramdisk/ld.script b/arch/sh/ramdisk/ld.script
deleted file mode 100644
index 94beee2..0000000
--- a/arch/sh/ramdisk/ld.script
+++ /dev/null
@@ -1,9 +0,0 @@
-OUTPUT_ARCH(sh)
-SECTIONS
-{
-  .initrd :
-  {
-       *(.data)
-  }
-}
-
diff --git a/arch/sh64/kernel/ptrace.c b/arch/sh64/kernel/ptrace.c
index 71f2eec..cd22e94 100644
--- a/arch/sh64/kernel/ptrace.c
+++ b/arch/sh64/kernel/ptrace.c
@@ -28,6 +28,7 @@
 #include <linux/ptrace.h>
 #include <linux/user.h>
 #include <linux/signal.h>
+#include <linux/syscalls.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -121,61 +122,11 @@
 	return 0;
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-	struct task_struct *child;
-	extern void poke_real_address_q(unsigned long long addr, unsigned long long data);
-#define WPC_DBRMODE 0x0d104008
-	static int first_call = 1;
 	int ret;
 
-	lock_kernel();
-
-	if (first_call) {
-		/* Set WPC.DBRMODE to 0.  This makes all debug events get
-		 * delivered through RESVEC, i.e. into the handlers in entry.S.
-		 * (If the kernel was downloaded using a remote gdb, WPC.DBRMODE
-		 * would normally be left set to 1, which makes debug events get
-		 * delivered through DBRVEC, i.e. into the remote gdb's
-		 * handlers.  This prevents ptrace getting them, and confuses
-		 * the remote gdb.) */
-		printk("DBRMODE set to 0 to permit native debugging\n");
-		poke_real_address_q(WPC_DBRMODE, 0);
-		first_call = 0;
-	}
-
-	ret = -EPERM;
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
-		goto out;
-	}
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (!child)
-		goto out;
-
-	ret = -EPERM;
-	if (pid == 1)		/* you may not mess with init */
-		goto out_tsk;
-
-	if (request == PTRACE_ATTACH) {
-		ret = ptrace_attach(child);
-			goto out_tsk;
-		}
-
-	ret = ptrace_check_attach(child, request == PTRACE_KILL);
-	if (ret < 0)
-		goto out_tsk;
-
 	switch (request) {
 	/* when I and D space are separate, these will need to be fixed. */
 	case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -313,13 +264,33 @@
 		ret = ptrace_request(child, request, addr, data);
 		break;
 	}
-out_tsk:
-	put_task_struct(child);
-out:
-	unlock_kernel();
 	return ret;
 }
 
+asmlinkage int sh64_ptrace(long request, long pid, long addr, long data)
+{
+	extern void poke_real_address_q(unsigned long long addr, unsigned long long data);
+#define WPC_DBRMODE 0x0d104008
+	static int first_call = 1;
+
+	lock_kernel();
+	if (first_call) {
+		/* Set WPC.DBRMODE to 0.  This makes all debug events get
+		 * delivered through RESVEC, i.e. into the handlers in entry.S.
+		 * (If the kernel was downloaded using a remote gdb, WPC.DBRMODE
+		 * would normally be left set to 1, which makes debug events get
+		 * delivered through DBRVEC, i.e. into the remote gdb's
+		 * handlers.  This prevents ptrace getting them, and confuses
+		 * the remote gdb.) */
+		printk("DBRMODE set to 0 to permit native debugging\n");
+		poke_real_address_q(WPC_DBRMODE, 0);
+		first_call = 0;
+	}
+	unlock_kernel();
+
+	return sys_ptrace(request, pid, addr, data);
+}
+
 asmlinkage void syscall_trace(void)
 {
 	struct task_struct *tsk = current;
diff --git a/arch/sh64/kernel/syscalls.S b/arch/sh64/kernel/syscalls.S
index a3d0378..c0079d5 100644
--- a/arch/sh64/kernel/syscalls.S
+++ b/arch/sh64/kernel/syscalls.S
@@ -46,7 +46,7 @@
 	.long sys_setuid16
 	.long sys_getuid16
 	.long sys_stime			/* 25 */
-	.long sys_ptrace
+	.long sh64_ptrace
 	.long sys_alarm
 	.long sys_fstat
 	.long sys_pause
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index 1e9d863..3fded69 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -377,8 +377,21 @@
 
 source "fs/Kconfig"
 
+menu "Instrumentation Support"
+        depends on EXPERIMENTAL
+
 source "arch/sparc64/oprofile/Kconfig"
 
+config KPROBES
+	bool "Kprobes (EXPERIMENTAL)"
+	help
+	  Kprobes allows you to trap at almost any kernel address and
+	  execute a callback function.  register_kprobe() establishes
+	  a probepoint and specifies the callback.  Kprobes is useful
+	  for kernel debugging, non-intrusive instrumentation and testing.
+	  If in doubt, say "N".
+endmenu
+
 source "arch/sparc64/Kconfig.debug"
 
 source "security/Kconfig"
diff --git a/arch/sparc64/Kconfig.debug b/arch/sparc64/Kconfig.debug
index fa06ea0..3e31be4 100644
--- a/arch/sparc64/Kconfig.debug
+++ b/arch/sparc64/Kconfig.debug
@@ -11,16 +11,6 @@
 
 	  This option will slow down process creation somewhat.
 
-config KPROBES
-	bool "Kprobes"
-	depends on DEBUG_KERNEL
-	help
-	  Kprobes allows you to trap at almost any kernel address and
-	  execute a callback function.  register_kprobe() establishes
-	  a probepoint and specifies the callback.  Kprobes is useful
-	  for kernel debugging, non-intrusive instrumentation and testing.
-	  If in doubt, say "N".
-
 config DEBUG_DCFLUSH
 	bool "D-cache flush debugging"
 	depends on DEBUG_KERNEL
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
index 0d66d07..96bd09b 100644
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -38,6 +38,9 @@
  * - Mark that we are no longer actively in a kprobe.
  */
 
+DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+
 int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
 	return 0;
@@ -66,46 +69,39 @@
 {
 }
 
-static struct kprobe *current_kprobe;
-static unsigned long current_kprobe_orig_tnpc;
-static unsigned long current_kprobe_orig_tstate_pil;
-static unsigned int kprobe_status;
-static struct kprobe *kprobe_prev;
-static unsigned long kprobe_orig_tnpc_prev;
-static unsigned long kprobe_orig_tstate_pil_prev;
-static unsigned int kprobe_status_prev;
-
-static inline void save_previous_kprobe(void)
+static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-	kprobe_status_prev = kprobe_status;
-	kprobe_orig_tnpc_prev = current_kprobe_orig_tnpc;
-	kprobe_orig_tstate_pil_prev = current_kprobe_orig_tstate_pil;
-	kprobe_prev = current_kprobe;
+	kcb->prev_kprobe.kp = kprobe_running();
+	kcb->prev_kprobe.status = kcb->kprobe_status;
+	kcb->prev_kprobe.orig_tnpc = kcb->kprobe_orig_tnpc;
+	kcb->prev_kprobe.orig_tstate_pil = kcb->kprobe_orig_tstate_pil;
 }
 
-static inline void restore_previous_kprobe(void)
+static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-	kprobe_status = kprobe_status_prev;
-	current_kprobe_orig_tnpc = kprobe_orig_tnpc_prev;
-	current_kprobe_orig_tstate_pil = kprobe_orig_tstate_pil_prev;
-	current_kprobe = kprobe_prev;
+	__get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+	kcb->kprobe_status = kcb->prev_kprobe.status;
+	kcb->kprobe_orig_tnpc = kcb->prev_kprobe.orig_tnpc;
+	kcb->kprobe_orig_tstate_pil = kcb->prev_kprobe.orig_tstate_pil;
 }
 
-static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs)
+static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
+				struct kprobe_ctlblk *kcb)
 {
-	current_kprobe_orig_tnpc = regs->tnpc;
-	current_kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL);
-	current_kprobe = p;
+	__get_cpu_var(current_kprobe) = p;
+	kcb->kprobe_orig_tnpc = regs->tnpc;
+	kcb->kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL);
 }
 
-static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
+static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs,
+			struct kprobe_ctlblk *kcb)
 {
 	regs->tstate |= TSTATE_PIL;
 
 	/*single step inline, if it a breakpoint instruction*/
 	if (p->opcode == BREAKPOINT_INSTRUCTION) {
 		regs->tpc = (unsigned long) p->addr;
-		regs->tnpc = current_kprobe_orig_tnpc;
+		regs->tnpc = kcb->kprobe_orig_tnpc;
 	} else {
 		regs->tpc = (unsigned long) &p->ainsn.insn[0];
 		regs->tnpc = (unsigned long) &p->ainsn.insn[1];
@@ -117,19 +113,21 @@
 	struct kprobe *p;
 	void *addr = (void *) regs->tpc;
 	int ret = 0;
+	struct kprobe_ctlblk *kcb;
 
+	/*
+	 * We don't want to be preempted for the entire
+	 * duration of kprobe processing
+	 */
 	preempt_disable();
+	kcb = get_kprobe_ctlblk();
 
 	if (kprobe_running()) {
-		/* We *are* holding lock here, so this is safe.
-		 * Disarm the probe we just hit, and ignore it.
-		 */
 		p = get_kprobe(addr);
 		if (p) {
-			if (kprobe_status == KPROBE_HIT_SS) {
+			if (kcb->kprobe_status == KPROBE_HIT_SS) {
 				regs->tstate = ((regs->tstate & ~TSTATE_PIL) |
-					current_kprobe_orig_tstate_pil);
-				unlock_kprobes();
+					kcb->kprobe_orig_tstate_pil);
 				goto no_kprobe;
 			}
 			/* We have reentered the kprobe_handler(), since
@@ -138,25 +136,22 @@
 			 * just single step on the instruction of the new probe
 			 * without calling any user handlers.
 			 */
-			save_previous_kprobe();
-			set_current_kprobe(p, regs);
+			save_previous_kprobe(kcb);
+			set_current_kprobe(p, regs, kcb);
 			p->nmissed++;
-			kprobe_status = KPROBE_REENTER;
-			prepare_singlestep(p, regs);
+			kcb->kprobe_status = KPROBE_REENTER;
+			prepare_singlestep(p, regs, kcb);
 			return 1;
 		} else {
-			p = current_kprobe;
+			p = __get_cpu_var(current_kprobe);
 			if (p->break_handler && p->break_handler(p, regs))
 				goto ss_probe;
 		}
-		/* If it's not ours, can't be delete race, (we hold lock). */
 		goto no_kprobe;
 	}
 
-	lock_kprobes();
 	p = get_kprobe(addr);
 	if (!p) {
-		unlock_kprobes();
 		if (*(u32 *)addr != BREAKPOINT_INSTRUCTION) {
 			/*
 			 * The breakpoint instruction was removed right
@@ -171,14 +166,14 @@
 		goto no_kprobe;
 	}
 
-	set_current_kprobe(p, regs);
-	kprobe_status = KPROBE_HIT_ACTIVE;
+	set_current_kprobe(p, regs, kcb);
+	kcb->kprobe_status = KPROBE_HIT_ACTIVE;
 	if (p->pre_handler && p->pre_handler(p, regs))
 		return 1;
 
 ss_probe:
-	prepare_singlestep(p, regs);
-	kprobe_status = KPROBE_HIT_SS;
+	prepare_singlestep(p, regs, kcb);
+	kcb->kprobe_status = KPROBE_HIT_SS;
 	return 1;
 
 no_kprobe:
@@ -260,11 +255,12 @@
  * This function prepares to return from the post-single-step
  * breakpoint trap.
  */
-static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes resume_execution(struct kprobe *p,
+		struct pt_regs *regs, struct kprobe_ctlblk *kcb)
 {
 	u32 insn = p->ainsn.insn[0];
 
-	regs->tpc = current_kprobe_orig_tnpc;
+	regs->tpc = kcb->kprobe_orig_tnpc;
 	regs->tnpc = relbranch_fixup(insn,
 				     (unsigned long) p->addr,
 				     (unsigned long) &p->ainsn.insn[0],
@@ -272,44 +268,48 @@
 	retpc_fixup(regs, insn, (unsigned long) p->addr);
 
 	regs->tstate = ((regs->tstate & ~TSTATE_PIL) |
-			current_kprobe_orig_tstate_pil);
+			kcb->kprobe_orig_tstate_pil);
 }
 
 static inline int post_kprobe_handler(struct pt_regs *regs)
 {
-	if (!kprobe_running())
+	struct kprobe *cur = kprobe_running();
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	if (!cur)
 		return 0;
 
-	if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
-		kprobe_status = KPROBE_HIT_SSDONE;
-		current_kprobe->post_handler(current_kprobe, regs, 0);
+	if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
+		kcb->kprobe_status = KPROBE_HIT_SSDONE;
+		cur->post_handler(cur, regs, 0);
 	}
 
-	resume_execution(current_kprobe, regs);
+	resume_execution(cur, regs, kcb);
 
 	/*Restore back the original saved kprobes variables and continue. */
-	if (kprobe_status == KPROBE_REENTER) {
-		restore_previous_kprobe();
+	if (kcb->kprobe_status == KPROBE_REENTER) {
+		restore_previous_kprobe(kcb);
 		goto out;
 	}
-	unlock_kprobes();
+	reset_current_kprobe();
 out:
 	preempt_enable_no_resched();
 
 	return 1;
 }
 
-/* Interrupts disabled, kprobe_lock held. */
 static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 {
-	if (current_kprobe->fault_handler
-	    && current_kprobe->fault_handler(current_kprobe, regs, trapnr))
+	struct kprobe *cur = kprobe_running();
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
 		return 1;
 
-	if (kprobe_status & KPROBE_HIT_SS) {
-		resume_execution(current_kprobe, regs);
+	if (kcb->kprobe_status & KPROBE_HIT_SS) {
+		resume_execution(cur, regs, kcb);
 
-		unlock_kprobes();
+		reset_current_kprobe();
 		preempt_enable_no_resched();
 	}
 	return 0;
@@ -322,29 +322,30 @@
 				       unsigned long val, void *data)
 {
 	struct die_args *args = (struct die_args *)data;
+	int ret = NOTIFY_DONE;
+
 	switch (val) {
 	case DIE_DEBUG:
 		if (kprobe_handler(args->regs))
-			return NOTIFY_STOP;
+			ret = NOTIFY_STOP;
 		break;
 	case DIE_DEBUG_2:
 		if (post_kprobe_handler(args->regs))
-			return NOTIFY_STOP;
+			ret = NOTIFY_STOP;
 		break;
 	case DIE_GPF:
-		if (kprobe_running() &&
-		    kprobe_fault_handler(args->regs, args->trapnr))
-			return NOTIFY_STOP;
-		break;
 	case DIE_PAGE_FAULT:
+		/* kprobe_running() needs smp_processor_id() */
+		preempt_disable();
 		if (kprobe_running() &&
 		    kprobe_fault_handler(args->regs, args->trapnr))
-			return NOTIFY_STOP;
+			ret = NOTIFY_STOP;
+		preempt_enable();
 		break;
 	default:
 		break;
 	}
-	return NOTIFY_DONE;
+	return ret;
 }
 
 asmlinkage void __kprobes kprobe_trap(unsigned long trap_level,
@@ -368,24 +369,21 @@
 }
 
 /* Jprobes support.  */
-static struct pt_regs jprobe_saved_regs;
-static struct pt_regs *jprobe_saved_regs_location;
-static struct sparc_stackf jprobe_saved_stack;
-
 int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct jprobe *jp = container_of(p, struct jprobe, kp);
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 
-	jprobe_saved_regs_location = regs;
-	memcpy(&jprobe_saved_regs, regs, sizeof(*regs));
+	kcb->jprobe_saved_regs_location = regs;
+	memcpy(&(kcb->jprobe_saved_regs), regs, sizeof(*regs));
 
 	/* Save a whole stack frame, this gets arguments
 	 * pushed onto the stack after using up all the
 	 * arg registers.
 	 */
-	memcpy(&jprobe_saved_stack,
+	memcpy(&(kcb->jprobe_saved_stack),
 	       (char *) (regs->u_regs[UREG_FP] + STACK_BIAS),
-	       sizeof(jprobe_saved_stack));
+	       sizeof(kcb->jprobe_saved_stack));
 
 	regs->tpc  = (unsigned long) jp->entry;
 	regs->tnpc = ((unsigned long) jp->entry) + 0x4UL;
@@ -396,7 +394,6 @@
 
 void __kprobes jprobe_return(void)
 {
-	preempt_enable_no_resched();
 	__asm__ __volatile__(
 		".globl	jprobe_return_trap_instruction\n"
 "jprobe_return_trap_instruction:\n\t"
@@ -410,14 +407,15 @@
 int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	u32 *addr = (u32 *) regs->tpc;
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 
 	if (addr == (u32 *) jprobe_return_trap_instruction) {
-		if (jprobe_saved_regs_location != regs) {
+		if (kcb->jprobe_saved_regs_location != regs) {
 			printk("JPROBE: Current regs (%p) does not match "
 			       "saved regs (%p).\n",
-			       regs, jprobe_saved_regs_location);
+			       regs, kcb->jprobe_saved_regs_location);
 			printk("JPROBE: Saved registers\n");
-			__show_regs(jprobe_saved_regs_location);
+			__show_regs(kcb->jprobe_saved_regs_location);
 			printk("JPROBE: Current registers\n");
 			__show_regs(regs);
 			BUG();
@@ -426,12 +424,13 @@
 		 * first so that UREG_FP is the original one for
 		 * the stack frame restore.
 		 */
-		memcpy(regs, &jprobe_saved_regs, sizeof(*regs));
+		memcpy(regs, &(kcb->jprobe_saved_regs), sizeof(*regs));
 
 		memcpy((char *) (regs->u_regs[UREG_FP] + STACK_BIAS),
-		       &jprobe_saved_stack,
-		       sizeof(jprobe_saved_stack));
+		       &(kcb->jprobe_saved_stack),
+		       sizeof(kcb->jprobe_saved_stack));
 
+		preempt_enable_no_resched();
 		return 1;
 	}
 	return 0;
diff --git a/arch/sparc64/kernel/us2e_cpufreq.c b/arch/sparc64/kernel/us2e_cpufreq.c
index 686e526..b35dc8d 100644
--- a/arch/sparc64/kernel/us2e_cpufreq.c
+++ b/arch/sparc64/kernel/us2e_cpufreq.c
@@ -388,10 +388,8 @@
 			kfree(driver);
 			cpufreq_us2e_driver = NULL;
 		}
-		if (us2e_freq_table) {
-			kfree(us2e_freq_table);
-			us2e_freq_table = NULL;
-		}
+		kfree(us2e_freq_table);
+		us2e_freq_table = NULL;
 		return ret;
 	}
 
@@ -402,7 +400,6 @@
 {
 	if (cpufreq_us2e_driver) {
 		cpufreq_unregister_driver(cpufreq_us2e_driver);
-
 		kfree(cpufreq_us2e_driver);
 		cpufreq_us2e_driver = NULL;
 		kfree(us2e_freq_table);
diff --git a/arch/sparc64/kernel/us3_cpufreq.c b/arch/sparc64/kernel/us3_cpufreq.c
index 0340041..6d1f9a3 100644
--- a/arch/sparc64/kernel/us3_cpufreq.c
+++ b/arch/sparc64/kernel/us3_cpufreq.c
@@ -249,10 +249,8 @@
 			kfree(driver);
 			cpufreq_us3_driver = NULL;
 		}
-		if (us3_freq_table) {
-			kfree(us3_freq_table);
-			us3_freq_table = NULL;
-		}
+		kfree(us3_freq_table);
+		us3_freq_table = NULL;
 		return ret;
 	}
 
@@ -263,7 +261,6 @@
 {
 	if (cpufreq_us3_driver) {
 		cpufreq_unregister_driver(cpufreq_us3_driver);
-
 		kfree(cpufreq_us3_driver);
 		cpufreq_us3_driver = NULL;
 		kfree(us3_freq_table);
diff --git a/arch/sparc64/oprofile/Kconfig b/arch/sparc64/oprofile/Kconfig
index 5ade198..d8a8408 100644
--- a/arch/sparc64/oprofile/Kconfig
+++ b/arch/sparc64/oprofile/Kconfig
@@ -1,7 +1,3 @@
-
-menu "Profiling support"
-	depends on EXPERIMENTAL
-
 config PROFILING
 	bool "Profiling support (EXPERIMENTAL)"
 	help
@@ -19,5 +15,3 @@
 
 	  If unsure, say N.
 
-endmenu
-
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index cd06ed7..3b5f47c 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -65,6 +65,30 @@
 	chroot, and you disable CONFIG_MODE_TT, you probably want to say Y
 	here.
 
+config HOST_2G_2G
+	bool "2G/2G host address space split"
+	default n
+	depends on MODE_TT
+	help
+	This is needed when the host on which you run has a 2G/2G memory
+	split, instead of the customary 3G/1G.
+
+	Note that to enable such a host
+	configuration, which makes sense only in some cases, you need special
+	host patches.
+
+	So, if you do not know what to do here, say 'N'.
+
+config KERNEL_HALF_GIGS
+	int "Kernel address space size (in .5G units)"
+	default "1"
+	depends on MODE_TT
+	help
+        This determines the amount of address space that UML will allocate for
+        its own, measured in half Gigabyte units.  The default is 1.
+        Change this only if you need to boot UML with an unusually large amount
+        of physical memory.
+
 config MODE_SKAS
 	bool "Separate Kernel Address Space support"
 	default y
@@ -182,19 +206,6 @@
 	The keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
 	unless you really know what this hack does.
 
-config HOST_2G_2G
-	bool "2G/2G host address space split"
-	default n
-	help
-	This is needed when the host on which you run has a 2G/2G memory
-	split, instead of the customary 3G/1G.
-
-	Note that to enable such a host
-	configuration, which makes sense only in some cases, you need special
-	host patches.
-
-	So, if you do not know what to do here, say 'N'.
-
 config SMP
 	bool "Symmetric multi-processing support (EXPERIMENTAL)"
 	default n
@@ -241,15 +252,6 @@
         set to the host's CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS.
         Only change this if you are running nested UMLs.
 
-config KERNEL_HALF_GIGS
-	int "Kernel address space size (in .5G units)"
-	default "1"
-	help
-        This determines the amount of address space that UML will allocate for
-        its own, measured in half Gigabyte units.  The default is 1.
-        Change this only if you need to boot UML with an unusually large amount
-        of physical memory.
-
 config HIGHMEM
 	bool "Highmem support"
 	depends on !64BIT
diff --git a/arch/um/Makefile b/arch/um/Makefile
index e1ffad2..e55d32e 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -60,7 +60,7 @@
 
 USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
 USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
-	$(MODE_INCLUDE)
+	$(MODE_INCLUDE) -D_FILE_OFFSET_BITS=64
 
 # -Derrno=kernel_errno - This turns all kernel references to errno into
 # kernel_errno to separate them from the libc errno.  This allows -fno-common
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index aef7c50..1f7dcb0 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -17,8 +17,6 @@
 ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)")
 CFLAGS			+= $(call cc-option,-m32)
 USER_CFLAGS		+= $(call cc-option,-m32)
-HOSTCFLAGS		+= $(call cc-option,-m32)
-HOSTLDFLAGS		+= $(call cc-option,-m32)
 AFLAGS			+= $(call cc-option,-m32)
 LINK-y			+= $(call cc-option,-m32)
 UML_OBJCOPYFLAGS	+= -F $(ELF_FORMAT)
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index de3bce7..1c55d58 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -16,7 +16,6 @@
 #include "user_util.h"
 #include "chan_user.h"
 #include "user.h"
-#include "helper.h"
 #include "os.h"
 #include "choose-mode.h"
 #include "mode.h"
diff --git a/arch/um/drivers/harddog_kern.c b/arch/um/drivers/harddog_kern.c
index 147ec19..49acb2b 100644
--- a/arch/um/drivers/harddog_kern.c
+++ b/arch/um/drivers/harddog_kern.c
@@ -46,7 +46,6 @@
 #include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
-#include "helper.h"
 #include "mconsole.h"
 
 MODULE_LICENSE("GPL");
diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c
index d934181..def013b 100644
--- a/arch/um/drivers/harddog_user.c
+++ b/arch/um/drivers/harddog_user.c
@@ -8,7 +8,6 @@
 #include <errno.h>
 #include "user_util.h"
 #include "user.h"
-#include "helper.h"
 #include "mconsole.h"
 #include "os.h"
 #include "choose-mode.h"
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 721e260..fe865d9 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -96,7 +96,6 @@
 static int uml_net_open(struct net_device *dev)
 {
 	struct uml_net_private *lp = dev->priv;
-	char addr[sizeof("255.255.255.255\0")];
 	int err;
 
 	spin_lock(&lp->lock);
@@ -107,7 +106,7 @@
 	}
 
 	if(!lp->have_mac){
- 		dev_ip_addr(dev, addr, &lp->mac[2]);
+ 		dev_ip_addr(dev, &lp->mac[2]);
  		set_ether_mac(dev, lp->mac);
 	}
 
@@ -664,8 +663,6 @@
 			      void *ptr)
 {
 	struct in_ifaddr *ifa = ptr;
-	u32 addr = ifa->ifa_address;
-	u32 netmask = ifa->ifa_mask;
 	struct net_device *dev = ifa->ifa_dev->dev;
 	struct uml_net_private *lp;
 	void (*proc)(unsigned char *, unsigned char *, void *);
@@ -685,14 +682,8 @@
 		break;
 	}
 	if(proc != NULL){
-		addr_buf[0] = addr & 0xff;
-		addr_buf[1] = (addr >> 8) & 0xff;
-		addr_buf[2] = (addr >> 16) & 0xff;
-		addr_buf[3] = addr >> 24;
-		netmask_buf[0] = netmask & 0xff;
-		netmask_buf[1] = (netmask >> 8) & 0xff;
-		netmask_buf[2] = (netmask >> 16) & 0xff;
-		netmask_buf[3] = netmask >> 24;
+		memcpy(addr_buf, &ifa->ifa_address, sizeof(addr_buf));
+		memcpy(netmask_buf, &ifa->ifa_mask, sizeof(netmask_buf));
 		(*proc)(addr_buf, netmask_buf, &lp->user);
 	}
 	return(NOTIFY_DONE);
@@ -774,27 +765,18 @@
 	return(1);
 }
 
-void dev_ip_addr(void *d, char *buf, char *bin_buf)
+void dev_ip_addr(void *d, unsigned char *bin_buf)
 {
 	struct net_device *dev = d;
 	struct in_device *ip = dev->ip_ptr;
 	struct in_ifaddr *in;
-	u32 addr;
 
 	if((ip == NULL) || ((in = ip->ifa_list) == NULL)){
 		printk(KERN_WARNING "dev_ip_addr - device not assigned an "
 		       "IP address\n");
 		return;
 	}
-	addr = in->ifa_address;
-	sprintf(buf, "%d.%d.%d.%d", addr & 0xff, (addr >> 8) & 0xff, 
-		(addr >> 16) & 0xff, addr >> 24);
-	if(bin_buf){
-		bin_buf[0] = addr & 0xff;
-		bin_buf[1] = (addr >> 8) & 0xff;
-		bin_buf[2] = (addr >> 16) & 0xff;
-		bin_buf[3] = addr >> 24;
-	}
+	memcpy(bin_buf, &in->ifa_address, sizeof(in->ifa_address));
 }
 
 void set_ether_mac(void *d, unsigned char *addr)
@@ -829,14 +811,8 @@
 	if(ip == NULL) return;
 	in = ip->ifa_list;
 	while(in != NULL){
-		address[0] = in->ifa_address & 0xff;
-		address[1] = (in->ifa_address >> 8) & 0xff;
-		address[2] = (in->ifa_address >> 16) & 0xff;
-		address[3] = in->ifa_address >> 24;
-		netmask[0] = in->ifa_mask & 0xff;
-		netmask[1] = (in->ifa_mask >> 8) & 0xff;
-		netmask[2] = (in->ifa_mask >> 16) & 0xff;
-		netmask[3] = in->ifa_mask >> 24;
+		memcpy(address, &in->ifa_address, sizeof(address));
+		memcpy(netmask, &in->ifa_mask, sizeof(netmask));
 		(*cb)(address, netmask, arg);
 		in = in->ifa_next;
 	}
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index 3730d4f..098fa65 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -16,7 +16,6 @@
 #include "user_util.h"
 #include "kern_util.h"
 #include "net_user.h"
-#include "helper.h"
 #include "os.h"
 
 int tap_open_common(void *dev, char *gate_addr)
diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
index 14dd200..ed4a1a6 100644
--- a/arch/um/drivers/port_user.c
+++ b/arch/um/drivers/port_user.c
@@ -18,7 +18,6 @@
 #include "user.h"
 #include "chan_user.h"
 #include "port.h"
-#include "helper.h"
 #include "os.h"
 
 struct port_chan {
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index f9e2219..ba471f5 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -58,10 +58,8 @@
                         if (filp->f_flags & O_NONBLOCK)
                                 return ret ? : -EAGAIN;
 
-                        if(need_resched()){
-                                current->state = TASK_INTERRUPTIBLE;
-                                schedule_timeout(1);
-                        }
+                        if(need_resched())
+                                schedule_timeout_interruptible(1);
                 }
                 else return n;
 		if (signal_pending (current))
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
index 71af444..89fbec1 100644
--- a/arch/um/drivers/slip_user.c
+++ b/arch/um/drivers/slip_user.c
@@ -14,7 +14,6 @@
 #include "net_user.h"
 #include "slip.h"
 #include "slip_common.h"
-#include "helper.h"
 #include "os.h"
 
 void slip_user_init(void *data, void *dev)
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
index 8d91f66..b94c661 100644
--- a/arch/um/drivers/slirp_user.c
+++ b/arch/um/drivers/slirp_user.c
@@ -13,7 +13,6 @@
 #include "net_user.h"
 #include "slirp.h"
 #include "slip_common.h"
-#include "helper.h"
 #include "os.h"
 
 void slirp_user_init(void *data, void *dev)
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index 90e0e5f..b530f1a 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -14,7 +14,6 @@
 #include <sys/socket.h>
 #include "kern_util.h"
 #include "chan_user.h"
-#include "helper.h"
 #include "user_util.h"
 #include "user.h"
 #include "os.h"
diff --git a/arch/um/include/helper.h b/arch/um/include/helper.h
deleted file mode 100644
index 162ac31..0000000
--- a/arch/um/include/helper.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __HELPER_H__
-#define __HELPER_H__
-
-extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
-		      unsigned long *stack_out);
-extern int run_helper_thread(int (*proc)(void *), void *arg, 
-			     unsigned int flags, unsigned long *stack_out,
-			     int stack_order);
-extern int helper_wait(int pid);
-
-#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/mem_user.h b/arch/um/include/mem_user.h
index 9fef412..a1064c5 100644
--- a/arch/um/include/mem_user.h
+++ b/arch/um/include/mem_user.h
@@ -57,7 +57,7 @@
 		     unsigned long highmem);
 extern unsigned long get_vm(unsigned long len);
 extern void setup_physmem(unsigned long start, unsigned long usable,
-			  unsigned long len, unsigned long highmem);
+			  unsigned long len, unsigned long long highmem);
 extern void add_iomem(char *name, int fd, unsigned long size);
 extern unsigned long phys_offset(unsigned long phys);
 extern void unmap_physmem(void);
diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h
index 89885a7..800c403 100644
--- a/arch/um/include/net_user.h
+++ b/arch/um/include/net_user.h
@@ -25,7 +25,7 @@
 };
 
 extern void ether_user_init(void *data, void *dev);
-extern void dev_ip_addr(void *d, char *buf, char *bin_buf);
+extern void dev_ip_addr(void *d, unsigned char *bin_buf);
 extern void set_ether_mac(void *d, unsigned char *addr);
 extern void iter_addresses(void *d, void (*cb)(unsigned char *, 
 					       unsigned char *, void *), 
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 2e58e30..2cccfa5 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -167,7 +167,7 @@
 #endif
 
 /* mem.c */
-extern int create_mem_file(unsigned long len);
+extern int create_mem_file(unsigned long long len);
 
 /* process.c */
 extern unsigned long os_process_pc(int pid);
@@ -199,6 +199,20 @@
 extern int start_fork_tramp(void *arg, unsigned long temp_stack,
 			    int clone_flags, int (*tramp)(void *));
 
+/* uaccess.c */
+extern unsigned long __do_user_copy(void *to, const void *from, int n,
+				    void **fault_addr, void **fault_catcher,
+				    void (*op)(void *to, const void *from,
+					       int n), int *faulted_out);
+
+/* helper.c */
+extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
+		      unsigned long *stack_out);
+extern int run_helper_thread(int (*proc)(void *), void *arg,
+			     unsigned int flags, unsigned long *stack_out,
+			     int stack_order);
+extern int helper_wait(int pid);
+
 #endif
 
 /*
diff --git a/arch/um/include/sysdep-i386/stub.h b/arch/um/include/sysdep-i386/stub.h
index d3699fe..a49ceb1 100644
--- a/arch/um/include/sysdep-i386/stub.h
+++ b/arch/um/include/sysdep-i386/stub.h
@@ -16,45 +16,69 @@
 #define STUB_MMAP_NR __NR_mmap2
 #define MMAP_OFFSET(o) ((o) >> PAGE_SHIFT)
 
+static inline long stub_syscall1(long syscall, long arg1)
+{
+	long ret;
+
+	__asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1));
+
+	return ret;
+}
+
 static inline long stub_syscall2(long syscall, long arg1, long arg2)
 {
 	long ret;
 
-	__asm__("movl %0, %%ecx; " : : "g" (arg2) : "%ecx");
-	__asm__("movl %0, %%ebx; " : : "g" (arg1) : "%ebx");
-	__asm__("movl %0, %%eax; " : : "g" (syscall) : "%eax");
-	__asm__("int $0x80;" : : : "%eax");
-	__asm__ __volatile__("movl %%eax, %0; " : "=g" (ret) :);
-	return(ret);
+	__asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
+			"c" (arg2));
+
+	return ret;
 }
 
 static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3)
 {
-	__asm__("movl %0, %%edx; " : : "g" (arg3) : "%edx");
-	return(stub_syscall2(syscall, arg1, arg2));
+	long ret;
+
+	__asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
+			"c" (arg2), "d" (arg3));
+
+	return ret;
 }
 
 static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3,
 				 long arg4)
 {
-	__asm__("movl %0, %%esi; " : : "g" (arg4) : "%esi");
-	return(stub_syscall3(syscall, arg1, arg2, arg3));
+	long ret;
+
+	__asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
+			"c" (arg2), "d" (arg3), "S" (arg4));
+
+	return ret;
+}
+
+static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3,
+				 long arg4, long arg5)
+{
+	long ret;
+
+	__asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
+			"c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5));
+
+	return ret;
 }
 
 static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3,
 				 long arg4, long arg5, long arg6)
 {
 	long ret;
-	__asm__("movl %0, %%eax; " : : "g" (syscall) : "%eax");
-	__asm__("movl %0, %%ebx; " : : "g" (arg1) : "%ebx");
-	__asm__("movl %0, %%ecx; " : : "g" (arg2) : "%ecx");
-	__asm__("movl %0, %%edx; " : : "g" (arg3) : "%edx");
-	__asm__("movl %0, %%esi; " : : "g" (arg4) : "%esi");
-	__asm__("movl %0, %%edi; " : : "g" (arg5) : "%edi");
-	__asm__ __volatile__("pushl %%ebp ; movl %1, %%ebp; "
-		"int $0x80; popl %%ebp ; "
-		"movl %%eax, %0; " : "=g" (ret) : "g" (arg6) : "%eax");
-	return(ret);
+
+	__asm__ volatile ("push %%ebp ; movl %%eax,%%ebp ; movl %1,%%eax ; "
+			"int $0x80 ; pop %%ebp"
+			: "=a" (ret)
+			: "g" (syscall), "b" (arg1), "c" (arg2), "d" (arg3),
+			  "S" (arg4), "D" (arg5), "0" (arg6));
+
+	return ret;
 }
 
 static inline void trap_myself(void)
diff --git a/arch/um/include/sysdep-x86_64/stub.h b/arch/um/include/sysdep-x86_64/stub.h
index f599058..2bd6e7a 100644
--- a/arch/um/include/sysdep-x86_64/stub.h
+++ b/arch/um/include/sysdep-x86_64/stub.h
@@ -17,37 +17,72 @@
 #define STUB_MMAP_NR __NR_mmap
 #define MMAP_OFFSET(o) (o)
 
+#define __syscall_clobber "r11","rcx","memory"
+#define __syscall "syscall"
+
 static inline long stub_syscall2(long syscall, long arg1, long arg2)
 {
 	long ret;
 
-	__asm__("movq %0, %%rsi; " : : "g" (arg2) : "%rsi");
-	__asm__("movq %0, %%rdi; " : : "g" (arg1) : "%rdi");
-	__asm__("movq %0, %%rax; " : : "g" (syscall) : "%rax");
-	__asm__("syscall;" : : : "%rax", "%r11", "%rcx");
-	__asm__ __volatile__("movq %%rax, %0; " : "=g" (ret) :);
-	return(ret);
+	__asm__ volatile (__syscall
+		: "=a" (ret)
+		: "0" (syscall), "D" (arg1), "S" (arg2) : __syscall_clobber );
+
+	return ret;
 }
 
 static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3)
 {
-	__asm__("movq %0, %%rdx; " : : "g" (arg3) : "%rdx");
-	return(stub_syscall2(syscall, arg1, arg2));
+	long ret;
+
+	__asm__ volatile (__syscall
+		: "=a" (ret)
+		: "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3)
+		: __syscall_clobber );
+
+	return ret;
 }
 
 static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3,
 				 long arg4)
 {
-	__asm__("movq %0, %%r10; " : : "g" (arg4) : "%r10");
-	return(stub_syscall3(syscall, arg1, arg2, arg3));
+	long ret;
+
+	__asm__ volatile ("movq %5,%%r10 ; " __syscall
+		: "=a" (ret)
+		: "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3),
+		  "g" (arg4)
+		: __syscall_clobber, "r10" );
+
+	return ret;
+}
+
+static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3,
+				 long arg4, long arg5)
+{
+	long ret;
+
+	__asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; " __syscall
+		: "=a" (ret)
+		: "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3),
+		  "g" (arg4), "g" (arg5)
+		: __syscall_clobber, "r10", "r8" );
+
+	return ret;
 }
 
 static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3,
 				 long arg4, long arg5, long arg6)
 {
-	__asm__("movq %0, %%r9; " : : "g" (arg6) : "%r9");
-	__asm__("movq %0, %%r8; " : : "g" (arg5) : "%r8");
-	return(stub_syscall4(syscall, arg1, arg2, arg3, arg4));
+	long ret;
+
+	__asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; "
+		"movq %7, %%r9; " __syscall : "=a" (ret)
+		: "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3),
+		  "g" (arg4), "g" (arg5), "g" (arg6)
+		: __syscall_clobber, "r10", "r8", "r9" );
+
+	return ret;
 }
 
 static inline void trap_myself(void)
diff --git a/arch/um/include/uml_uaccess.h b/arch/um/include/uml_uaccess.h
index f77eb64..c0df11d 100644
--- a/arch/um/include/uml_uaccess.h
+++ b/arch/um/include/uml_uaccess.h
@@ -8,10 +8,6 @@
 
 extern int __do_copy_to_user(void *to, const void *from, int n,
 			     void **fault_addr, void **fault_catcher);
-extern unsigned long __do_user_copy(void *to, const void *from, int n,
-				    void **fault_addr, void **fault_catcher,
-				    void (*op)(void *to, const void *from,
-					       int n), int *faulted_out);
 void __do_copy(void *to, const void *from, int n);
 
 #endif
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index 1a0001b..3de9d21 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -7,10 +7,10 @@
 clean-files :=
 
 obj-y = config.o exec_kern.o exitcode.o \
-	helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o physmem.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 signal_user.o smp.o syscall_kern.o sysrq.o time.o \
-	time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o \
+	time_kern.o tlb.o trap_kern.o trap_user.o uaccess.o um_arch.o \
 	umid.o user_util.o
 
 obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
@@ -24,8 +24,7 @@
 
 user-objs-$(CONFIG_TTY_LOG) += tty_log.o
 
-USER_OBJS := $(user-objs-y) config.o helper.o main.o time.o tty_log.o umid.o \
-	user_util.o
+USER_OBJS := $(user-objs-y) config.o time.o tty_log.o umid.o user_util.o
 
 include arch/um/scripts/Makefile.rules
 
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index a97a72e..7713e7a 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -20,7 +20,6 @@
 #include "user_util.h"
 #include "mem_user.h"
 #include "os.h"
-#include "helper.h"
 
 EXPORT_SYMBOL(stop);
 EXPORT_SYMBOL(uml_physmem);
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index 462cc9d..fa4f915 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -234,8 +234,8 @@
 	empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
 	for(i=0;i<sizeof(zones_size)/sizeof(zones_size[0]);i++) 
 		zones_size[i] = 0;
-	zones_size[0] = (end_iomem >> PAGE_SHIFT) - (uml_physmem >> PAGE_SHIFT);
-	zones_size[2] = highmem >> PAGE_SHIFT;
+	zones_size[ZONE_DMA] = (end_iomem >> PAGE_SHIFT) - (uml_physmem >> PAGE_SHIFT);
+	zones_size[ZONE_HIGHMEM] = highmem >> PAGE_SHIFT;
 	free_area_init(zones_size);
 
 	/*
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index ea670fc..f3b583a 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -246,7 +246,7 @@
 /* Changed during early boot */
 unsigned long high_physmem;
 
-extern unsigned long physmem_size;
+extern unsigned long long physmem_size;
 
 int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem)
 {
@@ -321,7 +321,7 @@
 extern int __syscall_stub_start, __binary_start;
 
 void setup_physmem(unsigned long start, unsigned long reserve_end,
-		   unsigned long len, unsigned long highmem)
+		   unsigned long len, unsigned long long highmem)
 {
 	unsigned long reserve = reserve_end - start;
 	int pfn = PFN_UP(__pa(reserve_end));
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index 71af4d5..98e0939 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -43,53 +43,10 @@
 extern int peek_user(struct task_struct * child, long addr, long data);
 extern int poke_user(struct task_struct * child, long addr, long data);
 
-long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-	struct task_struct *child;
 	int i, ret;
 
-	lock_kernel();
-	ret = -EPERM;
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-
-		ret = security_ptrace(current->parent, current);
-		if (ret)
- 			goto out;
-
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
-		goto out;
-	}
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (!child)
-		goto out;
-
-	ret = -EPERM;
-	if (pid == 1)		/* you may not mess with init */
-		goto out_tsk;
-
-	if (request == PTRACE_ATTACH) {
-		ret = ptrace_attach(child);
-		goto out_tsk;
-	}
-
-#ifdef SUBACH_PTRACE_SPECIAL
-        SUBARCH_PTRACE_SPECIAL(child,request,addr,data);
-#endif
-
-	ret = ptrace_check_attach(child, request == PTRACE_KILL);
-	if (ret < 0)
-		goto out_tsk;
-
 	switch (request) {
 		/* when I and D space are separate, these will need to be fixed. */
 	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
@@ -282,10 +239,7 @@
 		ret = ptrace_request(child, request, addr, data);
 		break;
 	}
- out_tsk:
-	put_task_struct(child);
- out:
-	unlock_kernel();
+
 	return ret;
 }
 
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c
index a527511..48b1f64 100644
--- a/arch/um/kernel/sigio_user.c
+++ b/arch/um/kernel/sigio_user.c
@@ -18,7 +18,6 @@
 #include "kern_util.h"
 #include "user_util.h"
 #include "sigio.h"
-#include "helper.h"
 #include "os.h"
 
 /* Changed during early boot */
@@ -225,7 +224,7 @@
 		next_poll.used = n;
 		return(0);
 	}
-	if(next_poll.poll != NULL) kfree(next_poll.poll);
+	kfree(next_poll.poll);
 	next_poll.poll = um_kmalloc_atomic(n * sizeof(struct pollfd));
 	if(next_poll.poll == NULL){
 		printk("need_poll : failed to allocate new pollfds\n");
diff --git a/arch/um/kernel/skas/include/mmu-skas.h b/arch/um/kernel/skas/include/mmu-skas.h
index 09536f8..44110c5 100644
--- a/arch/um/kernel/skas/include/mmu-skas.h
+++ b/arch/um/kernel/skas/include/mmu-skas.h
@@ -8,6 +8,7 @@
 
 #include "linux/config.h"
 #include "mm_id.h"
+#include "asm/ldt.h"
 
 struct mmu_context_skas {
 	struct mm_id id;
@@ -15,6 +16,7 @@
 #ifdef CONFIG_3_LEVEL_PGTABLES
         unsigned long last_pmd;
 #endif
+	uml_ldt_t ldt;
 };
 
 extern void switch_mm_skas(struct mm_id * mm_idp);
diff --git a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h
index 0609347..daa2f85 100644
--- a/arch/um/kernel/skas/include/skas.h
+++ b/arch/um/kernel/skas/include/skas.h
@@ -10,7 +10,8 @@
 #include "sysdep/ptrace.h"
 
 extern int userspace_pid[];
-extern int proc_mm, ptrace_faultinfo;
+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);
diff --git a/arch/um/kernel/skas/mem.c b/arch/um/kernel/skas/mem.c
index 147466d..88ab96c 100644
--- a/arch/um/kernel/skas/mem.c
+++ b/arch/um/kernel/skas/mem.c
@@ -20,7 +20,7 @@
 	*task_size_out = CONFIG_HOST_TASK_SIZE;
 #else
 	*host_size_out = top;
-	if (proc_mm && ptrace_faultinfo)
+	if (!skas_needs_stub)
 		*task_size_out = top;
 	else *task_size_out = CONFIG_STUB_START & PGDIR_MASK;
 #endif
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index 9e5e39c..677871f 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -15,6 +15,7 @@
 #include "asm/mmu.h"
 #include "asm/pgalloc.h"
 #include "asm/pgtable.h"
+#include "asm/ldt.h"
 #include "os.h"
 #include "skas.h"
 
@@ -74,13 +75,12 @@
 
 int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
 {
-	struct mm_struct *cur_mm = current->mm;
-	struct mm_id *cur_mm_id = &cur_mm->context.skas.id;
-	struct mm_id *mm_id = &mm->context.skas.id;
+ 	struct mmu_context_skas *from_mm = NULL;
+	struct mmu_context_skas *to_mm = &mm->context.skas;
 	unsigned long stack = 0;
-	int from, ret = -ENOMEM;
+	int from_fd, ret = -ENOMEM;
 
-	if(!proc_mm || !ptrace_faultinfo){
+	if(skas_needs_stub){
 		stack = get_zeroed_page(GFP_KERNEL);
 		if(stack == 0)
 			goto out;
@@ -102,33 +102,43 @@
 
 		mm->nr_ptes--;
 	}
-	mm_id->stack = stack;
+
+	to_mm->id.stack = stack;
+	if(current->mm != NULL && current->mm != &init_mm)
+		from_mm = &current->mm->context.skas;
 
 	if(proc_mm){
-		if((cur_mm != NULL) && (cur_mm != &init_mm))
-			from = cur_mm_id->u.mm_fd;
-		else from = -1;
+		if(from_mm)
+			from_fd = from_mm->id.u.mm_fd;
+		else from_fd = -1;
 
-		ret = new_mm(from, stack);
+		ret = new_mm(from_fd, stack);
 		if(ret < 0){
 			printk("init_new_context_skas - new_mm failed, "
 			       "errno = %d\n", ret);
 			goto out_free;
 		}
-		mm_id->u.mm_fd = ret;
+		to_mm->id.u.mm_fd = ret;
 	}
 	else {
-		if((cur_mm != NULL) && (cur_mm != &init_mm))
-			mm_id->u.pid = copy_context_skas0(stack,
-							  cur_mm_id->u.pid);
-		else mm_id->u.pid = start_userspace(stack);
+		if(from_mm)
+			to_mm->id.u.pid = copy_context_skas0(stack,
+							     from_mm->id.u.pid);
+		else to_mm->id.u.pid = start_userspace(stack);
+	}
+
+	ret = init_new_ldt(to_mm, from_mm);
+	if(ret < 0){
+		printk("init_new_context_skas - init_ldt"
+		       " failed, errno = %d\n", ret);
+		goto out_free;
 	}
 
 	return 0;
 
  out_free:
-	if(mm_id->stack != 0)
-		free_page(mm_id->stack);
+	if(to_mm->id.stack != 0)
+		free_page(to_mm->id.stack);
  out:
 	return ret;
 }
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index 5cd0e99..599d679 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -69,6 +69,17 @@
 
         if((n < 0) || !WIFSTOPPED(status) ||
            (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){
+		unsigned long regs[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 < 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);
@@ -370,9 +381,9 @@
 }
 
 /*
- * This is used only, if proc_mm is available, while PTRACE_FAULTINFO
- * isn't. Opening /proc/mm creates a new mm_context, which lacks the stub-pages
- * Thus, we map them using /proc/mm-fd
+ * 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)
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index efe92e8..9c99025 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -145,7 +145,7 @@
 			       "err = %d\n", -n);
 	}
 
-	if(!ptrace_faultinfo)
+	if(skas_needs_stub)
 		map_stub_pages(fd, CONFIG_STUB_CODE, CONFIG_STUB_DATA, stack);
 
 	return(fd);
diff --git a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c
index 8c220f0..6c92bbc 100644
--- a/arch/um/kernel/tt/uaccess_user.c
+++ b/arch/um/kernel/tt/uaccess_user.c
@@ -10,6 +10,7 @@
 #include "uml_uaccess.h"
 #include "task.h"
 #include "kern_util.h"
+#include "os.h"
 
 int __do_copy_from_user(void *to, const void *from, int n,
 			void **fault_addr, void **fault_catcher)
diff --git a/arch/um/kernel/uaccess.c b/arch/um/kernel/uaccess.c
new file mode 100644
index 0000000..054e3de
--- /dev/null
+++ b/arch/um/kernel/uaccess.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+/* These are here rather than tt/uaccess.c because skas mode needs them in
+ * order to do SIGBUS recovery when a tmpfs mount runs out of room.
+ */
+
+#include <linux/string.h>
+#include "os.h"
+
+void __do_copy(void *to, const void *from, int n)
+{
+	memcpy(to, from, n);
+}
+
+
+int __do_copy_to_user(void *to, const void *from, int n,
+		      void **fault_addr, void **fault_catcher)
+{
+	unsigned long fault;
+	int faulted;
+
+	fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
+			       __do_copy, &faulted);
+	if(!faulted) return(0);
+	else return(n - (fault - (unsigned long) to));
+}
diff --git a/arch/um/kernel/uaccess_user.c b/arch/um/kernel/uaccess_user.c
deleted file mode 100644
index d035257..0000000
--- a/arch/um/kernel/uaccess_user.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* 
- * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
- * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <setjmp.h>
-#include <string.h>
-
-/* These are here rather than tt/uaccess.c because skas mode needs them in
- * order to do SIGBUS recovery when a tmpfs mount runs out of room.
- */
-
-unsigned long __do_user_copy(void *to, const void *from, int n,
-			     void **fault_addr, void **fault_catcher,
-			     void (*op)(void *to, const void *from,
-					int n), int *faulted_out)
-{
-	unsigned long *faddrp = (unsigned long *) fault_addr, ret;
-
-	sigjmp_buf jbuf;
-	*fault_catcher = &jbuf;
-	if(sigsetjmp(jbuf, 1) == 0){
-		(*op)(to, from, n);
-		ret = 0;
-		*faulted_out = 0;
-	} 
-	else {
-		ret = *faddrp;
-		*faulted_out = 1;
-	}
-	*fault_addr = NULL;
-	*fault_catcher = NULL;
-	return ret;
-}
-
-void __do_copy(void *to, const void *from, int n)
-{
-	memcpy(to, from, n);
-}	
-
-
-int __do_copy_to_user(void *to, const void *from, int n,
-		      void **fault_addr, void **fault_catcher)
-{
-	unsigned long fault;
-	int faulted;
-
-	fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
-			       __do_copy, &faulted);
-	if(!faulted) return(0);
-	else return(n - (fault - (unsigned long) to));
-}
-
-/*
- * 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/um_arch.c b/arch/um/kernel/um_arch.c
index 93dc782..142a949 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -137,7 +137,7 @@
 
 /* Set in early boot */
 static int have_root __initdata = 0;
-long physmem_size = 32 * 1024 * 1024;
+long long physmem_size = 32 * 1024 * 1024;
 
 void set_cmdline(char *cmd)
 {
@@ -402,7 +402,7 @@
 #ifndef CONFIG_HIGHMEM
 		highmem = 0;
 		printf("CONFIG_HIGHMEM not enabled - physical memory shrunk "
-		       "to %ld bytes\n", physmem_size);
+		       "to %lu bytes\n", physmem_size);
 #endif
 	}
 
@@ -414,8 +414,8 @@
 
 	setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem);
 	if(init_maps(physmem_size, iomem_size, highmem)){
-		printf("Failed to allocate mem_map for %ld bytes of physical "
-		       "memory and %ld bytes of highmem\n", physmem_size,
+		printf("Failed to allocate mem_map for %lu bytes of physical "
+		       "memory and %lu bytes of highmem\n", physmem_size,
 		       highmem);
 		exit(1);
 	}
@@ -426,7 +426,7 @@
 	end_vm = start_vm + virtmem_size;
 
 	if(virtmem_size < physmem_size)
-		printf("Kernel virtual memory size shrunk to %ld bytes\n",
+		printf("Kernel virtual memory size shrunk to %lu bytes\n",
 		       virtmem_size);
 
   	uml_postsetup();
diff --git a/arch/um/kernel/user_util.c b/arch/um/kernel/user_util.c
index 41d17c7..4c23116 100644
--- a/arch/um/kernel/user_util.c
+++ b/arch/um/kernel/user_util.c
@@ -27,7 +27,6 @@
 #include "user.h"
 #include "mem_user.h"
 #include "init.h"
-#include "helper.h"
 #include "ptrace_user.h"
 #include "uml-config.h"
 
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index d15ec2a..b83ac8e 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -3,11 +3,12 @@
 # Licensed under the GPL
 #
 
-obj-y = aio.o elf_aux.o file.o mem.o process.o signal.o start_up.o time.o \
-	tt.o tty.o user_syms.o drivers/ sys-$(SUBARCH)/
+obj-y = aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
+	start_up.o time.o tt.o tty.o uaccess.o user_syms.o drivers/ \
+	sys-$(SUBARCH)/
 
-USER_OBJS := aio.o elf_aux.o file.o mem.o process.o signal.o start_up.o \
-	time.o tt.o tty.o
+USER_OBJS := aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
+	start_up.o time.o tt.o tty.o uaccess.o
 
 elf_aux.o: $(ARCH_DIR)/kernel-offsets.h
 CFLAGS_elf_aux.o += -I$(objtree)/arch/um
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c
index 41cfb09..ffa759a 100644
--- a/arch/um/os-Linux/aio.c
+++ b/arch/um/os-Linux/aio.c
@@ -10,7 +10,6 @@
 #include <sched.h>
 #include <sys/syscall.h>
 #include "os.h"
-#include "helper.h"
 #include "aio.h"
 #include "init.h"
 #include "user.h"
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
index cd4d654..901b85e 100644
--- a/arch/um/os-Linux/drivers/ethertap_user.c
+++ b/arch/um/os-Linux/drivers/ethertap_user.c
@@ -19,7 +19,6 @@
 #include "user_util.h"
 #include "net_user.h"
 #include "etap.h"
-#include "helper.h"
 #include "os.h"
 
 #define MAX_PACKET ETH_MAX_PACKET
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
index 4ba9b17..5294533 100644
--- a/arch/um/os-Linux/drivers/tuntap_user.c
+++ b/arch/um/os-Linux/drivers/tuntap_user.c
@@ -20,7 +20,6 @@
 #include "kern_util.h"
 #include "user_util.h"
 #include "user.h"
-#include "helper.h"
 #include "os.h"
 
 #define MAX_PACKET ETH_MAX_PACKET
diff --git a/arch/um/kernel/helper.c b/arch/um/os-Linux/helper.c
similarity index 93%
rename from arch/um/kernel/helper.c
rename to arch/um/os-Linux/helper.c
index 33fb0bd..36cc847 100644
--- a/arch/um/kernel/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
@@ -13,7 +13,6 @@
 #include "user.h"
 #include "kern_util.h"
 #include "user_util.h"
-#include "helper.h"
 #include "os.h"
 
 struct helper_data {
@@ -46,7 +45,7 @@
 	errval = errno;
 	printk("execvp of '%s' failed - errno = %d\n", argv[0], errno);
 	os_write_file(data->fd, &errval, sizeof(errval));
-	os_kill_process(os_getpid(), 0);
+	kill(os_getpid(), SIGKILL);
 	return(0);
 }
 
@@ -90,7 +89,7 @@
 		goto out_close;
 	}
 
-	os_close_file(fds[1]);
+	close(fds[1]);
 	fds[1] = -1;
 
 	/*Read the errno value from the child.*/
@@ -98,7 +97,8 @@
 	if(n < 0){
 		printk("run_helper : read on pipe failed, ret = %d\n", -n);
 		ret = n;
-		os_kill_process(pid, 1);
+		kill(pid, SIGKILL);
+		CATCH_EINTR(waitpid(pid, NULL, 0));
 	}
 	else if(n != 0){
 		CATCH_EINTR(n = waitpid(pid, NULL, 0));
@@ -109,8 +109,8 @@
 
 out_close:
 	if (fds[1] != -1)
-		os_close_file(fds[1]);
-	os_close_file(fds[0]);
+		close(fds[1]);
+	close(fds[0]);
 out_free:
 	if(stack_out == NULL)
 		free_stack(stack, 0);
@@ -118,7 +118,7 @@
 	return(ret);
 }
 
-int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, 
+int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
 		      unsigned long *stack_out, int stack_order)
 {
 	unsigned long stack, sp;
@@ -131,7 +131,7 @@
 	pid = clone(proc, (void *) sp, flags | SIGCHLD, arg);
 	if(pid < 0){
 		err = -errno;
-		printk("run_helper_thread : clone failed, errno = %d\n", 
+		printk("run_helper_thread : clone failed, errno = %d\n",
 		       errno);
 		return err;
 	}
diff --git a/arch/um/kernel/main.c b/arch/um/os-Linux/main.c
similarity index 82%
rename from arch/um/kernel/main.c
rename to arch/um/os-Linux/main.c
index d31027f..23da27d 100644
--- a/arch/um/kernel/main.c
+++ b/arch/um/os-Linux/main.c
@@ -157,25 +157,25 @@
 	 */
 	change_sig(SIGPROF, 0);
 
-        /* This signal stuff used to be in the reboot case.  However,
-         * sometimes a SIGVTALRM can come in when we're halting (reproducably
-         * when writing out gcov information, presumably because that takes
-         * some time) and cause a segfault.
-         */
+	/* This signal stuff used to be in the reboot case.  However,
+	 * sometimes a SIGVTALRM can come in when we're halting (reproducably
+	 * when writing out gcov information, presumably because that takes
+	 * some time) and cause a segfault.
+	 */
 
-        /* stop timers and set SIG*ALRM to be ignored */
-        disable_timer();
+	/* stop timers and set SIG*ALRM to be ignored */
+	disable_timer();
 
-        /* disable SIGIO for the fds and set SIGIO to be ignored */
-        err = deactivate_all_fds();
-        if(err)
-                printf("deactivate_all_fds failed, errno = %d\n", -err);
+	/* disable SIGIO for the fds and set SIGIO to be ignored */
+	err = deactivate_all_fds();
+	if(err)
+		printf("deactivate_all_fds failed, errno = %d\n", -err);
 
-        /* Let any pending signals fire now.  This ensures
-         * that they won't be delivered after the exec, when
-         * they are definitely not expected.
-         */
-        unblock_signals();
+	/* Let any pending signals fire now.  This ensures
+	 * that they won't be delivered after the exec, when
+	 * they are definitely not expected.
+	 */
+	unblock_signals();
 
 	/* Reboot */
 	if(ret){
@@ -257,14 +257,3 @@
 	}
 	else __real_free(ptr);
 }
-
-/*
- * 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/mem.c b/arch/um/os-Linux/mem.c
index 8e71eda..9d7d69a 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -88,7 +88,7 @@
  * This proc is used in start_up.c
  * So it isn't 'static'.
  */
-int create_tmp_file(unsigned long len)
+int create_tmp_file(unsigned long long len)
 {
 	int fd, err;
 	char zero;
@@ -121,7 +121,7 @@
 	return(fd);
 }
 
-static int create_anon_file(unsigned long len)
+static int create_anon_file(unsigned long long len)
 {
 	void *addr;
 	int fd;
@@ -144,7 +144,7 @@
 
 extern int have_devanon;
 
-int create_mem_file(unsigned long len)
+int create_mem_file(unsigned long long len)
 {
 	int err, fd;
 
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index b99ab41..37517d4 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -135,7 +135,9 @@
 }
 
 int ptrace_faultinfo = 1;
+int ptrace_ldt = 1;
 int proc_mm = 1;
+int skas_needs_stub = 0;
 
 static int __init skas0_cmd_param(char *str, int* add)
 {
@@ -294,7 +296,7 @@
 	check_sysemu();
 }
 
-extern int create_tmp_file(unsigned long len);
+extern int create_tmp_file(unsigned long long len);
 
 static void check_tmpexec(void)
 {
@@ -352,14 +354,26 @@
 "    it. To support PTRACE_FAULTINFO, the host needs to be patched\n"
 "    using the current skas3 patch.\n\n");
 
+static int __init noptraceldt_cmd_param(char *str, int* add)
+{
+	ptrace_ldt = 0;
+	return 0;
+}
+
+__uml_setup("noptraceldt", noptraceldt_cmd_param,
+"noptraceldt\n"
+"    Turns off usage of PTRACE_LDT, even if host supports it.\n"
+"    To support PTRACE_LDT, the host needs to be patched using\n"
+"    the current skas3 patch.\n\n");
+
 #ifdef UML_CONFIG_MODE_SKAS
-static inline void check_skas3_ptrace_support(void)
+static inline void check_skas3_ptrace_faultinfo(void)
 {
 	struct ptrace_faultinfo fi;
 	void *stack;
 	int pid, n;
 
-	printf("Checking for the skas3 patch in the host...");
+	printf("  - PTRACE_FAULTINFO...");
 	pid = start_ptraced_child(&stack);
 
 	n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
@@ -381,9 +395,49 @@
 	stop_ptraced_child(pid, stack, 1, 1);
 }
 
-int can_do_skas(void)
+static inline void check_skas3_ptrace_ldt(void)
 {
-	printf("Checking for /proc/mm...");
+#ifdef PTRACE_LDT
+	void *stack;
+	int pid, n;
+	unsigned char ldtbuf[40];
+	struct ptrace_ldt ldt_op = (struct ptrace_ldt) {
+		.func = 2, /* read default ldt */
+		.ptr = ldtbuf,
+		.bytecount = sizeof(ldtbuf)};
+
+	printf("  - PTRACE_LDT...");
+	pid = start_ptraced_child(&stack);
+
+	n = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op);
+	if (n < 0) {
+		if(errno == EIO)
+			printf("not found\n");
+		else {
+			perror("not found");
+		}
+		ptrace_ldt = 0;
+	}
+	else {
+		if(ptrace_ldt)
+			printf("found\n");
+		else
+			printf("found, but use is disabled\n");
+	}
+
+	stop_ptraced_child(pid, stack, 1, 1);
+#else
+	/* PTRACE_LDT might be disabled via cmdline option.
+	 * We want to override this, else we might use the stub
+	 * without real need
+	 */
+	ptrace_ldt = 1;
+#endif
+}
+
+static inline void check_skas3_proc_mm(void)
+{
+	printf("  - /proc/mm...");
 	if (os_access("/proc/mm", OS_ACC_W_OK) < 0) {
  		proc_mm = 0;
 		printf("not found\n");
@@ -394,8 +448,19 @@
 		else
 			printf("found\n");
 	}
+}
 
-	check_skas3_ptrace_support();
+int can_do_skas(void)
+{
+	printf("Checking for the skas3 patch in the host:\n");
+
+	check_skas3_proc_mm();
+	check_skas3_ptrace_faultinfo();
+	check_skas3_ptrace_ldt();
+
+	if(!proc_mm || !ptrace_faultinfo || !ptrace_ldt)
+		skas_needs_stub = 1;
+
 	return 1;
 }
 #else
diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c
new file mode 100644
index 0000000..38d7101
--- /dev/null
+++ b/arch/um/os-Linux/uaccess.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#include <setjmp.h>
+#include <string.h>
+
+unsigned long __do_user_copy(void *to, const void *from, int n,
+			     void **fault_addr, void **fault_catcher,
+			     void (*op)(void *to, const void *from,
+					int n), int *faulted_out)
+{
+	unsigned long *faddrp = (unsigned long *) fault_addr, ret;
+
+	sigjmp_buf jbuf;
+	*fault_catcher = &jbuf;
+	if(sigsetjmp(jbuf, 1) == 0){
+		(*op)(to, from, n);
+		ret = 0;
+		*faulted_out = 0;
+	}
+	else {
+		ret = *faddrp;
+		*faulted_out = 1;
+	}
+	*fault_addr = NULL;
+	*fault_catcher = NULL;
+	return ret;
+}
+
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index 651d9d8..b3fbf12 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -26,8 +26,13 @@
 	$(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1)))
 endef
 
+# cmd_make_link checks to see if the $(foo-dir) variable starts with a /.  If
+# so, it's considered to be a path relative to $(srcdir) rather than
+# $(srcdir)/arch/$(SUBARCH).  This is because x86_64 wants to get ldt.c from
+# arch/um/sys-i386 rather than arch/i386 like the other borrowed files.  So,
+# it sets $(ldt.c-dir) to /arch/um/sys-i386.
 quiet_cmd_make_link = SYMLINK $@
-cmd_make_link       = ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@
+cmd_make_link       = rm -f $@; ln -sf $(srctree)$(if $(filter-out /%,$($(notdir $@)-dir)),/arch/$(SUBARCH))/$($(notdir $@)-dir)/$(notdir $@) $@
 
 # this needs to be before the foreach, because targets does not accept
 # complete paths like $(obj)/$(f). To make sure this works, use a := assignment
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index 36b5c2c..6360f1c 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -3,53 +3,26 @@
  * Licensed under the GPL
  */
 
+#include "linux/stddef.h"
 #include "linux/config.h"
 #include "linux/sched.h"
 #include "linux/slab.h"
 #include "linux/types.h"
+#include "linux/errno.h"
 #include "asm/uaccess.h"
-#include "asm/ptrace.h"
 #include "asm/smp.h"
 #include "asm/ldt.h"
+#include "asm/unistd.h"
 #include "choose-mode.h"
 #include "kern.h"
 #include "mode_kern.h"
 
-#ifdef CONFIG_MODE_TT
-
 extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
 
-static int do_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
-{
-	return modify_ldt(func, ptr, bytecount);
-}
+#ifdef CONFIG_MODE_TT
 
-#endif
-
-#ifdef CONFIG_MODE_SKAS
-
-#include "skas.h"
-#include "skas_ptrace.h"
-
-static int do_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
-{
-	struct ptrace_ldt ldt;
-	u32 cpu;
-	int res;
-
-	ldt = ((struct ptrace_ldt) { .func	= func,
-				     .ptr	= ptr,
-				     .bytecount = bytecount });
-
-	cpu = get_cpu();
-	res = ptrace(PTRACE_LDT, userspace_pid[cpu], 0, (unsigned long) &ldt);
-	put_cpu();
-
-	return res;
-}
-#endif
-
-int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
+static long do_modify_ldt_tt(int func, void __user *ptr,
+			      unsigned long bytecount)
 {
 	struct user_desc info;
 	int res = 0;
@@ -89,8 +62,7 @@
 		goto out;
 	}
 
-	res = CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func,
-				p, bytecount);
+	res = modify_ldt(func, p, bytecount);
 	if(res < 0)
 		goto out;
 
@@ -108,3 +80,467 @@
 	kfree(buf);
 	return res;
 }
+
+#endif
+
+#ifdef CONFIG_MODE_SKAS
+
+#include "skas.h"
+#include "skas_ptrace.h"
+#include "asm/mmu_context.h"
+
+long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
+		     void **addr, int done)
+{
+	long res;
+
+	if(proc_mm){
+		/* This is a special handling for the case, that the mm to
+		 * modify isn't current->active_mm.
+		 * If this is called directly by modify_ldt,
+		 *     (current->active_mm->context.skas.u == mm_idp)
+		 * will be true. So no call to switch_mm_skas(mm_idp) is done.
+		 * If this is called in case of init_new_ldt or PTRACE_LDT,
+		 * mm_idp won't belong to current->active_mm, but child->mm.
+		 * So we need to switch child's mm into our userspace, then
+		 * later switch back.
+		 *
+		 * Note: I'm unshure: should interrupts be disabled here?
+		 */
+		if(!current->active_mm || current->active_mm == &init_mm ||
+		   mm_idp != &current->active_mm->context.skas.id)
+			switch_mm_skas(mm_idp);
+	}
+
+	if(ptrace_ldt) {
+		struct ptrace_ldt ldt_op = (struct ptrace_ldt) {
+			.func = func,
+			.ptr = desc,
+			.bytecount = sizeof(*desc)};
+		u32 cpu;
+		int pid;
+
+		if(!proc_mm)
+			pid = mm_idp->u.pid;
+		else {
+			cpu = get_cpu();
+			pid = userspace_pid[cpu];
+		}
+
+		res = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op);
+		if(res)
+			res = errno;
+
+		if(proc_mm)
+			put_cpu();
+	}
+	else {
+		void *stub_addr;
+		res = syscall_stub_data(mm_idp, (unsigned long *)desc,
+					(sizeof(*desc) + sizeof(long) - 1) &
+					    ~(sizeof(long) - 1),
+					addr, &stub_addr);
+		if(!res){
+			unsigned long args[] = { func,
+						 (unsigned long)stub_addr,
+						 sizeof(*desc),
+						 0, 0, 0 };
+			res = run_syscall_stub(mm_idp, __NR_modify_ldt, args,
+					       0, addr, done);
+		}
+	}
+
+	if(proc_mm){
+		/* This is the second part of special handling, that makes
+		 * PTRACE_LDT possible to implement.
+		 */
+		if(current->active_mm && current->active_mm != &init_mm &&
+		   mm_idp != &current->active_mm->context.skas.id)
+			switch_mm_skas(&current->active_mm->context.skas.id);
+	}
+
+	return res;
+}
+
+static long read_ldt_from_host(void __user * ptr, unsigned long bytecount)
+{
+	int res, n;
+	struct ptrace_ldt ptrace_ldt = (struct ptrace_ldt) {
+			.func = 0,
+			.bytecount = bytecount,
+			.ptr = (void *)kmalloc(bytecount, GFP_KERNEL)};
+	u32 cpu;
+
+	if(ptrace_ldt.ptr == NULL)
+		return -ENOMEM;
+
+	/* This is called from sys_modify_ldt only, so userspace_pid gives
+	 * us the right number
+	 */
+
+	cpu = get_cpu();
+	res = ptrace(PTRACE_LDT, userspace_pid[cpu], 0,
+		     (unsigned long) &ptrace_ldt);
+	put_cpu();
+	if(res < 0)
+		goto out;
+
+	n = copy_to_user(ptr, ptrace_ldt.ptr, res);
+	if(n != 0)
+		res = -EFAULT;
+
+  out:
+	kfree(ptrace_ldt.ptr);
+
+	return res;
+}
+
+/*
+ * In skas mode, we hold our own ldt data in UML.
+ * Thus, the code implementing sys_modify_ldt_skas
+ * is very similar to (and mostly stolen from) sys_modify_ldt
+ * for arch/i386/kernel/ldt.c
+ * The routines copied and modified in part are:
+ * - read_ldt
+ * - read_default_ldt
+ * - write_ldt
+ * - sys_modify_ldt_skas
+ */
+
+static int read_ldt(void __user * ptr, unsigned long bytecount)
+{
+	int i, err = 0;
+	unsigned long size;
+	uml_ldt_t * ldt = &current->mm->context.skas.ldt;
+
+	if(!ldt->entry_count)
+		goto out;
+	if(bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
+		bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
+	err = bytecount;
+
+	if(ptrace_ldt){
+		return read_ldt_from_host(ptr, bytecount);
+	}
+
+	down(&ldt->semaphore);
+	if(ldt->entry_count <= LDT_DIRECT_ENTRIES){
+		size = LDT_ENTRY_SIZE*LDT_DIRECT_ENTRIES;
+		if(size > bytecount)
+			size = bytecount;
+		if(copy_to_user(ptr, ldt->entries, size))
+			err = -EFAULT;
+		bytecount -= size;
+		ptr += size;
+	}
+	else {
+		for(i=0; i<ldt->entry_count/LDT_ENTRIES_PER_PAGE && bytecount;
+			 i++){
+			size = PAGE_SIZE;
+			if(size > bytecount)
+				size = bytecount;
+			if(copy_to_user(ptr, ldt->pages[i], size)){
+				err = -EFAULT;
+				break;
+			}
+			bytecount -= size;
+			ptr += size;
+		}
+	}
+	up(&ldt->semaphore);
+
+	if(bytecount == 0 || err == -EFAULT)
+		goto out;
+
+	if(clear_user(ptr, bytecount))
+		err = -EFAULT;
+
+out:
+	return err;
+}
+
+static int read_default_ldt(void __user * ptr, unsigned long bytecount)
+{
+	int err;
+
+	if(bytecount > 5*LDT_ENTRY_SIZE)
+		bytecount = 5*LDT_ENTRY_SIZE;
+
+	err = bytecount;
+	/* UML doesn't support lcall7 and lcall27.
+	 * So, we don't really have a default ldt, but emulate
+	 * an empty ldt of common host default ldt size.
+	 */
+	if(clear_user(ptr, bytecount))
+		err = -EFAULT;
+
+	return err;
+}
+
+static int write_ldt(void __user * ptr, unsigned long bytecount, int func)
+{
+	uml_ldt_t * ldt = &current->mm->context.skas.ldt;
+	struct mm_id * mm_idp = &current->mm->context.skas.id;
+	int i, err;
+	struct user_desc ldt_info;
+	struct ldt_entry entry0, *ldt_p;
+	void *addr = NULL;
+
+	err = -EINVAL;
+	if(bytecount != sizeof(ldt_info))
+		goto out;
+	err = -EFAULT;
+	if(copy_from_user(&ldt_info, ptr, sizeof(ldt_info)))
+		goto out;
+
+	err = -EINVAL;
+	if(ldt_info.entry_number >= LDT_ENTRIES)
+		goto out;
+	if(ldt_info.contents == 3){
+		if (func == 1)
+			goto out;
+		if (ldt_info.seg_not_present == 0)
+			goto out;
+	}
+
+        if(!ptrace_ldt)
+                down(&ldt->semaphore);
+
+	err = write_ldt_entry(mm_idp, func, &ldt_info, &addr, 1);
+	if(err)
+		goto out_unlock;
+        else if(ptrace_ldt) {
+	/* With PTRACE_LDT available, this is used as a flag only */
+                ldt->entry_count = 1;
+                goto out;
+        }
+
+	if(ldt_info.entry_number >= ldt->entry_count &&
+	   ldt_info.entry_number >= LDT_DIRECT_ENTRIES){
+		for(i=ldt->entry_count/LDT_ENTRIES_PER_PAGE;
+		    i*LDT_ENTRIES_PER_PAGE <= ldt_info.entry_number;
+		    i++){
+			if(i == 0)
+				memcpy(&entry0, ldt->entries, sizeof(entry0));
+			ldt->pages[i] = (struct ldt_entry *)
+					__get_free_page(GFP_KERNEL|__GFP_ZERO);
+			if(!ldt->pages[i]){
+				err = -ENOMEM;
+				/* Undo the change in host */
+				memset(&ldt_info, 0, sizeof(ldt_info));
+				write_ldt_entry(mm_idp, 1, &ldt_info, &addr, 1);
+				goto out_unlock;
+			}
+			if(i == 0) {
+				memcpy(ldt->pages[0], &entry0, sizeof(entry0));
+				memcpy(ldt->pages[0]+1, ldt->entries+1,
+				       sizeof(entry0)*(LDT_DIRECT_ENTRIES-1));
+			}
+			ldt->entry_count = (i + 1) * LDT_ENTRIES_PER_PAGE;
+		}
+	}
+	if(ldt->entry_count <= ldt_info.entry_number)
+		ldt->entry_count = ldt_info.entry_number + 1;
+
+	if(ldt->entry_count <= LDT_DIRECT_ENTRIES)
+		ldt_p = ldt->entries + ldt_info.entry_number;
+	else
+		ldt_p = ldt->pages[ldt_info.entry_number/LDT_ENTRIES_PER_PAGE] +
+			ldt_info.entry_number%LDT_ENTRIES_PER_PAGE;
+
+	if(ldt_info.base_addr == 0 && ldt_info.limit == 0 &&
+	   (func == 1 || LDT_empty(&ldt_info))){
+		ldt_p->a = 0;
+		ldt_p->b = 0;
+	}
+	else{
+		if (func == 1)
+			ldt_info.useable = 0;
+		ldt_p->a = LDT_entry_a(&ldt_info);
+		ldt_p->b = LDT_entry_b(&ldt_info);
+	}
+	err = 0;
+
+out_unlock:
+	up(&ldt->semaphore);
+out:
+	return err;
+}
+
+static long do_modify_ldt_skas(int func, void __user *ptr,
+			       unsigned long bytecount)
+{
+	int ret = -ENOSYS;
+
+	switch (func) {
+		case 0:
+			ret = read_ldt(ptr, bytecount);
+			break;
+		case 1:
+		case 0x11:
+			ret = write_ldt(ptr, bytecount, func);
+			break;
+		case 2:
+			ret = read_default_ldt(ptr, bytecount);
+			break;
+	}
+	return ret;
+}
+
+short dummy_list[9] = {0, -1};
+short * host_ldt_entries = NULL;
+
+void ldt_get_host_info(void)
+{
+	long ret;
+	struct ldt_entry * ldt;
+	int i, size, k, order;
+
+	host_ldt_entries = dummy_list+1;
+
+	for(i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++);
+
+	ldt = (struct ldt_entry *)
+	      __get_free_pages(GFP_KERNEL|__GFP_ZERO, order);
+	if(ldt == NULL) {
+		printk("ldt_get_host_info: couldn't allocate buffer for host ldt\n");
+		return;
+	}
+
+	ret = modify_ldt(0, ldt, (1<<order)*PAGE_SIZE);
+	if(ret < 0) {
+		printk("ldt_get_host_info: couldn't read host ldt\n");
+		goto out_free;
+	}
+	if(ret == 0) {
+		/* default_ldt is active, simply write an empty entry 0 */
+		host_ldt_entries = dummy_list;
+		goto out_free;
+	}
+
+	for(i=0, size=0; i<ret/LDT_ENTRY_SIZE; i++){
+		if(ldt[i].a != 0 || ldt[i].b != 0)
+			size++;
+	}
+
+	if(size < sizeof(dummy_list)/sizeof(dummy_list[0])) {
+		host_ldt_entries = dummy_list;
+	}
+	else {
+		size = (size + 1) * sizeof(dummy_list[0]);
+		host_ldt_entries = (short *)kmalloc(size, GFP_KERNEL);
+		if(host_ldt_entries == NULL) {
+			printk("ldt_get_host_info: couldn't allocate host ldt list\n");
+			goto out_free;
+		}
+	}
+
+	for(i=0, k=0; i<ret/LDT_ENTRY_SIZE; i++){
+		if(ldt[i].a != 0 || ldt[i].b != 0) {
+			host_ldt_entries[k++] = i;
+		}
+	}
+	host_ldt_entries[k] = -1;
+
+out_free:
+	free_pages((unsigned long)ldt, order);
+}
+
+long init_new_ldt(struct mmu_context_skas * new_mm,
+		  struct mmu_context_skas * from_mm)
+{
+	struct user_desc desc;
+	short * num_p;
+	int i;
+	long page, err=0;
+	void *addr = NULL;
+
+	memset(&desc, 0, sizeof(desc));
+
+	if(!ptrace_ldt)
+		init_MUTEX(&new_mm->ldt.semaphore);
+
+	if(!from_mm){
+		/*
+		 * We have to initialize a clean ldt.
+		 */
+		if(proc_mm) {
+			/*
+			 * If the new mm was created using proc_mm, host's
+			 * default-ldt currently is assigned, which normally
+			 * contains the call-gates for lcall7 and lcall27.
+			 * To remove these gates, we simply write an empty
+			 * entry as number 0 to the host.
+			 */
+			err = write_ldt_entry(&new_mm->id, 1, &desc,
+					      &addr, 1);
+		}
+		else{
+			/*
+			 * Now we try to retrieve info about the ldt, we
+			 * inherited from the host. All ldt-entries found
+			 * will be reset in the following loop
+			 */
+			if(host_ldt_entries == NULL)
+				ldt_get_host_info();
+			for(num_p=host_ldt_entries; *num_p != -1; num_p++){
+				desc.entry_number = *num_p;
+				err = write_ldt_entry(&new_mm->id, 1, &desc,
+						      &addr, *(num_p + 1) == -1);
+				if(err)
+					break;
+			}
+		}
+		new_mm->ldt.entry_count = 0;
+	}
+	else 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
+		 * can't handle the big read buffer of up to 64kB.
+		 */
+		down(&from_mm->ldt.semaphore);
+		if(from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES){
+			memcpy(new_mm->ldt.entries, from_mm->ldt.entries,
+			       sizeof(new_mm->ldt.entries));
+		}
+		else{
+			i = from_mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE;
+			while(i-->0){
+				page = __get_free_page(GFP_KERNEL|__GFP_ZERO);
+				if (!page){
+					err = -ENOMEM;
+					break;
+				}
+				new_mm->ldt.pages[i] = (struct ldt_entry*)page;
+				memcpy(new_mm->ldt.pages[i],
+				       from_mm->ldt.pages[i], PAGE_SIZE);
+			}
+		}
+		new_mm->ldt.entry_count = from_mm->ldt.entry_count;
+		up(&from_mm->ldt.semaphore);
+	}
+
+	return err;
+}
+
+
+void free_ldt(struct mmu_context_skas * mm)
+{
+	int i;
+
+	if(!ptrace_ldt && mm->ldt.entry_count > LDT_DIRECT_ENTRIES){
+		i = mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE;
+		while(i-- > 0){
+			free_page((long )mm->ldt.pages[i]);
+		}
+	}
+	mm->ldt.entry_count = 0;
+}
+#endif
+
+int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
+{
+	return(CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func,
+	                        ptr, bytecount));
+}
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index 06c3633..ea977df 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -5,7 +5,7 @@
 #
 
 #XXX: why into lib-y?
-lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \
+lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o ldt.o mem.o memcpy.o \
 	ptrace.o ptrace_user.o sigcontext.o signal.o stub.o \
 	stub_segv.o syscalls.o syscall_table.o sysrq.o thunk.o
 
@@ -14,7 +14,7 @@
 
 USER_OBJS := ptrace_user.o sigcontext.o
 
-SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c memcpy.S \
+SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c ldt.c memcpy.S \
 	thunk.S module.c
 
 include arch/um/scripts/Makefile.rules
@@ -23,6 +23,7 @@
 csum-copy.S-dir = lib
 csum-partial.c-dir = lib
 csum-wrappers.c-dir = lib
+ldt.c-dir = /arch/um/sys-i386
 memcpy.S-dir = lib
 thunk.S-dir = lib
 module.c-dir = kernel
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
index 3259a4d..6acee5c 100644
--- a/arch/um/sys-x86_64/syscalls.c
+++ b/arch/um/sys-x86_64/syscalls.c
@@ -29,81 +29,6 @@
 }
 
 #ifdef CONFIG_MODE_TT
-extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
-
-long sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
-{
-	/* XXX This should check VERIFY_WRITE depending on func, check this
-	 * in i386 as well.
-	 */
-	if (!access_ok(VERIFY_READ, ptr, bytecount))
-		return -EFAULT;
-	return(modify_ldt(func, ptr, bytecount));
-}
-#endif
-
-#ifdef CONFIG_MODE_SKAS
-extern int userspace_pid[];
-
-#include "skas_ptrace.h"
-
-long sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
-{
-	struct ptrace_ldt ldt;
-        void *buf;
-        int res, n;
-
-        buf = kmalloc(bytecount, GFP_KERNEL);
-        if(buf == NULL)
-                return(-ENOMEM);
-
-        res = 0;
-
-        switch(func){
-        case 1:
-        case 0x11:
-                res = copy_from_user(buf, ptr, bytecount);
-                break;
-        }
-
-        if(res != 0){
-                res = -EFAULT;
-                goto out;
-        }
-
-	ldt = ((struct ptrace_ldt) { .func	= func,
-				     .ptr	= buf,
-				     .bytecount = bytecount });
-#warning Need to look up userspace_pid by cpu
-	res = ptrace(PTRACE_LDT, userspace_pid[0], 0, (unsigned long) &ldt);
-        if(res < 0)
-                goto out;
-
-        switch(func){
-        case 0:
-        case 2:
-                n = res;
-                res = copy_to_user(ptr, buf, n);
-                if(res != 0)
-                        res = -EFAULT;
-                else
-                        res = n;
-                break;
-        }
-
- out:
-        kfree(buf);
-        return(res);
-}
-#endif
-
-long sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
-{
-        return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func,
-                                ptr, bytecount));
-}
-
-#ifdef CONFIG_MODE_TT
 extern long arch_prctl(int code, unsigned long addr);
 
 static long arch_prctl_tt(int code, unsigned long addr)
diff --git a/arch/v850/kernel/ptrace.c b/arch/v850/kernel/ptrace.c
index d6077ff..18492d0 100644
--- a/arch/v850/kernel/ptrace.c
+++ b/arch/v850/kernel/ptrace.c
@@ -113,45 +113,10 @@
 	return 1;
 }
 
-long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-	struct task_struct *child;
 	int rval;
 
-	lock_kernel();
-
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED) {
-			rval = -EPERM;
-			goto out;
-		}
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		rval = 0;
-		goto out;
-	}
-	rval = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (!child)
-		goto out;
-
-	rval = -EPERM;
-	if (pid == 1)		/* you may not mess with init */
-		goto out_tsk;
-
-	if (request == PTRACE_ATTACH) {
-		rval = ptrace_attach(child);
-		goto out_tsk;
-	}
-	rval = ptrace_check_attach(child, request == PTRACE_KILL);
-	if (rval < 0)
-		goto out_tsk;
-
 	switch (request) {
 		unsigned long val, copied;
 
@@ -248,11 +213,7 @@
 		rval = -EIO;
 		goto out;
 	}
-
-out_tsk:
-	put_task_struct(child);
-out:
-	unlock_kernel();
+ out:
 	return rval;
 }
 
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 21afa69..4cce2f6 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -532,8 +532,21 @@
 
 source fs/Kconfig
 
+menu "Instrumentation Support"
+        depends on EXPERIMENTAL
+
 source "arch/x86_64/oprofile/Kconfig"
 
+config KPROBES
+	bool "Kprobes (EXPERIMENTAL)"
+	help
+	  Kprobes allows you to trap at almost any kernel address and
+	  execute a callback function.  register_kprobe() establishes
+	  a probepoint and specifies the callback.  Kprobes is useful
+	  for kernel debugging, non-intrusive instrumentation and testing.
+	  If in doubt, say "N".
+endmenu
+
 source "arch/x86_64/Kconfig.debug"
 
 source "security/Kconfig"
diff --git a/arch/x86_64/Kconfig.debug b/arch/x86_64/Kconfig.debug
index 9cf1410..d584ecc 100644
--- a/arch/x86_64/Kconfig.debug
+++ b/arch/x86_64/Kconfig.debug
@@ -33,16 +33,6 @@
 	 options. See Documentation/x86_64/boot-options.txt for more
 	 details.
 
-config KPROBES
-	bool "Kprobes"
-	depends on DEBUG_KERNEL
-	help
-	  Kprobes allows you to trap at almost any kernel address and
-	  execute a callback function.  register_kprobe() establishes
-	  a probepoint and specifies the callback.  Kprobes is useful
-	  for kernel debugging, non-intrusive instrumentation and testing.
-	  If in doubt, say "N".
-
 config IOMMU_LEAK
        bool "IOMMU leak tracing"
        depends on DEBUG_KERNEL
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c
index 76a28b0..dddeb67 100644
--- a/arch/x86_64/kernel/kprobes.c
+++ b/arch/x86_64/kernel/kprobes.c
@@ -34,7 +34,6 @@
 #include <linux/config.h>
 #include <linux/kprobes.h>
 #include <linux/ptrace.h>
-#include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/preempt.h>
@@ -44,17 +43,10 @@
 #include <asm/kdebug.h>
 
 static DECLARE_MUTEX(kprobe_mutex);
-
-static struct kprobe *current_kprobe;
-static unsigned long kprobe_status, kprobe_old_rflags, kprobe_saved_rflags;
-static struct kprobe *kprobe_prev;
-static unsigned long kprobe_status_prev, kprobe_old_rflags_prev, kprobe_saved_rflags_prev;
-static struct pt_regs jprobe_saved_regs;
-static long *jprobe_saved_rsp;
 void jprobe_return_end(void);
 
-/* copy of the kernel stack at the probe fire time */
-static kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
+DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
 /*
  * returns non-zero if opcode modifies the interrupt flag.
@@ -236,29 +228,30 @@
 	up(&kprobe_mutex);
 }
 
-static inline void save_previous_kprobe(void)
+static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-	kprobe_prev = current_kprobe;
-	kprobe_status_prev = kprobe_status;
-	kprobe_old_rflags_prev = kprobe_old_rflags;
-	kprobe_saved_rflags_prev = kprobe_saved_rflags;
+	kcb->prev_kprobe.kp = kprobe_running();
+	kcb->prev_kprobe.status = kcb->kprobe_status;
+	kcb->prev_kprobe.old_rflags = kcb->kprobe_old_rflags;
+	kcb->prev_kprobe.saved_rflags = kcb->kprobe_saved_rflags;
 }
 
-static inline void restore_previous_kprobe(void)
+static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-	current_kprobe = kprobe_prev;
-	kprobe_status = kprobe_status_prev;
-	kprobe_old_rflags = kprobe_old_rflags_prev;
-	kprobe_saved_rflags = kprobe_saved_rflags_prev;
+	__get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+	kcb->kprobe_status = kcb->prev_kprobe.status;
+	kcb->kprobe_old_rflags = kcb->prev_kprobe.old_rflags;
+	kcb->kprobe_saved_rflags = kcb->prev_kprobe.saved_rflags;
 }
 
-static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs)
+static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
+				struct kprobe_ctlblk *kcb)
 {
-	current_kprobe = p;
-	kprobe_saved_rflags = kprobe_old_rflags
+	__get_cpu_var(current_kprobe) = p;
+	kcb->kprobe_saved_rflags = kcb->kprobe_old_rflags
 		= (regs->eflags & (TF_MASK | IF_MASK));
 	if (is_IF_modifier(p->ainsn.insn))
-		kprobe_saved_rflags &= ~IF_MASK;
+		kcb->kprobe_saved_rflags &= ~IF_MASK;
 }
 
 static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
@@ -272,6 +265,7 @@
 		regs->rip = (unsigned long)p->ainsn.insn;
 }
 
+/* Called with kretprobe_lock held */
 void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
 				      struct pt_regs *regs)
 {
@@ -292,32 +286,30 @@
         }
 }
 
-/*
- * Interrupts are disabled on entry as trap3 is an interrupt gate and they
- * remain disabled thorough out this function.
- */
 int __kprobes kprobe_handler(struct pt_regs *regs)
 {
 	struct kprobe *p;
 	int ret = 0;
 	kprobe_opcode_t *addr = (kprobe_opcode_t *)(regs->rip - sizeof(kprobe_opcode_t));
+	struct kprobe_ctlblk *kcb;
 
-	/* We're in an interrupt, but this is clear and BUG()-safe. */
+	/*
+	 * We don't want to be preempted for the entire
+	 * duration of kprobe processing
+	 */
 	preempt_disable();
+	kcb = get_kprobe_ctlblk();
 
 	/* Check we're not actually recursing */
 	if (kprobe_running()) {
-		/* We *are* holding lock here, so this is safe.
-		   Disarm the probe we just hit, and ignore it. */
 		p = get_kprobe(addr);
 		if (p) {
-			if (kprobe_status == KPROBE_HIT_SS &&
+			if (kcb->kprobe_status == KPROBE_HIT_SS &&
 				*p->ainsn.insn == BREAKPOINT_INSTRUCTION) {
 				regs->eflags &= ~TF_MASK;
-				regs->eflags |= kprobe_saved_rflags;
-				unlock_kprobes();
+				regs->eflags |= kcb->kprobe_saved_rflags;
 				goto no_kprobe;
-			} else if (kprobe_status == KPROBE_HIT_SSDONE) {
+			} else if (kcb->kprobe_status == KPROBE_HIT_SSDONE) {
 				/* TODO: Provide re-entrancy from
 				 * post_kprobes_handler() and avoid exception
 				 * stack corruption while single-stepping on
@@ -325,6 +317,7 @@
 				 */
 				arch_disarm_kprobe(p);
 				regs->rip = (unsigned long)p->addr;
+				reset_current_kprobe();
 				ret = 1;
 			} else {
 				/* We have reentered the kprobe_handler(), since
@@ -334,27 +327,24 @@
 				 * of the new probe without calling any user
 				 * handlers.
 				 */
-				save_previous_kprobe();
-				set_current_kprobe(p, regs);
+				save_previous_kprobe(kcb);
+				set_current_kprobe(p, regs, kcb);
 				p->nmissed++;
 				prepare_singlestep(p, regs);
-				kprobe_status = KPROBE_REENTER;
+				kcb->kprobe_status = KPROBE_REENTER;
 				return 1;
 			}
 		} else {
-			p = current_kprobe;
+			p = __get_cpu_var(current_kprobe);
 			if (p->break_handler && p->break_handler(p, regs)) {
 				goto ss_probe;
 			}
 		}
-		/* If it's not ours, can't be delete race, (we hold lock). */
 		goto no_kprobe;
 	}
 
-	lock_kprobes();
 	p = get_kprobe(addr);
 	if (!p) {
-		unlock_kprobes();
 		if (*addr != BREAKPOINT_INSTRUCTION) {
 			/*
 			 * The breakpoint instruction was removed right
@@ -372,8 +362,8 @@
 		goto no_kprobe;
 	}
 
-	kprobe_status = KPROBE_HIT_ACTIVE;
-	set_current_kprobe(p, regs);
+	set_current_kprobe(p, regs, kcb);
+	kcb->kprobe_status = KPROBE_HIT_ACTIVE;
 
 	if (p->pre_handler && p->pre_handler(p, regs))
 		/* handler has already set things up, so skip ss setup */
@@ -381,7 +371,7 @@
 
 ss_probe:
 	prepare_singlestep(p, regs);
-	kprobe_status = KPROBE_HIT_SS;
+	kcb->kprobe_status = KPROBE_HIT_SS;
 	return 1;
 
 no_kprobe:
@@ -409,9 +399,10 @@
         struct kretprobe_instance *ri = NULL;
         struct hlist_head *head;
         struct hlist_node *node, *tmp;
-	unsigned long orig_ret_address = 0;
+	unsigned long flags, orig_ret_address = 0;
 	unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
 
+	spin_lock_irqsave(&kretprobe_lock, flags);
         head = kretprobe_inst_table_head(current);
 
 	/*
@@ -450,13 +441,14 @@
 	BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
 	regs->rip = orig_ret_address;
 
-	unlock_kprobes();
+	reset_current_kprobe();
+	spin_unlock_irqrestore(&kretprobe_lock, flags);
 	preempt_enable_no_resched();
 
         /*
          * By returning a non-zero value, we are telling
-         * kprobe_handler() that we have handled unlocking
-         * and re-enabling preemption.
+         * kprobe_handler() that we don't want the post_handler
+	 * to run (and have re-enabled preemption)
          */
         return 1;
 }
@@ -483,7 +475,8 @@
  * that is atop the stack is the address following the copied instruction.
  * We need to make it the address following the original instruction.
  */
-static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes resume_execution(struct kprobe *p,
+		struct pt_regs *regs, struct kprobe_ctlblk *kcb)
 {
 	unsigned long *tos = (unsigned long *)regs->rsp;
 	unsigned long next_rip = 0;
@@ -498,7 +491,7 @@
 	switch (*insn) {
 	case 0x9c:		/* pushfl */
 		*tos &= ~(TF_MASK | IF_MASK);
-		*tos |= kprobe_old_rflags;
+		*tos |= kcb->kprobe_old_rflags;
 		break;
 	case 0xc3:		/* ret/lret */
 	case 0xcb:
@@ -537,30 +530,28 @@
 	}
 }
 
-/*
- * Interrupts are disabled on entry as trap1 is an interrupt gate and they
- * remain disabled thoroughout this function.  And we hold kprobe lock.
- */
 int __kprobes post_kprobe_handler(struct pt_regs *regs)
 {
-	if (!kprobe_running())
+	struct kprobe *cur = kprobe_running();
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	if (!cur)
 		return 0;
 
-	if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
-		kprobe_status = KPROBE_HIT_SSDONE;
-		current_kprobe->post_handler(current_kprobe, regs, 0);
+	if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
+		kcb->kprobe_status = KPROBE_HIT_SSDONE;
+		cur->post_handler(cur, regs, 0);
 	}
 
-	resume_execution(current_kprobe, regs);
-	regs->eflags |= kprobe_saved_rflags;
+	resume_execution(cur, regs, kcb);
+	regs->eflags |= kcb->kprobe_saved_rflags;
 
 	/* Restore the original saved kprobes variables and continue. */
-	if (kprobe_status == KPROBE_REENTER) {
-		restore_previous_kprobe();
+	if (kcb->kprobe_status == KPROBE_REENTER) {
+		restore_previous_kprobe(kcb);
 		goto out;
-	} else {
-		unlock_kprobes();
 	}
+	reset_current_kprobe();
 out:
 	preempt_enable_no_resched();
 
@@ -575,18 +566,19 @@
 	return 1;
 }
 
-/* Interrupts disabled, kprobe_lock held. */
 int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 {
-	if (current_kprobe->fault_handler
-	    && current_kprobe->fault_handler(current_kprobe, regs, trapnr))
+	struct kprobe *cur = kprobe_running();
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
 		return 1;
 
-	if (kprobe_status & KPROBE_HIT_SS) {
-		resume_execution(current_kprobe, regs);
-		regs->eflags |= kprobe_old_rflags;
+	if (kcb->kprobe_status & KPROBE_HIT_SS) {
+		resume_execution(cur, regs, kcb);
+		regs->eflags |= kcb->kprobe_old_rflags;
 
-		unlock_kprobes();
+		reset_current_kprobe();
 		preempt_enable_no_resched();
 	}
 	return 0;
@@ -599,39 +591,41 @@
 				       unsigned long val, void *data)
 {
 	struct die_args *args = (struct die_args *)data;
+	int ret = NOTIFY_DONE;
+
 	switch (val) {
 	case DIE_INT3:
 		if (kprobe_handler(args->regs))
-			return NOTIFY_STOP;
+			ret = NOTIFY_STOP;
 		break;
 	case DIE_DEBUG:
 		if (post_kprobe_handler(args->regs))
-			return NOTIFY_STOP;
+			ret = NOTIFY_STOP;
 		break;
 	case DIE_GPF:
-		if (kprobe_running() &&
-		    kprobe_fault_handler(args->regs, args->trapnr))
-			return NOTIFY_STOP;
-		break;
 	case DIE_PAGE_FAULT:
+		/* kprobe_running() needs smp_processor_id() */
+		preempt_disable();
 		if (kprobe_running() &&
 		    kprobe_fault_handler(args->regs, args->trapnr))
-			return NOTIFY_STOP;
+			ret = NOTIFY_STOP;
+		preempt_enable();
 		break;
 	default:
 		break;
 	}
-	return NOTIFY_DONE;
+	return ret;
 }
 
 int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct jprobe *jp = container_of(p, struct jprobe, kp);
 	unsigned long addr;
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 
-	jprobe_saved_regs = *regs;
-	jprobe_saved_rsp = (long *) regs->rsp;
-	addr = (unsigned long)jprobe_saved_rsp;
+	kcb->jprobe_saved_regs = *regs;
+	kcb->jprobe_saved_rsp = (long *) regs->rsp;
+	addr = (unsigned long)(kcb->jprobe_saved_rsp);
 	/*
 	 * As Linus pointed out, gcc assumes that the callee
 	 * owns the argument space and could overwrite it, e.g.
@@ -639,7 +633,8 @@
 	 * we also save and restore enough stack bytes to cover
 	 * the argument area.
 	 */
-	memcpy(jprobes_stack, (kprobe_opcode_t *) addr, MIN_STACK_SIZE(addr));
+	memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr,
+			MIN_STACK_SIZE(addr));
 	regs->eflags &= ~IF_MASK;
 	regs->rip = (unsigned long)(jp->entry);
 	return 1;
@@ -647,36 +642,40 @@
 
 void __kprobes jprobe_return(void)
 {
-	preempt_enable_no_resched();
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
 	asm volatile ("       xchg   %%rbx,%%rsp     \n"
 		      "       int3			\n"
 		      "       .globl jprobe_return_end	\n"
 		      "       jprobe_return_end:	\n"
 		      "       nop			\n"::"b"
-		      (jprobe_saved_rsp):"memory");
+		      (kcb->jprobe_saved_rsp):"memory");
 }
 
 int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 	u8 *addr = (u8 *) (regs->rip - 1);
-	unsigned long stack_addr = (unsigned long)jprobe_saved_rsp;
+	unsigned long stack_addr = (unsigned long)(kcb->jprobe_saved_rsp);
 	struct jprobe *jp = container_of(p, struct jprobe, kp);
 
 	if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) {
-		if ((long *)regs->rsp != jprobe_saved_rsp) {
+		if ((long *)regs->rsp != kcb->jprobe_saved_rsp) {
 			struct pt_regs *saved_regs =
-			    container_of(jprobe_saved_rsp, struct pt_regs, rsp);
+			    container_of(kcb->jprobe_saved_rsp,
+					    struct pt_regs, rsp);
 			printk("current rsp %p does not match saved rsp %p\n",
-			       (long *)regs->rsp, jprobe_saved_rsp);
+			       (long *)regs->rsp, kcb->jprobe_saved_rsp);
 			printk("Saved registers for jprobe %p\n", jp);
 			show_registers(saved_regs);
 			printk("Current registers\n");
 			show_registers(regs);
 			BUG();
 		}
-		*regs = jprobe_saved_regs;
-		memcpy((kprobe_opcode_t *) stack_addr, jprobes_stack,
+		*regs = kcb->jprobe_saved_regs;
+		memcpy((kprobe_opcode_t *) stack_addr, kcb->jprobes_stack,
 		       MIN_STACK_SIZE(stack_addr));
+		preempt_enable_no_resched();
 		return 1;
 	}
 	return 0;
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
index bbf64b5..a87b6ce 100644
--- a/arch/x86_64/kernel/ptrace.c
+++ b/arch/x86_64/kernel/ptrace.c
@@ -313,48 +313,11 @@
 
 }
 
-asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-	struct task_struct *child;
 	long i, ret;
 	unsigned ui;
 
-	/* This lock_kernel fixes a subtle race with suid exec */
-	lock_kernel();
-	ret = -EPERM;
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-		ret = security_ptrace(current->parent, current);
-		if (ret)
-			goto out;
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
-		goto out;
-	}
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (!child)
-		goto out;
-
-	ret = -EPERM;
-	if (pid == 1)		/* you may not mess with init */
-		goto out_tsk;
-
-	if (request == PTRACE_ATTACH) {
-		ret = ptrace_attach(child);
-		goto out_tsk;
-	}
-	ret = ptrace_check_attach(child, request == PTRACE_KILL); 
-	if (ret < 0) 
-		goto out_tsk;
-
 	switch (request) {
 	/* when I and D space are separate, these will need to be fixed. */
 	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
@@ -608,10 +571,6 @@
 		ret = ptrace_request(child, request, addr, data);
 		break;
 	}
-out_tsk:
-	put_task_struct(child);
-out:
-	unlock_kernel();
 	return ret;
 }
 
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 658a81b..4b5b088 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -65,8 +65,6 @@
 /* Package ID of each logical CPU */
 u8 phys_proc_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
 u8 cpu_core_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
-EXPORT_SYMBOL(phys_proc_id);
-EXPORT_SYMBOL(cpu_core_id);
 
 /* Bitmask of currently online CPUs */
 cpumask_t cpu_online_map __read_mostly;
diff --git a/arch/x86_64/oprofile/Kconfig b/arch/x86_64/oprofile/Kconfig
index 5ade198..d8a8408 100644
--- a/arch/x86_64/oprofile/Kconfig
+++ b/arch/x86_64/oprofile/Kconfig
@@ -1,7 +1,3 @@
-
-menu "Profiling support"
-	depends on EXPERIMENTAL
-
 config PROFILING
 	bool "Profiling support (EXPERIMENTAL)"
 	help
@@ -19,5 +15,3 @@
 
 	  If unsure, say N.
 
-endmenu
-
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
index 1446074..ab5c4c6 100644
--- a/arch/xtensa/kernel/ptrace.c
+++ b/arch/xtensa/kernel/ptrace.c
@@ -45,58 +45,10 @@
 	/* Nothing to do.. */
 }
 
-long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-	struct task_struct *child;
 	int ret = -EPERM;
 
-	lock_kernel();
-
-#if 0
-	if ((int)request != 1)
-	printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n",
-	       (int) request, (int) pid, (unsigned long) addr,
-	       (unsigned long) data);
-#endif
-
-	if (request == PTRACE_TRACEME) {
-
-		/* Are we already being traced? */
-
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-
-		if ((ret = security_ptrace(current->parent, current)))
-			goto out;
-
-		/* Set the ptrace bit in the process flags. */
-
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
-		goto out;
-	}
-
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (!child)
-		goto out;
-
-	ret = -EPERM;
-	if (pid == 1)		/* you may not mess with init */
-		goto out;
-
-	if (request == PTRACE_ATTACH) {
-		ret = ptrace_attach(child);
-		goto out_tsk;
-	}
-
-	if ((ret = ptrace_check_attach(child, request == PTRACE_KILL)) < 0)
-		goto out_tsk;
-
 	switch (request) {
 	case PTRACE_PEEKTEXT: /* read word at location addr. */
 	case PTRACE_PEEKDATA:
@@ -375,10 +327,7 @@
 		ret = ptrace_request(child, request, addr, data);
 		goto out;
 	}
-out_tsk:
-	put_task_struct(child);
-out:
-	unlock_kernel();
+ out:
 	return ret;
 }
 
diff --git a/block/Kconfig b/block/Kconfig
new file mode 100644
index 0000000..eb48edb
--- /dev/null
+++ b/block/Kconfig
@@ -0,0 +1,14 @@
+#
+# Block layer core configuration
+#
+#XXX - it makes sense to enable this only for 32-bit subarch's, not for x86_64
+#for instance.
+config LBD
+	bool "Support for Large Block Devices"
+	depends on X86 || (MIPS && 32BIT) || PPC32 || ARCH_S390_31 || SUPERH || UML
+	help
+	  Say Y here if you want to attach large (bigger than 2TB) discs to
+	  your machine, or if you want to have a raid or loopback device
+	  bigger than 2TB.  Otherwise say N.
+
+source block/Kconfig.iosched
diff --git a/drivers/block/Kconfig.iosched b/block/Kconfig.iosched
similarity index 94%
rename from drivers/block/Kconfig.iosched
rename to block/Kconfig.iosched
index 5b90d2f..f3b7753 100644
--- a/drivers/block/Kconfig.iosched
+++ b/block/Kconfig.iosched
@@ -46,13 +46,13 @@
 	  block devices.
 
 	config DEFAULT_AS
-		bool "Anticipatory" if IOSCHED_AS
+		bool "Anticipatory" if IOSCHED_AS=y
 
 	config DEFAULT_DEADLINE
-		bool "Deadline" if IOSCHED_DEADLINE
+		bool "Deadline" if IOSCHED_DEADLINE=y
 
 	config DEFAULT_CFQ
-		bool "CFQ" if IOSCHED_CFQ
+		bool "CFQ" if IOSCHED_CFQ=y
 
 	config DEFAULT_NOOP
 		bool "No-op"
diff --git a/block/Makefile b/block/Makefile
new file mode 100644
index 0000000..7e4f93e
--- /dev/null
+++ b/block/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the kernel block layer
+#
+
+obj-y	:= elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o
+
+obj-$(CONFIG_IOSCHED_NOOP)	+= noop-iosched.o
+obj-$(CONFIG_IOSCHED_AS)	+= as-iosched.o
+obj-$(CONFIG_IOSCHED_DEADLINE)	+= deadline-iosched.o
+obj-$(CONFIG_IOSCHED_CFQ)	+= cfq-iosched.o
diff --git a/drivers/block/as-iosched.c b/block/as-iosched.c
similarity index 94%
rename from drivers/block/as-iosched.c
rename to block/as-iosched.c
index c6744ff..a78e160 100644
--- a/drivers/block/as-iosched.c
+++ b/block/as-iosched.c
@@ -4,7 +4,7 @@
  *  Anticipatory & deadline i/o scheduler.
  *
  *  Copyright (C) 2002 Jens Axboe <axboe@suse.de>
- *                     Nick Piggin <piggin@cyberone.com.au>
+ *                     Nick Piggin <nickpiggin@yahoo.com.au>
  *
  */
 #include <linux/kernel.h>
@@ -69,7 +69,7 @@
 
 /* Bits in as_io_context.state */
 enum as_io_states {
-	AS_TASK_RUNNING=0,	/* Process has not exitted */
+	AS_TASK_RUNNING=0,	/* Process has not exited */
 	AS_TASK_IOSTARTED,	/* Process has started some IO */
 	AS_TASK_IORUNNING,	/* Process has completed some IO */
 };
@@ -102,6 +102,9 @@
 
 	unsigned long exit_prob;	/* probability a task will exit while
 					   being waited on */
+	unsigned long exit_no_coop;	/* probablility an exited task will
+					   not be part of a later cooperating
+					   request */
 	unsigned long new_ttime_total; 	/* mean thinktime on new proc */
 	unsigned long new_ttime_mean;
 	u64 new_seek_total;		/* mean seek on new proc */
@@ -636,37 +639,152 @@
 		kblockd_schedule_work(&ad->antic_work);
 
 		if (aic->ttime_samples == 0) {
-			/* process anticipated on has exitted or timed out*/
+			/* process anticipated on has exited or timed out*/
 			ad->exit_prob = (7*ad->exit_prob + 256)/8;
 		}
+		if (!test_bit(AS_TASK_RUNNING, &aic->state)) {
+			/* process not "saved" by a cooperating request */
+			ad->exit_no_coop = (7*ad->exit_no_coop + 256)/8;
+		}
 	}
 	spin_unlock_irqrestore(q->queue_lock, flags);
 }
 
+static void as_update_thinktime(struct as_data *ad, struct as_io_context *aic,
+				unsigned long ttime)
+{
+	/* fixed point: 1.0 == 1<<8 */
+	if (aic->ttime_samples == 0) {
+		ad->new_ttime_total = (7*ad->new_ttime_total + 256*ttime) / 8;
+		ad->new_ttime_mean = ad->new_ttime_total / 256;
+
+		ad->exit_prob = (7*ad->exit_prob)/8;
+	}
+	aic->ttime_samples = (7*aic->ttime_samples + 256) / 8;
+	aic->ttime_total = (7*aic->ttime_total + 256*ttime) / 8;
+	aic->ttime_mean = (aic->ttime_total + 128) / aic->ttime_samples;
+}
+
+static void as_update_seekdist(struct as_data *ad, struct as_io_context *aic,
+				sector_t sdist)
+{
+	u64 total;
+
+	if (aic->seek_samples == 0) {
+		ad->new_seek_total = (7*ad->new_seek_total + 256*(u64)sdist)/8;
+		ad->new_seek_mean = ad->new_seek_total / 256;
+	}
+
+	/*
+	 * Don't allow the seek distance to get too large from the
+	 * odd fragment, pagein, etc
+	 */
+	if (aic->seek_samples <= 60) /* second&third seek */
+		sdist = min(sdist, (aic->seek_mean * 4) + 2*1024*1024);
+	else
+		sdist = min(sdist, (aic->seek_mean * 4)	+ 2*1024*64);
+
+	aic->seek_samples = (7*aic->seek_samples + 256) / 8;
+	aic->seek_total = (7*aic->seek_total + (u64)256*sdist) / 8;
+	total = aic->seek_total + (aic->seek_samples/2);
+	do_div(total, aic->seek_samples);
+	aic->seek_mean = (sector_t)total;
+}
+
+/*
+ * as_update_iohist keeps a decaying histogram of IO thinktimes, and
+ * updates @aic->ttime_mean based on that. It is called when a new
+ * request is queued.
+ */
+static void as_update_iohist(struct as_data *ad, struct as_io_context *aic,
+				struct request *rq)
+{
+	struct as_rq *arq = RQ_DATA(rq);
+	int data_dir = arq->is_sync;
+	unsigned long thinktime = 0;
+	sector_t seek_dist;
+
+	if (aic == NULL)
+		return;
+
+	if (data_dir == REQ_SYNC) {
+		unsigned long in_flight = atomic_read(&aic->nr_queued)
+					+ atomic_read(&aic->nr_dispatched);
+		spin_lock(&aic->lock);
+		if (test_bit(AS_TASK_IORUNNING, &aic->state) ||
+			test_bit(AS_TASK_IOSTARTED, &aic->state)) {
+			/* Calculate read -> read thinktime */
+			if (test_bit(AS_TASK_IORUNNING, &aic->state)
+							&& in_flight == 0) {
+				thinktime = jiffies - aic->last_end_request;
+				thinktime = min(thinktime, MAX_THINKTIME-1);
+			}
+			as_update_thinktime(ad, aic, thinktime);
+
+			/* Calculate read -> read seek distance */
+			if (aic->last_request_pos < rq->sector)
+				seek_dist = rq->sector - aic->last_request_pos;
+			else
+				seek_dist = aic->last_request_pos - rq->sector;
+			as_update_seekdist(ad, aic, seek_dist);
+		}
+		aic->last_request_pos = rq->sector + rq->nr_sectors;
+		set_bit(AS_TASK_IOSTARTED, &aic->state);
+		spin_unlock(&aic->lock);
+	}
+}
+
 /*
  * as_close_req decides if one request is considered "close" to the
  * previous one issued.
  */
-static int as_close_req(struct as_data *ad, struct as_rq *arq)
+static int as_close_req(struct as_data *ad, struct as_io_context *aic,
+				struct as_rq *arq)
 {
 	unsigned long delay;	/* milliseconds */
 	sector_t last = ad->last_sector[ad->batch_data_dir];
 	sector_t next = arq->request->sector;
 	sector_t delta; /* acceptable close offset (in sectors) */
+	sector_t s;
 
 	if (ad->antic_status == ANTIC_OFF || !ad->ioc_finished)
 		delay = 0;
 	else
 		delay = ((jiffies - ad->antic_start) * 1000) / HZ;
 
-	if (delay <= 1)
-		delta = 64;
+	if (delay == 0)
+		delta = 8192;
 	else if (delay <= 20 && delay <= ad->antic_expire)
-		delta = 64 << (delay-1);
+		delta = 8192 << delay;
 	else
 		return 1;
 
-	return (last - (delta>>1) <= next) && (next <= last + delta);
+	if ((last <= next + (delta>>1)) && (next <= last + delta))
+		return 1;
+
+	if (last < next)
+		s = next - last;
+	else
+		s = last - next;
+
+	if (aic->seek_samples == 0) {
+		/*
+		 * Process has just started IO. Use past statistics to
+		 * gauge success possibility
+		 */
+		if (ad->new_seek_mean > s) {
+			/* this request is better than what we're expecting */
+			return 1;
+		}
+
+	} else {
+		if (aic->seek_mean > s) {
+			/* this request is better than what we're expecting */
+			return 1;
+		}
+	}
+
+	return 0;
 }
 
 /*
@@ -678,7 +796,7 @@
  * dispatch it ASAP, because we know that application will not be submitting
  * any new reads.
  *
- * If the task which has submitted the request has exitted, break anticipation.
+ * If the task which has submitted the request has exited, break anticipation.
  *
  * If this task has queued some other IO, do not enter enticipation.
  */
@@ -686,7 +804,6 @@
 {
 	struct io_context *ioc;
 	struct as_io_context *aic;
-	sector_t s;
 
 	ioc = ad->io_context;
 	BUG_ON(!ioc);
@@ -708,13 +825,6 @@
 	if (!aic)
 		return 0;
 
-	if (!test_bit(AS_TASK_RUNNING, &aic->state)) {
-		/* process anticipated on has exitted */
-		if (aic->ttime_samples == 0)
-			ad->exit_prob = (7*ad->exit_prob + 256)/8;
-		return 1;
-	}
-
 	if (atomic_read(&aic->nr_queued) > 0) {
 		/* process has more requests queued */
 		return 1;
@@ -725,57 +835,45 @@
 		return 1;
 	}
 
-	if (arq && arq->is_sync == REQ_SYNC && as_close_req(ad, arq)) {
+	if (arq && arq->is_sync == REQ_SYNC && as_close_req(ad, aic, arq)) {
 		/*
 		 * Found a close request that is not one of ours.
 		 *
-		 * This makes close requests from another process reset
-		 * our thinktime delay. Is generally useful when there are
+		 * This makes close requests from another process update
+		 * our IO history. Is generally useful when there are
 		 * two or more cooperating processes working in the same
 		 * area.
 		 */
-		spin_lock(&aic->lock);
-		aic->last_end_request = jiffies;
-		spin_unlock(&aic->lock);
+		if (!test_bit(AS_TASK_RUNNING, &aic->state)) {
+			if (aic->ttime_samples == 0)
+				ad->exit_prob = (7*ad->exit_prob + 256)/8;
+
+			ad->exit_no_coop = (7*ad->exit_no_coop)/8;
+		}
+
+		as_update_iohist(ad, aic, arq->request);
 		return 1;
 	}
 
+	if (!test_bit(AS_TASK_RUNNING, &aic->state)) {
+		/* process anticipated on has exited */
+		if (aic->ttime_samples == 0)
+			ad->exit_prob = (7*ad->exit_prob + 256)/8;
+
+		if (ad->exit_no_coop > 128)
+			return 1;
+	}
 
 	if (aic->ttime_samples == 0) {
 		if (ad->new_ttime_mean > ad->antic_expire)
 			return 1;
-		if (ad->exit_prob > 128)
+		if (ad->exit_prob * ad->exit_no_coop > 128*256)
 			return 1;
 	} else if (aic->ttime_mean > ad->antic_expire) {
 		/* the process thinks too much between requests */
 		return 1;
 	}
 
-	if (!arq)
-		return 0;
-
-	if (ad->last_sector[REQ_SYNC] < arq->request->sector)
-		s = arq->request->sector - ad->last_sector[REQ_SYNC];
-	else
-		s = ad->last_sector[REQ_SYNC] - arq->request->sector;
-
-	if (aic->seek_samples == 0) {
-		/*
-		 * Process has just started IO. Use past statistics to
-		 * guage success possibility
-		 */
-		if (ad->new_seek_mean > s) {
-			/* this request is better than what we're expecting */
-			return 1;
-		}
-
-	} else {
-		if (aic->seek_mean > s) {
-			/* this request is better than what we're expecting */
-			return 1;
-		}
-	}
-
 	return 0;
 }
 
@@ -809,94 +907,11 @@
 	 * Status is either ANTIC_OFF so start waiting,
 	 * ANTIC_WAIT_REQ so continue waiting for request to finish
 	 * or ANTIC_WAIT_NEXT so continue waiting for an acceptable request.
-	 *
 	 */
 
 	return 1;
 }
 
-static void as_update_thinktime(struct as_data *ad, struct as_io_context *aic, unsigned long ttime)
-{
-	/* fixed point: 1.0 == 1<<8 */
-	if (aic->ttime_samples == 0) {
-		ad->new_ttime_total = (7*ad->new_ttime_total + 256*ttime) / 8;
-		ad->new_ttime_mean = ad->new_ttime_total / 256;
-
-		ad->exit_prob = (7*ad->exit_prob)/8;
-	}
-	aic->ttime_samples = (7*aic->ttime_samples + 256) / 8;
-	aic->ttime_total = (7*aic->ttime_total + 256*ttime) / 8;
-	aic->ttime_mean = (aic->ttime_total + 128) / aic->ttime_samples;
-}
-
-static void as_update_seekdist(struct as_data *ad, struct as_io_context *aic, sector_t sdist)
-{
-	u64 total;
-
-	if (aic->seek_samples == 0) {
-		ad->new_seek_total = (7*ad->new_seek_total + 256*(u64)sdist)/8;
-		ad->new_seek_mean = ad->new_seek_total / 256;
-	}
-
-	/*
-	 * Don't allow the seek distance to get too large from the
-	 * odd fragment, pagein, etc
-	 */
-	if (aic->seek_samples <= 60) /* second&third seek */
-		sdist = min(sdist, (aic->seek_mean * 4) + 2*1024*1024);
-	else
-		sdist = min(sdist, (aic->seek_mean * 4)	+ 2*1024*64);
-
-	aic->seek_samples = (7*aic->seek_samples + 256) / 8;
-	aic->seek_total = (7*aic->seek_total + (u64)256*sdist) / 8;
-	total = aic->seek_total + (aic->seek_samples/2);
-	do_div(total, aic->seek_samples);
-	aic->seek_mean = (sector_t)total;
-}
-
-/*
- * as_update_iohist keeps a decaying histogram of IO thinktimes, and
- * updates @aic->ttime_mean based on that. It is called when a new
- * request is queued.
- */
-static void as_update_iohist(struct as_data *ad, struct as_io_context *aic, struct request *rq)
-{
-	struct as_rq *arq = RQ_DATA(rq);
-	int data_dir = arq->is_sync;
-	unsigned long thinktime;
-	sector_t seek_dist;
-
-	if (aic == NULL)
-		return;
-
-	if (data_dir == REQ_SYNC) {
-		unsigned long in_flight = atomic_read(&aic->nr_queued)
-					+ atomic_read(&aic->nr_dispatched);
-		spin_lock(&aic->lock);
-		if (test_bit(AS_TASK_IORUNNING, &aic->state) ||
-			test_bit(AS_TASK_IOSTARTED, &aic->state)) {
-			/* Calculate read -> read thinktime */
-			if (test_bit(AS_TASK_IORUNNING, &aic->state)
-							&& in_flight == 0) {
-				thinktime = jiffies - aic->last_end_request;
-				thinktime = min(thinktime, MAX_THINKTIME-1);
-			} else
-				thinktime = 0;
-			as_update_thinktime(ad, aic, thinktime);
-
-			/* Calculate read -> read seek distance */
-			if (aic->last_request_pos < rq->sector)
-				seek_dist = rq->sector - aic->last_request_pos;
-			else
-				seek_dist = aic->last_request_pos - rq->sector;
-			as_update_seekdist(ad, aic, seek_dist);
-		}
-		aic->last_request_pos = rq->sector + rq->nr_sectors;
-		set_bit(AS_TASK_IOSTARTED, &aic->state);
-		spin_unlock(&aic->lock);
-	}
-}
-
 /*
  * as_update_arq must be called whenever a request (arq) is added to
  * the sort_list. This function keeps caches up to date, and checks if the
@@ -1201,7 +1216,7 @@
 		|| ad->changed_batch)
 		return 0;
 
-	if (!(reads && writes && as_batch_expired(ad)) ) {
+	if (!(reads && writes && as_batch_expired(ad))) {
 		/*
 		 * batch is still running or no reads or no writes
 		 */
@@ -1316,7 +1331,8 @@
  * Add arq to a list behind alias
  */
 static inline void
-as_add_aliased_request(struct as_data *ad, struct as_rq *arq, struct as_rq *alias)
+as_add_aliased_request(struct as_data *ad, struct as_rq *arq,
+				struct as_rq *alias)
 {
 	struct request  *req = arq->request;
 	struct list_head *insert = alias->request->queuelist.prev;
@@ -1441,8 +1457,8 @@
 		&& list_empty(&ad->fifo_list[REQ_SYNC]);
 }
 
-static struct request *
-as_former_request(request_queue_t *q, struct request *rq)
+static struct request *as_former_request(request_queue_t *q,
+					struct request *rq)
 {
 	struct as_rq *arq = RQ_DATA(rq);
 	struct rb_node *rbprev = rb_prev(&arq->rb_node);
@@ -1454,8 +1470,8 @@
 	return ret;
 }
 
-static struct request *
-as_latter_request(request_queue_t *q, struct request *rq)
+static struct request *as_latter_request(request_queue_t *q,
+					struct request *rq)
 {
 	struct as_rq *arq = RQ_DATA(rq);
 	struct rb_node *rbnext = rb_next(&arq->rb_node);
@@ -1537,7 +1553,7 @@
 		 * currently don't bother. Ditto the next function.
 		 */
 		as_del_arq_rb(ad, arq);
-		if ((alias = as_add_arq_rb(ad, arq)) ) {
+		if ((alias = as_add_arq_rb(ad, arq))) {
 			list_del_init(&arq->fifo);
 			as_add_aliased_request(ad, arq, alias);
 			if (next_arq)
@@ -1551,9 +1567,8 @@
 	}
 }
 
-static void
-as_merged_requests(request_queue_t *q, struct request *req,
-			 struct request *next)
+static void as_merged_requests(request_queue_t *q, struct request *req,
+			 	struct request *next)
 {
 	struct as_data *ad = q->elevator->elevator_data;
 	struct as_rq *arq = RQ_DATA(req);
@@ -1576,7 +1591,7 @@
 			next_arq = as_find_next_arq(ad, arq);
 
 		as_del_arq_rb(ad, arq);
-		if ((alias = as_add_arq_rb(ad, arq)) ) {
+		if ((alias = as_add_arq_rb(ad, arq))) {
 			list_del_init(&arq->fifo);
 			as_add_aliased_request(ad, arq, alias);
 			if (next_arq)
@@ -1806,9 +1821,14 @@
 {
 	int pos = 0;
 
-	pos += sprintf(page+pos, "%lu %% exit probability\n", 100*ad->exit_prob/256);
+	pos += sprintf(page+pos, "%lu %% exit probability\n",
+				100*ad->exit_prob/256);
+	pos += sprintf(page+pos, "%lu %% probability of exiting without a "
+				"cooperating process submitting IO\n",
+				100*ad->exit_no_coop/256);
 	pos += sprintf(page+pos, "%lu ms new thinktime\n", ad->new_ttime_mean);
-	pos += sprintf(page+pos, "%llu sectors new seek distance\n", (unsigned long long)ad->new_seek_mean);
+	pos += sprintf(page+pos, "%llu sectors new seek distance\n",
+				(unsigned long long)ad->new_seek_mean);
 
 	return pos;
 }
diff --git a/drivers/block/cfq-iosched.c b/block/cfq-iosched.c
similarity index 100%
rename from drivers/block/cfq-iosched.c
rename to block/cfq-iosched.c
diff --git a/drivers/block/deadline-iosched.c b/block/deadline-iosched.c
similarity index 100%
rename from drivers/block/deadline-iosched.c
rename to block/deadline-iosched.c
diff --git a/drivers/block/elevator.c b/block/elevator.c
similarity index 100%
rename from drivers/block/elevator.c
rename to block/elevator.c
diff --git a/drivers/block/genhd.c b/block/genhd.c
similarity index 100%
rename from drivers/block/genhd.c
rename to block/genhd.c
diff --git a/drivers/block/ioctl.c b/block/ioctl.c
similarity index 100%
rename from drivers/block/ioctl.c
rename to block/ioctl.c
diff --git a/drivers/block/ll_rw_blk.c b/block/ll_rw_blk.c
similarity index 99%
rename from drivers/block/ll_rw_blk.c
rename to block/ll_rw_blk.c
index 2747741..5f52e30 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -706,7 +706,6 @@
 
 /**
  * blk_queue_find_tag - find a request by its tag and queue
- *
  * @q:	 The request queue for the device
  * @tag: The tag of the request
  *
diff --git a/drivers/block/noop-iosched.c b/block/noop-iosched.c
similarity index 100%
rename from drivers/block/noop-iosched.c
rename to block/noop-iosched.c
diff --git a/drivers/block/scsi_ioctl.c b/block/scsi_ioctl.c
similarity index 100%
rename from drivers/block/scsi_ioctl.c
rename to block/scsi_ioctl.c
diff --git a/drivers/Makefile b/drivers/Makefile
index 65670be..fac1e16 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -7,6 +7,7 @@
 
 obj-$(CONFIG_PCI)		+= pci/ usb/
 obj-$(CONFIG_PARISC)		+= parisc/
+obj-$(CONFIG_RAPIDIO)		+= rapidio/
 obj-y				+= video/
 obj-$(CONFIG_ACPI)		+= acpi/
 # PnP must come after ACPI since it will eventually need to check if acpi
@@ -67,3 +68,4 @@
 obj-$(CONFIG_SGI_IOC4)		+= sn/
 obj-y				+= firmware/
 obj-$(CONFIG_CRYPTO)		+= crypto/
+obj-$(CONFIG_SUPERH)		+= sh/
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 10dd695..27ec12c 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -118,11 +118,9 @@
 {
 	acpi_status status = AE_OK;
 	struct acpi_container *pc = NULL;
+
 	pc = (struct acpi_container *)acpi_driver_data(device);
-
-	if (pc)
-		kfree(pc);
-
+	kfree(pc);
 	return status;
 }
 
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index d528c75..e3cd0b1 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -313,8 +313,7 @@
 
 void acpi_os_sleep(acpi_integer ms)
 {
-	current->state = TASK_INTERRUPTIBLE;
-	schedule_timeout(((signed long)ms * HZ) / 1000);
+	schedule_timeout_interruptible(msecs_to_jiffies(ms));
 }
 
 EXPORT_SYMBOL(acpi_os_sleep);
@@ -838,8 +837,7 @@
 
 			ret = down_trylock(sem);
 			for (i = timeout; (i > 0 && ret < 0); i -= quantum_ms) {
-				current->state = TASK_INTERRUPTIBLE;
-				schedule_timeout(1);
+				schedule_timeout_interruptible(1);
 				ret = down_trylock(sem);
 			}
 
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index c6db591..23e2c69 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -28,8 +28,7 @@
 static void acpi_device_release(struct kobject *kobj)
 {
 	struct acpi_device *dev = container_of(kobj, struct acpi_device, kobj);
-	if (dev->pnp.cid_list)
-		kfree(dev->pnp.cid_list);
+	kfree(dev->pnp.cid_list);
 	kfree(dev);
 }
 
@@ -1117,8 +1116,7 @@
 	if (!result)
 		*child = device;
 	else {
-		if (device->pnp.cid_list)
-			kfree(device->pnp.cid_list);
+		kfree(device->pnp.cid_list);
 		kfree(device);
 	}
 
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index e383d61..f051b15 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -334,8 +334,7 @@
 	return_VALUE(0);
 
       err:
-	if (buffer.pointer)
-		kfree(buffer.pointer);
+	kfree(buffer.pointer);
 
 	return_VALUE(status);
 }
@@ -1488,8 +1487,7 @@
 	}
 	active_device_list[count].value.int_val = ACPI_VIDEO_HEAD_END;
 
-	if (video->attached_array)
-		kfree(video->attached_array);
+	kfree(video->attached_array);
 
 	video->attached_array = active_device_list;
 	video->attached_count = count;
@@ -1645,8 +1643,7 @@
 			printk(KERN_WARNING PREFIX
 			       "hhuuhhuu bug in acpi video driver.\n");
 
-		if (data->brightness)
-			kfree(data->brightness);
+		kfree(data->brightness);
 
 		kfree(data);
 	}
@@ -1831,8 +1828,7 @@
 	acpi_video_bus_put_devices(video);
 	acpi_video_bus_remove_fs(device);
 
-	if (video->attached_array)
-		kfree(video->attached_array);
+	kfree(video->attached_array);
 	kfree(video);
 
 	return_VALUE(0);
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index 89c5787..f3a0c56 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -3,6 +3,7 @@
  */
 
 #include <linux/device.h>
+#include <linux/string.h>
 #include "power.h"
 
 
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 3760edf..70eaa5c 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -417,14 +417,12 @@
             * Remember the beginning of the group, but don't free it
 	    * until we've reached the beginning of the next group.
 	    */
-	   if (CommandGroup != NULL)
-		kfree(CommandGroup);
-	    CommandGroup = Command;
+	   kfree(CommandGroup);
+	   CommandGroup = Command;
       }
       Controller->Commands[i] = NULL;
     }
-  if (CommandGroup != NULL)
-      kfree(CommandGroup);
+  kfree(CommandGroup);
 
   if (Controller->CombinedStatusBuffer != NULL)
     {
@@ -435,30 +433,23 @@
 
   if (ScatterGatherPool != NULL)
   	pci_pool_destroy(ScatterGatherPool);
-  if (Controller->FirmwareType == DAC960_V1_Controller) return;
+  if (Controller->FirmwareType == DAC960_V1_Controller)
+  	return;
 
   if (RequestSensePool != NULL)
 	pci_pool_destroy(RequestSensePool);
 
-  for (i = 0; i < DAC960_MaxLogicalDrives; i++)
-    if (Controller->V2.LogicalDeviceInformation[i] != NULL)
-      {
+  for (i = 0; i < DAC960_MaxLogicalDrives; i++) {
 	kfree(Controller->V2.LogicalDeviceInformation[i]);
 	Controller->V2.LogicalDeviceInformation[i] = NULL;
-      }
+  }
 
   for (i = 0; i < DAC960_V2_MaxPhysicalDevices; i++)
     {
-      if (Controller->V2.PhysicalDeviceInformation[i] != NULL)
-	{
-	  kfree(Controller->V2.PhysicalDeviceInformation[i]);
-	  Controller->V2.PhysicalDeviceInformation[i] = NULL;
-	}
-      if (Controller->V2.InquiryUnitSerialNumber[i] != NULL)
-	{
-	  kfree(Controller->V2.InquiryUnitSerialNumber[i]);
-	  Controller->V2.InquiryUnitSerialNumber[i] = NULL;
-	}
+      kfree(Controller->V2.PhysicalDeviceInformation[i]);
+      Controller->V2.PhysicalDeviceInformation[i] = NULL;
+      kfree(Controller->V2.InquiryUnitSerialNumber[i]);
+      Controller->V2.InquiryUnitSerialNumber[i] = NULL;
     }
 }
 
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 51b0af1..7b1cd93 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -409,16 +409,6 @@
 	  for details.
 
 
-#XXX - it makes sense to enable this only for 32-bit subarch's, not for x86_64
-#for instance.
-config LBD
-	bool "Support for Large Block Devices"
-	depends on X86 || (MIPS && 32BIT) || PPC32 || ARCH_S390_31 || SUPERH || UML
-	help
-	  Say Y here if you want to attach large (bigger than 2TB) discs to
-	  your machine, or if you want to have a raid or loopback device
-	  bigger than 2TB.  Otherwise say N.
-
 config CDROM_PKTCDVD
 	tristate "Packet writing on CD/DVD media"
 	depends on !UML
@@ -455,8 +445,6 @@
 
 source "drivers/s390/block/Kconfig"
 
-source "drivers/block/Kconfig.iosched"
-
 config ATA_OVER_ETH
 	tristate "ATA over Ethernet support"
 	depends on NET
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 1cf09a1..3ec1f8d 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -4,21 +4,7 @@
 # 12 June 2000, Christoph Hellwig <hch@infradead.org>
 # Rewritten to use lists instead of if-statements.
 # 
-# Note : at this point, these files are compiled on all systems.
-# In the future, some of these should be built conditionally.
-#
 
-#
-# NOTE that ll_rw_blk.c must come early in linkage order - it starts the
-# kblockd threads
-#
-
-obj-y	:= elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o
-
-obj-$(CONFIG_IOSCHED_NOOP)	+= noop-iosched.o
-obj-$(CONFIG_IOSCHED_AS)	+= as-iosched.o
-obj-$(CONFIG_IOSCHED_DEADLINE)	+= deadline-iosched.o
-obj-$(CONFIG_IOSCHED_CFQ)	+= cfq-iosched.o
 obj-$(CONFIG_MAC_FLOPPY)	+= swim3.o
 obj-$(CONFIG_BLK_DEV_FD)	+= floppy.o
 obj-$(CONFIG_BLK_DEV_FD98)	+= floppy98.o
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 486b6e1..a97c80b 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1096,14 +1096,11 @@
 cleanup1:
 		if (buff) {
 			for(i=0; i<sg_used; i++)
-				if(buff[i] != NULL)
-					kfree(buff[i]);
+				kfree(buff[i]);
 			kfree(buff);
 		}
-		if (buff_size)
-			kfree(buff_size);
-		if (ioc)
-			kfree(ioc);
+		kfree(buff_size);
+		kfree(ioc);
 		return(status);
 	}
 	default:
@@ -3034,8 +3031,7 @@
 	return(1);
 
 clean4:
-	if(hba[i]->cmd_pool_bits)
-               	kfree(hba[i]->cmd_pool_bits);
+	kfree(hba[i]->cmd_pool_bits);
 	if(hba[i]->cmd_pool)
 		pci_free_consistent(hba[i]->pdev,
 			NR_CMDS * sizeof(CommandList_struct),
diff --git a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c
index 5fd3e4c..8e7fb35 100644
--- a/drivers/bluetooth/bcm203x.c
+++ b/drivers/bluetooth/bcm203x.c
@@ -179,14 +179,12 @@
 	if (ignore || (intf->cur_altsetting->desc.bInterfaceNumber != 0))
 		return -ENODEV;
 
-	data = kmalloc(sizeof(*data), GFP_KERNEL);
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
 	if (!data) {
 		BT_ERR("Can't allocate memory for data structure");
 		return -ENOMEM;
 	}
 
-	memset(data, 0, sizeof(*data));
-
 	data->udev  = udev;
 	data->state = BCM203X_LOAD_MINIDRV;
 
diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
index 1e9db01..067e278 100644
--- a/drivers/bluetooth/bfusb.c
+++ b/drivers/bluetooth/bfusb.c
@@ -673,13 +673,11 @@
 	}
 
 	/* Initialize control structure and load firmware */
-	if (!(bfusb = kmalloc(sizeof(struct bfusb), GFP_KERNEL))) {
+	if (!(bfusb = kzalloc(sizeof(struct bfusb), GFP_KERNEL))) {
 		BT_ERR("Can't allocate memory for control structure");
 		goto done;
 	}
 
-	memset(bfusb, 0, sizeof(struct bfusb));
-
 	bfusb->udev = udev;
 	bfusb->bulk_in_ep    = bulk_in_ep->desc.bEndpointAddress;
 	bfusb->bulk_out_ep   = bulk_out_ep->desc.bEndpointAddress;
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 26fe9c0..f36c563 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -870,10 +870,9 @@
 	int ret;
 
 	/* Create new info device */
-	info = kmalloc(sizeof(*info), GFP_KERNEL);
+	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
 		return NULL;
-	memset(info, 0, sizeof(*info));
 
 	link = &info->link;
 	link->priv = info;
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
index 0db0400..ecbeb7e 100644
--- a/drivers/bluetooth/bpa10x.c
+++ b/drivers/bluetooth/bpa10x.c
@@ -553,14 +553,12 @@
 	if (intf->cur_altsetting->desc.bInterfaceNumber > 0)
 		return -ENODEV;
 
-	data = kmalloc(sizeof(*data), GFP_KERNEL);
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
 	if (!data) {
 		BT_ERR("Can't allocate data structure");
 		return -ENOMEM;
 	}
 
-	memset(data, 0, sizeof(*data));
-
 	data->udev = udev;
 
 	rwlock_init(&data->lock);
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 2e0338d..d2a0add 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -671,10 +671,9 @@
 	int ret;
 
 	/* Create new info device */
-	info = kmalloc(sizeof(*info), GFP_KERNEL);
+	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
 		return NULL;
-	memset(info, 0, sizeof(*info));
 
 	link = &info->link;
 	link->priv = info;
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index 89486ea..529a28a 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -590,10 +590,9 @@
 	int ret;
 
 	/* Create new info device */
-	info = kmalloc(sizeof(*info), GFP_KERNEL);
+	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
 		return NULL;
-	memset(info, 0, sizeof(*info));
 
 	link = &info->link;
 	link->priv = info;
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index 84c1f88..dec5980 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -569,10 +569,9 @@
 	int ret;
 
 	/* Create new info device */
-	info = kmalloc(sizeof(*info), GFP_KERNEL);
+	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
 		return NULL;
-	memset(info, 0, sizeof(*info));
 
 	link = &info->link;
 	link->priv = info;
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
index 0a47614..8fddfdf 100644
--- a/drivers/bluetooth/hci_bcsp.c
+++ b/drivers/bluetooth/hci_bcsp.c
@@ -715,10 +715,9 @@
 
 	BT_DBG("hu %p", hu);
 
-	bcsp = kmalloc(sizeof(*bcsp), GFP_ATOMIC);
+	bcsp = kzalloc(sizeof(*bcsp), GFP_ATOMIC);
 	if (!bcsp)
 		return -ENOMEM;
-	memset(bcsp, 0, sizeof(*bcsp));
 
 	hu->priv = bcsp;
 	skb_queue_head_init(&bcsp->unack);
diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c
index 12e369a..4804d47 100644
--- a/drivers/bluetooth/hci_h4.c
+++ b/drivers/bluetooth/hci_h4.c
@@ -76,12 +76,10 @@
 
 	BT_DBG("hu %p", hu);
 
-	h4 = kmalloc(sizeof(*h4), GFP_ATOMIC);
+	h4 = kzalloc(sizeof(*h4), GFP_ATOMIC);
 	if (!h4)
 		return -ENOMEM;
 
-	memset(h4, 0, sizeof(*h4));
-
 	skb_queue_head_init(&h4->txq);
 
 	hu->priv = h4;
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 4a775f6..573ff6c 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -272,13 +272,11 @@
 	if (hu)
 		return -EEXIST;
 
-	if (!(hu = kmalloc(sizeof(struct hci_uart), GFP_KERNEL))) {
+	if (!(hu = kzalloc(sizeof(struct hci_uart), GFP_KERNEL))) {
 		BT_ERR("Can't allocate controll structure");
 		return -ENFILE;
 	}
 
-	memset(hu, 0, sizeof(struct hci_uart));
-
 	tty->disc_data = hu;
 	hu->tty = tty;
 
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index 6756cb2..f510b25 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -875,13 +875,11 @@
 		goto done;
 	}
 
-	if (!(husb = kmalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
+	if (!(husb = kzalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
 		BT_ERR("Can't allocate: control structure");
 		goto done;
 	}
 
-	memset(husb, 0, sizeof(struct hci_usb));
-
 	husb->udev = udev;
 	husb->bulk_out_ep = bulk_out_ep;
 	husb->bulk_in_ep  = bulk_in_ep;
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index 52cbd45..8573822 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -261,12 +261,10 @@
 	struct vhci_data *vhci;
 	struct hci_dev *hdev;
 
-	vhci = kmalloc(sizeof(struct vhci_data), GFP_KERNEL);
+	vhci = kzalloc(sizeof(struct vhci_data), GFP_KERNEL);
 	if (!vhci)
 		return -ENOMEM;
 
-	memset(vhci, 0, sizeof(struct vhci_data));
-
 	skb_queue_head_init(&vhci->readq);
 	init_waitqueue_head(&vhci->read_wait);
 
diff --git a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c
index b89420e..a0b580c 100644
--- a/drivers/cdrom/mcdx.c
+++ b/drivers/cdrom/mcdx.c
@@ -1085,7 +1085,7 @@
 
 	xtrace(INIT, "kmalloc space for stuffpt's\n");
 	xtrace(MALLOC, "init() malloc %d bytes\n", size);
-	if (!(stuffp = kmalloc(size, GFP_KERNEL))) {
+	if (!(stuffp = kzalloc(size, GFP_KERNEL))) {
 		xwarn("init() malloc failed\n");
 		return 1;
 	}
@@ -1101,8 +1101,6 @@
 	       sizeof(*stuffp), stuffp);
 
 	/* set default values */
-	memset(stuffp, 0, sizeof(*stuffp));
-
 	stuffp->present = 0;	/* this should be 0 already */
 	stuffp->toc = NULL;	/* this should be NULL already */
 
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 0e6c3a3..78ce98a 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -13,6 +13,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/agp_backend.h>
+#include <linux/mmzone.h>
 #include <asm/page.h>		/* PAGE_SIZE */
 #include "agp.h"
 
diff --git a/drivers/char/consolemap.c b/drivers/char/consolemap.c
index 406dea9..c85a4fa 100644
--- a/drivers/char/consolemap.c
+++ b/drivers/char/consolemap.c
@@ -345,17 +345,15 @@
 	for (i = 0; i < 32; i++) {
 		if ((p1 = p->uni_pgdir[i]) != NULL) {
 			for (j = 0; j < 32; j++)
-				if (p1[j])
-					kfree(p1[j]);
+				kfree(p1[j]);
 			kfree(p1);
 		}
 		p->uni_pgdir[i] = NULL;
 	}
-	for (i = 0; i < 4; i++)
-		if (p->inverse_translations[i]) {
-			kfree(p->inverse_translations[i]);
-			p->inverse_translations[i] = NULL;
-		}
+	for (i = 0; i < 4; i++) {
+		kfree(p->inverse_translations[i]);
+		p->inverse_translations[i] = NULL;
+	}
 }
 
 void con_free_unimap(struct vc_data *vc)
diff --git a/drivers/char/drm/ffb_context.c b/drivers/char/drm/ffb_context.c
index 8a6cc27..1383727 100644
--- a/drivers/char/drm/ffb_context.c
+++ b/drivers/char/drm/ffb_context.c
@@ -526,10 +526,8 @@
 	if (idx < 0 || idx >= FFB_MAX_CTXS)
 		return -EINVAL;
 
-	if (fpriv->hw_state[idx] != NULL) {
-		kfree(fpriv->hw_state[idx]);
-		fpriv->hw_state[idx] = NULL;
-	}
+	kfree(fpriv->hw_state[idx]);
+	fpriv->hw_state[idx] = NULL;
 	return 0;
 }
 
diff --git a/drivers/char/drm/ffb_drv.c b/drivers/char/drm/ffb_drv.c
index 5c121d6..c13f9ab 100644
--- a/drivers/char/drm/ffb_drv.c
+++ b/drivers/char/drm/ffb_drv.c
@@ -245,14 +245,12 @@
 
 static void ffb_driver_pretakedown(drm_device_t * dev)
 {
-	if (dev->dev_private)
-		kfree(dev->dev_private);
+	kfree(dev->dev_private);
 }
 
 static int ffb_driver_postcleanup(drm_device_t * dev)
 {
-	if (ffb_position != NULL)
-		kfree(ffb_position);
+	kfree(ffb_position);
 	return 0;
 }
 
diff --git a/drivers/char/ip2/i2ellis.c b/drivers/char/ip2/i2ellis.c
index f834d05..dd761a1 100644
--- a/drivers/char/ip2/i2ellis.c
+++ b/drivers/char/ip2/i2ellis.c
@@ -106,9 +106,7 @@
 static void
 iiEllisCleanup(void)
 {
-	if ( pDelayTimer != NULL ) {
-		kfree ( pDelayTimer );
-	}
+	kfree(pDelayTimer);
 }
 
 //******************************************************************************
diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c
index 3386267..58dcdee 100644
--- a/drivers/char/ipmi/ipmi_bt_sm.c
+++ b/drivers/char/ipmi/ipmi_bt_sm.c
@@ -28,6 +28,8 @@
 
 #include <linux/kernel.h> /* For printk. */
 #include <linux/string.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/ipmi_msgdefs.h>		/* for completion codes */
 #include "ipmi_si_sm.h"
 
@@ -36,6 +38,8 @@
 #define	BT_DEBUG_ENABLE	1
 #define BT_DEBUG_MSG	2
 #define BT_DEBUG_STATES	4
+module_param(bt_debug, int, 0644);
+MODULE_PARM_DESC(bt_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
 
 /* Typical "Get BT Capabilities" values are 2-3 retries, 5-10 seconds,
    and 64 byte buffers.  However, one HP implementation wants 255 bytes of
@@ -43,7 +47,7 @@
    Since the Open IPMI architecture is single-message oriented at this
    stage, the queue depth of BT is of no concern. */
 
-#define BT_NORMAL_TIMEOUT	2000000	/* seconds in microseconds */
+#define BT_NORMAL_TIMEOUT	5000000	/* seconds in microseconds */
 #define BT_RETRY_LIMIT		2
 #define BT_RESET_DELAY		6000000	/* 6 seconds after warm reset */
 
@@ -202,7 +206,7 @@
 	msg_len = bt->read_count - 2;		/* account for length & seq */
 	/* Always NetFn, Cmd, cCode */
 	if (msg_len < 3 || msg_len > IPMI_MAX_MSG_LENGTH) {
-		printk(KERN_WARNING "BT results: bad msg_len = %d\n", msg_len);
+		printk(KERN_DEBUG "BT results: bad msg_len = %d\n", msg_len);
 		data[0] = bt->write_data[1] | 0x4;	/* Kludge a response */
 		data[1] = bt->write_data[3];
 		data[2] = IPMI_ERR_UNSPECIFIED;
@@ -240,7 +244,7 @@
 	       BT_CONTROL(BT_B_BUSY);
 	BT_CONTROL(BT_CLR_WR_PTR);
 	BT_CONTROL(BT_SMS_ATN);
-#ifdef DEVELOPMENT_ONLY_NOT_FOR_PRODUCTION
+
 	if (BT_STATUS & BT_B2H_ATN) {
 		int i;
 		BT_CONTROL(BT_H_BUSY);
@@ -250,7 +254,6 @@
 		       BMC2HOST;
 		BT_CONTROL(BT_H_BUSY);
 	}
-#endif
 }
 
 static inline void write_all_bytes(struct si_sm_data *bt)
@@ -295,7 +298,7 @@
 	    	printk ("\n");
 	}
 	if (bt->seq != bt->write_data[2])	/* idiot check */
-		printk(KERN_WARNING "BT: internal error: sequence mismatch\n");
+		printk(KERN_DEBUG "BT: internal error: sequence mismatch\n");
 
 	/* per the spec, the (NetFn, Seq, Cmd) tuples should match */
 	if ((bt->read_data[3] == bt->write_data[3]) &&		/* Cmd */
@@ -321,18 +324,17 @@
 	bt->timeout = BT_NORMAL_TIMEOUT; /* various places want to retry */
 
 	status = BT_STATUS;
-	printk(KERN_WARNING "BT: %s in %s %s ", reason, STATE2TXT,
+	printk(KERN_DEBUG "BT: %s in %s %s\n", reason, STATE2TXT,
 	       STATUS2TXT(buf));
 
 	(bt->error_retries)++;
 	if (bt->error_retries > BT_RETRY_LIMIT) {
-		printk("retry limit (%d) exceeded\n", BT_RETRY_LIMIT);
+		printk(KERN_DEBUG "retry limit (%d) exceeded\n", BT_RETRY_LIMIT);
 		bt->state = BT_STATE_HOSED;
 		if (!bt->nonzero_status)
 			printk(KERN_ERR "IPMI: BT stuck, try power cycle\n");
-		else if (bt->seq == FIRST_SEQ + BT_RETRY_LIMIT) {
-			/* most likely during insmod */
-			printk(KERN_WARNING "IPMI: BT reset (takes 5 secs)\n");
+		else if (bt->error_retries <= BT_RETRY_LIMIT + 1) {
+			printk(KERN_DEBUG "IPMI: BT reset (takes 5 secs)\n");
         		bt->state = BT_STATE_RESET1;
 		}
 	return;
@@ -340,11 +342,11 @@
 
 	/* Sometimes the BMC queues get in an "off-by-one" state...*/
 	if ((bt->state == BT_STATE_B2H_WAIT) && (status & BT_B2H_ATN)) {
-    		printk("retry B2H_WAIT\n");
+    		printk(KERN_DEBUG "retry B2H_WAIT\n");
 		return;
 	}
 
-	printk("restart command\n");
+	printk(KERN_DEBUG "restart command\n");
 	bt->state = BT_STATE_RESTART;
 }
 
@@ -372,17 +374,6 @@
 	       return SI_SM_HOSED;
 
 	if (bt->state != BT_STATE_IDLE) {	/* do timeout test */
-
-		/* Certain states, on error conditions, can lock up a CPU
-		   because they are effectively in an infinite loop with
-		   CALL_WITHOUT_DELAY (right back here with time == 0).
-		   Prevent infinite lockup by ALWAYS decrementing timeout. */
-
-    	/* FIXME: bt_event is sometimes called with time > BT_NORMAL_TIMEOUT
-              (noticed in ipmi_smic_sm.c January 2004) */
-
-		if ((time <= 0) || (time >= BT_NORMAL_TIMEOUT))
-		       time = 100;
 		bt->timeout -= time;
 		if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1)) {
 			error_recovery(bt, "timed out");
@@ -483,6 +474,7 @@
 		break;
 
 	case BT_STATE_RESTART:		/* don't reset retries! */
+		reset_flags(bt);
 		bt->write_data[2] = ++bt->seq;
 		bt->read_count = 0;
 		bt->nonzero_status = 0;
diff --git a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c
index d21853a..da15541 100644
--- a/drivers/char/ipmi/ipmi_kcs_sm.c
+++ b/drivers/char/ipmi/ipmi_kcs_sm.c
@@ -38,16 +38,25 @@
  */
 
 #include <linux/kernel.h> /* For printk. */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/string.h>
+#include <linux/jiffies.h>
 #include <linux/ipmi_msgdefs.h>		/* for completion codes */
 #include "ipmi_si_sm.h"
 
-/* Set this if you want a printout of why the state machine was hosed
-   when it gets hosed. */
-#define DEBUG_HOSED_REASON
+/* kcs_debug is a bit-field
+ *	KCS_DEBUG_ENABLE -	turned on for now
+ *	KCS_DEBUG_MSG    -	commands and their responses
+ *	KCS_DEBUG_STATES -	state machine
+ */
+#define KCS_DEBUG_STATES	4
+#define KCS_DEBUG_MSG		2
+#define	KCS_DEBUG_ENABLE	1
 
-/* Print the state machine state on entry every time. */
-#undef DEBUG_STATE
+static int kcs_debug;
+module_param(kcs_debug, int, 0644);
+MODULE_PARM_DESC(kcs_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
 
 /* The states the KCS driver may be in. */
 enum kcs_states {
@@ -91,6 +100,7 @@
 #define IBF_RETRY_TIMEOUT 1000000
 #define OBF_RETRY_TIMEOUT 1000000
 #define MAX_ERROR_RETRIES 10
+#define ERROR0_OBF_WAIT_JIFFIES (2*HZ)
 
 struct si_sm_data
 {
@@ -107,6 +117,7 @@
 	unsigned int  error_retries;
 	long          ibf_timeout;
 	long          obf_timeout;
+	unsigned long  error0_timeout;
 };
 
 static unsigned int init_kcs_data(struct si_sm_data *kcs,
@@ -175,11 +186,11 @@
 {
 	(kcs->error_retries)++;
 	if (kcs->error_retries > MAX_ERROR_RETRIES) {
-#ifdef DEBUG_HOSED_REASON
-		printk("ipmi_kcs_sm: kcs hosed: %s\n", reason);
-#endif
+		if (kcs_debug & KCS_DEBUG_ENABLE)
+			printk(KERN_DEBUG "ipmi_kcs_sm: kcs hosed: %s\n", reason);
 		kcs->state = KCS_HOSED;
 	} else {
+		kcs->error0_timeout = jiffies + ERROR0_OBF_WAIT_JIFFIES;
 		kcs->state = KCS_ERROR0;
 	}
 }
@@ -248,14 +259,21 @@
 static int start_kcs_transaction(struct si_sm_data *kcs, unsigned char *data,
 				 unsigned int size)
 {
+	unsigned int i;
+
 	if ((size < 2) || (size > MAX_KCS_WRITE_SIZE)) {
 		return -1;
 	}
-
 	if ((kcs->state != KCS_IDLE) && (kcs->state != KCS_HOSED)) {
 		return -2;
 	}
-
+	if (kcs_debug & KCS_DEBUG_MSG) {
+		printk(KERN_DEBUG "start_kcs_transaction -");
+		for (i = 0; i < size; i ++) {
+			printk(" %02x", (unsigned char) (data [i]));
+		}
+		printk ("\n");
+	}
 	kcs->error_retries = 0;
 	memcpy(kcs->write_data, data, size);
 	kcs->write_count = size;
@@ -305,9 +323,9 @@
 
 	status = read_status(kcs);
 
-#ifdef DEBUG_STATE
-	printk("  State = %d, %x\n", kcs->state, status);
-#endif
+	if (kcs_debug & KCS_DEBUG_STATES)
+		printk(KERN_DEBUG "KCS: State = %d, %x\n", kcs->state, status);
+
 	/* All states wait for ibf, so just do it here. */
 	if (!check_ibf(kcs, status, time))
 		return SI_SM_CALL_WITH_DELAY;
@@ -409,6 +427,10 @@
 
 	case KCS_ERROR0:
 		clear_obf(kcs, status);
+		status = read_status(kcs);
+		if  (GET_STATUS_OBF(status)) /* controller isn't responding */
+			if (time_before(jiffies, kcs->error0_timeout))
+				return SI_SM_CALL_WITH_TICK_DELAY;
 		write_cmd(kcs, KCS_GET_STATUS_ABORT);
 		kcs->state = KCS_ERROR1;
 		break;
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 32fa82c..c1d06ba 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -38,13 +38,13 @@
 #include <linux/sched.h>
 #include <linux/poll.h>
 #include <linux/spinlock.h>
-#include <linux/rwsem.h>
 #include <linux/slab.h>
 #include <linux/ipmi.h>
 #include <linux/ipmi_smi.h>
 #include <linux/notifier.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
+#include <linux/rcupdate.h>
 
 #define PFX "IPMI message handler: "
 
@@ -65,10 +65,19 @@
    the max message timer.  This is in milliseconds. */
 #define MAX_MSG_TIMEOUT		60000
 
+
+/*
+ * The main "user" data structure.
+ */
 struct ipmi_user
 {
 	struct list_head link;
 
+	/* Set to "0" when the user is destroyed. */
+	int valid;
+
+	struct kref refcount;
+
 	/* The upper layer that handles receive messages. */
 	struct ipmi_user_hndl *handler;
 	void             *handler_data;
@@ -87,6 +96,15 @@
 	ipmi_user_t   user;
 	unsigned char netfn;
 	unsigned char cmd;
+
+	/*
+	 * This is used to form a linked lised during mass deletion.
+	 * Since this is in an RCU list, we cannot use the link above
+	 * or change any data until the RCU period completes.  So we
+	 * use this next variable during mass deletion so we can have
+	 * a list and don't have to wait and restart the search on
+	 * every individual deletion of a command. */
+	struct cmd_rcvr *next;
 };
 
 struct seq_table
@@ -150,13 +168,11 @@
 	/* What interface number are we? */
 	int intf_num;
 
-	/* The list of upper layers that are using me.  We read-lock
-           this when delivering messages to the upper layer to keep
-           the user from going away while we are processing the
-           message.  This means that you cannot add or delete a user
-           from the receive callback. */
-	rwlock_t                users_lock;
-	struct list_head        users;
+	struct kref refcount;
+
+	/* The list of upper layers that are using me.  seq_lock
+	 * protects this. */
+	struct list_head users;
 
 	/* Used for wake ups at startup. */
 	wait_queue_head_t waitq;
@@ -193,7 +209,7 @@
 
 	/* The list of command receivers that are registered for commands
 	   on this interface. */
-	rwlock_t	 cmd_rcvr_lock;
+	struct semaphore cmd_rcvrs_lock;
 	struct list_head cmd_rcvrs;
 
 	/* Events that were queues because no one was there to receive
@@ -296,16 +312,17 @@
 	unsigned int events;
 };
 
+/* Used to mark an interface entry that cannot be used but is not a
+ * free entry, either, primarily used at creation and deletion time so
+ * a slot doesn't get reused too quickly. */
+#define IPMI_INVALID_INTERFACE_ENTRY ((ipmi_smi_t) ((long) 1))
+#define IPMI_INVALID_INTERFACE(i) (((i) == NULL) \
+				   || (i == IPMI_INVALID_INTERFACE_ENTRY))
+
 #define MAX_IPMI_INTERFACES 4
 static ipmi_smi_t ipmi_interfaces[MAX_IPMI_INTERFACES];
 
-/* Used to keep interfaces from going away while operations are
-   operating on interfaces.  Grab read if you are not modifying the
-   interfaces, write if you are. */
-static DECLARE_RWSEM(interfaces_sem);
-
-/* Directly protects the ipmi_interfaces data structure.  This is
-   claimed in the timer interrupt. */
+/* Directly protects the ipmi_interfaces data structure. */
 static DEFINE_SPINLOCK(interfaces_lock);
 
 /* List of watchers that want to know when smi's are added and
@@ -313,20 +330,72 @@
 static struct list_head smi_watchers = LIST_HEAD_INIT(smi_watchers);
 static DECLARE_RWSEM(smi_watchers_sem);
 
-int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher)
-{
-	int i;
 
-	down_read(&interfaces_sem);
-	down_write(&smi_watchers_sem);
-	list_add(&(watcher->link), &smi_watchers);
-	for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
-		if (ipmi_interfaces[i] != NULL) {
-			watcher->new_smi(i);
+static void free_recv_msg_list(struct list_head *q)
+{
+	struct ipmi_recv_msg *msg, *msg2;
+
+	list_for_each_entry_safe(msg, msg2, q, link) {
+		list_del(&msg->link);
+		ipmi_free_recv_msg(msg);
+	}
+}
+
+static void clean_up_interface_data(ipmi_smi_t intf)
+{
+	int              i;
+	struct cmd_rcvr  *rcvr, *rcvr2;
+	struct list_head list;
+
+	free_recv_msg_list(&intf->waiting_msgs);
+	free_recv_msg_list(&intf->waiting_events);
+
+	/* Wholesale remove all the entries from the list in the
+	 * interface and wait for RCU to know that none are in use. */
+	down(&intf->cmd_rcvrs_lock);
+	list_add_rcu(&list, &intf->cmd_rcvrs);
+	list_del_rcu(&intf->cmd_rcvrs);
+	up(&intf->cmd_rcvrs_lock);
+	synchronize_rcu();
+
+	list_for_each_entry_safe(rcvr, rcvr2, &list, link)
+		kfree(rcvr);
+
+	for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) {
+		if ((intf->seq_table[i].inuse)
+		    && (intf->seq_table[i].recv_msg))
+		{
+			ipmi_free_recv_msg(intf->seq_table[i].recv_msg);
 		}
 	}
+}
+
+static void intf_free(struct kref *ref)
+{
+	ipmi_smi_t intf = container_of(ref, struct ipmi_smi, refcount);
+
+	clean_up_interface_data(intf);
+	kfree(intf);
+}
+
+int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher)
+{
+	int           i;
+	unsigned long flags;
+
+	down_write(&smi_watchers_sem);
+	list_add(&(watcher->link), &smi_watchers);
 	up_write(&smi_watchers_sem);
-	up_read(&interfaces_sem);
+	spin_lock_irqsave(&interfaces_lock, flags);
+	for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
+		ipmi_smi_t intf = ipmi_interfaces[i];
+		if (IPMI_INVALID_INTERFACE(intf))
+			continue;
+		spin_unlock_irqrestore(&interfaces_lock, flags);
+		watcher->new_smi(i);
+		spin_lock_irqsave(&interfaces_lock, flags);
+	}
+	spin_unlock_irqrestore(&interfaces_lock, flags);
 	return 0;
 }
 
@@ -471,8 +540,8 @@
 		}
 		ipmi_free_recv_msg(msg);
 	} else {
-		msg->user->handler->ipmi_recv_hndl(msg,
-						   msg->user->handler_data);
+		ipmi_user_t user = msg->user;
+		user->handler->ipmi_recv_hndl(msg, user->handler_data);
 	}
 }
 
@@ -662,15 +731,18 @@
 	if (! new_user)
 		return -ENOMEM;
 
-	down_read(&interfaces_sem);
-	if ((if_num >= MAX_IPMI_INTERFACES) || ipmi_interfaces[if_num] == NULL)
-	{
-		rv = -EINVAL;
-		goto out_unlock;
+	spin_lock_irqsave(&interfaces_lock, flags);
+	intf = ipmi_interfaces[if_num];
+	if ((if_num >= MAX_IPMI_INTERFACES) || IPMI_INVALID_INTERFACE(intf)) {
+		spin_unlock_irqrestore(&interfaces_lock, flags);
+		return -EINVAL;
 	}
 
-	intf = ipmi_interfaces[if_num];
+	/* Note that each existing user holds a refcount to the interface. */
+	kref_get(&intf->refcount);
+	spin_unlock_irqrestore(&interfaces_lock, flags);
 
+	kref_init(&new_user->refcount);
 	new_user->handler = handler;
 	new_user->handler_data = handler_data;
 	new_user->intf = intf;
@@ -678,98 +750,92 @@
 
 	if (!try_module_get(intf->handlers->owner)) {
 		rv = -ENODEV;
-		goto out_unlock;
+		goto out_err;
 	}
 
 	if (intf->handlers->inc_usecount) {
 		rv = intf->handlers->inc_usecount(intf->send_info);
 		if (rv) {
 			module_put(intf->handlers->owner);
-			goto out_unlock;
+			goto out_err;
 		}
 	}
 
-	write_lock_irqsave(&intf->users_lock, flags);
-	list_add_tail(&new_user->link, &intf->users);
-	write_unlock_irqrestore(&intf->users_lock, flags);
+	new_user->valid = 1;
+	spin_lock_irqsave(&intf->seq_lock, flags);
+	list_add_rcu(&new_user->link, &intf->users);
+	spin_unlock_irqrestore(&intf->seq_lock, flags);
+	*user = new_user;
+	return 0;
 
- out_unlock:	
-	if (rv) {
-		kfree(new_user);
-	} else {
-		*user = new_user;
-	}
-
-	up_read(&interfaces_sem);
+ out_err:
+	kfree(new_user);
+	kref_put(&intf->refcount, intf_free);
 	return rv;
 }
 
-static int ipmi_destroy_user_nolock(ipmi_user_t user)
+static void free_user(struct kref *ref)
 {
-	int              rv = -ENODEV;
-	ipmi_user_t      t_user;
-	struct cmd_rcvr  *rcvr, *rcvr2;
-	int              i;
-	unsigned long    flags;
-
-	/* Find the user and delete them from the list. */
-	list_for_each_entry(t_user, &(user->intf->users), link) {
-		if (t_user == user) {
-			list_del(&t_user->link);
-			rv = 0;
-			break;
-		}
-	}
-
-	if (rv) {
-		goto out_unlock;
-	}
-
-	/* Remove the user from the interfaces sequence table. */
-	spin_lock_irqsave(&(user->intf->seq_lock), flags);
-	for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) {
-		if (user->intf->seq_table[i].inuse
-		    && (user->intf->seq_table[i].recv_msg->user == user))
-		{
-			user->intf->seq_table[i].inuse = 0;
-		}
-	}
-	spin_unlock_irqrestore(&(user->intf->seq_lock), flags);
-
-	/* Remove the user from the command receiver's table. */
-	write_lock_irqsave(&(user->intf->cmd_rcvr_lock), flags);
-	list_for_each_entry_safe(rcvr, rcvr2, &(user->intf->cmd_rcvrs), link) {
-		if (rcvr->user == user) {
-			list_del(&rcvr->link);
-			kfree(rcvr);
-		}
-	}
-	write_unlock_irqrestore(&(user->intf->cmd_rcvr_lock), flags);
-
+	ipmi_user_t user = container_of(ref, struct ipmi_user, refcount);
 	kfree(user);
-
- out_unlock:
-
-	return rv;
 }
 
 int ipmi_destroy_user(ipmi_user_t user)
 {
-	int           rv;
-	ipmi_smi_t    intf = user->intf;
-	unsigned long flags;
+	int              rv = -ENODEV;
+	ipmi_smi_t       intf = user->intf;
+	int              i;
+	unsigned long    flags;
+	struct cmd_rcvr  *rcvr;
+	struct list_head *entry1, *entry2;
+	struct cmd_rcvr  *rcvrs = NULL;
 
-	down_read(&interfaces_sem);
-	write_lock_irqsave(&intf->users_lock, flags);
-	rv = ipmi_destroy_user_nolock(user);
-	if (!rv) {
-		module_put(intf->handlers->owner);
-		if (intf->handlers->dec_usecount)
-			intf->handlers->dec_usecount(intf->send_info);
+	user->valid = 1;
+
+	/* Remove the user from the interface's sequence table. */
+	spin_lock_irqsave(&intf->seq_lock, flags);
+	list_del_rcu(&user->link);
+
+	for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) {
+		if (intf->seq_table[i].inuse
+		    && (intf->seq_table[i].recv_msg->user == user))
+		{
+			intf->seq_table[i].inuse = 0;
+		}
 	}
-		
-	write_unlock_irqrestore(&intf->users_lock, flags);
-	up_read(&interfaces_sem);
+	spin_unlock_irqrestore(&intf->seq_lock, flags);
+
+	/*
+	 * Remove the user from the command receiver's table.  First
+	 * we build a list of everything (not using the standard link,
+	 * since other things may be using it till we do
+	 * synchronize_rcu()) then free everything in that list.
+	 */
+	down(&intf->cmd_rcvrs_lock);
+	list_for_each_safe_rcu(entry1, entry2, &intf->cmd_rcvrs) {
+		rcvr = list_entry(entry1, struct cmd_rcvr, link);
+		if (rcvr->user == user) {
+			list_del_rcu(&rcvr->link);
+			rcvr->next = rcvrs;
+			rcvrs = rcvr;
+		}
+	}
+	up(&intf->cmd_rcvrs_lock);
+	synchronize_rcu();
+	while (rcvrs) {
+		rcvr = rcvrs;
+		rcvrs = rcvr->next;
+		kfree(rcvr);
+	}
+
+	module_put(intf->handlers->owner);
+	if (intf->handlers->dec_usecount)
+		intf->handlers->dec_usecount(intf->send_info);
+
+	kref_put(&intf->refcount, intf_free);
+
+	kref_put(&user->refcount, free_user);
+
 	return rv;
 }
 
@@ -823,62 +889,78 @@
 
 int ipmi_set_gets_events(ipmi_user_t user, int val)
 {
-	unsigned long         flags;
-	struct ipmi_recv_msg  *msg, *msg2;
+	unsigned long        flags;
+	ipmi_smi_t           intf = user->intf;
+	struct ipmi_recv_msg *msg, *msg2;
+	struct list_head     msgs;
 
-	read_lock(&(user->intf->users_lock));
-	spin_lock_irqsave(&(user->intf->events_lock), flags);
+	INIT_LIST_HEAD(&msgs);
+
+	spin_lock_irqsave(&intf->events_lock, flags);
 	user->gets_events = val;
 
 	if (val) {
 		/* Deliver any queued events. */
-		list_for_each_entry_safe(msg, msg2, &(user->intf->waiting_events), link) {
+		list_for_each_entry_safe(msg, msg2, &intf->waiting_events, link) {
 			list_del(&msg->link);
-			msg->user = user;
-			deliver_response(msg);
+			list_add_tail(&msg->link, &msgs);
 		}
 	}
-	
-	spin_unlock_irqrestore(&(user->intf->events_lock), flags);
-	read_unlock(&(user->intf->users_lock));
+
+	/* Hold the events lock while doing this to preserve order. */
+	list_for_each_entry_safe(msg, msg2, &msgs, link) {
+		msg->user = user;
+		kref_get(&user->refcount);
+		deliver_response(msg);
+	}
+
+	spin_unlock_irqrestore(&intf->events_lock, flags);
 
 	return 0;
 }
 
+static struct cmd_rcvr *find_cmd_rcvr(ipmi_smi_t    intf,
+				      unsigned char netfn,
+				      unsigned char cmd)
+{
+	struct cmd_rcvr *rcvr;
+
+	list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link) {
+		if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd))
+			return rcvr;
+	}
+	return NULL;
+}
+
 int ipmi_register_for_cmd(ipmi_user_t   user,
 			  unsigned char netfn,
 			  unsigned char cmd)
 {
-	struct cmd_rcvr  *cmp;
-	unsigned long    flags;
-	struct cmd_rcvr  *rcvr;
-	int              rv = 0;
+	ipmi_smi_t      intf = user->intf;
+	struct cmd_rcvr *rcvr;
+	struct cmd_rcvr *entry;
+	int             rv = 0;
 
 
 	rcvr = kmalloc(sizeof(*rcvr), GFP_KERNEL);
 	if (! rcvr)
 		return -ENOMEM;
+	rcvr->cmd = cmd;
+	rcvr->netfn = netfn;
+	rcvr->user = user;
 
-	read_lock(&(user->intf->users_lock));
-	write_lock_irqsave(&(user->intf->cmd_rcvr_lock), flags);
+	down(&intf->cmd_rcvrs_lock);
 	/* Make sure the command/netfn is not already registered. */
-	list_for_each_entry(cmp, &(user->intf->cmd_rcvrs), link) {
-		if ((cmp->netfn == netfn) && (cmp->cmd == cmd)) {
-			rv = -EBUSY;
-			break;
-		}
+	entry = find_cmd_rcvr(intf, netfn, cmd);
+	if (entry) {
+		rv = -EBUSY;
+		goto out_unlock;
 	}
 
-	if (! rv) {
-		rcvr->cmd = cmd;
-		rcvr->netfn = netfn;
-		rcvr->user = user;
-		list_add_tail(&(rcvr->link), &(user->intf->cmd_rcvrs));
-	}
+	list_add_rcu(&rcvr->link, &intf->cmd_rcvrs);
 
-	write_unlock_irqrestore(&(user->intf->cmd_rcvr_lock), flags);
-	read_unlock(&(user->intf->users_lock));
-
+ out_unlock:
+	up(&intf->cmd_rcvrs_lock);
 	if (rv)
 		kfree(rcvr);
 
@@ -889,31 +971,28 @@
 			    unsigned char netfn,
 			    unsigned char cmd)
 {
-	unsigned long    flags;
-	struct cmd_rcvr  *rcvr;
-	int              rv = -ENOENT;
+	ipmi_smi_t      intf = user->intf;
+	struct cmd_rcvr *rcvr;
 
-	read_lock(&(user->intf->users_lock));
-	write_lock_irqsave(&(user->intf->cmd_rcvr_lock), flags);
+	down(&intf->cmd_rcvrs_lock);
 	/* Make sure the command/netfn is not already registered. */
-	list_for_each_entry(rcvr, &(user->intf->cmd_rcvrs), link) {
-		if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd)) {
-			rv = 0;
-			list_del(&rcvr->link);
-			kfree(rcvr);
-			break;
-		}
+	rcvr = find_cmd_rcvr(intf, netfn, cmd);
+	if ((rcvr) && (rcvr->user == user)) {
+		list_del_rcu(&rcvr->link);
+		up(&intf->cmd_rcvrs_lock);
+		synchronize_rcu();
+		kfree(rcvr);
+		return 0;
+	} else {
+		up(&intf->cmd_rcvrs_lock);
+		return -ENOENT;
 	}
-	write_unlock_irqrestore(&(user->intf->cmd_rcvr_lock), flags);
-	read_unlock(&(user->intf->users_lock));
-
-	return rv;
 }
 
 void ipmi_user_set_run_to_completion(ipmi_user_t user, int val)
 {
-	user->intf->handlers->set_run_to_completion(user->intf->send_info,
-						    val);
+	ipmi_smi_t intf = user->intf;
+	intf->handlers->set_run_to_completion(intf->send_info, val);
 }
 
 static unsigned char
@@ -1010,19 +1089,19 @@
    supplied in certain circumstances (mainly at panic time).  If
    messages are supplied, they will be freed, even if an error
    occurs. */
-static inline int i_ipmi_request(ipmi_user_t          user,
-				 ipmi_smi_t           intf,
-				 struct ipmi_addr     *addr,
-				 long                 msgid,
-				 struct kernel_ipmi_msg *msg,
-				 void                 *user_msg_data,
-				 void                 *supplied_smi,
-				 struct ipmi_recv_msg *supplied_recv,
-				 int                  priority,
-				 unsigned char        source_address,
-				 unsigned char        source_lun,
-				 int                  retries,
-				 unsigned int         retry_time_ms)
+static int i_ipmi_request(ipmi_user_t          user,
+			  ipmi_smi_t           intf,
+			  struct ipmi_addr     *addr,
+			  long                 msgid,
+			  struct kernel_ipmi_msg *msg,
+			  void                 *user_msg_data,
+			  void                 *supplied_smi,
+			  struct ipmi_recv_msg *supplied_recv,
+			  int                  priority,
+			  unsigned char        source_address,
+			  unsigned char        source_lun,
+			  int                  retries,
+			  unsigned int         retry_time_ms)
 {
 	int                  rv = 0;
 	struct ipmi_smi_msg  *smi_msg;
@@ -1051,6 +1130,8 @@
 	}
 
 	recv_msg->user = user;
+	if (user)
+		kref_get(&user->refcount);
 	recv_msg->msgid = msgid;
 	/* Store the message to send in the receive message so timeout
 	   responses can get the proper response data. */
@@ -1725,11 +1806,11 @@
 		      unsigned char            version_major,
 		      unsigned char            version_minor,
 		      unsigned char            slave_addr,
-		      ipmi_smi_t               *intf)
+		      ipmi_smi_t               *new_intf)
 {
 	int              i, j;
 	int              rv;
-	ipmi_smi_t       new_intf;
+	ipmi_smi_t       intf;
 	unsigned long    flags;
 
 
@@ -1745,189 +1826,142 @@
 			return -ENODEV;
 	}
 
-	new_intf = kmalloc(sizeof(*new_intf), GFP_KERNEL);
-	if (!new_intf)
+	intf = kmalloc(sizeof(*intf), GFP_KERNEL);
+	if (!intf)
 		return -ENOMEM;
-	memset(new_intf, 0, sizeof(*new_intf));
+	memset(intf, 0, sizeof(*intf));
+	intf->intf_num = -1;
+	kref_init(&intf->refcount);
+	intf->version_major = version_major;
+	intf->version_minor = version_minor;
+	for (j = 0; j < IPMI_MAX_CHANNELS; j++) {
+		intf->channels[j].address = IPMI_BMC_SLAVE_ADDR;
+		intf->channels[j].lun = 2;
+	}
+	if (slave_addr != 0)
+		intf->channels[0].address = slave_addr;
+	INIT_LIST_HEAD(&intf->users);
+	intf->handlers = handlers;
+	intf->send_info = send_info;
+	spin_lock_init(&intf->seq_lock);
+	for (j = 0; j < IPMI_IPMB_NUM_SEQ; j++) {
+		intf->seq_table[j].inuse = 0;
+		intf->seq_table[j].seqid = 0;
+	}
+	intf->curr_seq = 0;
+#ifdef CONFIG_PROC_FS
+	spin_lock_init(&intf->proc_entry_lock);
+#endif
+	spin_lock_init(&intf->waiting_msgs_lock);
+	INIT_LIST_HEAD(&intf->waiting_msgs);
+	spin_lock_init(&intf->events_lock);
+	INIT_LIST_HEAD(&intf->waiting_events);
+	intf->waiting_events_count = 0;
+	init_MUTEX(&intf->cmd_rcvrs_lock);
+	INIT_LIST_HEAD(&intf->cmd_rcvrs);
+	init_waitqueue_head(&intf->waitq);
 
-	new_intf->proc_dir = NULL;
+	spin_lock_init(&intf->counter_lock);
+	intf->proc_dir = NULL;
 
 	rv = -ENOMEM;
-
-	down_write(&interfaces_sem);
+	spin_lock_irqsave(&interfaces_lock, flags);
 	for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
 		if (ipmi_interfaces[i] == NULL) {
-			new_intf->intf_num = i;
-			new_intf->version_major = version_major;
-			new_intf->version_minor = version_minor;
-			for (j = 0; j < IPMI_MAX_CHANNELS; j++) {
-				new_intf->channels[j].address
-					= IPMI_BMC_SLAVE_ADDR;
-				new_intf->channels[j].lun = 2;
-			}
-			if (slave_addr != 0)
-				new_intf->channels[0].address = slave_addr;
-			rwlock_init(&(new_intf->users_lock));
-			INIT_LIST_HEAD(&(new_intf->users));
-			new_intf->handlers = handlers;
-			new_intf->send_info = send_info;
-			spin_lock_init(&(new_intf->seq_lock));
-			for (j = 0; j < IPMI_IPMB_NUM_SEQ; j++) {
-				new_intf->seq_table[j].inuse = 0;
-				new_intf->seq_table[j].seqid = 0;
-			}
-			new_intf->curr_seq = 0;
-#ifdef CONFIG_PROC_FS
-			spin_lock_init(&(new_intf->proc_entry_lock));
-#endif
-			spin_lock_init(&(new_intf->waiting_msgs_lock));
-			INIT_LIST_HEAD(&(new_intf->waiting_msgs));
-			spin_lock_init(&(new_intf->events_lock));
-			INIT_LIST_HEAD(&(new_intf->waiting_events));
-			new_intf->waiting_events_count = 0;
-			rwlock_init(&(new_intf->cmd_rcvr_lock));
-			init_waitqueue_head(&new_intf->waitq);
-			INIT_LIST_HEAD(&(new_intf->cmd_rcvrs));
-
-			spin_lock_init(&(new_intf->counter_lock));
-
-			spin_lock_irqsave(&interfaces_lock, flags);
-			ipmi_interfaces[i] = new_intf;
-			spin_unlock_irqrestore(&interfaces_lock, flags);
-
+			intf->intf_num = i;
+			/* Reserve the entry till we are done. */
+			ipmi_interfaces[i] = IPMI_INVALID_INTERFACE_ENTRY;
 			rv = 0;
-			*intf = new_intf;
 			break;
 		}
 	}
+	spin_unlock_irqrestore(&interfaces_lock, flags);
+	if (rv)
+		goto out;
 
-	downgrade_write(&interfaces_sem);
+	/* FIXME - this is an ugly kludge, this sets the intf for the
+	   caller before sending any messages with it. */
+	*new_intf = intf;
+
+	if ((version_major > 1)
+	    || ((version_major == 1) && (version_minor >= 5)))
+	{
+		/* Start scanning the channels to see what is
+		   available. */
+		intf->null_user_handler = channel_handler;
+		intf->curr_channel = 0;
+		rv = send_channel_info_cmd(intf, 0);
+		if (rv)
+			goto out;
+
+		/* Wait for the channel info to be read. */
+		wait_event(intf->waitq,
+			   intf->curr_channel >= IPMI_MAX_CHANNELS);
+	} else {
+		/* Assume a single IPMB channel at zero. */
+		intf->channels[0].medium = IPMI_CHANNEL_MEDIUM_IPMB;
+		intf->channels[0].protocol = IPMI_CHANNEL_PROTOCOL_IPMB;
+	}
 
 	if (rv == 0)
-		rv = add_proc_entries(*intf, i);
+		rv = add_proc_entries(intf, i);
 
-	if (rv == 0) {
-		if ((version_major > 1)
-		    || ((version_major == 1) && (version_minor >= 5)))
-		{
-			/* Start scanning the channels to see what is
-			   available. */
-			(*intf)->null_user_handler = channel_handler;
-			(*intf)->curr_channel = 0;
-			rv = send_channel_info_cmd(*intf, 0);
-			if (rv)
-				goto out;
-
-			/* Wait for the channel info to be read. */
-			up_read(&interfaces_sem);
-			wait_event((*intf)->waitq,
-				   ((*intf)->curr_channel>=IPMI_MAX_CHANNELS));
-			down_read(&interfaces_sem);
-
-			if (ipmi_interfaces[i] != new_intf)
-				/* Well, it went away.  Just return. */
-				goto out;
-		} else {
-			/* Assume a single IPMB channel at zero. */
-			(*intf)->channels[0].medium = IPMI_CHANNEL_MEDIUM_IPMB;
-			(*intf)->channels[0].protocol
-				= IPMI_CHANNEL_PROTOCOL_IPMB;
-  		}
-
-		/* Call all the watcher interfaces to tell
-		   them that a new interface is available. */
+ out:
+	if (rv) {
+		if (intf->proc_dir)
+			remove_proc_entries(intf);
+		kref_put(&intf->refcount, intf_free);
+		if (i < MAX_IPMI_INTERFACES) {
+			spin_lock_irqsave(&interfaces_lock, flags);
+			ipmi_interfaces[i] = NULL;
+			spin_unlock_irqrestore(&interfaces_lock, flags);
+		}
+	} else {
+		spin_lock_irqsave(&interfaces_lock, flags);
+		ipmi_interfaces[i] = intf;
+		spin_unlock_irqrestore(&interfaces_lock, flags);
 		call_smi_watchers(i);
 	}
 
- out:
-	up_read(&interfaces_sem);
-
-	if (rv) {
-		if (new_intf->proc_dir)
-			remove_proc_entries(new_intf);
-		kfree(new_intf);
-	}
-
 	return rv;
 }
 
-static void free_recv_msg_list(struct list_head *q)
-{
-	struct ipmi_recv_msg *msg, *msg2;
-
-	list_for_each_entry_safe(msg, msg2, q, link) {
-		list_del(&msg->link);
-		ipmi_free_recv_msg(msg);
-	}
-}
-
-static void free_cmd_rcvr_list(struct list_head *q)
-{
-	struct cmd_rcvr  *rcvr, *rcvr2;
-
-	list_for_each_entry_safe(rcvr, rcvr2, q, link) {
-		list_del(&rcvr->link);
-		kfree(rcvr);
-	}
-}
-
-static void clean_up_interface_data(ipmi_smi_t intf)
-{
-	int i;
-
-	free_recv_msg_list(&(intf->waiting_msgs));
-	free_recv_msg_list(&(intf->waiting_events));
-	free_cmd_rcvr_list(&(intf->cmd_rcvrs));
-
-	for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) {
-		if ((intf->seq_table[i].inuse)
-		    && (intf->seq_table[i].recv_msg))
-		{
-			ipmi_free_recv_msg(intf->seq_table[i].recv_msg);
-		}	
-	}
-}
-
 int ipmi_unregister_smi(ipmi_smi_t intf)
 {
-	int                     rv = -ENODEV;
 	int                     i;
 	struct ipmi_smi_watcher *w;
 	unsigned long           flags;
 
-	down_write(&interfaces_sem);
-	if (list_empty(&(intf->users)))
-	{
-		for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
-			if (ipmi_interfaces[i] == intf) {
-				remove_proc_entries(intf);
-				spin_lock_irqsave(&interfaces_lock, flags);
-				ipmi_interfaces[i] = NULL;
-				clean_up_interface_data(intf);
-				spin_unlock_irqrestore(&interfaces_lock,flags);
-				kfree(intf);
-				rv = 0;
-				goto out_call_watcher;
-			}
+	spin_lock_irqsave(&interfaces_lock, flags);
+	for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
+		if (ipmi_interfaces[i] == intf) {
+			/* Set the interface number reserved until we
+			 * are done. */
+			ipmi_interfaces[i] = IPMI_INVALID_INTERFACE_ENTRY;
+			intf->intf_num = -1;
+			break;
 		}
-	} else {
-		rv = -EBUSY;
 	}
-	up_write(&interfaces_sem);
+	spin_unlock_irqrestore(&interfaces_lock,flags);
 
-	return rv;
+	if (i == MAX_IPMI_INTERFACES)
+		return -ENODEV;
 
- out_call_watcher:
-	downgrade_write(&interfaces_sem);
+	remove_proc_entries(intf);
 
 	/* Call all the watcher interfaces to tell them that
 	   an interface is gone. */
 	down_read(&smi_watchers_sem);
-	list_for_each_entry(w, &smi_watchers, link) {
+	list_for_each_entry(w, &smi_watchers, link)
 		w->smi_gone(i);
-	}
 	up_read(&smi_watchers_sem);
-	up_read(&interfaces_sem);
+
+	/* Allow the entry to be reused now. */
+	spin_lock_irqsave(&interfaces_lock, flags);
+	ipmi_interfaces[i] = NULL;
+	spin_unlock_irqrestore(&interfaces_lock,flags);
+
+	kref_put(&intf->refcount, intf_free);
 	return 0;
 }
 
@@ -1998,14 +2032,14 @@
 static int handle_ipmb_get_msg_cmd(ipmi_smi_t          intf,
 				   struct ipmi_smi_msg *msg)
 {
-	struct cmd_rcvr       *rcvr;
-	int                   rv = 0;
-	unsigned char         netfn;
-	unsigned char         cmd;
-	ipmi_user_t           user = NULL;
-	struct ipmi_ipmb_addr *ipmb_addr;
-	struct ipmi_recv_msg  *recv_msg;
-	unsigned long         flags;
+	struct cmd_rcvr          *rcvr;
+	int                      rv = 0;
+	unsigned char            netfn;
+	unsigned char            cmd;
+	ipmi_user_t              user = NULL;
+	struct ipmi_ipmb_addr    *ipmb_addr;
+	struct ipmi_recv_msg     *recv_msg;
+	unsigned long            flags;
 
 	if (msg->rsp_size < 10) {
 		/* Message not big enough, just ignore it. */
@@ -2023,16 +2057,14 @@
 	netfn = msg->rsp[4] >> 2;
 	cmd = msg->rsp[8];
 
-	read_lock(&(intf->cmd_rcvr_lock));
-	
-	/* Find the command/netfn. */
-	list_for_each_entry(rcvr, &(intf->cmd_rcvrs), link) {
-		if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd)) {
-			user = rcvr->user;
-			break;
-		}
-	}
-	read_unlock(&(intf->cmd_rcvr_lock));
+	rcu_read_lock();
+	rcvr = find_cmd_rcvr(intf, netfn, cmd);
+	if (rcvr) {
+		user = rcvr->user;
+		kref_get(&user->refcount);
+	} else
+		user = NULL;
+	rcu_read_unlock();
 
 	if (user == NULL) {
 		/* We didn't find a user, deliver an error response. */
@@ -2079,6 +2111,7 @@
                            message, so requeue it for handling
                            later. */
 			rv = 1;
+			kref_put(&user->refcount, free_user);
 		} else {
 			/* Extract the source address from the data. */
 			ipmb_addr = (struct ipmi_ipmb_addr *) &recv_msg->addr;
@@ -2179,14 +2212,14 @@
 static int handle_lan_get_msg_cmd(ipmi_smi_t          intf,
 				  struct ipmi_smi_msg *msg)
 {
-	struct cmd_rcvr       *rcvr;
-	int                   rv = 0;
-	unsigned char         netfn;
-	unsigned char         cmd;
-	ipmi_user_t           user = NULL;
-	struct ipmi_lan_addr  *lan_addr;
-	struct ipmi_recv_msg  *recv_msg;
-	unsigned long         flags;
+	struct cmd_rcvr          *rcvr;
+	int                      rv = 0;
+	unsigned char            netfn;
+	unsigned char            cmd;
+	ipmi_user_t              user = NULL;
+	struct ipmi_lan_addr     *lan_addr;
+	struct ipmi_recv_msg     *recv_msg;
+	unsigned long            flags;
 
 	if (msg->rsp_size < 12) {
 		/* Message not big enough, just ignore it. */
@@ -2204,19 +2237,17 @@
 	netfn = msg->rsp[6] >> 2;
 	cmd = msg->rsp[10];
 
-	read_lock(&(intf->cmd_rcvr_lock));
-
-	/* Find the command/netfn. */
-	list_for_each_entry(rcvr, &(intf->cmd_rcvrs), link) {
-		if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd)) {
-			user = rcvr->user;
-			break;
-		}
-	}
-	read_unlock(&(intf->cmd_rcvr_lock));
+	rcu_read_lock();
+	rcvr = find_cmd_rcvr(intf, netfn, cmd);
+	if (rcvr) {
+		user = rcvr->user;
+		kref_get(&user->refcount);
+	} else
+		user = NULL;
+	rcu_read_unlock();
 
 	if (user == NULL) {
-		/* We didn't find a user, deliver an error response. */
+		/* We didn't find a user, just give up. */
 		spin_lock_irqsave(&intf->counter_lock, flags);
 		intf->unhandled_commands++;
 		spin_unlock_irqrestore(&intf->counter_lock, flags);
@@ -2235,6 +2266,7 @@
                            message, so requeue it for handling
                            later. */
 			rv = 1;
+			kref_put(&user->refcount, free_user);
 		} else {
 			/* Extract the source address from the data. */
 			lan_addr = (struct ipmi_lan_addr *) &recv_msg->addr;
@@ -2286,8 +2318,6 @@
 	recv_msg->msg.data_len = msg->rsp_size - 3;
 }
 
-/* This will be called with the intf->users_lock read-locked, so no need
-   to do that here. */
 static int handle_read_event_rsp(ipmi_smi_t          intf,
 				 struct ipmi_smi_msg *msg)
 {
@@ -2313,7 +2343,7 @@
 
 	INIT_LIST_HEAD(&msgs);
 
-	spin_lock_irqsave(&(intf->events_lock), flags);
+	spin_lock_irqsave(&intf->events_lock, flags);
 
 	spin_lock(&intf->counter_lock);
 	intf->events++;
@@ -2321,12 +2351,14 @@
 
 	/* Allocate and fill in one message for every user that is getting
 	   events. */
-	list_for_each_entry(user, &(intf->users), link) {
+	rcu_read_lock();
+	list_for_each_entry_rcu(user, &intf->users, link) {
 		if (! user->gets_events)
 			continue;
 
 		recv_msg = ipmi_alloc_recv_msg();
 		if (! recv_msg) {
+			rcu_read_unlock();
 			list_for_each_entry_safe(recv_msg, recv_msg2, &msgs, link) {
 				list_del(&recv_msg->link);
 				ipmi_free_recv_msg(recv_msg);
@@ -2342,8 +2374,10 @@
 
 		copy_event_into_recv_msg(recv_msg, msg);
 		recv_msg->user = user;
+		kref_get(&user->refcount);
 		list_add_tail(&(recv_msg->link), &msgs);
 	}
+	rcu_read_unlock();
 
 	if (deliver_count) {
 		/* Now deliver all the messages. */
@@ -2382,9 +2416,8 @@
 			  struct ipmi_smi_msg *msg)
 {
 	struct ipmi_recv_msg *recv_msg;
-	int                  found = 0;
-	struct ipmi_user     *user;
 	unsigned long        flags;
+	struct ipmi_user     *user;
 
 	recv_msg = (struct ipmi_recv_msg *) msg->user_data;
 	if (recv_msg == NULL)
@@ -2396,16 +2429,9 @@
 		return 0;
 	}
 
+	user = recv_msg->user;
 	/* Make sure the user still exists. */
-	list_for_each_entry(user, &(intf->users), link) {
-		if (user == recv_msg->user) {
-			/* Found it, so we can deliver it */
-			found = 1;
-			break;
-		}
-	}
-
-	if ((! found) && recv_msg->user) {
+	if (user && !user->valid) {
 		/* The user for the message went away, so give up. */
 		spin_lock_irqsave(&intf->counter_lock, flags);
 		intf->unhandled_local_responses++;
@@ -2486,7 +2512,7 @@
 	{
 		/* It's a response to a response we sent.  For this we
 		   deliver a send message response to the user. */
-		struct ipmi_recv_msg *recv_msg = msg->user_data;
+		struct ipmi_recv_msg     *recv_msg = msg->user_data;
 
 		requeue = 0;
 		if (msg->rsp_size < 2)
@@ -2498,13 +2524,18 @@
 			/* Invalid channel number */
 			goto out;
 
-		if (recv_msg) {
-			recv_msg->recv_type = IPMI_RESPONSE_RESPONSE_TYPE;
-			recv_msg->msg.data = recv_msg->msg_data;
-			recv_msg->msg.data_len = 1;
-			recv_msg->msg_data[0] = msg->rsp[2];
-			deliver_response(recv_msg);
-		}
+		if (!recv_msg)
+			goto out;
+
+		/* Make sure the user still exists. */
+		if (!recv_msg->user || !recv_msg->user->valid)
+			goto out;
+
+		recv_msg->recv_type = IPMI_RESPONSE_RESPONSE_TYPE;
+		recv_msg->msg.data = recv_msg->msg_data;
+		recv_msg->msg.data_len = 1;
+		recv_msg->msg_data[0] = msg->rsp[2];
+		deliver_response(recv_msg);
 	} else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2))
 		   && (msg->rsp[1] == IPMI_GET_MSG_CMD))
 	{
@@ -2570,14 +2601,11 @@
 	int           rv;
 
 
-	/* Lock the user lock so the user can't go away while we are
-	   working on it. */
-	read_lock(&(intf->users_lock));
-
 	if ((msg->data_size >= 2)
 	    && (msg->data[0] == (IPMI_NETFN_APP_REQUEST << 2))
 	    && (msg->data[1] == IPMI_SEND_MSG_CMD)
-	    && (msg->user_data == NULL)) {
+	    && (msg->user_data == NULL))
+	{
 		/* This is the local response to a command send, start
                    the timer for these.  The user_data will not be
                    NULL if this is a response send, and we will let
@@ -2612,46 +2640,46 @@
 		}
 
 		ipmi_free_smi_msg(msg);
-		goto out_unlock;
+		goto out;
 	}
 
 	/* To preserve message order, if the list is not empty, we
            tack this message onto the end of the list. */
-	spin_lock_irqsave(&(intf->waiting_msgs_lock), flags);
-	if (!list_empty(&(intf->waiting_msgs))) {
-		list_add_tail(&(msg->link), &(intf->waiting_msgs));
-		spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
-		goto out_unlock;
+	spin_lock_irqsave(&intf->waiting_msgs_lock, flags);
+	if (!list_empty(&intf->waiting_msgs)) {
+		list_add_tail(&msg->link, &intf->waiting_msgs);
+		spin_unlock(&intf->waiting_msgs_lock);
+		goto out;
 	}
-	spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
+	spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags);
 		
 	rv = handle_new_recv_msg(intf, msg);
 	if (rv > 0) {
 		/* Could not handle the message now, just add it to a
                    list to handle later. */
-		spin_lock_irqsave(&(intf->waiting_msgs_lock), flags);
-		list_add_tail(&(msg->link), &(intf->waiting_msgs));
-		spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
+		spin_lock(&intf->waiting_msgs_lock);
+		list_add_tail(&msg->link, &intf->waiting_msgs);
+		spin_unlock(&intf->waiting_msgs_lock);
 	} else if (rv == 0) {
 		ipmi_free_smi_msg(msg);
 	}
 
- out_unlock:
-	read_unlock(&(intf->users_lock));
+ out:
+	return;
 }
 
 void ipmi_smi_watchdog_pretimeout(ipmi_smi_t intf)
 {
 	ipmi_user_t user;
 
-	read_lock(&(intf->users_lock));
-	list_for_each_entry(user, &(intf->users), link) {
+	rcu_read_lock();
+	list_for_each_entry_rcu(user, &intf->users, link) {
 		if (! user->handler->ipmi_watchdog_pretimeout)
 			continue;
 
 		user->handler->ipmi_watchdog_pretimeout(user->handler_data);
 	}
-	read_unlock(&(intf->users_lock));
+	rcu_read_unlock();
 }
 
 static void
@@ -2691,8 +2719,65 @@
 	return smi_msg;
 }
 
-static void
-ipmi_timeout_handler(long timeout_period)
+static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
+			      struct list_head *timeouts, long timeout_period,
+			      int slot, unsigned long *flags)
+{
+	struct ipmi_recv_msg *msg;
+
+	if (!ent->inuse)
+		return;
+
+	ent->timeout -= timeout_period;
+	if (ent->timeout > 0)
+		return;
+
+	if (ent->retries_left == 0) {
+		/* The message has used all its retries. */
+		ent->inuse = 0;
+		msg = ent->recv_msg;
+		list_add_tail(&msg->link, timeouts);
+		spin_lock(&intf->counter_lock);
+		if (ent->broadcast)
+			intf->timed_out_ipmb_broadcasts++;
+		else if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE)
+			intf->timed_out_lan_commands++;
+		else
+			intf->timed_out_ipmb_commands++;
+		spin_unlock(&intf->counter_lock);
+	} else {
+		struct ipmi_smi_msg *smi_msg;
+		/* More retries, send again. */
+
+		/* Start with the max timer, set to normal
+		   timer after the message is sent. */
+		ent->timeout = MAX_MSG_TIMEOUT;
+		ent->retries_left--;
+		spin_lock(&intf->counter_lock);
+		if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE)
+			intf->retransmitted_lan_commands++;
+		else
+			intf->retransmitted_ipmb_commands++;
+		spin_unlock(&intf->counter_lock);
+
+		smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot,
+					    ent->seqid);
+		if (! smi_msg)
+			return;
+
+		spin_unlock_irqrestore(&intf->seq_lock, *flags);
+		/* Send the new message.  We send with a zero
+		 * priority.  It timed out, I doubt time is
+		 * that critical now, and high priority
+		 * messages are really only for messages to the
+		 * local MC, which don't get resent. */
+		intf->handlers->sender(intf->send_info,
+				       smi_msg, 0);
+		spin_lock_irqsave(&intf->seq_lock, *flags);
+	}
+}
+
+static void ipmi_timeout_handler(long timeout_period)
 {
 	ipmi_smi_t           intf;
 	struct list_head     timeouts;
@@ -2706,14 +2791,14 @@
 	spin_lock(&interfaces_lock);
 	for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
 		intf = ipmi_interfaces[i];
-		if (intf == NULL)
+		if (IPMI_INVALID_INTERFACE(intf))
 			continue;
-
-		read_lock(&(intf->users_lock));
+		kref_get(&intf->refcount);
+		spin_unlock(&interfaces_lock);
 
 		/* See if any waiting messages need to be processed. */
-		spin_lock_irqsave(&(intf->waiting_msgs_lock), flags);
-		list_for_each_entry_safe(smi_msg, smi_msg2, &(intf->waiting_msgs), link) {
+		spin_lock_irqsave(&intf->waiting_msgs_lock, flags);
+		list_for_each_entry_safe(smi_msg, smi_msg2, &intf->waiting_msgs, link) {
 			if (! handle_new_recv_msg(intf, smi_msg)) {
 				list_del(&smi_msg->link);
 				ipmi_free_smi_msg(smi_msg);
@@ -2723,73 +2808,23 @@
 				break;
 			}
 		}
-		spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
+		spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags);
 
 		/* Go through the seq table and find any messages that
 		   have timed out, putting them in the timeouts
 		   list. */
-		spin_lock_irqsave(&(intf->seq_lock), flags);
-		for (j = 0; j < IPMI_IPMB_NUM_SEQ; j++) {
-			struct seq_table *ent = &(intf->seq_table[j]);
-			if (!ent->inuse)
-				continue;
+		spin_lock_irqsave(&intf->seq_lock, flags);
+		for (j = 0; j < IPMI_IPMB_NUM_SEQ; j++)
+			check_msg_timeout(intf, &(intf->seq_table[j]),
+					  &timeouts, timeout_period, j,
+					  &flags);
+		spin_unlock_irqrestore(&intf->seq_lock, flags);
 
-			ent->timeout -= timeout_period;
-			if (ent->timeout > 0)
-				continue;
-
-			if (ent->retries_left == 0) {
-				/* The message has used all its retries. */
-				ent->inuse = 0;
-				msg = ent->recv_msg;
-				list_add_tail(&(msg->link), &timeouts);
-				spin_lock(&intf->counter_lock);
-				if (ent->broadcast)
-					intf->timed_out_ipmb_broadcasts++;
-				else if (ent->recv_msg->addr.addr_type
-					 == IPMI_LAN_ADDR_TYPE)
-					intf->timed_out_lan_commands++;
-				else
-					intf->timed_out_ipmb_commands++;
-				spin_unlock(&intf->counter_lock);
-			} else {
-				struct ipmi_smi_msg *smi_msg;
-				/* More retries, send again. */
-
-				/* Start with the max timer, set to normal
-				   timer after the message is sent. */
-				ent->timeout = MAX_MSG_TIMEOUT;
-				ent->retries_left--;
-				spin_lock(&intf->counter_lock);
-				if (ent->recv_msg->addr.addr_type
-				    == IPMI_LAN_ADDR_TYPE)
-					intf->retransmitted_lan_commands++;
-				else
-					intf->retransmitted_ipmb_commands++;
-				spin_unlock(&intf->counter_lock);
-				smi_msg = smi_from_recv_msg(intf,
-						ent->recv_msg, j, ent->seqid);
-				if (! smi_msg)
-					continue;
-
-				spin_unlock_irqrestore(&(intf->seq_lock),flags);
-				/* Send the new message.  We send with a zero
-				 * priority.  It timed out, I doubt time is
-				 * that critical now, and high priority
-				 * messages are really only for messages to the
-				 * local MC, which don't get resent. */
-				intf->handlers->sender(intf->send_info,
-							smi_msg, 0);
-				spin_lock_irqsave(&(intf->seq_lock), flags);
-			}
-		}
-		spin_unlock_irqrestore(&(intf->seq_lock), flags);
-
-		list_for_each_entry_safe(msg, msg2, &timeouts, link) {
+		list_for_each_entry_safe(msg, msg2, &timeouts, link)
 			handle_msg_timeout(msg);
-		}
 
-		read_unlock(&(intf->users_lock));
+		kref_put(&intf->refcount, intf_free);
+		spin_lock(&interfaces_lock);
 	}
 	spin_unlock(&interfaces_lock);
 }
@@ -2802,7 +2837,7 @@
 	spin_lock(&interfaces_lock);
 	for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
 		intf = ipmi_interfaces[i];
-		if (intf == NULL)
+		if (IPMI_INVALID_INTERFACE(intf))
 			continue;
 
 		intf->handlers->request_events(intf->send_info);
@@ -2884,6 +2919,13 @@
 	return rv;
 }
 
+void ipmi_free_recv_msg(struct ipmi_recv_msg *msg)
+{
+	if (msg->user)
+		kref_put(&msg->user->refcount, free_user);
+	msg->done(msg);
+}
+
 #ifdef CONFIG_IPMI_PANIC_EVENT
 
 static void dummy_smi_done_handler(struct ipmi_smi_msg *msg)
@@ -2964,7 +3006,7 @@
 	/* For every registered interface, send the event. */
 	for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
 		intf = ipmi_interfaces[i];
-		if (intf == NULL)
+		if (IPMI_INVALID_INTERFACE(intf))
 			continue;
 
 		/* Send the event announcing the panic. */
@@ -2995,7 +3037,7 @@
 		int                   j;
 
 		intf = ipmi_interfaces[i];
-		if (intf == NULL)
+		if (IPMI_INVALID_INTERFACE(intf))
 			continue;
 
 		/* First job here is to figure out where to send the
@@ -3131,7 +3173,7 @@
 	/* For every registered interface, set it to run to completion. */
 	for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
 		intf = ipmi_interfaces[i];
-		if (intf == NULL)
+		if (IPMI_INVALID_INTERFACE(intf))
 			continue;
 
 		intf->handlers->set_run_to_completion(intf->send_info, 1);
@@ -3160,9 +3202,8 @@
 	printk(KERN_INFO "ipmi message handler version "
 	       IPMI_DRIVER_VERSION "\n");
 
-	for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
+	for (i = 0; i < MAX_IPMI_INTERFACES; i++)
 		ipmi_interfaces[i] = NULL;
-	}
 
 #ifdef CONFIG_PROC_FS
 	proc_ipmi_root = proc_mkdir("ipmi", NULL);
@@ -3258,3 +3299,4 @@
 EXPORT_SYMBOL(ipmi_smi_add_proc_entry);
 EXPORT_SYMBOL(proc_ipmi_root);
 EXPORT_SYMBOL(ipmi_user_set_run_to_completion);
+EXPORT_SYMBOL(ipmi_free_recv_msg);
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c
index f669477..e053ead 100644
--- a/drivers/char/ipmi/ipmi_poweroff.c
+++ b/drivers/char/ipmi/ipmi_poweroff.c
@@ -56,7 +56,7 @@
 
 /* parameter definition to allow user to flag power cycle */
 module_param(poweroff_powercycle, int, 0644);
-MODULE_PARM_DESC(poweroff_powercycles, " Set to non-zero to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down.");
+MODULE_PARM_DESC(poweroff_powercycle, " Set to non-zero to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down.");
 
 /* Stuff from the get device id command. */
 static unsigned int mfg_id;
@@ -611,9 +611,7 @@
 	}
 #endif
 
-#ifdef CONFIG_PROC_FS
 	rv = ipmi_smi_watcher_register(&smi_watcher);
-#endif
 	if (rv) {
 		unregister_sysctl_table(ipmi_table_header);
 		printk(KERN_ERR PFX "Unable to register SMI watcher: %d\n", rv);
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index b6e5cbf..ea89dca 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -51,6 +51,8 @@
 #include <linux/list.h>
 #include <linux/pci.h>
 #include <linux/ioport.h>
+#include <linux/notifier.h>
+#include <linux/kthread.h>
 #include <asm/irq.h>
 #ifdef CONFIG_HIGH_RES_TIMERS
 #include <linux/hrtime.h>
@@ -125,6 +127,7 @@
 
 struct smi_info
 {
+	int                    intf_num;
 	ipmi_smi_t             intf;
 	struct si_sm_data      *si_sm;
 	struct si_sm_handlers  *handlers;
@@ -192,8 +195,7 @@
 	unsigned long       last_timeout_jiffies;
 
 	/* Used to gracefully stop the timer without race conditions. */
-	volatile int        stop_operation;
-	volatile int        timer_stopped;
+	atomic_t            stop_operation;
 
 	/* The driver will disable interrupts when it gets into a
 	   situation where it cannot handle messages due to lack of
@@ -220,8 +222,16 @@
 	unsigned long events;
 	unsigned long watchdog_pretimeouts;
 	unsigned long incoming_messages;
+
+        struct task_struct *thread;
 };
 
+static struct notifier_block *xaction_notifier_list;
+static int register_xaction_notifier(struct notifier_block * nb)
+{
+	return notifier_chain_register(&xaction_notifier_list, nb);
+}
+
 static void si_restart_short_timer(struct smi_info *smi_info);
 
 static void deliver_recv_msg(struct smi_info *smi_info,
@@ -281,6 +291,11 @@
 		do_gettimeofday(&t);
 		printk("**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec);
 #endif
+		err = notifier_call_chain(&xaction_notifier_list, 0, smi_info);
+		if (err & NOTIFY_STOP_MASK) {
+			rv = SI_SM_CALL_WITHOUT_DELAY;
+			goto out;
+		}
 		err = smi_info->handlers->start_transaction(
 			smi_info->si_sm,
 			smi_info->curr_msg->data,
@@ -291,6 +306,7 @@
 
 		rv = SI_SM_CALL_WITHOUT_DELAY;
 	}
+	out:
 	spin_unlock(&(smi_info->msg_lock));
 
 	return rv;
@@ -766,6 +782,29 @@
 	spin_unlock_irqrestore(&(smi_info->si_lock), flags);
 }
 
+static int ipmi_thread(void *data)
+{
+	struct smi_info *smi_info = data;
+	unsigned long flags;
+	enum si_sm_result smi_result;
+
+	set_user_nice(current, 19);
+	while (!kthread_should_stop()) {
+		spin_lock_irqsave(&(smi_info->si_lock), flags);
+		smi_result=smi_event_handler(smi_info, 0);
+		spin_unlock_irqrestore(&(smi_info->si_lock), flags);
+		if (smi_result == SI_SM_CALL_WITHOUT_DELAY) {
+			/* do nothing */
+		}
+		else if (smi_result == SI_SM_CALL_WITH_DELAY)
+			udelay(1);
+		else
+			schedule_timeout_interruptible(1);
+	}
+	return 0;
+}
+
+
 static void poll(void *send_info)
 {
 	struct smi_info *smi_info = send_info;
@@ -819,15 +858,13 @@
 	enum si_sm_result smi_result;
 	unsigned long     flags;
 	unsigned long     jiffies_now;
-	unsigned long     time_diff;
+	long              time_diff;
 #ifdef DEBUG_TIMING
 	struct timeval    t;
 #endif
 
-	if (smi_info->stop_operation) {
-		smi_info->timer_stopped = 1;
+	if (atomic_read(&smi_info->stop_operation))
 		return;
-	}
 
 	spin_lock_irqsave(&(smi_info->si_lock), flags);
 #ifdef DEBUG_TIMING
@@ -835,7 +872,7 @@
 	printk("**Timer: %d.%9.9d\n", t.tv_sec, t.tv_usec);
 #endif
 	jiffies_now = jiffies;
-	time_diff = ((jiffies_now - smi_info->last_timeout_jiffies)
+	time_diff = (((long)jiffies_now - (long)smi_info->last_timeout_jiffies)
 		     * SI_USEC_PER_JIFFY);
 	smi_result = smi_event_handler(smi_info, time_diff);
 
@@ -900,7 +937,7 @@
 	smi_info->interrupts++;
 	spin_unlock(&smi_info->count_lock);
 
-	if (smi_info->stop_operation)
+	if (atomic_read(&smi_info->stop_operation))
 		goto out;
 
 #ifdef DEBUG_TIMING
@@ -1419,7 +1456,7 @@
 	smi_info->interrupts++;
 	spin_unlock(&smi_info->count_lock);
 
-	if (smi_info->stop_operation)
+	if (atomic_read(&smi_info->stop_operation))
 		goto out;
 
 #ifdef DEBUG_TIMING
@@ -1919,7 +1956,8 @@
 	smi_result = smi_info->handlers->event(smi_info->si_sm, 0);
 	for (;;)
 	{
-		if (smi_result == SI_SM_CALL_WITH_DELAY) {
+		if (smi_result == SI_SM_CALL_WITH_DELAY ||
+		    smi_result == SI_SM_CALL_WITH_TICK_DELAY) {
 			schedule_timeout_uninterruptible(1);
 			smi_result = smi_info->handlers->event(
 				smi_info->si_sm, 100);
@@ -2052,6 +2090,9 @@
  * IPMI Version = 0x51             IPMI 1.5
  * Manufacturer ID = A2 02 00      Dell IANA
  *
+ * Additionally, PowerEdge systems with IPMI < 1.5 may also assert
+ * OEM0_DATA_AVAIL and needs to be treated as RECEIVE_MSG_AVAIL.
+ *
  */
 #define DELL_POWEREDGE_8G_BMC_DEVICE_ID  0x20
 #define DELL_POWEREDGE_8G_BMC_DEVICE_REV 0x80
@@ -2061,16 +2102,87 @@
 {
 	struct ipmi_device_id *id = &smi_info->device_id;
 	const char mfr[3]=DELL_IANA_MFR_ID;
-	if (! memcmp(mfr, id->manufacturer_id, sizeof(mfr))
-	    && (id->device_id       == DELL_POWEREDGE_8G_BMC_DEVICE_ID)
-	    && (id->device_revision == DELL_POWEREDGE_8G_BMC_DEVICE_REV)
-	    && (id->ipmi_version    == DELL_POWEREDGE_8G_BMC_IPMI_VERSION))
-	{
-		smi_info->oem_data_avail_handler =
-			oem_data_avail_to_receive_msg_avail;
+	if (! memcmp(mfr, id->manufacturer_id, sizeof(mfr))) {
+		if (id->device_id       == DELL_POWEREDGE_8G_BMC_DEVICE_ID  &&
+		    id->device_revision == DELL_POWEREDGE_8G_BMC_DEVICE_REV &&
+		    id->ipmi_version    == DELL_POWEREDGE_8G_BMC_IPMI_VERSION) {
+			smi_info->oem_data_avail_handler =
+				oem_data_avail_to_receive_msg_avail;
+		}
+		else if (ipmi_version_major(id) < 1 ||
+			 (ipmi_version_major(id) == 1 &&
+			  ipmi_version_minor(id) < 5)) {
+			smi_info->oem_data_avail_handler =
+				oem_data_avail_to_receive_msg_avail;
+		}
 	}
 }
 
+#define CANNOT_RETURN_REQUESTED_LENGTH 0xCA
+static void return_hosed_msg_badsize(struct smi_info *smi_info)
+{
+	struct ipmi_smi_msg *msg = smi_info->curr_msg;
+
+	/* Make it a reponse */
+	msg->rsp[0] = msg->data[0] | 4;
+	msg->rsp[1] = msg->data[1];
+	msg->rsp[2] = CANNOT_RETURN_REQUESTED_LENGTH;
+	msg->rsp_size = 3;
+	smi_info->curr_msg = NULL;
+	deliver_recv_msg(smi_info, msg);
+}
+
+/*
+ * dell_poweredge_bt_xaction_handler
+ * @info - smi_info.device_id must be populated
+ *
+ * Dell PowerEdge servers with the BT interface (x6xx and 1750) will
+ * not respond to a Get SDR command if the length of the data
+ * requested is exactly 0x3A, which leads to command timeouts and no
+ * data returned.  This intercepts such commands, and causes userspace
+ * callers to try again with a different-sized buffer, which succeeds.
+ */
+
+#define STORAGE_NETFN 0x0A
+#define STORAGE_CMD_GET_SDR 0x23
+static int dell_poweredge_bt_xaction_handler(struct notifier_block *self,
+					     unsigned long unused,
+					     void *in)
+{
+	struct smi_info *smi_info = in;
+	unsigned char *data = smi_info->curr_msg->data;
+	unsigned int size   = smi_info->curr_msg->data_size;
+	if (size >= 8 &&
+	    (data[0]>>2) == STORAGE_NETFN &&
+	    data[1] == STORAGE_CMD_GET_SDR &&
+	    data[7] == 0x3A) {
+		return_hosed_msg_badsize(smi_info);
+		return NOTIFY_STOP;
+	}
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block dell_poweredge_bt_xaction_notifier = {
+	.notifier_call	= dell_poweredge_bt_xaction_handler,
+};
+
+/*
+ * setup_dell_poweredge_bt_xaction_handler
+ * @info - smi_info.device_id must be filled in already
+ *
+ * Fills in smi_info.device_id.start_transaction_pre_hook
+ * when we know what function to use there.
+ */
+static void
+setup_dell_poweredge_bt_xaction_handler(struct smi_info *smi_info)
+{
+	struct ipmi_device_id *id = &smi_info->device_id;
+	const char mfr[3]=DELL_IANA_MFR_ID;
+ 	if (! memcmp(mfr, id->manufacturer_id, sizeof(mfr)) &&
+	    smi_info->si_type == SI_BT)
+		register_xaction_notifier(&dell_poweredge_bt_xaction_notifier);
+}
+
 /*
  * setup_oem_data_handler
  * @info - smi_info.device_id must be filled in already
@@ -2084,6 +2196,18 @@
 	setup_dell_poweredge_oem_data_handler(smi_info);
 }
 
+static void setup_xaction_handlers(struct smi_info *smi_info)
+{
+	setup_dell_poweredge_bt_xaction_handler(smi_info);
+}
+
+static inline void wait_for_timer_and_thread(struct smi_info *smi_info)
+{
+	if (smi_info->thread != ERR_PTR(-ENOMEM))
+		kthread_stop(smi_info->thread);
+	del_timer_sync(&smi_info->si_timer);
+}
+
 /* Returns 0 if initialized, or negative on an error. */
 static int init_one_smi(int intf_num, struct smi_info **smi)
 {
@@ -2179,6 +2303,7 @@
 		goto out_err;
 
 	setup_oem_data_handler(new_smi);
+	setup_xaction_handlers(new_smi);
 
 	/* Try to claim any interrupts. */
 	new_smi->irq_setup(new_smi);
@@ -2190,8 +2315,8 @@
 	new_smi->run_to_completion = 0;
 
 	new_smi->interrupt_disabled = 0;
-	new_smi->timer_stopped = 0;
-	new_smi->stop_operation = 0;
+	atomic_set(&new_smi->stop_operation, 0);
+	new_smi->intf_num = intf_num;
 
 	/* Start clearing the flags before we enable interrupts or the
 	   timer to avoid racing with the timer. */
@@ -2209,7 +2334,11 @@
 	new_smi->si_timer.function = smi_timeout;
 	new_smi->last_timeout_jiffies = jiffies;
 	new_smi->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
+
 	add_timer(&(new_smi->si_timer));
+ 	if (new_smi->si_type != SI_BT)
+		new_smi->thread = kthread_run(ipmi_thread, new_smi,
+					      "kipmi%d", new_smi->intf_num);
 
 	rv = ipmi_register_smi(&handlers,
 			       new_smi,
@@ -2251,12 +2380,8 @@
 	return 0;
 
  out_err_stop_timer:
-	new_smi->stop_operation = 1;
-
-	/* Wait for the timer to stop.  This avoids problems with race
-	   conditions removing the timer here. */
-	while (!new_smi->timer_stopped)
-		schedule_timeout_uninterruptible(1);
+	atomic_inc(&new_smi->stop_operation);
+	wait_for_timer_and_thread(new_smi);
 
  out_err:
 	if (new_smi->intf)
@@ -2362,8 +2487,7 @@
 	spin_lock_irqsave(&(to_clean->si_lock), flags);
 	spin_lock(&(to_clean->msg_lock));
 
-	to_clean->stop_operation = 1;
-
+	atomic_inc(&to_clean->stop_operation);
 	to_clean->irq_cleanup(to_clean);
 
 	spin_unlock(&(to_clean->msg_lock));
@@ -2374,10 +2498,7 @@
 	   interrupt. */
 	synchronize_sched();
 
-	/* Wait for the timer to stop.  This avoids problems with race
-	   conditions removing the timer here. */
-	while (!to_clean->timer_stopped)
-		schedule_timeout_uninterruptible(1);
+	wait_for_timer_and_thread(to_clean);
 
 	/* Interrupts and timeouts are stopped, now make sure the
 	   interface is in a clean state. */
diff --git a/drivers/char/ipmi/ipmi_si_sm.h b/drivers/char/ipmi/ipmi_si_sm.h
index 62791dd..bf3d496 100644
--- a/drivers/char/ipmi/ipmi_si_sm.h
+++ b/drivers/char/ipmi/ipmi_si_sm.h
@@ -62,6 +62,7 @@
 {
 	SI_SM_CALL_WITHOUT_DELAY, /* Call the driver again immediately */
 	SI_SM_CALL_WITH_DELAY,	/* Delay some before calling again. */
+	SI_SM_CALL_WITH_TICK_DELAY,	/* Delay at least 1 tick before calling again. */
 	SI_SM_TRANSACTION_COMPLETE, /* A transaction is finished. */
 	SI_SM_IDLE,		/* The SM is in idle state. */
 	SI_SM_HOSED,		/* The hardware violated the state machine. */
diff --git a/drivers/char/ipmi/ipmi_smic_sm.c b/drivers/char/ipmi/ipmi_smic_sm.c
index add2aa2..39d7e5e 100644
--- a/drivers/char/ipmi/ipmi_smic_sm.c
+++ b/drivers/char/ipmi/ipmi_smic_sm.c
@@ -43,6 +43,8 @@
 
 #include <linux/kernel.h> /* For printk. */
 #include <linux/string.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/ipmi_msgdefs.h>		/* for completion codes */
 #include "ipmi_si_sm.h"
 
@@ -56,6 +58,8 @@
 #define	SMIC_DEBUG_ENABLE	1
 
 static int smic_debug = 1;
+module_param(smic_debug, int, 0644);
+MODULE_PARM_DESC(smic_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
 
 enum smic_states {
 	SMIC_IDLE,
@@ -76,11 +80,17 @@
 #define SMIC_MAX_ERROR_RETRIES 3
 
 /* Timeouts in microseconds. */
-#define SMIC_RETRY_TIMEOUT 100000
+#define SMIC_RETRY_TIMEOUT 2000000
 
 /* SMIC Flags Register Bits */
 #define SMIC_RX_DATA_READY	0x80
 #define SMIC_TX_DATA_READY	0x40
+/*
+ * SMIC_SMI and SMIC_EVM_DATA_AVAIL are only used by
+ * a few systems, and then only by Systems Management
+ * Interrupts, not by the OS.  Always ignore these bits.
+ *
+ */
 #define SMIC_SMI		0x10
 #define SMIC_EVM_DATA_AVAIL	0x08
 #define SMIC_SMS_DATA_AVAIL	0x04
@@ -364,8 +374,7 @@
 	switch (smic->state) {
 	case SMIC_IDLE:
 		/* in IDLE we check for available messages */
-		if (flags & (SMIC_SMI |
-			     SMIC_EVM_DATA_AVAIL | SMIC_SMS_DATA_AVAIL))
+		if (flags & SMIC_SMS_DATA_AVAIL)
 		{
 			return SI_SM_ATTN;
 		}
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 2da64bf..1f3159e 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -47,6 +47,9 @@
 #include <linux/reboot.h>
 #include <linux/wait.h>
 #include <linux/poll.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <asm/atomic.h>
 #ifdef CONFIG_X86_LOCAL_APIC
 #include <asm/apic.h>
 #endif
@@ -158,27 +161,120 @@
 static char pretimeout_since_last_heartbeat = 0;
 static char expect_close;
 
+static DECLARE_RWSEM(register_sem);
+
+/* Parameters to ipmi_set_timeout */
+#define IPMI_SET_TIMEOUT_NO_HB			0
+#define IPMI_SET_TIMEOUT_HB_IF_NECESSARY	1
+#define IPMI_SET_TIMEOUT_FORCE_HB		2
+
+static int ipmi_set_timeout(int do_heartbeat);
+
 /* If true, the driver will start running as soon as it is configured
    and ready. */
 static int start_now = 0;
 
-module_param(timeout, int, 0);
+static int set_param_int(const char *val, struct kernel_param *kp)
+{
+	char *endp;
+	int  l;
+	int  rv = 0;
+
+	if (!val)
+		return -EINVAL;
+	l = simple_strtoul(val, &endp, 0);
+	if (endp == val)
+		return -EINVAL;
+
+	down_read(&register_sem);
+	*((int *)kp->arg) = l;
+	if (watchdog_user)
+		rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
+	up_read(&register_sem);
+
+	return rv;
+}
+
+static int get_param_int(char *buffer, struct kernel_param *kp)
+{
+	return sprintf(buffer, "%i", *((int *)kp->arg));
+}
+
+typedef int (*action_fn)(const char *intval, char *outval);
+
+static int action_op(const char *inval, char *outval);
+static int preaction_op(const char *inval, char *outval);
+static int preop_op(const char *inval, char *outval);
+static void check_parms(void);
+
+static int set_param_str(const char *val, struct kernel_param *kp)
+{
+	action_fn  fn = (action_fn) kp->arg;
+	int        rv = 0;
+	const char *end;
+	char       valcp[16];
+	int        len;
+
+	/* Truncate leading and trailing spaces. */
+	while (isspace(*val))
+		val++;
+	end = val + strlen(val) - 1;
+	while ((end >= val) && isspace(*end))
+		end--;
+	len = end - val + 1;
+	if (len > sizeof(valcp) - 1)
+		return -EINVAL;
+	memcpy(valcp, val, len);
+	valcp[len] = '\0';
+
+	down_read(&register_sem);
+	rv = fn(valcp, NULL);
+	if (rv)
+		goto out_unlock;
+
+	check_parms();
+	if (watchdog_user)
+		rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
+
+ out_unlock:
+	up_read(&register_sem);
+	return rv;
+}
+
+static int get_param_str(char *buffer, struct kernel_param *kp)
+{
+	action_fn fn = (action_fn) kp->arg;
+	int       rv;
+
+	rv = fn(NULL, buffer);
+	if (rv)
+		return rv;
+	return strlen(buffer);
+}
+
+module_param_call(timeout, set_param_int, get_param_int, &timeout, 0644);
 MODULE_PARM_DESC(timeout, "Timeout value in seconds.");
-module_param(pretimeout, int, 0);
+
+module_param_call(pretimeout, set_param_int, get_param_int, &pretimeout, 0644);
 MODULE_PARM_DESC(pretimeout, "Pretimeout value in seconds.");
-module_param_string(action, action, sizeof(action), 0);
+
+module_param_call(action, set_param_str, get_param_str, action_op, 0644);
 MODULE_PARM_DESC(action, "Timeout action. One of: "
 		 "reset, none, power_cycle, power_off.");
-module_param_string(preaction, preaction, sizeof(preaction), 0);
+
+module_param_call(preaction, set_param_str, get_param_str, preaction_op, 0644);
 MODULE_PARM_DESC(preaction, "Pretimeout action.  One of: "
 		 "pre_none, pre_smi, pre_nmi, pre_int.");
-module_param_string(preop, preop, sizeof(preop), 0);
+
+module_param_call(preop, set_param_str, get_param_str, preop_op, 0644);
 MODULE_PARM_DESC(preop, "Pretimeout driver operation.  One of: "
 		 "preop_none, preop_panic, preop_give_data.");
+
 module_param(start_now, int, 0);
 MODULE_PARM_DESC(start_now, "Set to 1 to start the watchdog as"
 		 "soon as the driver is loaded.");
-module_param(nowayout, int, 0);
+
+module_param(nowayout, int, 0644);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
 /* Default state of the timer. */
@@ -200,6 +296,8 @@
 static unsigned char ipmi_version_major;
 static unsigned char ipmi_version_minor;
 
+/* If a pretimeout occurs, this is used to allow only one panic to happen. */
+static atomic_t preop_panic_excl = ATOMIC_INIT(-1);
 
 static int ipmi_heartbeat(void);
 static void panic_halt_ipmi_heartbeat(void);
@@ -294,11 +392,6 @@
 	return rv;
 }
 
-/* Parameters to ipmi_set_timeout */
-#define IPMI_SET_TIMEOUT_NO_HB			0
-#define IPMI_SET_TIMEOUT_HB_IF_NECESSARY	1
-#define IPMI_SET_TIMEOUT_FORCE_HB		2
-
 static int ipmi_set_timeout(int do_heartbeat)
 {
 	int send_heartbeat_now;
@@ -732,8 +825,6 @@
 	.fops		= &ipmi_wdog_fops
 };
 
-static DECLARE_RWSEM(register_sem);
-
 static void ipmi_wdog_msg_handler(struct ipmi_recv_msg *msg,
 				  void                 *handler_data)
 {
@@ -749,9 +840,10 @@
 static void ipmi_wdog_pretimeout_handler(void *handler_data)
 {
 	if (preaction_val != WDOG_PRETIMEOUT_NONE) {
-		if (preop_val == WDOG_PREOP_PANIC)
-			panic("Watchdog pre-timeout");
-		else if (preop_val == WDOG_PREOP_GIVE_DATA) {
+		if (preop_val == WDOG_PREOP_PANIC) {
+			if (atomic_inc_and_test(&preop_panic_excl))
+				panic("Watchdog pre-timeout");
+		} else if (preop_val == WDOG_PREOP_GIVE_DATA) {
 			spin_lock(&ipmi_read_lock);
 			data_to_read = 1;
 			wake_up_interruptible(&read_q);
@@ -825,7 +917,8 @@
 		   an error and not work unless we re-enable
 		   the timer.   So do so. */
 		pretimeout_since_last_heartbeat = 1;
-		panic(PFX "pre-timeout");
+		if (atomic_inc_and_test(&preop_panic_excl))
+			panic(PFX "pre-timeout");
 	}
 
 	return NOTIFY_DONE;
@@ -839,6 +932,7 @@
 	.handler  = ipmi_nmi,
 	.priority = 0, /* Call us last. */
 };
+int nmi_handler_registered;
 #endif
 
 static int wdog_reboot_handler(struct notifier_block *this,
@@ -921,59 +1015,86 @@
 	.smi_gone = ipmi_smi_gone
 };
 
-static int __init ipmi_wdog_init(void)
+static int action_op(const char *inval, char *outval)
 {
-	int rv;
+	if (outval)
+		strcpy(outval, action);
 
-	if (strcmp(action, "reset") == 0) {
+	if (!inval)
+		return 0;
+
+	if (strcmp(inval, "reset") == 0)
 		action_val = WDOG_TIMEOUT_RESET;
-	} else if (strcmp(action, "none") == 0) {
+	else if (strcmp(inval, "none") == 0)
 		action_val = WDOG_TIMEOUT_NONE;
-	} else if (strcmp(action, "power_cycle") == 0) {
+	else if (strcmp(inval, "power_cycle") == 0)
 		action_val = WDOG_TIMEOUT_POWER_CYCLE;
-	} else if (strcmp(action, "power_off") == 0) {
+	else if (strcmp(inval, "power_off") == 0)
 		action_val = WDOG_TIMEOUT_POWER_DOWN;
-	} else {
-		action_val = WDOG_TIMEOUT_RESET;
-		printk(KERN_INFO PFX "Unknown action '%s', defaulting to"
-		       " reset\n", action);
-	}
+	else
+		return -EINVAL;
+	strcpy(action, inval);
+	return 0;
+}
 
-	if (strcmp(preaction, "pre_none") == 0) {
+static int preaction_op(const char *inval, char *outval)
+{
+	if (outval)
+		strcpy(outval, preaction);
+
+	if (!inval)
+		return 0;
+
+	if (strcmp(inval, "pre_none") == 0)
 		preaction_val = WDOG_PRETIMEOUT_NONE;
-	} else if (strcmp(preaction, "pre_smi") == 0) {
+	else if (strcmp(inval, "pre_smi") == 0)
 		preaction_val = WDOG_PRETIMEOUT_SMI;
 #ifdef HAVE_NMI_HANDLER
-	} else if (strcmp(preaction, "pre_nmi") == 0) {
+	else if (strcmp(inval, "pre_nmi") == 0)
 		preaction_val = WDOG_PRETIMEOUT_NMI;
 #endif
-	} else if (strcmp(preaction, "pre_int") == 0) {
+	else if (strcmp(inval, "pre_int") == 0)
 		preaction_val = WDOG_PRETIMEOUT_MSG_INT;
-	} else {
-		preaction_val = WDOG_PRETIMEOUT_NONE;
-		printk(KERN_INFO PFX "Unknown preaction '%s', defaulting to"
-		       " none\n", preaction);
-	}
+	else
+		return -EINVAL;
+	strcpy(preaction, inval);
+	return 0;
+}
 
-	if (strcmp(preop, "preop_none") == 0) {
+static int preop_op(const char *inval, char *outval)
+{
+	if (outval)
+		strcpy(outval, preop);
+
+	if (!inval)
+		return 0;
+
+	if (strcmp(inval, "preop_none") == 0)
 		preop_val = WDOG_PREOP_NONE;
-	} else if (strcmp(preop, "preop_panic") == 0) {
+	else if (strcmp(inval, "preop_panic") == 0)
 		preop_val = WDOG_PREOP_PANIC;
-	} else if (strcmp(preop, "preop_give_data") == 0) {
+	else if (strcmp(inval, "preop_give_data") == 0)
 		preop_val = WDOG_PREOP_GIVE_DATA;
-	} else {
-		preop_val = WDOG_PREOP_NONE;
-		printk(KERN_INFO PFX "Unknown preop '%s', defaulting to"
-		       " none\n", preop);
-	}
+	else
+		return -EINVAL;
+	strcpy(preop, inval);
+	return 0;
+}
 
+static void check_parms(void)
+{
 #ifdef HAVE_NMI_HANDLER
+	int do_nmi = 0;
+	int rv;
+
 	if (preaction_val == WDOG_PRETIMEOUT_NMI) {
+		do_nmi = 1;
 		if (preop_val == WDOG_PREOP_GIVE_DATA) {
 			printk(KERN_WARNING PFX "Pretimeout op is to give data"
 			       " but NMI pretimeout is enabled, setting"
 			       " pretimeout op to none\n");
-			preop_val = WDOG_PREOP_NONE;
+			preop_op("preop_none", NULL);
+			do_nmi = 0;
 		}
 #ifdef CONFIG_X86_LOCAL_APIC
 		if (nmi_watchdog == NMI_IO_APIC) {
@@ -983,18 +1104,48 @@
 			       " Disabling IPMI nmi pretimeout.\n",
 			       nmi_watchdog);
 			preaction_val = WDOG_PRETIMEOUT_NONE;
-		} else {
-#endif
-		rv = request_nmi(&ipmi_nmi_handler);
-		if (rv) {
-			printk(KERN_WARNING PFX "Can't register nmi handler\n");
-			return rv;
-		}
-#ifdef CONFIG_X86_LOCAL_APIC
+			do_nmi = 0;
 		}
 #endif
 	}
+	if (do_nmi && !nmi_handler_registered) {
+		rv = request_nmi(&ipmi_nmi_handler);
+		if (rv) {
+			printk(KERN_WARNING PFX
+			       "Can't register nmi handler\n");
+			return;
+		} else
+			nmi_handler_registered = 1;
+	} else if (!do_nmi && nmi_handler_registered) {
+		release_nmi(&ipmi_nmi_handler);
+		nmi_handler_registered = 0;
+	}
 #endif
+}
+
+static int __init ipmi_wdog_init(void)
+{
+	int rv;
+
+	if (action_op(action, NULL)) {
+		action_op("reset", NULL);
+		printk(KERN_INFO PFX "Unknown action '%s', defaulting to"
+		       " reset\n", action);
+	}
+
+	if (preaction_op(preaction, NULL)) {
+		preaction_op("pre_none", NULL);
+		printk(KERN_INFO PFX "Unknown preaction '%s', defaulting to"
+		       " none\n", preaction);
+	}
+
+	if (preop_op(preop, NULL)) {
+		preop_op("preop_none", NULL);
+		printk(KERN_INFO PFX "Unknown preop '%s', defaulting to"
+		       " none\n", preop);
+	}
+
+	check_parms();
 
 	rv = ipmi_smi_watcher_register(&smi_watcher);
 	if (rv) {
@@ -1021,7 +1172,7 @@
 	down_write(&register_sem);
 
 #ifdef HAVE_NMI_HANDLER
-	if (preaction_val == WDOG_PRETIMEOUT_NMI)
+	if (nmi_handler_registered)
 		release_nmi(&ipmi_nmi_handler);
 #endif
 
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index e3ddbdb..ce3bc0d 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -860,10 +860,9 @@
 	if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
 		printk("STALLION: failed to un-register serial memory device, "
 			"errno=%d\n", -i);
-	if (stli_tmpwritebuf != (char *) NULL)
-		kfree(stli_tmpwritebuf);
-	if (stli_txcookbuf != (char *) NULL)
-		kfree(stli_txcookbuf);
+
+	kfree(stli_tmpwritebuf);
+	kfree(stli_txcookbuf);
 
 	for (i = 0; (i < stli_nrbrds); i++) {
 		if ((brdp = stli_brds[i]) == (stlibrd_t *) NULL)
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 45d012d..3b965a6 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -470,6 +470,8 @@
 	.stop = mxser_stop,
 	.start = mxser_start,
 	.hangup = mxser_hangup,
+	.break_ctl = mxser_rs_break,
+	.wait_until_sent = mxser_wait_until_sent,
 	.tiocmget = mxser_tiocmget,
 	.tiocmset = mxser_tiocmset,
 };
@@ -492,14 +494,18 @@
 
 static void __exit mxser_module_exit(void)
 {
-	int i, err = 0;
+	int i, err;
 
 	if (verbose)
 		printk(KERN_DEBUG "Unloading module mxser ...\n");
 
-	if ((err |= tty_unregister_driver(mxvar_sdriver)))
+	err = tty_unregister_driver(mxvar_sdriver);
+	if (!err)
+		put_tty_driver(mxvar_sdriver);
+	else
 		printk(KERN_ERR "Couldn't unregister MOXA Smartio/Industio family serial driver\n");
 
+
 	for (i = 0; i < MXSER_BOARDS; i++) {
 		struct pci_dev *pdev;
 
@@ -688,7 +694,6 @@
 static int mxser_init(void)
 {
 	int i, m, retval, b, n;
-	int ret1;
 	struct pci_dev *pdev = NULL;
 	int index;
 	unsigned char busnum, devnum;
@@ -722,24 +727,6 @@
 	mxvar_sdriver->termios = mxvar_termios;
 	mxvar_sdriver->termios_locked = mxvar_termios_locked;
 
-	mxvar_sdriver->open = mxser_open;
-	mxvar_sdriver->close = mxser_close;
-	mxvar_sdriver->write = mxser_write;
-	mxvar_sdriver->put_char = mxser_put_char;
-	mxvar_sdriver->flush_chars = mxser_flush_chars;
-	mxvar_sdriver->write_room = mxser_write_room;
-	mxvar_sdriver->chars_in_buffer = mxser_chars_in_buffer;
-	mxvar_sdriver->flush_buffer = mxser_flush_buffer;
-	mxvar_sdriver->ioctl = mxser_ioctl;
-	mxvar_sdriver->throttle = mxser_throttle;
-	mxvar_sdriver->unthrottle = mxser_unthrottle;
-	mxvar_sdriver->set_termios = mxser_set_termios;
-	mxvar_sdriver->stop = mxser_stop;
-	mxvar_sdriver->start = mxser_start;
-	mxvar_sdriver->hangup = mxser_hangup;
-	mxvar_sdriver->break_ctl = mxser_rs_break;
-	mxvar_sdriver->wait_until_sent = mxser_wait_until_sent;
-
 	mxvar_diagflag = 0;
 	memset(mxvar_table, 0, MXSER_PORTS * sizeof(struct mxser_struct));
 	memset(&mxvar_log, 0, sizeof(struct mxser_log));
@@ -870,14 +857,11 @@
 	}
 #endif
 
-	ret1 = 0;
-	if (!(ret1 = tty_register_driver(mxvar_sdriver))) {
-		return 0;
-	} else
+	retval = tty_register_driver(mxvar_sdriver);
+	if (retval) {
 		printk(KERN_ERR "Couldn't install MOXA Smartio/Industio family driver !\n");
+		put_tty_driver(mxvar_sdriver);
 
-
-	if (ret1) {
 		for (i = 0; i < MXSER_BOARDS; i++) {
 			if (mxsercfg[i].board_type == -1)
 				continue;
@@ -886,10 +870,10 @@
 				//todo: release io, vector
 			}
 		}
-		return -1;
+		return retval;
 	}
 
-	return (0);
+	return 0;
 }
 
 static void mxser_do_softint(void *private_)
@@ -933,6 +917,9 @@
 	struct mxser_struct *info;
 	int retval, line;
 
+	/* initialize driver_data in case something fails */
+	tty->driver_data = NULL;
+
 	line = tty->index;
 	if (line == MXSER_PORTS)
 		return 0;
@@ -995,7 +982,7 @@
 	if (tty->index == MXSER_PORTS)
 		return;
 	if (!info)
-		BUG();
+		return;
 
 	spin_lock_irqsave(&info->slock, flags);
 
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
index 5079beda..c3660d8 100644
--- a/drivers/char/n_hdlc.c
+++ b/drivers/char/n_hdlc.c
@@ -264,8 +264,7 @@
 		} else
 			break;
 	}
-	if (n_hdlc->tbuf)
-		kfree(n_hdlc->tbuf);
+	kfree(n_hdlc->tbuf);
 	kfree(n_hdlc);
 	
 }	/* end of n_hdlc_release() */
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 02d7f04..2c326ea 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -2994,8 +2994,7 @@
 
 void rx_free_buffers(MGSLPC_INFO *info)
 {
-	if (info->rx_buf)
-		kfree(info->rx_buf);
+	kfree(info->rx_buf);
 	info->rx_buf = NULL;
 }
 
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 928b850..d3bc731 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -2512,10 +2512,8 @@
 		       "rocketport driver\n", -retval);
 	put_tty_driver(rocket_driver);
 
-	for (i = 0; i < MAX_RP_PORTS; i++) {
-		if (rp_table[i])
-			kfree(rp_table[i]);
-	}
+	for (i = 0; i < MAX_RP_PORTS; i++)
+		kfree(rp_table[i]);
 
 	for (i = 0; i < NUM_BOARDS; i++) {
 		if (rcktpt_io_addr[i] <= 0 || is_PCI[i])
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index 63fff7c..a7f099f 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -149,8 +149,22 @@
 #ifdef RTC_IRQ
 static void rtc_dropped_irq(unsigned long data);
 
-static void set_rtc_irq_bit(unsigned char bit);
-static void mask_rtc_irq_bit(unsigned char bit);
+static void set_rtc_irq_bit_locked(unsigned char bit);
+static void mask_rtc_irq_bit_locked(unsigned char bit);
+
+static inline void set_rtc_irq_bit(unsigned char bit)
+{
+	spin_lock_irq(&rtc_lock);
+	set_rtc_irq_bit_locked(bit);
+	spin_unlock_irq(&rtc_lock);
+}
+
+static void mask_rtc_irq_bit(unsigned char bit)
+{
+	spin_lock_irq(&rtc_lock);
+	mask_rtc_irq_bit_locked(bit);
+	spin_unlock_irq(&rtc_lock);
+}
 #endif
 
 static int rtc_proc_open(struct inode *inode, struct file *file);
@@ -401,18 +415,19 @@
 	}
 	case RTC_PIE_OFF:	/* Mask periodic int. enab. bit	*/
 	{
-		mask_rtc_irq_bit(RTC_PIE);
+		unsigned long flags; /* can be called from isr via rtc_control() */
+		spin_lock_irqsave (&rtc_lock, flags);
+		mask_rtc_irq_bit_locked(RTC_PIE);
 		if (rtc_status & RTC_TIMER_ON) {
-			spin_lock_irq (&rtc_lock);
 			rtc_status &= ~RTC_TIMER_ON;
 			del_timer(&rtc_irq_timer);
-			spin_unlock_irq (&rtc_lock);
 		}
+		spin_unlock_irqrestore (&rtc_lock, flags);
 		return 0;
 	}
 	case RTC_PIE_ON:	/* Allow periodic ints		*/
 	{
-
+		unsigned long flags; /* can be called from isr via rtc_control() */
 		/*
 		 * We don't really want Joe User enabling more
 		 * than 64Hz of interrupts on a multi-user machine.
@@ -421,14 +436,14 @@
 			(!capable(CAP_SYS_RESOURCE)))
 			return -EACCES;
 
+		spin_lock_irqsave (&rtc_lock, flags);
 		if (!(rtc_status & RTC_TIMER_ON)) {
-			spin_lock_irq (&rtc_lock);
 			rtc_irq_timer.expires = jiffies + HZ/rtc_freq + 2*HZ/100;
 			add_timer(&rtc_irq_timer);
 			rtc_status |= RTC_TIMER_ON;
-			spin_unlock_irq (&rtc_lock);
 		}
-		set_rtc_irq_bit(RTC_PIE);
+		set_rtc_irq_bit_locked(RTC_PIE);
+		spin_unlock_irqrestore (&rtc_lock, flags);
 		return 0;
 	}
 	case RTC_UIE_OFF:	/* Mask ints from RTC updates.	*/
@@ -609,6 +624,7 @@
 	{
 		int tmp = 0;
 		unsigned char val;
+		unsigned long flags; /* can be called from isr via rtc_control() */
 
 		/* 
 		 * The max we can do is 8192Hz.
@@ -631,9 +647,9 @@
 		if (arg != (1<<tmp))
 			return -EINVAL;
 
-		spin_lock_irq(&rtc_lock);
+		spin_lock_irqsave(&rtc_lock, flags);
 		if (hpet_set_periodic_freq(arg)) {
-			spin_unlock_irq(&rtc_lock);
+			spin_unlock_irqrestore(&rtc_lock, flags);
 			return 0;
 		}
 		rtc_freq = arg;
@@ -641,7 +657,7 @@
 		val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0;
 		val |= (16 - tmp);
 		CMOS_WRITE(val, RTC_FREQ_SELECT);
-		spin_unlock_irq(&rtc_lock);
+		spin_unlock_irqrestore(&rtc_lock, flags);
 		return 0;
 	}
 #endif
@@ -844,12 +860,15 @@
 #ifndef RTC_IRQ
 	return -EIO;
 #else
-	spin_lock_irq(&rtc_task_lock);
+	unsigned long flags;
+	if (cmd != RTC_PIE_ON && cmd != RTC_PIE_OFF && cmd != RTC_IRQP_SET)
+		return -EINVAL;
+	spin_lock_irqsave(&rtc_task_lock, flags);
 	if (rtc_callback != task) {
-		spin_unlock_irq(&rtc_task_lock);
+		spin_unlock_irqrestore(&rtc_task_lock, flags);
 		return -ENXIO;
 	}
-	spin_unlock_irq(&rtc_task_lock);
+	spin_unlock_irqrestore(&rtc_task_lock, flags);
 	return rtc_do_ioctl(cmd, arg, 1);
 #endif
 }
@@ -1306,40 +1325,32 @@
  * meddles with the interrupt enable/disable bits.
  */
 
-static void mask_rtc_irq_bit(unsigned char bit)
+static void mask_rtc_irq_bit_locked(unsigned char bit)
 {
 	unsigned char val;
 
-	spin_lock_irq(&rtc_lock);
-	if (hpet_mask_rtc_irq_bit(bit)) {
-		spin_unlock_irq(&rtc_lock);
+	if (hpet_mask_rtc_irq_bit(bit))
 		return;
-	}
 	val = CMOS_READ(RTC_CONTROL);
 	val &=  ~bit;
 	CMOS_WRITE(val, RTC_CONTROL);
 	CMOS_READ(RTC_INTR_FLAGS);
 
 	rtc_irq_data = 0;
-	spin_unlock_irq(&rtc_lock);
 }
 
-static void set_rtc_irq_bit(unsigned char bit)
+static void set_rtc_irq_bit_locked(unsigned char bit)
 {
 	unsigned char val;
 
-	spin_lock_irq(&rtc_lock);
-	if (hpet_set_rtc_irq_bit(bit)) {
-		spin_unlock_irq(&rtc_lock);
+	if (hpet_set_rtc_irq_bit(bit))
 		return;
-	}
 	val = CMOS_READ(RTC_CONTROL);
 	val |= bit;
 	CMOS_WRITE(val, RTC_CONTROL);
 	CMOS_READ(RTC_INTR_FLAGS);
 
 	rtc_irq_data = 0;
-	spin_unlock_irq(&rtc_lock);
 }
 #endif
 
diff --git a/drivers/char/selection.c b/drivers/char/selection.c
index 16d630f..5b187c8 100644
--- a/drivers/char/selection.c
+++ b/drivers/char/selection.c
@@ -246,8 +246,7 @@
 		clear_selection();
 		return -ENOMEM;
 	}
-	if (sel_buffer)
-		kfree(sel_buffer);
+	kfree(sel_buffer);
 	sel_buffer = bp;
 
 	obp = bp;
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 1c68641..95af2a9 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -785,8 +785,7 @@
 			"errno=%d\n", -i);
 	class_destroy(stallion_class);
 
-	if (stl_tmpwritebuf != (char *) NULL)
-		kfree(stl_tmpwritebuf);
+	kfree(stl_tmpwritebuf);
 
 	for (i = 0; (i < stl_nrbrds); i++) {
 		if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL)
@@ -804,8 +803,7 @@
 					continue;
 				if (portp->tty != (struct tty_struct *) NULL)
 					stl_hangup(portp->tty);
-				if (portp->tx.buf != (char *) NULL)
-					kfree(portp->tx.buf);
+				kfree(portp->tx.buf);
 				kfree(portp);
 			}
 			kfree(panelp);
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 0133dc0..5d1ffa3 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -4016,9 +4016,7 @@
  */
 static void mgsl_free_intermediate_rxbuffer_memory(struct mgsl_struct *info)
 {
-	if ( info->intermediate_rxbuffer )
-		kfree(info->intermediate_rxbuffer);
-
+	kfree(info->intermediate_rxbuffer);
 	info->intermediate_rxbuffer = NULL;
 
 }	/* end of mgsl_free_intermediate_rxbuffer_memory() */
@@ -4072,10 +4070,8 @@
 	int i;
 
 	for ( i=0; i<info->num_tx_holding_buffers; ++i ) {
-		if ( info->tx_holding_buffers[i].buffer ) {
-				kfree(info->tx_holding_buffers[i].buffer);
-				info->tx_holding_buffers[i].buffer=NULL;
-		}
+		kfree(info->tx_holding_buffers[i].buffer);
+		info->tx_holding_buffers[i].buffer = NULL;
 	}
 
 	info->get_tx_holding_index = 0;
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index f185724..7c063c5 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -2788,10 +2788,8 @@
 	del_timer(&info->tx_timer);
 	del_timer(&info->status_timer);
 
-	if (info->tx_buf) {
-		kfree(info->tx_buf);
-		info->tx_buf = NULL;
-	}
+	kfree(info->tx_buf);
+	info->tx_buf = NULL;
 
 	spin_lock_irqsave(&info->lock,flags);
 
@@ -3611,8 +3609,7 @@
 
 void free_tmp_rx_buf(SLMP_INFO *info)
 {
-	if (info->tmp_rx_buf)
-		kfree(info->tmp_rx_buf);
+	kfree(info->tmp_rx_buf);
 	info->tmp_rx_buf = NULL;
 }
 
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
index 8d125c9..680a8e3 100644
--- a/drivers/char/tpm/tpm_nsc.c
+++ b/drivers/char/tpm/tpm_nsc.c
@@ -287,10 +287,6 @@
 	int lo, hi;
 	int nscAddrBase = TPM_ADDR;
 
-	driver_register(&nsc_drv);
-
-	/* select PM channel 1 */
-	tpm_write_index(nscAddrBase,NSC_LDN_INDEX, 0x12);
 
 	/* verify that it is a National part (SID) */
 	if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
@@ -300,6 +296,8 @@
 			return -ENODEV;
 	}
 
+	driver_register(&nsc_drv);
+
 	hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
 	lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
 	tpm_nsc.base = (hi<<8) | lo;
@@ -307,11 +305,11 @@
 	/* enable the DPM module */
 	tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
 
-	pdev = kmalloc(sizeof(struct platform_device), GFP_KERNEL);
-	if ( !pdev )
-		return -ENOMEM;
-
-	memset(pdev, 0, sizeof(struct platform_device));
+	pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
+	if (!pdev) {
+		rc = -ENOMEM;
+		goto err_unreg_drv;
+	}
 
 	pdev->name = "tpm_nscl0";
 	pdev->id = -1;
@@ -319,26 +317,16 @@
 	pdev->dev.release = tpm_nsc_remove;
 	pdev->dev.driver = &nsc_drv;
 
-	if ((rc=platform_device_register(pdev)) < 0) {
-		kfree(pdev);
-		pdev = NULL;
-		return rc;
-	}
+	if ((rc = platform_device_register(pdev)) < 0)
+		goto err_free_dev;
 
 	if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) {
-		platform_device_unregister(pdev);
-		kfree(pdev);
-		pdev = NULL;
-		return -EBUSY;
+		rc = -EBUSY;
+		goto err_unreg_dev;
 	}
 
-	if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0) {
-		release_region(tpm_nsc.base, 2);
-		platform_device_unregister(pdev);
-		kfree(pdev);
-		pdev = NULL;
-		return rc;
-	}
+	if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0)
+		goto err_rel_reg;
 
 	dev_dbg(&pdev->dev, "NSC TPM detected\n");
 	dev_dbg(&pdev->dev,
@@ -374,6 +362,16 @@
 		 tpm_read_index(nscAddrBase, 0x27) & 0x1F);
 
 	return 0;
+
+err_rel_reg:
+	release_region(tpm_nsc.base, 2);
+err_unreg_dev:
+	platform_device_unregister(pdev);
+err_free_dev:
+	kfree(pdev);
+err_unreg_drv:
+	driver_unregister(&nsc_drv);
+	return rc;
 }
 
 static void __exit cleanup_nsc(void)
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index c586bfa..4b1eef5 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1416,14 +1416,11 @@
 
 	/* Release locally allocated memory ... nothing placed in slots */
 free_mem_out:
-	if (o_tp)
-		kfree(o_tp);
+	kfree(o_tp);
 	if (o_tty)
 		free_tty_struct(o_tty);
-	if (ltp)
-		kfree(ltp);
-	if (tp)
-		kfree(tp);
+	kfree(ltp);
+	kfree(tp);
 	free_tty_struct(tty);
 
 fail_no_mem:
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 003dda1..24011e7 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -80,6 +80,9 @@
 	if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
 		return -EFAULT;
 
+	if (!capable(CAP_SYS_TTY_CONFIG))
+		perm = 0;
+
 	switch (cmd) {
 	case KDGKBENT:
 		key_map = key_maps[s];
@@ -193,7 +196,7 @@
 	int ret;
 
 	if (!capable(CAP_SYS_TTY_CONFIG))
-		return -EPERM;
+		perm = 0;
 
 	kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
 	if (!kbs) {
diff --git a/drivers/connector/Kconfig b/drivers/connector/Kconfig
index 0bc2059..e0bdc0d 100644
--- a/drivers/connector/Kconfig
+++ b/drivers/connector/Kconfig
@@ -10,4 +10,12 @@
 	  Connector support can also be built as a module.  If so, the module
 	  will be called cn.ko.
 
+config PROC_EVENTS
+	boolean "Report process events to userspace"
+	depends on CONNECTOR=y
+	default y
+	---help---
+	  Provide a connector that reports process events to userspace. Send
+	  events such as fork, exec, id change (uid, gid, suid, etc), and exit.
+
 endmenu
diff --git a/drivers/connector/Makefile b/drivers/connector/Makefile
index 12ca79e..1f255e4 100644
--- a/drivers/connector/Makefile
+++ b/drivers/connector/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_CONNECTOR)		+= cn.o
+obj-$(CONFIG_PROC_EVENTS)	+= cn_proc.o
 
 cn-y				+= cn_queue.o connector.o
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
new file mode 100644
index 0000000..fcdf0ff
--- /dev/null
+++ b/drivers/connector/cn_proc.c
@@ -0,0 +1,222 @@
+/*
+ * cn_proc.c - process events connector
+ *
+ * Copyright (C) Matt Helsley, IBM Corp. 2005
+ * Based on cn_fork.c by Guillaume Thouvenin <guillaume.thouvenin@bull.net>
+ * Original copyright notice follows:
+ * Copyright (C) 2005 BULL SA.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/atomic.h>
+
+#include <linux/cn_proc.h>
+
+#define CN_PROC_MSG_SIZE (sizeof(struct cn_msg) + sizeof(struct proc_event))
+
+static atomic_t proc_event_num_listeners = ATOMIC_INIT(0);
+static struct cb_id cn_proc_event_id = { CN_IDX_PROC, CN_VAL_PROC };
+
+/* proc_counts is used as the sequence number of the netlink message */
+static DEFINE_PER_CPU(__u32, proc_event_counts) = { 0 };
+
+static inline void get_seq(__u32 *ts, int *cpu)
+{
+	*ts = get_cpu_var(proc_event_counts)++;
+	*cpu = smp_processor_id();
+	put_cpu_var(proc_counts);
+}
+
+void proc_fork_connector(struct task_struct *task)
+{
+	struct cn_msg *msg;
+	struct proc_event *ev;
+	__u8 buffer[CN_PROC_MSG_SIZE];
+
+	if (atomic_read(&proc_event_num_listeners) < 1)
+		return;
+
+	msg = (struct cn_msg*)buffer;
+	ev = (struct proc_event*)msg->data;
+	get_seq(&msg->seq, &ev->cpu);
+	ev->what = PROC_EVENT_FORK;
+	ev->event_data.fork.parent_pid = task->real_parent->pid;
+	ev->event_data.fork.parent_tgid = task->real_parent->tgid;
+	ev->event_data.fork.child_pid = task->pid;
+	ev->event_data.fork.child_tgid = task->tgid;
+
+	memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
+	msg->ack = 0; /* not used */
+	msg->len = sizeof(*ev);
+	/*  If cn_netlink_send() failed, the data is not sent */
+	cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+}
+
+void proc_exec_connector(struct task_struct *task)
+{
+	struct cn_msg *msg;
+	struct proc_event *ev;
+	__u8 buffer[CN_PROC_MSG_SIZE];
+
+	if (atomic_read(&proc_event_num_listeners) < 1)
+		return;
+
+	msg = (struct cn_msg*)buffer;
+	ev = (struct proc_event*)msg->data;
+	get_seq(&msg->seq, &ev->cpu);
+	ev->what = PROC_EVENT_EXEC;
+	ev->event_data.exec.process_pid = task->pid;
+	ev->event_data.exec.process_tgid = task->tgid;
+
+	memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
+	msg->ack = 0; /* not used */
+	msg->len = sizeof(*ev);
+	cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+}
+
+void proc_id_connector(struct task_struct *task, int which_id)
+{
+	struct cn_msg *msg;
+	struct proc_event *ev;
+	__u8 buffer[CN_PROC_MSG_SIZE];
+
+	if (atomic_read(&proc_event_num_listeners) < 1)
+		return;
+
+	msg = (struct cn_msg*)buffer;
+	ev = (struct proc_event*)msg->data;
+	ev->what = which_id;
+	ev->event_data.id.process_pid = task->pid;
+	ev->event_data.id.process_tgid = task->tgid;
+	if (which_id == PROC_EVENT_UID) {
+	 	ev->event_data.id.r.ruid = task->uid;
+	 	ev->event_data.id.e.euid = task->euid;
+	} else if (which_id == PROC_EVENT_GID) {
+	   	ev->event_data.id.r.rgid = task->gid;
+	   	ev->event_data.id.e.egid = task->egid;
+	} else
+	     	return;
+	get_seq(&msg->seq, &ev->cpu);
+
+	memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
+	msg->ack = 0; /* not used */
+	msg->len = sizeof(*ev);
+	cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+}
+
+void proc_exit_connector(struct task_struct *task)
+{
+	struct cn_msg *msg;
+	struct proc_event *ev;
+	__u8 buffer[CN_PROC_MSG_SIZE];
+
+	if (atomic_read(&proc_event_num_listeners) < 1)
+		return;
+
+	msg = (struct cn_msg*)buffer;
+	ev = (struct proc_event*)msg->data;
+	get_seq(&msg->seq, &ev->cpu);
+	ev->what = PROC_EVENT_EXIT;
+	ev->event_data.exit.process_pid = task->pid;
+	ev->event_data.exit.process_tgid = task->tgid;
+	ev->event_data.exit.exit_code = task->exit_code;
+	ev->event_data.exit.exit_signal = task->exit_signal;
+
+	memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
+	msg->ack = 0; /* not used */
+	msg->len = sizeof(*ev);
+	cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+}
+
+/*
+ * Send an acknowledgement message to userspace
+ *
+ * Use 0 for success, EFOO otherwise.
+ * Note: this is the negative of conventional kernel error
+ * values because it's not being returned via syscall return
+ * mechanisms.
+ */
+static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
+{
+	struct cn_msg *msg;
+	struct proc_event *ev;
+	__u8 buffer[CN_PROC_MSG_SIZE];
+
+	if (atomic_read(&proc_event_num_listeners) < 1)
+		return;
+
+	msg = (struct cn_msg*)buffer;
+	ev = (struct proc_event*)msg->data;
+	msg->seq = rcvd_seq;
+	ev->cpu = -1;
+	ev->what = PROC_EVENT_NONE;
+	ev->event_data.ack.err = err;
+	memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
+	msg->ack = rcvd_ack + 1;
+	msg->len = sizeof(*ev);
+	cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+}
+
+/**
+ * cn_proc_mcast_ctl
+ * @data: message sent from userspace via the connector
+ */
+static void cn_proc_mcast_ctl(void *data)
+{
+	struct cn_msg *msg = data;
+	enum proc_cn_mcast_op *mc_op = NULL;
+	int err = 0;
+
+	if (msg->len != sizeof(*mc_op))
+		return;
+
+	mc_op = (enum proc_cn_mcast_op*)msg->data;
+	switch (*mc_op) {
+	case PROC_CN_MCAST_LISTEN:
+		atomic_inc(&proc_event_num_listeners);
+		break;
+	case PROC_CN_MCAST_IGNORE:
+		atomic_dec(&proc_event_num_listeners);
+		break;
+	default:
+		err = EINVAL;
+		break;
+	}
+	cn_proc_ack(err, msg->seq, msg->ack);
+}
+
+/*
+ * cn_proc_init - initialization entry point
+ *
+ * Adds the connector callback to the connector driver.
+ */
+static int __init cn_proc_init(void)
+{
+	int err;
+
+	if ((err = cn_add_callback(&cn_proc_event_id, "cn_proc",
+	 			   &cn_proc_mcast_ctl))) {
+		printk(KERN_WARNING "cn_proc failed to register\n");
+		return err;
+	}
+	return 0;
+}
+
+module_init(cn_proc_init);
diff --git a/drivers/dio/dio.c b/drivers/dio/dio.c
index a620f7d..17502d6 100644
--- a/drivers/dio/dio.c
+++ b/drivers/dio/dio.c
@@ -224,11 +224,10 @@
 		set_fs(fs);
 
                 /* Found a board, allocate it an entry in the list */
-		dev = kmalloc(sizeof(struct dio_dev), GFP_KERNEL);
+		dev = kzalloc(sizeof(struct dio_dev), GFP_KERNEL);
 		if (!dev)
 			return 0;
 
-		memset(dev, 0, sizeof(struct dio_dev));
 		dev->bus = &dio_bus;
 		dev->dev.parent = &dio_bus.dev;
 		dev->dev.bus = &dio_bus_type;
diff --git a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c
index 1937743..4196137 100644
--- a/drivers/eisa/eisa-bus.c
+++ b/drivers/eisa/eisa-bus.c
@@ -281,13 +281,11 @@
 	/* First try to get hold of slot 0. If there is no device
 	 * here, simply fail, unless root->force_probe is set. */
 	
-	if (!(edev = kmalloc (sizeof (*edev), GFP_KERNEL))) {
+	if (!(edev = kzalloc (sizeof (*edev), GFP_KERNEL))) {
 		printk (KERN_ERR "EISA: Couldn't allocate mainboard slot\n");
 		return -ENOMEM;
 	}
 		
-	memset (edev, 0, sizeof (*edev));
-
 	if (eisa_request_resources (root, edev, 0)) {
 		printk (KERN_WARNING \
 			"EISA: Cannot allocate resource for mainboard\n");
@@ -317,13 +315,11 @@
  force_probe:
 	
         for (c = 0, i = 1; i <= root->slots; i++) {
-		if (!(edev = kmalloc (sizeof (*edev), GFP_KERNEL))) {
+		if (!(edev = kzalloc (sizeof (*edev), GFP_KERNEL))) {
 			printk (KERN_ERR "EISA: Out of memory for slot %d\n",
 				i);
 			continue;
 		}
-		
-		memset (edev, 0, sizeof (*edev));
 
 		if (eisa_request_resources (root, edev, i)) {
 			printk (KERN_WARNING \
diff --git a/drivers/fc4/fc.c b/drivers/fc4/fc.c
index e4710d1..5c89435 100644
--- a/drivers/fc4/fc.c
+++ b/drivers/fc4/fc.c
@@ -266,13 +266,12 @@
 			printk ("FC: Bad magic from REPORT_AL_MAP on %s - %08x\n", fc->name, p->magic);
 			fc->state = FC_STATE_OFFLINE;
 		} else {
-			fc->posmap = (fcp_posmap *)kmalloc(sizeof(fcp_posmap)+p->len, GFP_KERNEL);
+			fc->posmap = (fcp_posmap *)kzalloc(sizeof(fcp_posmap)+p->len, GFP_KERNEL);
 			if (!fc->posmap) {
 				printk("FC: Not enough memory, offlining channel\n");
 				fc->state = FC_STATE_OFFLINE;
 			} else {
 				int k;
-				memset(fc->posmap, 0, sizeof(fcp_posmap)+p->len);
 				/* FIXME: This is where SOCAL transfers our AL-PA.
 				   Keep it here till we found out what other cards do... */
 				fc->sid = (p->magic & 0xff);
@@ -351,14 +350,12 @@
 			fc->dma_scsi_rsp = fc->dma_scsi_cmd + slots * sizeof (fcp_cmd);
 			fc->scsi_bitmap_end = (slots + 63) & ~63;
 			size = fc->scsi_bitmap_end / 8;
-			fc->scsi_bitmap = kmalloc (size, GFP_KERNEL);
-			memset (fc->scsi_bitmap, 0, size);
+			fc->scsi_bitmap = kzalloc (size, GFP_KERNEL);
 			set_bit (0, fc->scsi_bitmap);
 			for (i = fc->can_queue; i < fc->scsi_bitmap_end; i++)
 				set_bit (i, fc->scsi_bitmap);
 			fc->scsi_free = fc->can_queue;
-			fc->cmd_slots = (fcp_cmnd **)kmalloc(slots * sizeof(fcp_cmnd*), GFP_KERNEL);
-			memset(fc->cmd_slots, 0, slots * sizeof(fcp_cmnd*));
+			fc->cmd_slots = (fcp_cmnd **)kzalloc(slots * sizeof(fcp_cmnd*), GFP_KERNEL);
 			fc->abort_count = 0;
 		} else {
 			fc->scsi_name[0] = 0;
@@ -541,12 +538,11 @@
 	FCND(("fcp_inititialize %08lx\n", (long)fcp_init))
 	FCND(("fc_channels %08lx\n", (long)fc_channels))
 	FCND((" SID %d DID %d\n", fcchain->sid, fcchain->did))
-	l = kmalloc(sizeof (ls) + count, GFP_KERNEL);
+	l = kzalloc(sizeof (ls) + count, GFP_KERNEL);
 	if (!l) {
 		printk ("FC: Cannot allocate memory for initialization\n");
 		return -ENOMEM;
 	}
-	memset (l, 0, sizeof(ls) + count);
 	l->magic = LSMAGIC;
 	l->count = count;
 	FCND(("FCP Init for %d channels\n", count))
@@ -555,17 +551,15 @@
 	l->timer.function = fcp_login_timeout;
 	l->timer.data = (unsigned long)l;
 	atomic_set (&l->todo, count);
-	l->logi = kmalloc (count * 3 * sizeof(logi), GFP_KERNEL);
-	l->fcmds = kmalloc (count * sizeof(fcp_cmnd), GFP_KERNEL);
+	l->logi = kzalloc (count * 3 * sizeof(logi), GFP_KERNEL);
+	l->fcmds = kzalloc (count * sizeof(fcp_cmnd), GFP_KERNEL);
 	if (!l->logi || !l->fcmds) {
-		if (l->logi) kfree (l->logi);
-		if (l->fcmds) kfree (l->fcmds);
+		kfree (l->logi);
+		kfree (l->fcmds);
 		kfree (l);
 		printk ("FC: Cannot allocate DMA memory for initialization\n");
 		return -ENOMEM;
 	}
-	memset (l->logi, 0, count * 3 * sizeof(logi));
-	memset (l->fcmds, 0, count * sizeof(fcp_cmnd));
 	for (fc = fcchain, i = 0; fc && i < count; fc = fc->next, i++) {
 		fc->state = FC_STATE_UNINITED;
 		fc->rst_pkt = NULL;	/* kmalloc when first used */
@@ -678,13 +672,11 @@
 	l.timer.function = fcp_login_timeout;
 	l.timer.data = (unsigned long)&l;
 	atomic_set (&l.todo, count);
-	l.fcmds = kmalloc (count * sizeof(fcp_cmnd), GFP_KERNEL);
+	l.fcmds = kzalloc (count * sizeof(fcp_cmnd), GFP_KERNEL);
 	if (!l.fcmds) {
-		kfree (l.fcmds);
 		printk ("FC: Cannot allocate memory for forcing offline\n");
 		return -ENOMEM;
 	}
-	memset (l.fcmds, 0, count * sizeof(fcp_cmnd));
 	FCND(("Initializing OFFLINE packets\n"))
 	for (fc = fcchain, i = 0; fc && i < count; fc = fc->next, i++) {
 		fc->state = FC_STATE_UNINITED;
@@ -1114,9 +1106,8 @@
 	logi *l;
 	int status;
 
-	l = (logi *)kmalloc(2 * sizeof(logi), GFP_KERNEL);
+	l = (logi *)kzalloc(2 * sizeof(logi), GFP_KERNEL);
 	if (!l) return -ENOMEM;
-	memset(l, 0, 2 * sizeof(logi));
 	l->code = LS_PLOGI;
 	memcpy (&l->nport_wwn, &fc->wwn_nport, sizeof(fc_wwn));
 	memcpy (&l->node_wwn, &fc->wwn_node, sizeof(fc_wwn));
@@ -1149,9 +1140,8 @@
 	prli *p;
 	int status;
 
-	p = (prli *)kmalloc(2 * sizeof(prli), GFP_KERNEL);
+	p = (prli *)kzalloc(2 * sizeof(prli), GFP_KERNEL);
 	if (!p) return -ENOMEM;
-	memset(p, 0, 2 * sizeof(prli));
 	p->code = LS_PRLI;
 	p->params[0] = 0x08002000;
 	p->params[3] = 0x00000022;
diff --git a/drivers/fc4/soc.c b/drivers/fc4/soc.c
index 247b463..ec1f947 100644
--- a/drivers/fc4/soc.c
+++ b/drivers/fc4/soc.c
@@ -556,10 +556,9 @@
 	int size, i;
 	int irq;
 	
-	s = kmalloc (sizeof (struct soc), GFP_KERNEL);
+	s = kzalloc (sizeof (struct soc), GFP_KERNEL);
 	if (s == NULL)
 		return;
-	memset (s, 0, sizeof(struct soc));
 	spin_lock_init(&s->lock);
 	s->soc_no = no;
 
diff --git a/drivers/fc4/socal.c b/drivers/fc4/socal.c
index b2377db..922e961 100644
--- a/drivers/fc4/socal.c
+++ b/drivers/fc4/socal.c
@@ -665,9 +665,8 @@
 	int size, i;
 	int irq, node;
 	
-	s = kmalloc (sizeof (struct socal), GFP_KERNEL);
+	s = kzalloc (sizeof (struct socal), GFP_KERNEL);
 	if (!s) return;
-	memset (s, 0, sizeof(struct socal));
 	spin_lock_init(&s->lock);
 	s->socal_no = no;
 
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
index 125929c..ba17292 100644
--- a/drivers/firmware/dell_rbu.c
+++ b/drivers/firmware/dell_rbu.c
@@ -50,7 +50,7 @@
 MODULE_AUTHOR("Abhay Salunke <abhay_salunke@dell.com>");
 MODULE_DESCRIPTION("Driver for updating BIOS image on DELL systems");
 MODULE_LICENSE("GPL");
-MODULE_VERSION("3.0");
+MODULE_VERSION("3.1");
 
 #define BIOS_SCAN_LIMIT 0xffffffff
 #define MAX_IMAGE_LENGTH 16
@@ -73,6 +73,11 @@
 MODULE_PARM_DESC(image_type,
 	"BIOS image type. choose- mono or packet or init");
 
+static unsigned long allocation_floor = 0x100000;
+module_param(allocation_floor, ulong, 0644);
+MODULE_PARM_DESC(allocation_floor,
+    "Minimum address for allocations when using Packet mode");
+
 struct packet_data {
 	struct list_head list;
 	size_t length;
@@ -99,61 +104,122 @@
 {
 	struct packet_data *newpacket;
 	int ordernum = 0;
+	int retval = 0;
+	unsigned int packet_array_size = 0;
+	void **invalid_addr_packet_array = 0;
+	void *packet_data_temp_buf = 0;
+	unsigned int idx = 0;
 
 	pr_debug("create_packet: entry \n");
 
 	if (!rbu_data.packetsize) {
 		pr_debug("create_packet: packetsize not specified\n");
-		return -EINVAL;
+		retval = -EINVAL;
+		goto out_noalloc;
 	}
+
 	spin_unlock(&rbu_data.lock);
-	newpacket = kmalloc(sizeof (struct packet_data), GFP_KERNEL);
-	spin_lock(&rbu_data.lock);
+
+	newpacket = kzalloc(sizeof (struct packet_data), GFP_KERNEL);
 
 	if (!newpacket) {
 		printk(KERN_WARNING
 			"dell_rbu:%s: failed to allocate new "
 			"packet\n", __FUNCTION__);
-		return -ENOMEM;
+		retval = -ENOMEM;
+		spin_lock(&rbu_data.lock);
+		goto out_noalloc;
 	}
 
 	ordernum = get_order(length);
+
 	/*
-	 * there is no upper limit on memory
-	 * address for packetized mechanism
+	 * BIOS errata mean we cannot allocate packets below 1MB or they will
+	 * be overwritten by BIOS.
+	 *
+	 * array to temporarily hold packets
+	 * that are below the allocation floor
+	 *
+	 * NOTE: very simplistic because we only need the floor to be at 1MB
+	 *       due to BIOS errata. This shouldn't be used for higher floors
+	 *       or you will run out of mem trying to allocate the array.
 	 */
-	spin_unlock(&rbu_data.lock);
-	newpacket->data = (unsigned char *) __get_free_pages(GFP_KERNEL,
-		ordernum);
-	spin_lock(&rbu_data.lock);
+	packet_array_size = max(
+	       		(unsigned int)(allocation_floor / rbu_data.packetsize),
+			(unsigned int)1);
+	invalid_addr_packet_array = kzalloc(packet_array_size * sizeof(void*),
+						GFP_KERNEL);
 
-	pr_debug("create_packet: newpacket %p\n", newpacket->data);
-
-	if (!newpacket->data) {
+	if (!invalid_addr_packet_array) {
 		printk(KERN_WARNING
-			"dell_rbu:%s: failed to allocate new "
-			"packet\n", __FUNCTION__);
-		kfree(newpacket);
-		return -ENOMEM;
+			"dell_rbu:%s: failed to allocate "
+			"invalid_addr_packet_array \n",
+			__FUNCTION__);
+		retval = -ENOMEM;
+		spin_lock(&rbu_data.lock);
+		goto out_alloc_packet;
 	}
 
+	while (!packet_data_temp_buf) {
+		packet_data_temp_buf = (unsigned char *)
+			__get_free_pages(GFP_KERNEL, ordernum);
+		if (!packet_data_temp_buf) {
+			printk(KERN_WARNING
+				"dell_rbu:%s: failed to allocate new "
+				"packet\n", __FUNCTION__);
+			retval = -ENOMEM;
+			spin_lock(&rbu_data.lock);
+			goto out_alloc_packet_array;
+		}
+
+		if ((unsigned long)virt_to_phys(packet_data_temp_buf)
+				< allocation_floor) {
+			pr_debug("packet 0x%lx below floor at 0x%lx.\n",
+					(unsigned long)virt_to_phys(
+						packet_data_temp_buf),
+					allocation_floor);
+			invalid_addr_packet_array[idx++] = packet_data_temp_buf;
+			packet_data_temp_buf = 0;
+		}
+	}
+	spin_lock(&rbu_data.lock);
+
+	newpacket->data = packet_data_temp_buf;
+
+	pr_debug("create_packet: newpacket at physical addr %lx\n",
+		(unsigned long)virt_to_phys(newpacket->data));
+
+	/* packets may not have fixed size */
+	newpacket->length = length;
 	newpacket->ordernum = ordernum;
 	++rbu_data.num_packets;
-	/*
-	 * initialize the newly created packet headers
-	 */
+
+	/* initialize the newly created packet headers */
 	INIT_LIST_HEAD(&newpacket->list);
 	list_add_tail(&newpacket->list, &packet_data_head.list);
-	/*
-	 * packets may not have fixed size
-	 */
-	newpacket->length = length;
 
 	memcpy(newpacket->data, data, length);
 
 	pr_debug("create_packet: exit \n");
 
-	return 0;
+out_alloc_packet_array:
+	/* always free packet array */
+	for (;idx>0;idx--) {
+		pr_debug("freeing unused packet below floor 0x%lx.\n",
+			(unsigned long)virt_to_phys(
+				invalid_addr_packet_array[idx-1]));
+		free_pages((unsigned long)invalid_addr_packet_array[idx-1],
+			ordernum);
+	}
+	kfree(invalid_addr_packet_array);
+
+out_alloc_packet:
+	/* if error, free data */
+	if (retval)
+		kfree(newpacket);
+
+out_noalloc:
+	return retval;
 }
 
 static int packetize_data(void *data, size_t length)
@@ -693,3 +759,6 @@
 
 module_exit(dcdrbu_exit);
 module_init(dcdrbu_init);
+
+/* vim:noet:ts=8:sw=8
+*/
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c
index 6996476..b4502ed6 100644
--- a/drivers/firmware/edd.c
+++ b/drivers/firmware/edd.c
@@ -715,7 +715,6 @@
 
 	if (!edev)
 		return 1;
-	memset(edev, 0, sizeof (*edev));
 	edd_dev_set_info(edev, i);
 	kobject_set_name(&edev->kobj, "int13_dev%02x",
 			 0x80 + i);
@@ -756,7 +755,7 @@
 		return rc;
 
 	for (i = 0; i < edd_num_devices() && !rc; i++) {
-		edev = kmalloc(sizeof (*edev), GFP_KERNEL);
+		edev = kzalloc(sizeof (*edev), GFP_KERNEL);
 		if (!edev)
 			return -ENOMEM;
 
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index 33b17c6..bda5bce 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -614,16 +614,14 @@
 	char *short_name;
 	struct efivar_entry *new_efivar;
 
-	short_name = kmalloc(short_name_size + 1, GFP_KERNEL);
-	new_efivar = kmalloc(sizeof(struct efivar_entry), GFP_KERNEL);
+	short_name = kzalloc(short_name_size + 1, GFP_KERNEL);
+	new_efivar = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL);
 
 	if (!short_name || !new_efivar)  {
 		kfree(short_name);
 		kfree(new_efivar);
 		return 1;
 	}
-	memset(short_name, 0, short_name_size+1);
-	memset(new_efivar, 0, sizeof(struct efivar_entry));
 
 	memcpy(new_efivar->var.VariableName, variable_name,
 		variable_name_size);
@@ -674,14 +672,12 @@
 	if (!efi_enabled)
 		return -ENODEV;
 
-	variable_name = kmalloc(variable_name_size, GFP_KERNEL);
+	variable_name = kzalloc(variable_name_size, GFP_KERNEL);
 	if (!variable_name) {
 		printk(KERN_ERR "efivars: Memory allocation failed.\n");
 		return -ENOMEM;
 	}
 
-	memset(variable_name, 0, variable_name_size);
-
 	printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION,
 	       EFIVARS_DATE);
 
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c
index 6f48579..dddd3eb 100644
--- a/drivers/hwmon/hwmon.c
+++ b/drivers/hwmon/hwmon.c
@@ -16,6 +16,7 @@
 #include <linux/kdev_t.h>
 #include <linux/idr.h>
 #include <linux/hwmon.h>
+#include <linux/gfp.h>
 
 #define HWMON_ID_PREFIX "hwmon"
 #define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d"
diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c
index 6a82ffa..69e7e12 100644
--- a/drivers/hwmon/max1619.c
+++ b/drivers/hwmon/max1619.c
@@ -193,7 +193,7 @@
 	int err = 0;
 	const char *name = "";	
 	u8 reg_config=0, reg_convrate=0, reg_status=0;
-	u8 man_id, chip_id;
+
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		goto exit;
 
@@ -238,16 +238,15 @@
 	}
 
 	if (kind <= 0) { /* identification */
+		u8 man_id, chip_id;
 	
 		man_id = i2c_smbus_read_byte_data(new_client,
 			 MAX1619_REG_R_MAN_ID);
 		chip_id = i2c_smbus_read_byte_data(new_client,
 			  MAX1619_REG_R_CHIP_ID);
 		
-		if ((man_id == 0x4D) && (chip_id == 0x04)){  
-				kind = max1619;
-			}
-		}
+		if ((man_id == 0x4D) && (chip_id == 0x04))
+			kind = max1619;
 
 		if (kind <= 0) { /* identification failed */
 			dev_info(&adapter->dev,
@@ -255,12 +254,11 @@
 			    "chip_id=0x%02X).\n", man_id, chip_id);
 			goto exit_free;
 		}
-	
-
-	if (kind == max1619){
-		name = "max1619";
 	}
 
+	if (kind == max1619)
+		name = "max1619";
+
 	/* We can fill in the remaining client fields */
 	strlcpy(new_client->name, name, I2C_NAME_SIZE);
 	data->valid = 0;
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index 9265f32..ffdb3a0 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -976,11 +976,9 @@
 ERROR_SC_3:
 	i2c_detach_client(data->lm75[0]);
 ERROR_SC_2:
-	if (data->lm75[1])
-		kfree(data->lm75[1]);
+	kfree(data->lm75[1]);
 ERROR_SC_1:
-	if (data->lm75[0])
-		kfree(data->lm75[0]);
+	kfree(data->lm75[0]);
 ERROR_SC_0:
 	return err;
 }
diff --git a/drivers/i2c/busses/i2c-amd756-s4882.c b/drivers/i2c/busses/i2c-amd756-s4882.c
index f51ab65..56c7d98 100644
--- a/drivers/i2c/busses/i2c-amd756-s4882.c
+++ b/drivers/i2c/busses/i2c-amd756-s4882.c
@@ -245,10 +245,8 @@
 		kfree(s4882_adapter);
 		s4882_adapter = NULL;
 	}
-	if (s4882_algo) {
-		kfree(s4882_algo);
-		s4882_algo = NULL;
-	}
+	kfree(s4882_algo);
+	s4882_algo = NULL;
 
 	/* Restore physical bus */
 	if (i2c_add_adapter(&amd756_smbus))
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 8b9d855..c2f4792 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -3292,12 +3292,9 @@
 	ide_drive_t *drive = info->drive;
 	struct gendisk *g = info->disk;
 
-	if (info->buffer != NULL)
-		kfree(info->buffer);
-	if (info->toc != NULL)
-		kfree(info->toc);
-	if (info->changer_info != NULL)
-		kfree(info->changer_info);
+	kfree(info->buffer);
+	kfree(info->toc);
+	kfree(info->changer_info);
 	if (devinfo->handle == drive && unregister_cdrom(devinfo))
 		printk(KERN_ERR "%s: %s failed to unregister device from the cdrom "
 				"driver.\n", __FUNCTION__, drive->name);
@@ -3455,7 +3452,7 @@
 		printk(KERN_INFO "ide-cd: passing drive %s to ide-scsi emulation.\n", drive->name);
 		goto failed;
 	}
-	info = kmalloc(sizeof(struct cdrom_info), GFP_KERNEL);
+	info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL);
 	if (info == NULL) {
 		printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", drive->name);
 		goto failed;
@@ -3469,8 +3466,6 @@
 
 	ide_register_subdriver(drive, &ide_cdrom_driver);
 
-	memset(info, 0, sizeof (struct cdrom_info));
-
 	kref_init(&info->kref);
 
 	info->drive = drive;
@@ -3489,12 +3484,9 @@
 	if (ide_cdrom_setup(drive)) {
 		struct cdrom_device_info *devinfo = &info->devinfo;
 		ide_unregister_subdriver(drive, &ide_cdrom_driver);
-		if (info->buffer != NULL)
-			kfree(info->buffer);
-		if (info->toc != NULL)
-			kfree(info->toc);
-		if (info->changer_info != NULL)
-			kfree(info->changer_info);
+		kfree(info->buffer);
+		kfree(info->toc);
+		kfree(info->changer_info);
 		if (devinfo->handle == drive && unregister_cdrom(devinfo))
 			printk (KERN_ERR "%s: ide_cdrom_cleanup failed to unregister device from the cdrom driver.\n", drive->name);
 		kfree(info);
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 234f5de..e827b39 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1215,7 +1215,7 @@
 	if (drive->media != ide_disk)
 		goto failed;
 
-	idkp = kmalloc(sizeof(*idkp), GFP_KERNEL);
+	idkp = kzalloc(sizeof(*idkp), GFP_KERNEL);
 	if (!idkp)
 		goto failed;
 
@@ -1228,8 +1228,6 @@
 
 	ide_register_subdriver(drive, &idedisk_driver);
 
-	memset(idkp, 0, sizeof(*idkp));
-
 	kref_init(&idkp->kref);
 
 	idkp->drive = drive;
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 29c22fc2..e83f54d 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -2146,7 +2146,7 @@
 		printk("ide-floppy: passing drive %s to ide-scsi emulation.\n", drive->name);
 		goto failed;
 	}
-	if ((floppy = (idefloppy_floppy_t *) kmalloc (sizeof (idefloppy_floppy_t), GFP_KERNEL)) == NULL) {
+	if ((floppy = (idefloppy_floppy_t *) kzalloc (sizeof (idefloppy_floppy_t), GFP_KERNEL)) == NULL) {
 		printk (KERN_ERR "ide-floppy: %s: Can't allocate a floppy structure\n", drive->name);
 		goto failed;
 	}
@@ -2159,8 +2159,6 @@
 
 	ide_register_subdriver(drive, &idefloppy_driver);
 
-	memset(floppy, 0, sizeof(*floppy));
-
 	kref_init(&floppy->kref);
 
 	floppy->drive = drive;
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index c1128ae..02167a5 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -596,14 +596,13 @@
 	 *	Also note that 0 everywhere means "can't do X"
 	 */
  
-	drive->id = kmalloc(SECTOR_WORDS *4, GFP_KERNEL);
+	drive->id = kzalloc(SECTOR_WORDS *4, GFP_KERNEL);
 	drive->id_read = 0;
 	if(drive->id == NULL)
 	{
 		printk(KERN_ERR "ide: out of memory for id data.\n");
 		return 0;
 	}
-	memset(drive->id, 0, SECTOR_WORDS * 4);
 	strcpy(drive->id->model, "UNKNOWN");
 	
 	/* skip probing? */
@@ -1316,10 +1315,8 @@
 		drive->devfs_name[0] = '\0';
 	}
 	ide_remove_drive_from_hwgroup(drive);
-	if (drive->id != NULL) {
-		kfree(drive->id);
-		drive->id = NULL;
-	}
+	kfree(drive->id);
+	drive->id = NULL;
 	drive->present = 0;
 	/* Messed up locking ... */
 	spin_unlock_irq(&ide_lock);
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 47f2b83..0ac7eb8 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -4850,7 +4850,7 @@
 		printk(KERN_WARNING "ide-tape: Use drive %s with ide-scsi emulation and osst.\n", drive->name);
 		printk(KERN_WARNING "ide-tape: OnStream support will be removed soon from ide-tape!\n");
 	}
-	tape = (idetape_tape_t *) kmalloc (sizeof (idetape_tape_t), GFP_KERNEL);
+	tape = (idetape_tape_t *) kzalloc (sizeof (idetape_tape_t), GFP_KERNEL);
 	if (tape == NULL) {
 		printk(KERN_ERR "ide-tape: %s: Can't allocate a tape structure\n", drive->name);
 		goto failed;
@@ -4864,8 +4864,6 @@
 
 	ide_register_subdriver(drive, &idetape_driver);
 
-	memset(tape, 0, sizeof(*tape));
-
 	kref_init(&tape->kref);
 
 	tape->drive = drive;
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index ace8eda..7ec18fa 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -528,9 +528,8 @@
 
 //	printk("IDE Taskfile ...\n");
 
-	req_task = kmalloc(tasksize, GFP_KERNEL);
+	req_task = kzalloc(tasksize, GFP_KERNEL);
 	if (req_task == NULL) return -ENOMEM;
-	memset(req_task, 0, tasksize);
 	if (copy_from_user(req_task, buf, tasksize)) {
 		kfree(req_task);
 		return -EFAULT;
@@ -541,12 +540,11 @@
 
 	if (taskout) {
 		int outtotal = tasksize;
-		outbuf = kmalloc(taskout, GFP_KERNEL);
+		outbuf = kzalloc(taskout, GFP_KERNEL);
 		if (outbuf == NULL) {
 			err = -ENOMEM;
 			goto abort;
 		}
-		memset(outbuf, 0, taskout);
 		if (copy_from_user(outbuf, buf + outtotal, taskout)) {
 			err = -EFAULT;
 			goto abort;
@@ -555,12 +553,11 @@
 
 	if (taskin) {
 		int intotal = tasksize + taskout;
-		inbuf = kmalloc(taskin, GFP_KERNEL);
+		inbuf = kzalloc(taskin, GFP_KERNEL);
 		if (inbuf == NULL) {
 			err = -ENOMEM;
 			goto abort;
 		}
-		memset(inbuf, 0, taskin);
 		if (copy_from_user(inbuf, buf + intotal, taskin)) {
 			err = -EFAULT;
 			goto abort;
@@ -649,10 +646,8 @@
 	}
 abort:
 	kfree(req_task);
-	if (outbuf != NULL)
-		kfree(outbuf);
-	if (inbuf != NULL)
-		kfree(inbuf);
+	kfree(outbuf);
+	kfree(inbuf);
 
 //	printk("IDE Taskfile ioctl ended. rc = %i\n", err);
 
@@ -709,10 +704,9 @@
 
 	if (args[3]) {
 		argsize = 4 + (SECTOR_WORDS * 4 * args[3]);
-		argbuf = kmalloc(argsize, GFP_KERNEL);
+		argbuf = kzalloc(argsize, GFP_KERNEL);
 		if (argbuf == NULL)
 			return -ENOMEM;
-		memcpy(argbuf, args, 4);
 	}
 	if (set_transfer(drive, &tfargs)) {
 		xfer_rate = args[1];
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 73ca8f7..9fe1980 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -864,9 +864,8 @@
 	down(&ide_setting_sem);
 	while ((*p) && strcmp((*p)->name, name) < 0)
 		p = &((*p)->next);
-	if ((setting = kmalloc(sizeof(*setting), GFP_KERNEL)) == NULL)
+	if ((setting = kzalloc(sizeof(*setting), GFP_KERNEL)) == NULL)
 		goto abort;
-	memset(setting, 0, sizeof(*setting));
 	if ((setting->name = kmalloc(strlen(name) + 1, GFP_KERNEL)) == NULL)
 		goto abort;
 	strcpy(setting->name, name);
@@ -889,8 +888,7 @@
 	return 0;
 abort:
 	up(&ide_setting_sem);
-	if (setting)
-		kfree(setting);
+	kfree(setting);
 	return -1;
 }
 
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index a35a58b..1dafffa 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -116,9 +116,8 @@
     DEBUG(0, "ide_attach()\n");
 
     /* Create new ide device */
-    info = kmalloc(sizeof(*info), GFP_KERNEL);
+    info = kzalloc(sizeof(*info), GFP_KERNEL);
     if (!info) return NULL;
-    memset(info, 0, sizeof(*info));
     link = &info->link; link->priv = info;
 
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
@@ -221,9 +220,8 @@
 
     DEBUG(0, "ide_config(0x%p)\n", link);
 
-    stk = kmalloc(sizeof(*stk), GFP_KERNEL);
+    stk = kzalloc(sizeof(*stk), GFP_KERNEL);
     if (!stk) goto err_mem;
-    memset(stk, 0, sizeof(*stk));
     cfg = &stk->parse.cftable_entry;
 
     tuple.TupleData = (cisdata_t *)&stk->buf;
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index 127619a..7b589d9 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -1516,7 +1516,7 @@
 
 static void __devinit init_iops_hpt366(ide_hwif_t *hwif)
 {
-	struct hpt_info *info = kmalloc(sizeof(struct hpt_info), GFP_KERNEL);
+	struct hpt_info *info = kzalloc(sizeof(struct hpt_info), GFP_KERNEL);
 	unsigned long dmabase = pci_resource_start(hwif->pci_dev, 4);
 	u8 did, rid;
 
@@ -1524,7 +1524,6 @@
 		printk(KERN_WARNING "hpt366: out of memory.\n");
 		return;
 	}
-	memset(info, 0, sizeof(struct hpt_info));
 	ide_set_hwifdata(hwif, info);
 
 	if(dmabase) {
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
index e440036..108fda8 100644
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -642,14 +642,13 @@
 
 static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
 {
-	struct it821x_dev *idev = kmalloc(sizeof(struct it821x_dev), GFP_KERNEL);
+	struct it821x_dev *idev = kzalloc(sizeof(struct it821x_dev), GFP_KERNEL);
 	u8 conf;
 
 	if(idev == NULL) {
 		printk(KERN_ERR "it821x: out of memory, falling back to legacy behaviour.\n");
 		goto fallback;
 	}
-	memset(idev, 0, sizeof(struct it821x_dev));
 	ide_set_hwifdata(hwif, idev);
 
 	pci_read_config_byte(hwif->pci_dev, 0x50, &conf);
diff --git a/drivers/ieee1394/amdtp.c b/drivers/ieee1394/amdtp.c
index e8e2856..7589750 100644
--- a/drivers/ieee1394/amdtp.c
+++ b/drivers/ieee1394/amdtp.c
@@ -320,8 +320,7 @@
 			if ((control & OHCI1394_CONTEXT_ACTIVE) == 0)
 				break;
 
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(1);
+			schedule_timeout_interruptible(1);
 		}
 	}
 }
diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c
index 7545775..34b724a 100644
--- a/drivers/infiniband/core/agent.c
+++ b/drivers/infiniband/core/agent.c
@@ -37,6 +37,9 @@
  * $Id: agent.c 1389 2004-12-27 22:56:47Z roland $
  */
 
+#include <linux/slab.h>
+#include <linux/string.h>
+
 #include "agent.h"
 #include "smi.h"
 
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 3d8175e..41d6b40 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -508,8 +508,7 @@
 	wait_event(mad_agent_priv->wait,
 		   !atomic_read(&mad_agent_priv->refcount));
 
-	if (mad_agent_priv->reg_req)
-		kfree(mad_agent_priv->reg_req);
+	kfree(mad_agent_priv->reg_req);
 	ib_dereg_mr(mad_agent_priv->agent.mr);
 	kfree(mad_agent_priv);
 }
@@ -2500,8 +2499,7 @@
 static void destroy_mad_qp(struct ib_mad_qp_info *qp_info)
 {
 	ib_destroy_qp(qp_info->qp);
-	if (qp_info->snoop_table)
-		kfree(qp_info->snoop_table);
+	kfree(qp_info->snoop_table);
 }
 
 /*
diff --git a/drivers/infiniband/core/packer.c b/drivers/infiniband/core/packer.c
index 35df501..c972d72 100644
--- a/drivers/infiniband/core/packer.c
+++ b/drivers/infiniband/core/packer.c
@@ -33,6 +33,8 @@
  * $Id: packer.c 1349 2004-12-16 21:09:43Z roland $
  */
 
+#include <linux/string.h>
+
 #include <rdma/ib_pack.h>
 
 static u64 value_read(int offset, int size, void *structure)
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index b812065..08648b1a 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -36,6 +36,9 @@
 
 #include "core_priv.h"
 
+#include <linux/slab.h>
+#include <linux/string.h>
+
 #include <rdma/ib_mad.h>
 
 struct ib_port {
diff --git a/drivers/infiniband/core/ud_header.c b/drivers/infiniband/core/ud_header.c
index 527b234..997c07d 100644
--- a/drivers/infiniband/core/ud_header.c
+++ b/drivers/infiniband/core/ud_header.c
@@ -34,6 +34,7 @@
  */
 
 #include <linux/errno.h>
+#include <linux/string.h>
 
 #include <rdma/ib_pack.h>
 
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 72d3ef7..4186cc8 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -40,6 +40,7 @@
 
 #include <linux/errno.h>
 #include <linux/err.h>
+#include <linux/string.h>
 
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_cache.h>
diff --git a/drivers/infiniband/hw/mthca/mthca_catas.c b/drivers/infiniband/hw/mthca/mthca_catas.c
index 7ac52af..25ebab6 100644
--- a/drivers/infiniband/hw/mthca/mthca_catas.c
+++ b/drivers/infiniband/hw/mthca/mthca_catas.c
@@ -32,6 +32,9 @@
  * $Id$
  */
 
+#include <linux/jiffies.h>
+#include <linux/timer.h>
+
 #include "mthca_dev.h"
 
 enum {
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c
index 292f55b..26d5161 100644
--- a/drivers/infiniband/hw/mthca/mthca_srq.c
+++ b/drivers/infiniband/hw/mthca/mthca_srq.c
@@ -32,6 +32,9 @@
  * $Id: mthca_srq.c 3047 2005-08-10 03:59:35Z roland $
  */
 
+#include <linux/slab.h>
+#include <linux/string.h>
+
 #include "mthca_dev.h"
 #include "mthca_cmd.h"
 #include "mthca_memfree.h"
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 4015a91..948c1cc 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -271,8 +271,7 @@
 		goto exit;
 	}
 
-	if (dev->name)
-		kfree(dev->name);
+	kfree(dev->name);
 
 	size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
 	dev->name = name = kmalloc(size, GFP_KERNEL);
@@ -372,11 +371,8 @@
 	if (test_bit(UIST_CREATED, &udev->state))
 		uinput_destroy_device(udev);
 
-	if (udev->dev->name)
-		kfree(udev->dev->name);
-	if (udev->dev->phys)
-		kfree(udev->dev->phys);
-
+	kfree(udev->dev->name);
+	kfree(udev->dev->phys);
 	kfree(udev->dev);
 	kfree(udev);
 
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
index db9bad2..27391c3 100644
--- a/drivers/isdn/hardware/avm/avm_cs.c
+++ b/drivers/isdn/hardware/avm/avm_cs.c
@@ -212,11 +212,8 @@
     
     /* Unlink device structure, free pieces */
     *linkp = link->next;
-    if (link->priv) {
-	kfree(link->priv);
-    }
+    kfree(link->priv);
     kfree(link);
-    
 } /* avmcs_detach */
 
 /*======================================================================
diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c
index 625799a..5d8ee73 100644
--- a/drivers/isdn/hisax/avm_pci.c
+++ b/drivers/isdn/hisax/avm_pci.c
@@ -552,14 +552,10 @@
 {
 	modehdlc(bcs, 0, 0);
 	if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
-		if (bcs->hw.hdlc.rcvbuf) {
-			kfree(bcs->hw.hdlc.rcvbuf);
-			bcs->hw.hdlc.rcvbuf = NULL;
-		}
-		if (bcs->blog) {
-			kfree(bcs->blog);
-			bcs->blog = NULL;
-		}
+		kfree(bcs->hw.hdlc.rcvbuf);
+		bcs->hw.hdlc.rcvbuf = NULL;
+		kfree(bcs->blog);
+		bcs->blog = NULL;
 		skb_queue_purge(&bcs->rqueue);
 		skb_queue_purge(&bcs->squeue);
 		if (bcs->tx_skb) {
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index 0e22991..5f5a5ae7 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -236,9 +236,7 @@
     
     /* Unlink device structure, free pieces */
     *linkp = link->next;
-    if (link->priv) {
-	kfree(link->priv);
-    }
+    kfree(link->priv);
     kfree(link);
     
 } /* avma1cs_detach */
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index fbaab43..8159bce 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -787,8 +787,7 @@
 	ic.command = ISDN_STAT_UNLOAD;
 	ic.driver = cs->myid;
 	cs->iif.statcallb(&ic);
-	if (cs->status_buf)
-		kfree(cs->status_buf);
+	kfree(cs->status_buf);
 	cs->status_read = NULL;
 	cs->status_write = NULL;
 	cs->status_end = NULL;
@@ -807,10 +806,8 @@
 
 	skb_queue_purge(&csta->rq);
 	skb_queue_purge(&csta->sq);
-	if (csta->rcvbuf) {
-		kfree(csta->rcvbuf);
-		csta->rcvbuf = NULL;
-	}
+	kfree(csta->rcvbuf);
+	csta->rcvbuf = NULL;
 	if (csta->tx_skb) {
 		dev_kfree_skb(csta->tx_skb);
 		csta->tx_skb = NULL;
diff --git a/drivers/isdn/hisax/hfc_2bds0.c b/drivers/isdn/hisax/hfc_2bds0.c
index 7cf8779..637a261 100644
--- a/drivers/isdn/hisax/hfc_2bds0.c
+++ b/drivers/isdn/hisax/hfc_2bds0.c
@@ -1052,18 +1052,12 @@
 void
 release2bds0(struct IsdnCardState *cs)
 {
-	if (cs->bcs[0].hw.hfc.send) {
-		kfree(cs->bcs[0].hw.hfc.send);
-		cs->bcs[0].hw.hfc.send = NULL;
-	}
-	if (cs->bcs[1].hw.hfc.send) {
-		kfree(cs->bcs[1].hw.hfc.send);
-		cs->bcs[1].hw.hfc.send = NULL;
-	}
-	if (cs->hw.hfcD.send) {
-		kfree(cs->hw.hfcD.send);
-		cs->hw.hfcD.send = NULL;
-	}
+	kfree(cs->bcs[0].hw.hfc.send);
+	cs->bcs[0].hw.hfc.send = NULL;
+	kfree(cs->bcs[1].hw.hfc.send);
+	cs->bcs[1].hw.hfc.send = NULL;
+	kfree(cs->hw.hfcD.send);
+	cs->hw.hfcD.send = NULL;
 }
 
 void
diff --git a/drivers/isdn/hisax/hfc_2bs0.c b/drivers/isdn/hisax/hfc_2bs0.c
index f978a5a..c964539 100644
--- a/drivers/isdn/hisax/hfc_2bs0.c
+++ b/drivers/isdn/hisax/hfc_2bs0.c
@@ -582,12 +582,8 @@
 void
 releasehfc(struct IsdnCardState *cs)
 {
-	if (cs->bcs[0].hw.hfc.send) {
-		kfree(cs->bcs[0].hw.hfc.send);
-		cs->bcs[0].hw.hfc.send = NULL;
-	}
-	if (cs->bcs[1].hw.hfc.send) {
-		kfree(cs->bcs[1].hw.hfc.send);
-		cs->bcs[1].hw.hfc.send = NULL;
-	}
+	kfree(cs->bcs[0].hw.hfc.send);
+	cs->bcs[0].hw.hfc.send = NULL;
+	kfree(cs->bcs[1].hw.hfc.send);
+	cs->bcs[1].hw.hfc.send = NULL;
 }
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index e2c3af4..32bf0d5 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -1,7 +1,7 @@
 /*
  * hfc_usb.c
  *
- * $Id: hfc_usb.c,v 4.34 2005/01/26 17:25:53 martinb1 Exp $
+ * $Id: hfc_usb.c,v 4.36 2005/04/08 09:55:13 martinb1 Exp $
  *
  * modular HiSax ISDN driver for Colognechip HFC-S USB chip
  *
@@ -44,12 +44,8 @@
 #include "hisax_if.h"
 #include "hfc_usb.h"
 
-/*
-* Version Information
-* (do not modify the CVS Makros $Revision: 4.34 $ and $Date: 2005/01/26 17:25:53 $ !)
-*/
 static const char *hfcusb_revision =
-    "Revision: 4.34 $ Date: 2005/01/26 17:25:53 $ ";
+    "$Revision: 4.36 $ $Date: 2005/04/08 09:55:13 $ ";
 
 /* Hisax debug support
 * use "modprobe debug=x" where x is bitfield of USB_DBG & ISDN_DBG
@@ -63,81 +59,89 @@
 static int hfc_debug;
 #endif
 
+/* private vendor specific data */
+typedef struct {
+	__u8 led_scheme;	// led display scheme
+	signed short led_bits[8];	// array of 8 possible LED bitmask settings
+	char *vend_name;	// device name
+} hfcsusb_vdata;
 
 /****************************************/
 /* data defining the devices to be used */
 /****************************************/
-static struct usb_device_id hfc_usb_idtab[] = {
-	{USB_DEVICE(0x0959, 0x2bd0)},	/* Colognechip USB eval TA */
-	{USB_DEVICE(0x0675, 0x1688)},	/* DrayTek miniVigor 128 USB ISDN TA */
-	{USB_DEVICE(0x07b0, 0x0007)},	/* Billion USB TA 2 */
-	{USB_DEVICE(0x0742, 0x2008)},	/* Stollmann USB TA */
-	{USB_DEVICE(0x0742, 0x2009)},	/* Aceex USB ISDN TA */
-	{USB_DEVICE(0x0742, 0x200A)},	/* OEM USB ISDN TA */
-	{USB_DEVICE(0x08e3, 0x0301)},	/* OliTec ISDN USB */
-	{USB_DEVICE(0x07fa, 0x0846)},	/* Bewan ISDN USB TA */
-	{USB_DEVICE(0x07fa, 0x0847)},	/* Djinn Numeris USB */
-	{USB_DEVICE(0x07b0, 0x0006)},	/* Twister ISDN USB TA */
-	{}			/* end with an all-zeroes entry */
+static struct usb_device_id hfcusb_idtab[] = {
+	{
+	 .idVendor = 0x0959,
+	 .idProduct = 0x2bd0,
+	 .driver_info = (unsigned long) &((hfcsusb_vdata)
+			  {LED_OFF, {4, 0, 2, 1},
+			   "ISDN USB TA (Cologne Chip HFC-S USB based)"}),
+	},
+	{
+	 .idVendor = 0x0675,
+	 .idProduct = 0x1688,
+	 .driver_info = (unsigned long) &((hfcsusb_vdata)
+			  {LED_SCHEME1, {1, 2, 0, 0},
+			   "DrayTek miniVigor 128 USB ISDN TA"}),
+	},
+	{
+	 .idVendor = 0x07b0,
+	 .idProduct = 0x0007,
+	 .driver_info = (unsigned long) &((hfcsusb_vdata)
+			  {LED_SCHEME1, {0x80, -64, -32, -16},
+			   "Billion tiny USB ISDN TA 128"}),
+	},
+	{
+	 .idVendor = 0x0742,
+	 .idProduct = 0x2008,
+	 .driver_info = (unsigned long) &((hfcsusb_vdata)
+			  {LED_SCHEME1, {4, 0, 2, 1},
+			   "Stollmann USB TA"}),
+	 },
+	{
+	 .idVendor = 0x0742,
+	 .idProduct = 0x2009,
+	 .driver_info = (unsigned long) &((hfcsusb_vdata)
+			  {LED_SCHEME1, {4, 0, 2, 1},
+			   "Aceex USB ISDN TA"}),
+	 },
+	{
+	 .idVendor = 0x0742,
+	 .idProduct = 0x200A,
+	 .driver_info = (unsigned long) &((hfcsusb_vdata)
+			  {LED_SCHEME1, {4, 0, 2, 1},
+			   "OEM USB ISDN TA"}),
+	 },
+	{
+	 .idVendor = 0x08e3,
+	 .idProduct = 0x0301,
+	 .driver_info = (unsigned long) &((hfcsusb_vdata)
+			  {LED_SCHEME1, {2, 0, 1, 4},
+			   "Olitec USB RNIS"}),
+	 },
+	{
+	 .idVendor = 0x07fa,
+	 .idProduct = 0x0846,
+	 .driver_info = (unsigned long) &((hfcsusb_vdata)
+			  {LED_SCHEME1, {0x80, -64, -32, -16},
+			   "Bewan Modem RNIS USB"}),
+	 },
+	{
+	 .idVendor = 0x07fa,
+	 .idProduct = 0x0847,
+	 .driver_info = (unsigned long) &((hfcsusb_vdata)
+			  {LED_SCHEME1, {0x80, -64, -32, -16},
+			   "Djinn Numeris USB"}),
+	 },
+	{
+	 .idVendor = 0x07b0,
+	 .idProduct = 0x0006,
+	 .driver_info = (unsigned long) &((hfcsusb_vdata)
+			  {LED_SCHEME1, {0x80, -64, -32, -16},
+			   "Twister ISDN TA"}),
+	 },
 };
 
-/* driver internal device specific data:
-*   VendorID, ProductID, Devicename, LED_SCHEME,
-*   LED's BitMask in HFCUSB_P_DATA Register : LED_USB, LED_S0, LED_B1, LED_B2
-*/
-static vendor_data vdata[] = {
-	/* CologneChip Eval TA */
-	{0x0959, 0x2bd0, "ISDN USB TA (Cologne Chip HFC-S USB based)",
-	 LED_OFF, {4, 0, 2, 1}
-	 }
-	,
-	/* DrayTek miniVigor 128 USB ISDN TA */
-	{0x0675, 0x1688, "DrayTek miniVigor 128 USB ISDN TA",
-	 LED_SCHEME1, {1, 2, 0, 0}
-	 }
-	,
-	/* Billion TA */
-	{0x07b0, 0x0007, "Billion tiny USB ISDN TA 128",
-	 LED_SCHEME1, {0x80, -64, -32, -16}
-	 }
-	,
-	/* Stollmann TA */
-	{0x0742, 0x2008, "Stollmann USB TA",
-	 LED_SCHEME1, {4, 0, 2, 1}
-	 }
-	,
-	/* Aceex USB ISDN TA */
-	{0x0742, 0x2009, "Aceex USB ISDN TA",
-	 LED_SCHEME1, {4, 0, 2, 1}
-	 }
-	,
-	/* OEM USB ISDN TA */
-	{0x0742, 0x200A, "OEM USB ISDN TA",
-	 LED_SCHEME1, {4, 0, 2, 1}
-	 }
-	,
-	/* Olitec TA  */
-	{0x08e3, 0x0301, "Olitec USB RNIS",
-	 LED_SCHEME1, {2, 0, 1, 4}
-	 }
-	,
-	/* Bewan TA   */
-	{0x07fa, 0x0846, "Bewan Modem RNIS USB",
-	 LED_SCHEME1, {0x80, -64, -32, -16}
-	 }
-	,
-	/* Bewan TA   */
-	{0x07fa, 0x0847, "Djinn Numeris USB",
-	 LED_SCHEME1, {0x80, -64, -32, -16}
-	 }
-	,
-	/* Twister ISDN TA   */
-	{0x07b0, 0x0006, "Twister ISDN TA",
-	 LED_SCHEME1, {0x80, -64, -32, -16}
-	 }
-	,
-	{0, 0, 0}		/* EOL element */
-};
 
 /***************************************************************/
 /* structure defining input+output fifos (interrupt/bulk mode) */
@@ -211,8 +215,6 @@
 	volatile __u8 l1_state;	/* actual l1 state */
 	struct timer_list t3_timer;	/* timer 3 for activation/deactivation */
 	struct timer_list t4_timer;	/* timer 4 for activation/deactivation */
-	struct timer_list led_timer;	/* timer flashing leds */
-
 } hfcusb_data;
 
 
@@ -227,7 +229,7 @@
 	for (i = 0; list[i].name != NULL; i++)
 		if (list[i].num == num)
 			return (list[i].name);
-	return "<unkown>";
+	return "<unkown ERROR>";
 }
 
 
@@ -335,93 +337,57 @@
 	}
 }
 
-/******************************************/
-/* invert B-channel LEDs if data is sent  */
-/******************************************/
-static void
-led_timer(hfcusb_data * hfc)
-{
-	static int cnt = 0;
-
-	if (cnt) {
-		if (hfc->led_b_active & 1)
-			set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[2],
-				    0);
-		if (hfc->led_b_active & 2)
-			set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[3],
-				    0);
-	} else {
-		if (!(hfc->led_b_active & 1) || hfc->led_new_data & 1)
-			set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[2],
-				    1);
-		if (!(hfc->led_b_active & 2) || hfc->led_new_data & 2)
-			set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[3],
-				    1);
-	}
-
-	write_led(hfc, hfc->led_state);
-	hfc->led_new_data = 0;
-
-	cnt = !cnt;
-
-	/* restart 4 hz timer */
-	if (!timer_pending(&hfc->led_timer)) {
-		add_timer(&hfc->led_timer);
-		hfc->led_timer.expires = jiffies + (LED_TIME * HZ) / 1000;
-	}
-}
-
 /**************************/
 /* handle LED requests    */
 /**************************/
 static void
 handle_led(hfcusb_data * hfc, int event)
 {
+	hfcsusb_vdata *driver_info =
+	    (hfcsusb_vdata *) hfcusb_idtab[hfc->vend_idx].driver_info;
+
 	/* if no scheme -> no LED action */
-	if (vdata[hfc->vend_idx].led_scheme == LED_OFF)
+	if (driver_info->led_scheme == LED_OFF)
 		return;
 
 	switch (event) {
 		case LED_POWER_ON:
-			set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[0],
+			set_led_bit(hfc, driver_info->led_bits[0],
 				    0);
-			set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[1],
+			set_led_bit(hfc, driver_info->led_bits[1],
 				    1);
-			set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[2],
+			set_led_bit(hfc, driver_info->led_bits[2],
 				    1);
-			set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[3],
+			set_led_bit(hfc, driver_info->led_bits[3],
 				    1);
 			break;
 		case LED_POWER_OFF:	/* no Power off handling */
 			break;
 		case LED_S0_ON:
-			set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[1],
+			set_led_bit(hfc, driver_info->led_bits[1],
 				    0);
 			break;
 		case LED_S0_OFF:
-			set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[1],
+			set_led_bit(hfc, driver_info->led_bits[1],
 				    1);
 			break;
 		case LED_B1_ON:
-			hfc->led_b_active |= 1;
+			set_led_bit(hfc, driver_info->led_bits[2],
+				    0);
 			break;
 		case LED_B1_OFF:
-			hfc->led_b_active &= ~1;
-			break;
-		case LED_B1_DATA:
-			hfc->led_new_data |= 1;
+			set_led_bit(hfc, driver_info->led_bits[2],
+				    1);
 			break;
 		case LED_B2_ON:
-			hfc->led_b_active |= 2;
+			set_led_bit(hfc, driver_info->led_bits[3],
+				    0);
 			break;
 		case LED_B2_OFF:
-			hfc->led_b_active &= ~2;
-			break;
-		case LED_B2_DATA:
-			hfc->led_new_data |= 2;
+			set_led_bit(hfc, driver_info->led_bits[3],
+				    1);
 			break;
 	}
-
 	write_led(hfc, hfc->led_state);
 }
 
@@ -725,14 +691,6 @@
 				    current_len + 1;
 
 				tx_offset += (current_len + 1);
-				if (!transp_mode) {
-					if (fifon == HFCUSB_B1_TX)
-						handle_led(hfc,
-							   LED_B1_DATA);
-					if (fifon == HFCUSB_B2_TX)
-						handle_led(hfc,
-							   LED_B2_DATA);
-				}
 			} else {
 				urb->iso_frame_desc[k].offset =
 				    tx_offset++;
@@ -966,14 +924,6 @@
 			skb_trim(fifo->skbuff, 0);
 		}
 	}
-
-	/* LED flashing only in HDLC mode */
-	if (!transp_mode) {
-		if (fifon == HFCUSB_B1_RX)
-			handle_led(hfc, LED_B1_DATA);
-		if (fifon == HFCUSB_B2_RX)
-			handle_led(hfc, LED_B2_DATA);
-	}
 }
 
 /***********************************************/
@@ -1339,17 +1289,6 @@
 	hfc->t4_timer.data = (long) hfc;
 	hfc->t4_timer.function = (void *) l1_timer_expire_t4;
 
-	/* init the led timer */
-	init_timer(&hfc->led_timer);
-	hfc->led_timer.data = (long) hfc;
-	hfc->led_timer.function = (void *) led_timer;
-
-	/* trigger 4 hz led timer */
-	if (!timer_pending(&hfc->led_timer)) {
-		hfc->led_timer.expires = jiffies + (LED_TIME * HZ) / 1000;
-		add_timer(&hfc->led_timer);
-	}
-
 	/* init the background machinery for control requests */
 	hfc->ctrl_read.bRequestType = 0xc0;
 	hfc->ctrl_read.bRequest = 1;
@@ -1440,13 +1379,18 @@
 	    attr, cfg_found, cidx, ep_addr;
 	int cmptbl[16], small_match, iso_packet_size, packet_size,
 	    alt_used = 0;
+	hfcsusb_vdata *driver_info;
 
 	vend_idx = 0xffff;
-	for (i = 0; vdata[i].vendor; i++) {
-		if (dev->descriptor.idVendor == vdata[i].vendor
-		    && dev->descriptor.idProduct == vdata[i].prod_id)
+	for (i = 0; hfcusb_idtab[i].idVendor; i++) {
+		if (dev->descriptor.idVendor == hfcusb_idtab[i].idVendor
+		    && dev->descriptor.idProduct ==
+		    hfcusb_idtab[i].idProduct) {
 			vend_idx = i;
+			continue;
+		}
 	}
+
 #ifdef CONFIG_HISAX_DEBUG
 	DBG(USB_DBG,
 	    "HFC-USB: probing interface(%d) actalt(%d) minor(%d)\n", ifnum,
@@ -1457,10 +1401,6 @@
 	       ifnum, iface->desc.bAlternateSetting, intf->minor);
 
 	if (vend_idx != 0xffff) {
-#ifdef CONFIG_HISAX_DEBUG
-		DBG(USB_DBG, "HFC-S USB: found vendor idx:%d  name:%s",
-		    vend_idx, vdata[vend_idx].vend_name);
-#endif
 		/* if vendor and product ID is OK, start probing alternate settings */
 		alt_idx = 0;
 		small_match = 0xffff;
@@ -1687,9 +1627,11 @@
 			    usb_sndctrlpipe(context->dev, 0);
 			context->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);
 
-			printk(KERN_INFO
-			       "HFC-S USB: detected \"%s\"\n",
-			       vdata[vend_idx].vend_name);
+			driver_info =
+			    (hfcsusb_vdata *) hfcusb_idtab[vend_idx].
+			    driver_info;
+			printk(KERN_INFO "HFC-S USB: detected \"%s\"\n",
+			       driver_info->vend_name);
 #ifdef CONFIG_HISAX_DEBUG
 			DBG(USB_DBG,
 			    "HFC-S USB: Endpoint-Config: %s (if=%d alt=%d)\n",
@@ -1740,8 +1682,6 @@
 		del_timer(&context->t3_timer);
 	if (timer_pending(&context->t4_timer))
 		del_timer(&context->t4_timer);
-	if (timer_pending(&context->led_timer))
-		del_timer(&context->led_timer);
 	/* tell all fifos to terminate */
 	for (i = 0; i < HFCUSB_NUM_FIFOS; i++) {
 		if (context->fifos[i].usb_transfer_mode == USB_ISOC) {
@@ -1785,9 +1725,11 @@
 /* our driver information structure */
 /************************************/
 static struct usb_driver hfc_drv = {
-	.owner = THIS_MODULE,.name =
-	    "hfc_usb",.id_table = hfc_usb_idtab,.probe =
-	    hfc_usb_probe,.disconnect = hfc_usb_disconnect,
+	.owner = THIS_MODULE,
+	.name  = "hfc_usb",
+	.id_table = hfcusb_idtab,
+	.probe = hfc_usb_probe,
+	.disconnect = hfc_usb_disconnect,
 };
 static void __exit
 hfc_usb_exit(void)
@@ -1825,4 +1767,4 @@
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(usb, hfc_usb_idtab);
+MODULE_DEVICE_TABLE(usb, hfcusb_idtab);
diff --git a/drivers/isdn/hisax/hfc_usb.h b/drivers/isdn/hisax/hfc_usb.h
index 280dd29..ec52c1a 100644
--- a/drivers/isdn/hisax/hfc_usb.h
+++ b/drivers/isdn/hisax/hfc_usb.h
@@ -1,7 +1,7 @@
 /*
 * hfc_usb.h
 *
-* $Id: hfc_usb.h,v 4.1 2005/01/26 17:25:53 martinb1 Exp $
+* $Id: hfc_usb.h,v 4.2 2005/04/07 15:27:17 martinb1 Exp $
 */
 
 #ifndef __HFC_USB_H__
@@ -91,7 +91,7 @@
 /**********/
 /* macros */
 /**********/
-#define write_usb(a,b,c)usb_control_msg((a)->dev,(a)->ctrl_out_pipe,0,0x40,(c),(b),0,0,HFC_CTRL_TIMEOUT)
+#define write_usb(a,b,c)usb_control_msg((a)->dev,(a)->ctrl_out_pipe,0,0x40,(c),(b),NULL,0,HFC_CTRL_TIMEOUT)
 #define read_usb(a,b,c) usb_control_msg((a)->dev,(a)->ctrl_in_pipe,1,0xC0,0,(b),(c),1,HFC_CTRL_TIMEOUT)
 
 
@@ -186,6 +186,7 @@
 	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}	// EOL element
 };
 
+#ifdef CONFIG_HISAX_DEBUG
 // string description of chosen config
 static char *conf_str[] = {
 	"4 Interrupt IN + 3 Isochron OUT",
@@ -193,6 +194,7 @@
 	"4 Isochron IN + 3 Isochron OUT",
 	"3 Isochron IN + 3 Isochron OUT"
 };
+#endif
 
 
 typedef struct {
diff --git a/drivers/isdn/hisax/hscx.c b/drivers/isdn/hisax/hscx.c
index 66dbaee..c8f9951 100644
--- a/drivers/isdn/hisax/hscx.c
+++ b/drivers/isdn/hisax/hscx.c
@@ -156,14 +156,10 @@
 {
 	modehscx(bcs, 0, bcs->channel);
 	if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
-		if (bcs->hw.hscx.rcvbuf) {
-			kfree(bcs->hw.hscx.rcvbuf);
-			bcs->hw.hscx.rcvbuf = NULL;
-		}
-		if (bcs->blog) {
-			kfree(bcs->blog);
-			bcs->blog = NULL;
-		}
+		kfree(bcs->hw.hscx.rcvbuf);
+		bcs->hw.hscx.rcvbuf = NULL;
+		kfree(bcs->blog);
+		bcs->blog = NULL;
 		skb_queue_purge(&bcs->rqueue);
 		skb_queue_purge(&bcs->squeue);
 		if (bcs->tx_skb) {
diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c
index b4ca585..c615752 100644
--- a/drivers/isdn/hisax/icc.c
+++ b/drivers/isdn/hisax/icc.c
@@ -571,14 +571,10 @@
 
 static void
 DC_Close_icc(struct IsdnCardState *cs) {
-	if (cs->dc.icc.mon_rx) {
-		kfree(cs->dc.icc.mon_rx);
-		cs->dc.icc.mon_rx = NULL;
-	}
-	if (cs->dc.icc.mon_tx) {
-		kfree(cs->dc.icc.mon_tx);
-		cs->dc.icc.mon_tx = NULL;
-	}
+	kfree(cs->dc.icc.mon_rx);
+	cs->dc.icc.mon_rx = NULL;
+	kfree(cs->dc.icc.mon_tx);
+	cs->dc.icc.mon_tx = NULL;
 }
 
 static void
diff --git a/drivers/isdn/hisax/ipacx.c b/drivers/isdn/hisax/ipacx.c
index efba2f4..2e9afae 100644
--- a/drivers/isdn/hisax/ipacx.c
+++ b/drivers/isdn/hisax/ipacx.c
@@ -762,14 +762,10 @@
 {
 	bch_mode(bcs, 0, bcs->channel);
 	if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
-		if (bcs->hw.hscx.rcvbuf) {
-			kfree(bcs->hw.hscx.rcvbuf);
-			bcs->hw.hscx.rcvbuf = NULL;
-		}
-		if (bcs->blog) {
-			kfree(bcs->blog);
-			bcs->blog = NULL;
-		}
+		kfree(bcs->hw.hscx.rcvbuf);
+		bcs->hw.hscx.rcvbuf = NULL;
+		kfree(bcs->blog);
+		bcs->blog = NULL;
 		skb_queue_purge(&bcs->rqueue);
 		skb_queue_purge(&bcs->squeue);
 		if (bcs->tx_skb) {
diff --git a/drivers/isdn/hisax/isac.c b/drivers/isdn/hisax/isac.c
index 85e063a..565b789 100644
--- a/drivers/isdn/hisax/isac.c
+++ b/drivers/isdn/hisax/isac.c
@@ -570,15 +570,12 @@
 }
 
 static void
-DC_Close_isac(struct IsdnCardState *cs) {
-	if (cs->dc.isac.mon_rx) {
-		kfree(cs->dc.isac.mon_rx);
-		cs->dc.isac.mon_rx = NULL;
-	}
-	if (cs->dc.isac.mon_tx) {
-		kfree(cs->dc.isac.mon_tx);
-		cs->dc.isac.mon_tx = NULL;
-	}
+DC_Close_isac(struct IsdnCardState *cs)
+{
+	kfree(cs->dc.isac.mon_rx);
+	cs->dc.isac.mon_rx = NULL;
+	kfree(cs->dc.isac.mon_tx);
+	cs->dc.isac.mon_tx = NULL;
 }
 
 static void
diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c
index 642a87c..674af67 100644
--- a/drivers/isdn/hisax/isar.c
+++ b/drivers/isdn/hisax/isar.c
@@ -1688,10 +1688,8 @@
 {
 	modeisar(bcs, 0, bcs->channel);
 	if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
-		if (bcs->hw.isar.rcvbuf) {
-			kfree(bcs->hw.isar.rcvbuf);
-			bcs->hw.isar.rcvbuf = NULL;
-		}
+		kfree(bcs->hw.isar.rcvbuf);
+		bcs->hw.isar.rcvbuf = NULL;
 		skb_queue_purge(&bcs->rqueue);
 		skb_queue_purge(&bcs->squeue);
 		if (bcs->tx_skb) {
diff --git a/drivers/isdn/hisax/jade.c b/drivers/isdn/hisax/jade.c
index 363ae31..2659fec 100644
--- a/drivers/isdn/hisax/jade.c
+++ b/drivers/isdn/hisax/jade.c
@@ -195,14 +195,10 @@
 {
     modejade(bcs, 0, bcs->channel);
     if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
-	if (bcs->hw.hscx.rcvbuf) {
-		kfree(bcs->hw.hscx.rcvbuf);
-		bcs->hw.hscx.rcvbuf = NULL;
-	}
-	if (bcs->blog) {
-		kfree(bcs->blog);
-		bcs->blog = NULL;
-	}
+	kfree(bcs->hw.hscx.rcvbuf);
+	bcs->hw.hscx.rcvbuf = NULL;
+	kfree(bcs->blog);
+	bcs->blog = NULL;
 	skb_queue_purge(&bcs->rqueue);
 	skb_queue_purge(&bcs->squeue);
 	if (bcs->tx_skb) {
diff --git a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c
index 94da03c..47a47ef 100644
--- a/drivers/isdn/hisax/netjet.c
+++ b/drivers/isdn/hisax/netjet.c
@@ -855,14 +855,10 @@
 {
 	mode_tiger(bcs, 0, bcs->channel);
 	if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
-		if (bcs->hw.tiger.rcvbuf) {
-			kfree(bcs->hw.tiger.rcvbuf);
-			bcs->hw.tiger.rcvbuf = NULL;
-		}
-		if (bcs->hw.tiger.sendbuf) {
-			kfree(bcs->hw.tiger.sendbuf);
-			bcs->hw.tiger.sendbuf = NULL;
-		}
+		kfree(bcs->hw.tiger.rcvbuf);
+		bcs->hw.tiger.rcvbuf = NULL;
+		kfree(bcs->hw.tiger.sendbuf);
+		bcs->hw.tiger.sendbuf = NULL;
 		skb_queue_purge(&bcs->rqueue);
 		skb_queue_purge(&bcs->squeue);
 		if (bcs->tx_skb) {
@@ -967,20 +963,12 @@
 static void
 releasetiger(struct IsdnCardState *cs)
 {
-	if (cs->bcs[0].hw.tiger.send) {
-		kfree(cs->bcs[0].hw.tiger.send);
-		cs->bcs[0].hw.tiger.send = NULL;
-	}
-	if (cs->bcs[1].hw.tiger.send) {
-		cs->bcs[1].hw.tiger.send = NULL;
-	}
-	if (cs->bcs[0].hw.tiger.rec) {
-		kfree(cs->bcs[0].hw.tiger.rec);
-		cs->bcs[0].hw.tiger.rec = NULL;
-	}
-	if (cs->bcs[1].hw.tiger.rec) {
-		cs->bcs[1].hw.tiger.rec = NULL;
-	}
+	kfree(cs->bcs[0].hw.tiger.send);
+	cs->bcs[0].hw.tiger.send = NULL;
+	cs->bcs[1].hw.tiger.send = NULL;
+	kfree(cs->bcs[0].hw.tiger.rec);
+	cs->bcs[0].hw.tiger.rec = NULL;
+	cs->bcs[1].hw.tiger.rec = NULL;
 }
 
 void
diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c
index 89fbeb5..b096b64 100644
--- a/drivers/isdn/hisax/st5481_usb.c
+++ b/drivers/isdn/hisax/st5481_usb.c
@@ -335,14 +335,12 @@
 
 	// Stop and free Control and Interrupt URBs
 	usb_kill_urb(ctrl->urb);
-	if (ctrl->urb->transfer_buffer)
-		kfree(ctrl->urb->transfer_buffer);
+	kfree(ctrl->urb->transfer_buffer);
 	usb_free_urb(ctrl->urb);
 	ctrl->urb = NULL;
 
 	usb_kill_urb(intr->urb);
-	if (intr->urb->transfer_buffer)
-		kfree(intr->urb->transfer_buffer);
+	kfree(intr->urb->transfer_buffer);
 	usb_free_urb(intr->urb);
 	ctrl->urb = NULL;
 }
@@ -457,8 +455,7 @@
  err:
 	for (j = 0; j < 2; j++) {
 		if (urb[j]) {
-			if (urb[j]->transfer_buffer)
-				kfree(urb[j]->transfer_buffer);
+			kfree(urb[j]->transfer_buffer);
 			urb[j]->transfer_buffer = NULL;
 			usb_free_urb(urb[j]);
 			urb[j] = NULL;
@@ -473,8 +470,7 @@
 
 	for (j = 0; j < 2; j++) {
 		usb_kill_urb(urb[j]);
-		if (urb[j]->transfer_buffer)
-			kfree(urb[j]->transfer_buffer);			
+		kfree(urb[j]->transfer_buffer);
 		usb_free_urb(urb[j]);
 		urb[j] = NULL;
 	}
diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c
index 7baf8e4..0352ee5 100644
--- a/drivers/isdn/hisax/w6692.c
+++ b/drivers/isdn/hisax/w6692.c
@@ -819,14 +819,10 @@
 {
 	W6692Bmode(bcs, 0, bcs->channel);
 	if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
-		if (bcs->hw.w6692.rcvbuf) {
-			kfree(bcs->hw.w6692.rcvbuf);
-			bcs->hw.w6692.rcvbuf = NULL;
-		}
-		if (bcs->blog) {
-			kfree(bcs->blog);
-			bcs->blog = NULL;
-		}
+		kfree(bcs->hw.w6692.rcvbuf);
+		bcs->hw.w6692.rcvbuf = NULL;
+		kfree(bcs->blog);
+		bcs->blog = NULL;
 		skb_queue_purge(&bcs->rqueue);
 		skb_queue_purge(&bcs->squeue);
 		if (bcs->tx_skb) {
diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c
index 639582f..87f59a0 100644
--- a/drivers/isdn/hysdn/hysdn_procconf.c
+++ b/drivers/isdn/hysdn/hysdn_procconf.c
@@ -359,8 +359,7 @@
 	} else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
 		/* read access -> output card info data */
 
-		if (filep->private_data)
-			kfree(filep->private_data);	/* release memory */
+		kfree(filep->private_data);	/* release memory */
 	}
 	unlock_kernel();
 	return (retval);
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index d97a9be..1a19a0f 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -364,10 +364,8 @@
 		isdn_net_hangup(&p->dev);
 	}
 	for (i = 0; i < NUM_RCV_BUFFS; i++) {
-		if (is->rq[i].buf) {
-			kfree(is->rq[i].buf);
-			is->rq[i].buf = NULL;
-		}
+		kfree(is->rq[i].buf);
+		is->rq[i].buf = NULL;
 	}
 	is->first = is->rq + NUM_RCV_BUFFS - 1;	/* receive queue */
 	is->last = is->rq;
@@ -378,14 +376,10 @@
 	is->slcomp = NULL;
 #endif
 #ifdef CONFIG_IPPP_FILTER
-	if (is->pass_filter) {
-		kfree(is->pass_filter);
-		is->pass_filter = NULL;
-	}
-	if (is->active_filter) {
-		kfree(is->active_filter);
-		is->active_filter = NULL;
-	}
+	kfree(is->pass_filter);
+	is->pass_filter = NULL;
+	kfree(is->active_filter);
+	is->active_filter = NULL;
 #endif
 
 /* TODO: if this was the previous master: link the stuff to the new master */
@@ -914,8 +908,7 @@
 		kfree(ippp_table[i]);
 
 #ifdef CONFIG_ISDN_MPP
-	if (isdn_ppp_bundle_arr)
-		kfree(isdn_ppp_bundle_arr);
+	kfree(isdn_ppp_bundle_arr);
 #endif /* CONFIG_ISDN_MPP */
 
 }
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index b37ef1f..8c404b4 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -712,22 +712,14 @@
 #endif
 	info->emu.vpar[4] = 0;
 	info->emu.vpar[5] = 8;
-	if (info->dtmf_state) {
-		kfree(info->dtmf_state);
-		info->dtmf_state = NULL;
-	}
-	if (info->silence_state) {
-		kfree(info->silence_state);
-		info->silence_state = NULL;
-	}
-	if (info->adpcms) {
-		kfree(info->adpcms);
-		info->adpcms = NULL;
-	}
-	if (info->adpcmr) {
-		kfree(info->adpcmr);
-		info->adpcmr = NULL;
-	}
+	kfree(info->dtmf_state);
+	info->dtmf_state = NULL;
+	kfree(info->silence_state);
+	info->silence_state = NULL;
+	kfree(info->adpcms);
+	info->adpcms = NULL;
+	kfree(info->adpcmr);
+	info->adpcmr = NULL;
 #endif
 	if ((info->msr & UART_MSR_RI) &&
 		(info->emu.mdmreg[REG_RUNG] & BIT_RUNG))
@@ -1721,8 +1713,7 @@
 		 */
 		timeout = jiffies + HZ;
 		while (!(info->lsr & UART_LSR_TEMT)) {
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(20);
+			schedule_timeout_interruptible(20);
 			if (time_after(jiffies,timeout))
 				break;
 		}
diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c
index 386df71..6649f8b 100644
--- a/drivers/isdn/icn/icn.c
+++ b/drivers/isdn/icn/icn.c
@@ -947,8 +947,7 @@
 				icn_maprelease_channel(card, 0);
 				return -EIO;
 			}
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(10);
+			schedule_timeout_interruptible(10);
 		}
 	}
 	writeb(0x20, &sbuf_n);
diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c
index 14e1f8f..33d3397 100644
--- a/drivers/isdn/isdnloop/isdnloop.c
+++ b/drivers/isdn/isdnloop/isdnloop.c
@@ -1161,12 +1161,9 @@
 					if (a) {
 						if (!card->leased) {
 							card->leased = 1;
-							while (card->ptype == ISDN_PTYPE_UNKNOWN) {
-								set_current_state(TASK_INTERRUPTIBLE);
-								schedule_timeout(10);
-							}
-							set_current_state(TASK_INTERRUPTIBLE);
-							schedule_timeout(10);
+							while (card->ptype == ISDN_PTYPE_UNKNOWN)
+								schedule_timeout_interruptible(10);
+							schedule_timeout_interruptible(10);
 							sprintf(cbuf, "00;FV2ON\n01;EAZ1\n02;EAZ2\n");
 							i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
 							printk(KERN_INFO
diff --git a/drivers/isdn/pcbit/drv.c b/drivers/isdn/pcbit/drv.c
index 5de861f..94f2148 100644
--- a/drivers/isdn/pcbit/drv.c
+++ b/drivers/isdn/pcbit/drv.c
@@ -561,10 +561,8 @@
 		else
 			pcbit_fsm_event(dev, chan, EV_USR_RELEASE_REQ, NULL);
 
-		if (cbdata.data.setup.CalledPN)
-			kfree(cbdata.data.setup.CalledPN);
-		if (cbdata.data.setup.CallingPN)
-			kfree(cbdata.data.setup.CallingPN);
+		kfree(cbdata.data.setup.CalledPN);
+		kfree(cbdata.data.setup.CallingPN);
 		break;
     
 	case MSG_CONN_CONF:
diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c
index 1ebed04..62b7acf 100644
--- a/drivers/isdn/sc/init.c
+++ b/drivers/isdn/sc/init.c
@@ -529,8 +529,7 @@
 	 */
 	x = 0;
 	while((inb(iobase + FIFOSTAT_OFFSET) & RF_HAS_DATA) && x < 100) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_interruptible(1);
 		x++;
 	}
 	if(x == 100) {
diff --git a/drivers/isdn/sc/message.c b/drivers/isdn/sc/message.c
index ca204da..0a0fe6b 100644
--- a/drivers/isdn/sc/message.c
+++ b/drivers/isdn/sc/message.c
@@ -208,8 +208,7 @@
 	tries = 0;
 	/* wait for the response */
 	while (tries < timeout) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_interruptible(1);
 		
 		pr_debug("SAR waiting..\n");
 
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
index 8f02c15..c0b46bc 100644
--- a/drivers/macintosh/adbhid.c
+++ b/drivers/macintosh/adbhid.c
@@ -857,8 +857,7 @@
 static void adbhid_input_unregister(int id)
 {
 	input_unregister_device(adbhid[id]->input);
-	if (adbhid[id]->keycode)
-		kfree(adbhid[id]->keycode);
+	kfree(adbhid[id]->keycode);
 	kfree(adbhid[id]);
 	adbhid[id] = NULL;
 }
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index cc507ce..3fc8cdd 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -1678,10 +1678,9 @@
 		}
 
 		// FIXME: Deal with signals
-		set_current_state(TASK_INTERRUPTIBLE);
 		elapsed = jiffies - start;
 		if (elapsed < HZ)
-			schedule_timeout(HZ - elapsed);
+			schedule_timeout_interruptible(HZ - elapsed);
 	}
 
  out:
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 6497295..1223e98 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -1587,8 +1587,7 @@
 		/* make sure we don't swamp the stripe cache if someone else
 		 * is trying to get access 
 		 */
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	}
 	bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 0);
 	spin_lock(&sh->lock);	
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c
index 6437a95..7757869 100644
--- a/drivers/md/raid6main.c
+++ b/drivers/md/raid6main.c
@@ -1746,8 +1746,7 @@
 		/* make sure we don't swamp the stripe cache if someone else
 		 * is trying to get access
 		 */
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	}
 	bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 0);
 	spin_lock(&sh->lock);
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index 34a837a..b3c9d73 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -1331,9 +1331,7 @@
 {
 	/* check if the ASIC is there */
 	if (dst_probe(state) < 0) {
-		if (state)
-			kfree(state);
-
+		kfree(state);
 		return NULL;
 	}
 	/* determine settings based on type */
@@ -1349,9 +1347,7 @@
 		break;
 	default:
 		dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist.");
-		if (state)
-			kfree(state);
-
+		kfree(state);
 		return NULL;
 	}
 
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
index d4b9798..654d7dc 100644
--- a/drivers/media/dvb/frontends/cx24110.c
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -27,6 +27,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
+#include <linux/jiffies.h>
 
 #include "dvb_frontend.h"
 #include "cx24110.h"
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb/frontends/dvb_dummy_fe.c
index 794be52..645946a 100644
--- a/drivers/media/dvb/frontends/dvb_dummy_fe.c
+++ b/drivers/media/dvb/frontends/dvb_dummy_fe.c
@@ -148,7 +148,7 @@
 	return &state->frontend;
 
 error:
-	if (state) kfree(state);
+	kfree(state);
 	return NULL;
 }
 
@@ -171,7 +171,7 @@
 	return &state->frontend;
 
 error:
-	if (state) kfree(state);
+	kfree(state);
 	return NULL;
 }
 
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c
index faaad1a..19b4bf7 100644
--- a/drivers/media/dvb/frontends/l64781.c
+++ b/drivers/media/dvb/frontends/l64781.c
@@ -559,7 +559,8 @@
 	return &state->frontend;
 
 error:
-	if (reg0x3e >= 0) l64781_writereg (state, 0x3e, reg0x3e);  /* restore reg 0x3e */
+	if (reg0x3e >= 0)
+		l64781_writereg (state, 0x3e, reg0x3e);  /* restore reg 0x3e */
 	kfree(state);
 	return NULL;
 }
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
index 8dde72b..7852b83 100644
--- a/drivers/media/dvb/frontends/lgdt330x.c
+++ b/drivers/media/dvb/frontends/lgdt330x.c
@@ -731,8 +731,7 @@
 	return &state->frontend;
 
 error:
-	if (state)
-		kfree(state);
+	kfree(state);
 	dprintk("%s: ERROR\n",__FUNCTION__);
 	return NULL;
 }
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
index e384549..9c67f40 100644
--- a/drivers/media/dvb/frontends/mt312.c
+++ b/drivers/media/dvb/frontends/mt312.c
@@ -677,8 +677,7 @@
 	return &state->frontend;
 
 error:
-	if (state)
-		kfree(state);
+	kfree(state);
 	return NULL;
 }
 
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c
index 817b044..fc74c40 100644
--- a/drivers/media/dvb/frontends/or51132.c
+++ b/drivers/media/dvb/frontends/or51132.c
@@ -577,8 +577,7 @@
 	return &state->frontend;
 
 error:
-	if (state)
-		kfree(state);
+	kfree(state);
 	return NULL;
 }
 
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index 87fd3a7..0823dda 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -865,10 +865,8 @@
 
 out_irq:
 #endif
-	for (i = 0; i < MAX_AR_HEIGHT; i++) {
-		if (ar->frame[i])
-			kfree(ar->frame[i]);
-	}
+	for (i = 0; i < MAX_AR_HEIGHT; i++)
+		kfree(ar->frame[i]);
 
 out_line_buff:
 #if USE_INT
@@ -899,10 +897,8 @@
 #if USE_INT
 	free_irq(M32R_IRQ_INT3, ar);
 #endif
-	for (i = 0; i < MAX_AR_HEIGHT; i++) {
-		if (ar->frame[i])
-			kfree(ar->frame[i]);
-	}
+	for (i = 0; i < MAX_AR_HEIGHT; i++)
+		kfree(ar->frame[i]);
 #if USE_INT
 	kfree(ar->line_buff);
 #endif
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index c062a01..d538a99 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -1951,8 +1951,7 @@
 	}
 
 	down(&fh->cap.lock);
-	if (fh->ov.clips)
-		kfree(fh->ov.clips);
+	kfree(fh->ov.clips);
 	fh->ov.clips    = clips;
 	fh->ov.nclips   = n;
 
@@ -2723,8 +2722,7 @@
 			fh->ov.w.height = fb->fmt.height;
 			btv->init.ov.w.width  = fb->fmt.width;
 			btv->init.ov.w.height = fb->fmt.height;
-			if (fh->ov.clips)
-				kfree(fh->ov.clips);
+			kfree(fh->ov.clips);
 			fh->ov.clips = NULL;
 			fh->ov.nclips = 0;
 
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
index 262890c..e75e794 100644
--- a/drivers/media/video/msp3400.c
+++ b/drivers/media/video/msp3400.c
@@ -741,8 +741,8 @@
 			set_current_state(TASK_INTERRUPTIBLE);
 			schedule();
 		} else {
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(msecs_to_jiffies(timeout));
+			schedule_timeout_interruptible
+						(msecs_to_jiffies(timeout));
 		}
 	}
 
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
index badf2f9..61a2d6b 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -342,8 +342,8 @@
 			set_current_state(TASK_INTERRUPTIBLE);
 			schedule();
 		} else {
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(msecs_to_jiffies(timeout));
+			schedule_timeout_interruptible
+						(msecs_to_jiffies(timeout));
 		}
 	}
 	remove_wait_queue(&dev->thread.wq, &wait);
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index 59bb713..d679ca2 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -1006,10 +1006,8 @@
 		break;
 	}
 
-	if (cap2)
-		kfree(cap2);
-	if (fmt2)
-		kfree(fmt2);
+	kfree(cap2);
+	kfree(fmt2);
 	return err;
 }
 
diff --git a/drivers/media/video/videocodec.c b/drivers/media/video/videocodec.c
index c9d5f1a..839db62 100644
--- a/drivers/media/video/videocodec.c
+++ b/drivers/media/video/videocodec.c
@@ -353,8 +353,7 @@
 	dprintk(3, "videocodec_build table: %d entries, %d bytes\n", i,
 		size);
 
-	if (videocodec_buf)
-		kfree(videocodec_buf);
+	kfree(videocodec_buf);
 	videocodec_buf = (char *) kmalloc(size, GFP_KERNEL);
 
 	i = 0;
@@ -471,8 +470,7 @@
 {
 #ifdef CONFIG_PROC_FS
 	remove_proc_entry("videocodecs", NULL);
-	if (videocodec_buf)
-		kfree(videocodec_buf);
+	kfree(videocodec_buf);
 #endif
 }
 
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 06df15f..83c49f9 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -215,8 +215,7 @@
 	}
 
 out:
-	if (mbuf)
-		kfree(mbuf);
+	kfree(mbuf);
 	return err;
 }
 
diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c
index eed2ace..39a0d23 100644
--- a/drivers/media/video/zoran_card.c
+++ b/drivers/media/video/zoran_card.c
@@ -1057,10 +1057,8 @@
 			KERN_ERR
 			"%s: zr36057_init() - kmalloc (STAT_COM) failed\n",
 			ZR_DEVNAME(zr));
-		if (vdev)
-			kfree(vdev);
-		if (mem)
-			kfree((void *)mem);
+		kfree(vdev);
+		kfree((void *)mem);
 		return -ENOMEM;
 	}
 	memset((void *) mem, 0, mem_needed);
@@ -1105,15 +1103,15 @@
 	/* unregister videocodec bus */
 	if (zr->codec) {
 		struct videocodec_master *master = zr->codec->master_data;
+
 		videocodec_detach(zr->codec);
-		if (master)
-			kfree(master);
+		kfree(master);
 	}
 	if (zr->vfe) {
 		struct videocodec_master *master = zr->vfe->master_data;
+
 		videocodec_detach(zr->vfe);
-		if (master)
-			kfree(master);
+		kfree(master);
 	}
 
 	/* unregister i2c bus */
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
index 53adeb7..07bde9a 100644
--- a/drivers/media/video/zoran_driver.c
+++ b/drivers/media/video/zoran_driver.c
@@ -996,8 +996,6 @@
 		return -EINVAL;
 	}
 
-	spin_lock_irqsave(&zr->spinlock, flags);
-
 	if (fh->jpg_buffers.active == ZORAN_FREE) {
 		if (zr->jpg_buffers.active == ZORAN_FREE) {
 			zr->jpg_buffers = fh->jpg_buffers;
@@ -1016,6 +1014,8 @@
 		zr36057_enable_jpg(zr, mode);
 	}
 
+	spin_lock_irqsave(&zr->spinlock, flags);
+
 	if (!res) {
 		switch (zr->jpg_buffers.buffer[num].state) {
 		case BUZ_STATE_DONE:
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
index ed3c891..014085d 100644
--- a/drivers/message/fusion/mptlan.c
+++ b/drivers/message/fusion/mptlan.c
@@ -511,7 +511,7 @@
 {
 	struct mpt_lan_priv *priv = netdev_priv(dev);
 	MPT_ADAPTER *mpt_dev = priv->mpt_dev;
-	unsigned int timeout;
+	unsigned long timeout;
 	int i;
 
 	dlprintk((KERN_INFO MYNAM ": mpt_lan_close called\n"));
@@ -526,11 +526,9 @@
 
 	mpt_lan_reset(dev);
 
-	timeout = 2 * HZ;
-	while (atomic_read(&priv->buckets_out) && --timeout) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
-	}
+	timeout = jiffies + 2 * HZ;
+	while (atomic_read(&priv->buckets_out) && time_before(jiffies, timeout))
+		schedule_timeout_interruptible(1);
 
 	for (i = 0; i < priv->max_buckets_out; i++) {
 		if (priv->RcvCtl[i].skb != NULL) {
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 5cb07eb2..4330ed0 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1013,10 +1013,8 @@
 	spin_lock_irqsave(&dvtaskQ_lock, flags);
 	if (dvtaskQ_active) {
 		spin_unlock_irqrestore(&dvtaskQ_lock, flags);
-		while(dvtaskQ_active && --count) {
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(1);
-		}
+		while(dvtaskQ_active && --count)
+			schedule_timeout_interruptible(1);
 	} else {
 		spin_unlock_irqrestore(&dvtaskQ_lock, flags);
 	}
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
index b675b4e..9c339a2 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/message/i2o/exec-osm.c
@@ -33,6 +33,7 @@
 #include <linux/workqueue.h>
 #include <linux/string.h>
 #include <linux/slab.h>
+#include <linux/sched.h>   /* wait_event_interruptible_timeout() needs this */
 #include <asm/param.h>		/* HZ */
 #include "core.h"
 
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c
index 61b837d..4eb5325 100644
--- a/drivers/message/i2o/iop.c
+++ b/drivers/message/i2o/iop.c
@@ -93,8 +93,7 @@
 				  c->name);
 			return I2O_QUEUE_EMPTY;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	}
 
 	return m;
@@ -485,8 +484,7 @@
 			osm_warn("%s: Timeout Initializing\n", c->name);
 			return -ETIMEDOUT;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	}
 
 	m = c->out_queue.phys;
@@ -548,8 +546,7 @@
 		if (time_after(jiffies, timeout))
 			break;
 
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	}
 
 	switch (*status) {
@@ -577,8 +574,7 @@
 				rc = -ETIMEDOUT;
 				goto exit;
 			}
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
+			schedule_timeout_uninterruptible(1);
 
 			m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_RESET);
 		}
@@ -989,8 +985,7 @@
 			return -ETIMEDOUT;
 		}
 
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	}
 
 #ifdef DEBUG
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c
index c75d713..55ba230 100644
--- a/drivers/mfd/mcp-core.c
+++ b/drivers/mfd/mcp-core.c
@@ -15,6 +15,8 @@
 #include <linux/errno.h>
 #include <linux/smp.h>
 #include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/string.h>
 
 #include <asm/dma.h>
 #include <asm/system.h>
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index 4ff67e7..e954b83 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -1602,8 +1602,7 @@
 	if (host->dma_addr)
 		dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE,
 			DMA_BIDIRECTIONAL);
-	if (host->dma_buffer)
-		kfree(host->dma_buffer);
+	kfree(host->dma_buffer);
 	if (host->dma >= 0)
 		free_dma(host->dma);
 
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 0cfcd88..c3fc9b2 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -455,8 +455,7 @@
 
  setup_err:
 	if(mtd) {
-		if(mtd->eraseregions)
-			kfree(mtd->eraseregions);
+		kfree(mtd->eraseregions);
 		kfree(mtd);
 	}
 	kfree(cfi->cmdset_priv);
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 8505f11..0e64750 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -378,8 +378,7 @@
 
  setup_err:
 	if(mtd) {
-		if(mtd->eraseregions)
-			kfree(mtd->eraseregions);
+		kfree(mtd->eraseregions);
 		kfree(mtd);
 	}
 	kfree(cfi->cmdset_priv);
@@ -1742,6 +1741,7 @@
 {
 	struct map_info *map = mtd->priv;
 	struct cfi_private *cfi = map->fldrv_priv;
+
 	kfree(cfi->cmdset_priv);
 	kfree(cfi->cfiq);
 	kfree(cfi);
diff --git a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c
index 662e807..59a29e6 100644
--- a/drivers/mtd/devices/blkmtd.c
+++ b/drivers/mtd/devices/blkmtd.c
@@ -539,11 +539,8 @@
 {
 	DEBUG(2, "blkmtd: free_device() dev = %p\n", dev);
 	if(dev) {
-		if(dev->mtd_info.eraseregions)
-			kfree(dev->mtd_info.eraseregions);
-		if(dev->mtd_info.name)
-			kfree(dev->mtd_info.name);
-
+		kfree(dev->mtd_info.eraseregions);
+		kfree(dev->mtd_info.name);
 		if(dev->blkdev) {
 			invalidate_inode_pages(dev->blkdev->bd_inode->i_mapping);
 			close_bdev_excl(dev->blkdev);
diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c
index 39eb53f..8db65bf 100644
--- a/drivers/mtd/inftlcore.c
+++ b/drivers/mtd/inftlcore.c
@@ -126,10 +126,8 @@
 	}
 
 	if (add_mtd_blktrans_dev(&inftl->mbd)) {
-		if (inftl->PUtable)
-			kfree(inftl->PUtable);
-		if (inftl->VUtable)
-			kfree(inftl->VUtable);
+		kfree(inftl->PUtable);
+		kfree(inftl->VUtable);
 		kfree(inftl);
 		return;
 	}
@@ -147,10 +145,8 @@
 
 	del_mtd_blktrans_dev(dev);
 
-	if (inftl->PUtable)
-		kfree(inftl->PUtable);
-	if (inftl->VUtable)
-		kfree(inftl->VUtable);
+	kfree(inftl->PUtable);
+	kfree(inftl->VUtable);
 	kfree(inftl);
 }
 
diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c
index b5dda47..3dac53f 100644
--- a/drivers/mtd/inftlmount.c
+++ b/drivers/mtd/inftlmount.c
@@ -574,6 +574,12 @@
 
 	/* Temporary buffer to store ANAC numbers. */
 	ANACtable = kmalloc(s->nb_blocks * sizeof(u8), GFP_KERNEL);
+	if (!ANACtable) {
+		printk(KERN_WARNING "INFTL: allocation of ANACtable "
+				"failed (%zd bytes)\n",
+				s->nb_blocks * sizeof(u8));
+		return -ENOMEM;
+	}
 	memset(ANACtable, 0, s->nb_blocks);
 
 	/*
diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c
index e8a900a..9a64149 100644
--- a/drivers/mtd/maps/amd76xrom.c
+++ b/drivers/mtd/maps/amd76xrom.c
@@ -259,9 +259,7 @@
 
  out:
 	/* Free any left over map structures */
-	if (map) {
-		kfree(map);
-	}
+	kfree(map);
 	/* See if I have any map structures */
 	if (list_empty(&window->maps)) {
 		amd76xrom_cleanup(window);
diff --git a/drivers/mtd/maps/bast-flash.c b/drivers/mtd/maps/bast-flash.c
index bfe994e..8c19d72 100644
--- a/drivers/mtd/maps/bast-flash.c
+++ b/drivers/mtd/maps/bast-flash.c
@@ -104,8 +104,7 @@
 		map_destroy(info->mtd);
 	}
 
-	if (info->partitions)
-		kfree(info->partitions);
+	kfree(info->partitions);
 
 	if (info->area) {
 		release_resource(info->area);
diff --git a/drivers/mtd/maps/ceiva.c b/drivers/mtd/maps/ceiva.c
index c68b31d..5a95ab3 100644
--- a/drivers/mtd/maps/ceiva.c
+++ b/drivers/mtd/maps/ceiva.c
@@ -313,8 +313,7 @@
 
 static void __exit clps_destroy_partitions(void)
 {
-	if (parsed_parts)
-		kfree(parsed_parts);
+	kfree(parsed_parts);
 }
 
 static struct mtd_info *mymtd;
diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c
index e505207..c5e2111 100644
--- a/drivers/mtd/maps/ichxrom.c
+++ b/drivers/mtd/maps/ichxrom.c
@@ -306,9 +306,8 @@
 
  out:
 	/* Free any left over map structures */
-	if (map) {
-		kfree(map);
-	}
+	kfree(map);
+
 	/* See if I have any map structures */
 	if (list_empty(&window->maps)) {
 		ichxrom_cleanup(window);
diff --git a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c
index d14a018..93f50d6 100644
--- a/drivers/mtd/maps/integrator-flash.c
+++ b/drivers/mtd/maps/integrator-flash.c
@@ -148,8 +148,7 @@
 			del_mtd_partitions(info->mtd);
 			map_destroy(info->mtd);
 		}
-		if (info->parts)
-			kfree(info->parts);
+		kfree(info->parts);
 
  no_device:
 		iounmap(base);
@@ -176,8 +175,7 @@
 			del_mtd_partitions(info->mtd);
 			map_destroy(info->mtd);
 		}
-		if (info->parts)
-			kfree(info->parts);
+		kfree(info->parts);
 
 		iounmap(info->map.virt);
 		release_resource(info->res);
diff --git a/drivers/mtd/maps/ipaq-flash.c b/drivers/mtd/maps/ipaq-flash.c
index 7124018..70b0e0b 100644
--- a/drivers/mtd/maps/ipaq-flash.c
+++ b/drivers/mtd/maps/ipaq-flash.c
@@ -431,8 +431,7 @@
 				if (my_sub_mtd[i])
 					map_destroy(my_sub_mtd[i]);
 			}
-		if (parsed_parts)
-			kfree(parsed_parts);
+		kfree(parsed_parts);
 	}
 }
 
diff --git a/drivers/mtd/maps/iq80310.c b/drivers/mtd/maps/iq80310.c
index 558d014..2e75774 100644
--- a/drivers/mtd/maps/iq80310.c
+++ b/drivers/mtd/maps/iq80310.c
@@ -103,8 +103,7 @@
 	if (mymtd) {
 		del_mtd_partitions(mymtd);
 		map_destroy(mymtd);
-		if (parsed_parts)
-			kfree(parsed_parts);
+		kfree(parsed_parts);
 	}
 	if (iq80310_map.virt)
 		iounmap((void *)iq80310_map.virt);
diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c
index 00b9f67..6f36497 100644
--- a/drivers/mtd/maps/ixp2000.c
+++ b/drivers/mtd/maps/ixp2000.c
@@ -129,8 +129,7 @@
 	if (info->map.map_priv_1)
 		iounmap((void *) info->map.map_priv_1);
 
-	if (info->partitions) {
-		kfree(info->partitions); }
+	kfree(info->partitions);
 
 	if (info->res) {
 		release_resource(info->res);
diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c
index 733a929..0d87c02 100644
--- a/drivers/mtd/maps/ixp4xx.c
+++ b/drivers/mtd/maps/ixp4xx.c
@@ -124,8 +124,7 @@
 	if (info->map.map_priv_1)
 		iounmap((void *) info->map.map_priv_1);
 
-	if (info->partitions)
-		kfree(info->partitions);
+	kfree(info->partitions);
 
 	if (info->res) {
 		release_resource(info->res);
diff --git a/drivers/mtd/maps/lubbock-flash.c b/drivers/mtd/maps/lubbock-flash.c
index 2337e0c..2b4c505 100644
--- a/drivers/mtd/maps/lubbock-flash.c
+++ b/drivers/mtd/maps/lubbock-flash.c
@@ -158,8 +158,7 @@
 		if (lubbock_maps[i].cached)
 			iounmap(lubbock_maps[i].cached);
 
-		if (parsed_parts[i])
-			kfree(parsed_parts[i]);
+		kfree(parsed_parts[i]);
 	}
 }
 
diff --git a/drivers/mtd/maps/omap-toto-flash.c b/drivers/mtd/maps/omap-toto-flash.c
index da36e8d..7633041 100644
--- a/drivers/mtd/maps/omap-toto-flash.c
+++ b/drivers/mtd/maps/omap-toto-flash.c
@@ -124,8 +124,7 @@
 	if (flash_mtd) {
 		del_mtd_partitions(flash_mtd);
 		map_destroy(flash_mtd);
-		if (parsed_parts)
-			kfree(parsed_parts);
+		kfree(parsed_parts);
 	}
 }
 
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
index c8d0da1..a31f6ee 100644
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -241,8 +241,7 @@
 #endif
 	}
 
-	if (info->parts)
-		kfree(info->parts);
+	kfree(info->parts);
 
 	for (i = info->num_subdev - 1; i >= 0; i--)
 		sa1100_destroy_subdev(&info->subdev[i]);
diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c
index 29091d1..1355c28 100644
--- a/drivers/mtd/maps/sun_uflash.c
+++ b/drivers/mtd/maps/sun_uflash.c
@@ -166,9 +166,7 @@
 			iounmap(udev->map.virt);
 			udev->map.virt = NULL;
 		}
-		if(0 != udev->name) {
-			kfree(udev->name);
-		}
+		kfree(udev->name);
 		kfree(udev);
 	}	
 }
diff --git a/drivers/mtd/maps/tqm8xxl.c b/drivers/mtd/maps/tqm8xxl.c
index 4e28b97..0aca817 100644
--- a/drivers/mtd/maps/tqm8xxl.c
+++ b/drivers/mtd/maps/tqm8xxl.c
@@ -224,10 +224,8 @@
 error_mem:
 	for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
 		if(map_banks[idx] != NULL) {
-			if(map_banks[idx]->name != NULL) {
-				kfree(map_banks[idx]->name);
-				map_banks[idx]->name = NULL;
-			}
+			kfree(map_banks[idx]->name);
+			map_banks[idx]->name = NULL;
 			kfree(map_banks[idx]);
 			map_banks[idx] = NULL;
 		}
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 04e5431..8e78d7b 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2676,9 +2676,8 @@
 	/* Deregister the device */
 	del_mtd_device (mtd);
 
-	/* Free bad block table memory, if allocated */
-	if (this->bbt)
-		kfree (this->bbt);
+	/* Free bad block table memory */
+	kfree (this->bbt);
 	/* Buffer allocated by nand_scan ? */
 	if (this->options & NAND_OOBBUF_ALLOC)
 		kfree (this->oob_buf);
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index b201404..062ff38 100644
--- a/drivers/mtd/nftlcore.c
+++ b/drivers/mtd/nftlcore.c
@@ -114,10 +114,8 @@
 	}
 
 	if (add_mtd_blktrans_dev(&nftl->mbd)) {
-		if (nftl->ReplUnitTable)
-			kfree(nftl->ReplUnitTable);
-		if (nftl->EUNtable)
-			kfree(nftl->EUNtable);
+		kfree(nftl->ReplUnitTable);
+		kfree(nftl->EUNtable);
 		kfree(nftl);
 		return;
 	}
@@ -133,10 +131,8 @@
 	DEBUG(MTD_DEBUG_LEVEL1, "NFTL: remove_dev (i=%d)\n", dev->devnum);
 
 	del_mtd_blktrans_dev(dev);
-	if (nftl->ReplUnitTable)
-		kfree(nftl->ReplUnitTable);
-	if (nftl->EUNtable)
-		kfree(nftl->EUNtable);
+	kfree(nftl->ReplUnitTable);
+	kfree(nftl->EUNtable);
 	kfree(nftl);
 }
 
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 455ba91..7488ee7 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -602,7 +602,7 @@
    First the windows.  There are eight register windows, with the command
    and status registers available in each.
    */
-#define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD)
+#define EL3WINDOW(win_num) iowrite16(SelectWindow + (win_num), ioaddr + EL3_CMD)
 #define EL3_CMD 0x0e
 #define EL3_STATUS 0x0e
 
@@ -776,7 +776,8 @@
 
 	/* PCI configuration space information. */
 	struct device *gendev;
-	char __iomem *cb_fn_base;		/* CardBus function status addr space. */
+	void __iomem *ioaddr;			/* IO address space */
+	void __iomem *cb_fn_base;		/* CardBus function status addr space. */
 
 	/* Some values here only for performance evaluation and path-coverage */
 	int rx_nocopy, rx_copy, queued_packet, rx_csumhits;
@@ -869,12 +870,12 @@
 /* number of ETHTOOL_GSTATS u64's */
 #define VORTEX_NUM_STATS     3
 
-static int vortex_probe1(struct device *gendev, long ioaddr, int irq,
+static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq,
 				   int chip_idx, int card_idx);
 static void vortex_up(struct net_device *dev);
 static void vortex_down(struct net_device *dev, int final);
 static int vortex_open(struct net_device *dev);
-static void mdio_sync(long ioaddr, int bits);
+static void mdio_sync(void __iomem *ioaddr, int bits);
 static int mdio_read(struct net_device *dev, int phy_id, int location);
 static void mdio_write(struct net_device *vp, int phy_id, int location, int value);
 static void vortex_timer(unsigned long arg);
@@ -887,7 +888,7 @@
 static irqreturn_t boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static int vortex_close(struct net_device *dev);
 static void dump_tx_ring(struct net_device *dev);
-static void update_stats(long ioaddr, struct net_device *dev);
+static void update_stats(void __iomem *ioaddr, struct net_device *dev);
 static struct net_device_stats *vortex_get_stats(struct net_device *dev);
 static void set_rx_mode(struct net_device *dev);
 #ifdef CONFIG_PCI
@@ -902,14 +903,16 @@
 /* This driver uses 'options' to pass the media type, full-duplex flag, etc. */
 /* Option count limit only -- unlimited interfaces are supported. */
 #define MAX_UNITS 8
-static int options[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1,};
-static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
-static int hw_checksums[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
-static int flow_ctrl[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
-static int enable_wol[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+static int options[MAX_UNITS] = { [0 ... MAX_UNITS-1] = -1 };
+static int full_duplex[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
+static int hw_checksums[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
+static int flow_ctrl[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
+static int enable_wol[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
+static int use_mmio[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
 static int global_options = -1;
 static int global_full_duplex = -1;
 static int global_enable_wol = -1;
+static int global_use_mmio = -1;
 
 /* #define dev_alloc_skb dev_alloc_skb_debug */
 
@@ -934,21 +937,25 @@
 module_param(compaq_irq, int, 0);
 module_param(compaq_device_id, int, 0);
 module_param(watchdog, int, 0);
+module_param(global_use_mmio, int, 0);
+module_param_array(use_mmio, int, NULL, 0);
 MODULE_PARM_DESC(debug, "3c59x debug level (0-6)");
 MODULE_PARM_DESC(options, "3c59x: Bits 0-3: media type, bit 4: bus mastering, bit 9: full duplex");
 MODULE_PARM_DESC(global_options, "3c59x: same as options, but applies to all NICs if options is unset");
 MODULE_PARM_DESC(full_duplex, "3c59x full duplex setting(s) (1)");
-MODULE_PARM_DESC(global_full_duplex, "3c59x: same as full_duplex, but applies to all NICs if options is unset");
+MODULE_PARM_DESC(global_full_duplex, "3c59x: same as full_duplex, but applies to all NICs if full_duplex is unset");
 MODULE_PARM_DESC(hw_checksums, "3c59x Hardware checksum checking by adapter(s) (0-1)");
 MODULE_PARM_DESC(flow_ctrl, "3c59x 802.3x flow control usage (PAUSE only) (0-1)");
 MODULE_PARM_DESC(enable_wol, "3c59x: Turn on Wake-on-LAN for adapter(s) (0-1)");
-MODULE_PARM_DESC(global_enable_wol, "3c59x: same as enable_wol, but applies to all NICs if options is unset");
+MODULE_PARM_DESC(global_enable_wol, "3c59x: same as enable_wol, but applies to all NICs if enable_wol is unset");
 MODULE_PARM_DESC(rx_copybreak, "3c59x copy breakpoint for copy-only-tiny-frames");
 MODULE_PARM_DESC(max_interrupt_work, "3c59x maximum events handled per interrupt");
 MODULE_PARM_DESC(compaq_ioaddr, "3c59x PCI I/O base address (Compaq BIOS problem workaround)");
 MODULE_PARM_DESC(compaq_irq, "3c59x PCI IRQ number (Compaq BIOS problem workaround)");
 MODULE_PARM_DESC(compaq_device_id, "3c59x PCI device ID (Compaq BIOS problem workaround)");
 MODULE_PARM_DESC(watchdog, "3c59x transmit timeout in milliseconds");
+MODULE_PARM_DESC(global_use_mmio, "3c59x: same as use_mmio, but applies to all NICs if options is unset");
+MODULE_PARM_DESC(use_mmio, "3c59x: use memory-mapped PCI I/O resource (0-1)");
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void poll_vortex(struct net_device *dev)
@@ -1029,18 +1036,19 @@
 
 static int vortex_eisa_probe (struct device *device)
 {
-	long ioaddr;
+	void __iomem *ioaddr;
 	struct eisa_device *edev;
 
 	edev = to_eisa_device (device);
-	ioaddr = edev->base_addr;
 
-	if (!request_region(ioaddr, VORTEX_TOTAL_SIZE, DRV_NAME))
+	if (!request_region(edev->base_addr, VORTEX_TOTAL_SIZE, DRV_NAME))
 		return -EBUSY;
 
-	if (vortex_probe1(device, ioaddr, inw(ioaddr + 0xC88) >> 12,
+	ioaddr = ioport_map(edev->base_addr, VORTEX_TOTAL_SIZE);
+
+	if (vortex_probe1(device, ioaddr, ioread16(ioaddr + 0xC88) >> 12,
 					  edev->id.driver_data, vortex_cards_found)) {
-		release_region (ioaddr, VORTEX_TOTAL_SIZE);
+		release_region (edev->base_addr, VORTEX_TOTAL_SIZE);
 		return -ENODEV;
 	}
 
@@ -1054,7 +1062,7 @@
 	struct eisa_device *edev;
 	struct net_device *dev;
 	struct vortex_private *vp;
-	long ioaddr;
+	void __iomem *ioaddr;
 
 	edev = to_eisa_device (device);
 	dev = eisa_get_drvdata (edev);
@@ -1065,11 +1073,11 @@
 	}
 
 	vp = netdev_priv(dev);
-	ioaddr = dev->base_addr;
+	ioaddr = vp->ioaddr;
 	
 	unregister_netdev (dev);
-	outw (TotalReset|0x14, ioaddr + EL3_CMD);
-	release_region (ioaddr, VORTEX_TOTAL_SIZE);
+	iowrite16 (TotalReset|0x14, ioaddr + EL3_CMD);
+	release_region (dev->base_addr, VORTEX_TOTAL_SIZE);
 
 	free_netdev (dev);
 	return 0;
@@ -1096,8 +1104,8 @@
 	
 	/* Special code to work-around the Compaq PCI BIOS32 problem. */
 	if (compaq_ioaddr) {
-		vortex_probe1(NULL, compaq_ioaddr, compaq_irq,
-					  compaq_device_id, vortex_cards_found++);
+		vortex_probe1(NULL, ioport_map(compaq_ioaddr, VORTEX_TOTAL_SIZE),
+			      compaq_irq, compaq_device_id, vortex_cards_found++);
 	}
 
 	return vortex_cards_found - orig_cards_found + eisa_found;
@@ -1107,15 +1115,32 @@
 static int __devinit vortex_init_one (struct pci_dev *pdev,
 				      const struct pci_device_id *ent)
 {
-	int rc;
+	int rc, unit, pci_bar;
+	struct vortex_chip_info *vci;
+	void __iomem *ioaddr;
 
 	/* wake up and enable device */		
 	rc = pci_enable_device (pdev);
 	if (rc < 0)
 		goto out;
 
-	rc = vortex_probe1 (&pdev->dev, pci_resource_start (pdev, 0),
-						pdev->irq, ent->driver_data, vortex_cards_found);
+	unit = vortex_cards_found;
+
+	if (global_use_mmio < 0 && (unit >= MAX_UNITS || use_mmio[unit] < 0)) {
+		/* Determine the default if the user didn't override us */
+		vci = &vortex_info_tbl[ent->driver_data];
+		pci_bar = vci->drv_flags & (IS_CYCLONE | IS_TORNADO) ? 1 : 0;
+	} else if (unit < MAX_UNITS && use_mmio[unit] >= 0)
+		pci_bar = use_mmio[unit] ? 1 : 0;
+	else
+		pci_bar = global_use_mmio ? 1 : 0;
+
+	ioaddr = pci_iomap(pdev, pci_bar, 0);
+	if (!ioaddr) /* If mapping fails, fall-back to BAR 0... */
+		ioaddr = pci_iomap(pdev, 0, 0);
+
+	rc = vortex_probe1(&pdev->dev, ioaddr, pdev->irq,
+			   ent->driver_data, unit);
 	if (rc < 0) {
 		pci_disable_device (pdev);
 		goto out;
@@ -1134,7 +1159,7 @@
  * NOTE: pdev can be NULL, for the case of a Compaq device
  */
 static int __devinit vortex_probe1(struct device *gendev,
-				   long ioaddr, int irq,
+				   void __iomem *ioaddr, int irq,
 				   int chip_idx, int card_idx)
 {
 	struct vortex_private *vp;
@@ -1202,15 +1227,16 @@
 	if (print_info)
 		printk (KERN_INFO "See Documentation/networking/vortex.txt\n");
 
-	printk(KERN_INFO "%s: 3Com %s %s at 0x%lx. Vers " DRV_VERSION "\n",
+	printk(KERN_INFO "%s: 3Com %s %s at %p. Vers " DRV_VERSION "\n",
 	       print_name,
 	       pdev ? "PCI" : "EISA",
 	       vci->name,
 	       ioaddr);
 
-	dev->base_addr = ioaddr;
+	dev->base_addr = (unsigned long)ioaddr;
 	dev->irq = irq;
 	dev->mtu = mtu;
+	vp->ioaddr = ioaddr;
 	vp->large_frames = mtu > 1500;
 	vp->drv_flags = vci->drv_flags;
 	vp->has_nway = (vci->drv_flags & HAS_NWAY) ? 1 : 0;
@@ -1226,7 +1252,7 @@
 	if (pdev) {
 		/* EISA resources already marked, so only PCI needs to do this here */
 		/* Ignore return value, because Cardbus drivers already allocate for us */
-		if (request_region(ioaddr, vci->io_size, print_name) != NULL)
+		if (request_region(dev->base_addr, vci->io_size, print_name) != NULL)
 			vp->must_free_region = 1;
 
 		/* enable bus-mastering if necessary */		
@@ -1316,14 +1342,14 @@
 
 		for (i = 0; i < 0x40; i++) {
 			int timer;
-			outw(base + i, ioaddr + Wn0EepromCmd);
+			iowrite16(base + i, ioaddr + Wn0EepromCmd);
 			/* Pause for at least 162 us. for the read to take place. */
 			for (timer = 10; timer >= 0; timer--) {
 				udelay(162);
-				if ((inw(ioaddr + Wn0EepromCmd) & 0x8000) == 0)
+				if ((ioread16(ioaddr + Wn0EepromCmd) & 0x8000) == 0)
 					break;
 			}
-			eeprom[i] = inw(ioaddr + Wn0EepromData);
+			eeprom[i] = ioread16(ioaddr + Wn0EepromData);
 		}
 	}
 	for (i = 0; i < 0x18; i++)
@@ -1338,6 +1364,7 @@
 		printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
 	for (i = 0; i < 3; i++)
 		((u16 *)dev->dev_addr)[i] = htons(eeprom[i + 10]);
+	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 	if (print_info) {
 		for (i = 0; i < 6; i++)
 			printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]);
@@ -1351,7 +1378,7 @@
 	}
 	EL3WINDOW(2);
 	for (i = 0; i < 6; i++)
-		outb(dev->dev_addr[i], ioaddr + i);
+		iowrite8(dev->dev_addr[i], ioaddr + i);
 
 #ifdef __sparc__
 	if (print_info)
@@ -1366,7 +1393,7 @@
 #endif
 
 	EL3WINDOW(4);
-	step = (inb(ioaddr + Wn4_NetDiag) & 0x1e) >> 1;
+	step = (ioread8(ioaddr + Wn4_NetDiag) & 0x1e) >> 1;
 	if (print_info) {
 		printk(KERN_INFO "  product code %02x%02x rev %02x.%d date %02d-"
 			"%02d-%02d\n", eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14],
@@ -1375,31 +1402,30 @@
 
 
 	if (pdev && vci->drv_flags & HAS_CB_FNS) {
-		unsigned long fn_st_addr;			/* Cardbus function status space */
 		unsigned short n;
 
-		fn_st_addr = pci_resource_start (pdev, 2);
-		if (fn_st_addr) {
-			vp->cb_fn_base = ioremap(fn_st_addr, 128);
+		vp->cb_fn_base = pci_iomap(pdev, 2, 0);
+		if (!vp->cb_fn_base) {
 			retval = -ENOMEM;
-			if (!vp->cb_fn_base)
-				goto free_ring;
+			goto free_ring;
 		}
+
 		if (print_info) {
 			printk(KERN_INFO "%s: CardBus functions mapped %8.8lx->%p\n",
-				print_name, fn_st_addr, vp->cb_fn_base);
+				print_name, pci_resource_start(pdev, 2),
+				vp->cb_fn_base);
 		}
 		EL3WINDOW(2);
 
-		n = inw(ioaddr + Wn2_ResetOptions) & ~0x4010;
+		n = ioread16(ioaddr + Wn2_ResetOptions) & ~0x4010;
 		if (vp->drv_flags & INVERT_LED_PWR)
 			n |= 0x10;
 		if (vp->drv_flags & INVERT_MII_PWR)
 			n |= 0x4000;
-		outw(n, ioaddr + Wn2_ResetOptions);
+		iowrite16(n, ioaddr + Wn2_ResetOptions);
 		if (vp->drv_flags & WNO_XCVR_PWR) {
 			EL3WINDOW(0);
-			outw(0x0800, ioaddr);
+			iowrite16(0x0800, ioaddr);
 		}
 	}
 
@@ -1418,13 +1444,13 @@
 		static const char * ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
 		unsigned int config;
 		EL3WINDOW(3);
-		vp->available_media = inw(ioaddr + Wn3_Options);
+		vp->available_media = ioread16(ioaddr + Wn3_Options);
 		if ((vp->available_media & 0xff) == 0)		/* Broken 3c916 */
 			vp->available_media = 0x40;
-		config = inl(ioaddr + Wn3_Config);
+		config = ioread32(ioaddr + Wn3_Config);
 		if (print_info) {
 			printk(KERN_DEBUG "  Internal config register is %4.4x, "
-				   "transceivers %#x.\n", config, inw(ioaddr + Wn3_Options));
+				   "transceivers %#x.\n", config, ioread16(ioaddr + Wn3_Options));
 			printk(KERN_INFO "  %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
 				   8 << RAM_SIZE(config),
 				   RAM_WIDTH(config) ? "word" : "byte",
@@ -1455,7 +1481,7 @@
 		if (vp->drv_flags & EXTRA_PREAMBLE)
 			mii_preamble_required++;
 		mdio_sync(ioaddr, 32);
-		mdio_read(dev, 24, 1);
+		mdio_read(dev, 24, MII_BMSR);
 		for (phy = 0; phy < 32 && phy_idx < 1; phy++) {
 			int mii_status, phyx;
 
@@ -1469,7 +1495,7 @@
 				phyx = phy - 1;
 			else
 				phyx = phy;
-			mii_status = mdio_read(dev, phyx, 1);
+			mii_status = mdio_read(dev, phyx, MII_BMSR);
 			if (mii_status  &&  mii_status != 0xffff) {
 				vp->phys[phy_idx++] = phyx;
 				if (print_info) {
@@ -1485,7 +1511,7 @@
 			printk(KERN_WARNING"  ***WARNING*** No MII transceivers found!\n");
 			vp->phys[0] = 24;
 		} else {
-			vp->advertising = mdio_read(dev, vp->phys[0], 4);
+			vp->advertising = mdio_read(dev, vp->phys[0], MII_ADVERTISE);
 			if (vp->full_duplex) {
 				/* Only advertise the FD media types. */
 				vp->advertising &= ~0x02A0;
@@ -1510,10 +1536,10 @@
 	if (vp->full_bus_master_tx) {
 		dev->hard_start_xmit = boomerang_start_xmit;
 		/* Actually, it still should work with iommu. */
-		dev->features |= NETIF_F_SG;
-		if (((hw_checksums[card_idx] == -1) && (vp->drv_flags & HAS_HWCKSM)) ||
-					(hw_checksums[card_idx] == 1)) {
-				dev->features |= NETIF_F_IP_CSUM;
+		if (card_idx < MAX_UNITS &&
+		    ((hw_checksums[card_idx] == -1 && (vp->drv_flags & HAS_HWCKSM)) ||
+				hw_checksums[card_idx] == 1)) {
+			dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
 		}
 	} else {
 		dev->hard_start_xmit = vortex_start_xmit;
@@ -1555,7 +1581,7 @@
 						vp->rx_ring_dma);
 free_region:
 	if (vp->must_free_region)
-		release_region(ioaddr, vci->io_size);
+		release_region(dev->base_addr, vci->io_size);
 	free_netdev(dev);
 	printk(KERN_ERR PFX "vortex_probe1 fails.  Returns %d\n", retval);
 out:
@@ -1565,17 +1591,19 @@
 static void
 issue_and_wait(struct net_device *dev, int cmd)
 {
+	struct vortex_private *vp = netdev_priv(dev);
+	void __iomem *ioaddr = vp->ioaddr;
 	int i;
 
-	outw(cmd, dev->base_addr + EL3_CMD);
+	iowrite16(cmd, ioaddr + EL3_CMD);
 	for (i = 0; i < 2000; i++) {
-		if (!(inw(dev->base_addr + EL3_STATUS) & CmdInProgress))
+		if (!(ioread16(ioaddr + EL3_STATUS) & CmdInProgress))
 			return;
 	}
 
 	/* OK, that didn't work.  Do it the slow way.  One second */
 	for (i = 0; i < 100000; i++) {
-		if (!(inw(dev->base_addr + EL3_STATUS) & CmdInProgress)) {
+		if (!(ioread16(ioaddr + EL3_STATUS) & CmdInProgress)) {
 			if (vortex_debug > 1)
 				printk(KERN_INFO "%s: command 0x%04x took %d usecs\n",
 					   dev->name, cmd, i * 10);
@@ -1584,14 +1612,14 @@
 		udelay(10);
 	}
 	printk(KERN_ERR "%s: command 0x%04x did not complete! Status=0x%x\n",
-			   dev->name, cmd, inw(dev->base_addr + EL3_STATUS));
+			   dev->name, cmd, ioread16(ioaddr + EL3_STATUS));
 }
 
 static void
 vortex_up(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
 	struct vortex_private *vp = netdev_priv(dev);
+	void __iomem *ioaddr = vp->ioaddr;
 	unsigned int config;
 	int i;
 
@@ -1604,7 +1632,7 @@
 
 	/* Before initializing select the active media port. */
 	EL3WINDOW(3);
-	config = inl(ioaddr + Wn3_Config);
+	config = ioread32(ioaddr + Wn3_Config);
 
 	if (vp->media_override != 7) {
 		printk(KERN_INFO "%s: Media override to transceiver %d (%s).\n",
@@ -1651,14 +1679,14 @@
 	config = BFINS(config, dev->if_port, 20, 4);
 	if (vortex_debug > 6)
 		printk(KERN_DEBUG "vortex_up(): writing 0x%x to InternalConfig\n", config);
-	outl(config, ioaddr + Wn3_Config);
+	iowrite32(config, ioaddr + Wn3_Config);
 
 	if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
 		int mii_reg1, mii_reg5;
 		EL3WINDOW(4);
 		/* Read BMSR (reg1) only to clear old status. */
-		mii_reg1 = mdio_read(dev, vp->phys[0], 1);
-		mii_reg5 = mdio_read(dev, vp->phys[0], 5);
+		mii_reg1 = mdio_read(dev, vp->phys[0], MII_BMSR);
+		mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA);
 		if (mii_reg5 == 0xffff  ||  mii_reg5 == 0x0000) {
 			netif_carrier_off(dev); /* No MII device or no link partner report */
 		} else {
@@ -1679,7 +1707,7 @@
 	}
 
 	/* Set the full-duplex bit. */
-	outw(	((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) |
+	iowrite16(	((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) |
 		 	(vp->large_frames ? 0x40 : 0) |
 			((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 0x100 : 0),
 			ioaddr + Wn3_MAC_Ctrl);
@@ -1695,51 +1723,51 @@
 	 */
 	issue_and_wait(dev, RxReset|0x04);
 
-	outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
+	iowrite16(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
 
 	if (vortex_debug > 1) {
 		EL3WINDOW(4);
 		printk(KERN_DEBUG "%s: vortex_up() irq %d media status %4.4x.\n",
-			   dev->name, dev->irq, inw(ioaddr + Wn4_Media));
+			   dev->name, dev->irq, ioread16(ioaddr + Wn4_Media));
 	}
 
 	/* Set the station address and mask in window 2 each time opened. */
 	EL3WINDOW(2);
 	for (i = 0; i < 6; i++)
-		outb(dev->dev_addr[i], ioaddr + i);
+		iowrite8(dev->dev_addr[i], ioaddr + i);
 	for (; i < 12; i+=2)
-		outw(0, ioaddr + i);
+		iowrite16(0, ioaddr + i);
 
 	if (vp->cb_fn_base) {
-		unsigned short n = inw(ioaddr + Wn2_ResetOptions) & ~0x4010;
+		unsigned short n = ioread16(ioaddr + Wn2_ResetOptions) & ~0x4010;
 		if (vp->drv_flags & INVERT_LED_PWR)
 			n |= 0x10;
 		if (vp->drv_flags & INVERT_MII_PWR)
 			n |= 0x4000;
-		outw(n, ioaddr + Wn2_ResetOptions);
+		iowrite16(n, ioaddr + Wn2_ResetOptions);
 	}
 
 	if (dev->if_port == XCVR_10base2)
 		/* Start the thinnet transceiver. We should really wait 50ms...*/
-		outw(StartCoax, ioaddr + EL3_CMD);
+		iowrite16(StartCoax, ioaddr + EL3_CMD);
 	if (dev->if_port != XCVR_NWAY) {
 		EL3WINDOW(4);
-		outw((inw(ioaddr + Wn4_Media) & ~(Media_10TP|Media_SQE)) |
+		iowrite16((ioread16(ioaddr + Wn4_Media) & ~(Media_10TP|Media_SQE)) |
 			 media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media);
 	}
 
 	/* Switch to the stats window, and clear all stats by reading. */
-	outw(StatsDisable, ioaddr + EL3_CMD);
+	iowrite16(StatsDisable, ioaddr + EL3_CMD);
 	EL3WINDOW(6);
 	for (i = 0; i < 10; i++)
-		inb(ioaddr + i);
-	inw(ioaddr + 10);
-	inw(ioaddr + 12);
+		ioread8(ioaddr + i);
+	ioread16(ioaddr + 10);
+	ioread16(ioaddr + 12);
 	/* New: On the Vortex we must also clear the BadSSD counter. */
 	EL3WINDOW(4);
-	inb(ioaddr + 12);
+	ioread8(ioaddr + 12);
 	/* ..and on the Boomerang we enable the extra statistics bits. */
-	outw(0x0040, ioaddr + Wn4_NetDiag);
+	iowrite16(0x0040, ioaddr + Wn4_NetDiag);
 
 	/* Switch to register set 7 for normal use. */
 	EL3WINDOW(7);
@@ -1747,30 +1775,30 @@
 	if (vp->full_bus_master_rx) { /* Boomerang bus master. */
 		vp->cur_rx = vp->dirty_rx = 0;
 		/* Initialize the RxEarly register as recommended. */
-		outw(SetRxThreshold + (1536>>2), ioaddr + EL3_CMD);
-		outl(0x0020, ioaddr + PktStatus);
-		outl(vp->rx_ring_dma, ioaddr + UpListPtr);
+		iowrite16(SetRxThreshold + (1536>>2), ioaddr + EL3_CMD);
+		iowrite32(0x0020, ioaddr + PktStatus);
+		iowrite32(vp->rx_ring_dma, ioaddr + UpListPtr);
 	}
 	if (vp->full_bus_master_tx) { 		/* Boomerang bus master Tx. */
 		vp->cur_tx = vp->dirty_tx = 0;
 		if (vp->drv_flags & IS_BOOMERANG)
-			outb(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold); /* Room for a packet. */
+			iowrite8(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold); /* Room for a packet. */
 		/* Clear the Rx, Tx rings. */
 		for (i = 0; i < RX_RING_SIZE; i++)	/* AKPM: this is done in vortex_open, too */
 			vp->rx_ring[i].status = 0;
 		for (i = 0; i < TX_RING_SIZE; i++)
 			vp->tx_skbuff[i] = NULL;
-		outl(0, ioaddr + DownListPtr);
+		iowrite32(0, ioaddr + DownListPtr);
 	}
 	/* Set receiver mode: presumably accept b-case and phys addr only. */
 	set_rx_mode(dev);
 	/* enable 802.1q tagged frames */
 	set_8021q_mode(dev, 1);
-	outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
+	iowrite16(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
 
 //	issue_and_wait(dev, SetTxStart|0x07ff);
-	outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
-	outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
+	iowrite16(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
+	iowrite16(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
 	/* Allow status bits to be seen. */
 	vp->status_enable = SetStatusEnb | HostError|IntReq|StatsFull|TxComplete|
 		(vp->full_bus_master_tx ? DownComplete : TxAvailable) |
@@ -1780,13 +1808,13 @@
 		(vp->full_bus_master_rx ? 0 : RxComplete) |
 		StatsFull | HostError | TxComplete | IntReq
 		| (vp->bus_master ? DMADone : 0) | UpComplete | DownComplete;
-	outw(vp->status_enable, ioaddr + EL3_CMD);
+	iowrite16(vp->status_enable, ioaddr + EL3_CMD);
 	/* Ack all pending events, and set active indicator mask. */
-	outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
+	iowrite16(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
 		 ioaddr + EL3_CMD);
-	outw(vp->intr_enable, ioaddr + EL3_CMD);
+	iowrite16(vp->intr_enable, ioaddr + EL3_CMD);
 	if (vp->cb_fn_base)			/* The PCMCIA people are idiots.  */
-		writel(0x8000, vp->cb_fn_base + 4);
+		iowrite32(0x8000, vp->cb_fn_base + 4);
 	netif_start_queue (dev);
 }
 
@@ -1852,7 +1880,7 @@
 {
 	struct net_device *dev = (struct net_device *)data;
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 	int next_tick = 60*HZ;
 	int ok = 0;
 	int media_status, mii_status, old_window;
@@ -1866,9 +1894,9 @@
 	if (vp->medialock)
 		goto leave_media_alone;
 	disable_irq(dev->irq);
-	old_window = inw(ioaddr + EL3_CMD) >> 13;
+	old_window = ioread16(ioaddr + EL3_CMD) >> 13;
 	EL3WINDOW(4);
-	media_status = inw(ioaddr + Wn4_Media);
+	media_status = ioread16(ioaddr + Wn4_Media);
 	switch (dev->if_port) {
 	case XCVR_10baseT:  case XCVR_100baseTx:  case XCVR_100baseFx:
 		if (media_status & Media_LnkBeat) {
@@ -1888,14 +1916,17 @@
 	case XCVR_MII: case XCVR_NWAY:
 		{
 			spin_lock_bh(&vp->lock);
-			mii_status = mdio_read(dev, vp->phys[0], 1);
-			mii_status = mdio_read(dev, vp->phys[0], 1);
+			mii_status = mdio_read(dev, vp->phys[0], MII_BMSR);
+			if (!(mii_status & BMSR_LSTATUS)) {
+				/* Re-read to get actual link status */
+				mii_status = mdio_read(dev, vp->phys[0], MII_BMSR);
+			}
 			ok = 1;
 			if (vortex_debug > 2)
 				printk(KERN_DEBUG "%s: MII transceiver has status %4.4x.\n",
 					dev->name, mii_status);
 			if (mii_status & BMSR_LSTATUS) {
-				int mii_reg5 = mdio_read(dev, vp->phys[0], 5);
+				int mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA);
 				if (! vp->force_fd  &&  mii_reg5 != 0xffff) {
 					int duplex;
 
@@ -1909,7 +1940,7 @@
 							vp->phys[0], mii_reg5);
 						/* Set the full-duplex bit. */
 						EL3WINDOW(3);
-						outw(	(vp->full_duplex ? 0x20 : 0) |
+						iowrite16(	(vp->full_duplex ? 0x20 : 0) |
 								(vp->large_frames ? 0x40 : 0) |
 								((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 0x100 : 0),
 								ioaddr + Wn3_MAC_Ctrl);
@@ -1950,15 +1981,15 @@
 					   dev->name, media_tbl[dev->if_port].name);
 			next_tick = media_tbl[dev->if_port].wait;
 		}
-		outw((media_status & ~(Media_10TP|Media_SQE)) |
+		iowrite16((media_status & ~(Media_10TP|Media_SQE)) |
 			 media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media);
 
 		EL3WINDOW(3);
-		config = inl(ioaddr + Wn3_Config);
+		config = ioread32(ioaddr + Wn3_Config);
 		config = BFINS(config, dev->if_port, 20, 4);
-		outl(config, ioaddr + Wn3_Config);
+		iowrite32(config, ioaddr + Wn3_Config);
 
-		outw(dev->if_port == XCVR_10base2 ? StartCoax : StopCoax,
+		iowrite16(dev->if_port == XCVR_10base2 ? StartCoax : StopCoax,
 			 ioaddr + EL3_CMD);
 		if (vortex_debug > 1)
 			printk(KERN_DEBUG "wrote 0x%08x to Wn3_Config\n", config);
@@ -1974,29 +2005,29 @@
 
 	mod_timer(&vp->timer, RUN_AT(next_tick));
 	if (vp->deferred)
-		outw(FakeIntr, ioaddr + EL3_CMD);
+		iowrite16(FakeIntr, ioaddr + EL3_CMD);
 	return;
 }
 
 static void vortex_tx_timeout(struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 
 	printk(KERN_ERR "%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
-		   dev->name, inb(ioaddr + TxStatus),
-		   inw(ioaddr + EL3_STATUS));
+		   dev->name, ioread8(ioaddr + TxStatus),
+		   ioread16(ioaddr + EL3_STATUS));
 	EL3WINDOW(4);
 	printk(KERN_ERR "  diagnostics: net %04x media %04x dma %08x fifo %04x\n",
-			inw(ioaddr + Wn4_NetDiag),
-			inw(ioaddr + Wn4_Media),
-			inl(ioaddr + PktStatus),
-			inw(ioaddr + Wn4_FIFODiag));
+			ioread16(ioaddr + Wn4_NetDiag),
+			ioread16(ioaddr + Wn4_Media),
+			ioread32(ioaddr + PktStatus),
+			ioread16(ioaddr + Wn4_FIFODiag));
 	/* Slight code bloat to be user friendly. */
-	if ((inb(ioaddr + TxStatus) & 0x88) == 0x88)
+	if ((ioread8(ioaddr + TxStatus) & 0x88) == 0x88)
 		printk(KERN_ERR "%s: Transmitter encountered 16 collisions --"
 			   " network cable problem?\n", dev->name);
-	if (inw(ioaddr + EL3_STATUS) & IntLatch) {
+	if (ioread16(ioaddr + EL3_STATUS) & IntLatch) {
 		printk(KERN_ERR "%s: Interrupt posted but not delivered --"
 			   " IRQ blocked by another device?\n", dev->name);
 		/* Bad idea here.. but we might as well handle a few events. */
@@ -2022,21 +2053,21 @@
 	vp->stats.tx_errors++;
 	if (vp->full_bus_master_tx) {
 		printk(KERN_DEBUG "%s: Resetting the Tx ring pointer.\n", dev->name);
-		if (vp->cur_tx - vp->dirty_tx > 0  &&  inl(ioaddr + DownListPtr) == 0)
-			outl(vp->tx_ring_dma + (vp->dirty_tx % TX_RING_SIZE) * sizeof(struct boom_tx_desc),
+		if (vp->cur_tx - vp->dirty_tx > 0  &&  ioread32(ioaddr + DownListPtr) == 0)
+			iowrite32(vp->tx_ring_dma + (vp->dirty_tx % TX_RING_SIZE) * sizeof(struct boom_tx_desc),
 				 ioaddr + DownListPtr);
 		if (vp->cur_tx - vp->dirty_tx < TX_RING_SIZE)
 			netif_wake_queue (dev);
 		if (vp->drv_flags & IS_BOOMERANG)
-			outb(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold);
-		outw(DownUnstall, ioaddr + EL3_CMD);
+			iowrite8(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold);
+		iowrite16(DownUnstall, ioaddr + EL3_CMD);
 	} else {
 		vp->stats.tx_dropped++;
 		netif_wake_queue(dev);
 	}
 	
 	/* Issue Tx Enable */
-	outw(TxEnable, ioaddr + EL3_CMD);
+	iowrite16(TxEnable, ioaddr + EL3_CMD);
 	dev->trans_start = jiffies;
 	
 	/* Switch to register set 7 for normal use. */
@@ -2051,7 +2082,7 @@
 vortex_error(struct net_device *dev, int status)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 	int do_tx_reset = 0, reset_mask = 0;
 	unsigned char tx_status = 0;
 
@@ -2060,7 +2091,7 @@
 	}
 
 	if (status & TxComplete) {			/* Really "TxError" for us. */
-		tx_status = inb(ioaddr + TxStatus);
+		tx_status = ioread8(ioaddr + TxStatus);
 		/* Presumably a tx-timeout. We must merely re-enable. */
 		if (vortex_debug > 2
 			|| (tx_status != 0x88 && vortex_debug > 0)) {
@@ -2074,20 +2105,20 @@
 		}
 		if (tx_status & 0x14)  vp->stats.tx_fifo_errors++;
 		if (tx_status & 0x38)  vp->stats.tx_aborted_errors++;
-		outb(0, ioaddr + TxStatus);
+		iowrite8(0, ioaddr + TxStatus);
 		if (tx_status & 0x30) {			/* txJabber or txUnderrun */
 			do_tx_reset = 1;
 		} else if ((tx_status & 0x08) && (vp->drv_flags & MAX_COLLISION_RESET)) {	/* maxCollisions */
 			do_tx_reset = 1;
 			reset_mask = 0x0108;		/* Reset interface logic, but not download logic */
 		} else {						/* Merely re-enable the transmitter. */
-			outw(TxEnable, ioaddr + EL3_CMD);
+			iowrite16(TxEnable, ioaddr + EL3_CMD);
 		}
 	}
 
 	if (status & RxEarly) {				/* Rx early is unused. */
 		vortex_rx(dev);
-		outw(AckIntr | RxEarly, ioaddr + EL3_CMD);
+		iowrite16(AckIntr | RxEarly, ioaddr + EL3_CMD);
 	}
 	if (status & StatsFull) {			/* Empty statistics. */
 		static int DoneDidThat;
@@ -2097,29 +2128,29 @@
 		/* HACK: Disable statistics as an interrupt source. */
 		/* This occurs when we have the wrong media type! */
 		if (DoneDidThat == 0  &&
-			inw(ioaddr + EL3_STATUS) & StatsFull) {
+			ioread16(ioaddr + EL3_STATUS) & StatsFull) {
 			printk(KERN_WARNING "%s: Updating statistics failed, disabling "
 				   "stats as an interrupt source.\n", dev->name);
 			EL3WINDOW(5);
-			outw(SetIntrEnb | (inw(ioaddr + 10) & ~StatsFull), ioaddr + EL3_CMD);
+			iowrite16(SetIntrEnb | (ioread16(ioaddr + 10) & ~StatsFull), ioaddr + EL3_CMD);
 			vp->intr_enable &= ~StatsFull;
 			EL3WINDOW(7);
 			DoneDidThat++;
 		}
 	}
 	if (status & IntReq) {		/* Restore all interrupt sources.  */
-		outw(vp->status_enable, ioaddr + EL3_CMD);
-		outw(vp->intr_enable, ioaddr + EL3_CMD);
+		iowrite16(vp->status_enable, ioaddr + EL3_CMD);
+		iowrite16(vp->intr_enable, ioaddr + EL3_CMD);
 	}
 	if (status & HostError) {
 		u16 fifo_diag;
 		EL3WINDOW(4);
-		fifo_diag = inw(ioaddr + Wn4_FIFODiag);
+		fifo_diag = ioread16(ioaddr + Wn4_FIFODiag);
 		printk(KERN_ERR "%s: Host error, FIFO diagnostic register %4.4x.\n",
 			   dev->name, fifo_diag);
 		/* Adapter failure requires Tx/Rx reset and reinit. */
 		if (vp->full_bus_master_tx) {
-			int bus_status = inl(ioaddr + PktStatus);
+			int bus_status = ioread32(ioaddr + PktStatus);
 			/* 0x80000000 PCI master abort. */
 			/* 0x40000000 PCI target abort. */
 			if (vortex_debug)
@@ -2139,14 +2170,14 @@
 			set_rx_mode(dev);
 			/* enable 802.1q VLAN tagged frames */
 			set_8021q_mode(dev, 1);
-			outw(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */
-			outw(AckIntr | HostError, ioaddr + EL3_CMD);
+			iowrite16(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */
+			iowrite16(AckIntr | HostError, ioaddr + EL3_CMD);
 		}
 	}
 
 	if (do_tx_reset) {
 		issue_and_wait(dev, TxReset|reset_mask);
-		outw(TxEnable, ioaddr + EL3_CMD);
+		iowrite16(TxEnable, ioaddr + EL3_CMD);
 		if (!vp->full_bus_master_tx)
 			netif_wake_queue(dev);
 	}
@@ -2156,29 +2187,29 @@
 vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 
 	/* Put out the doubleword header... */
-	outl(skb->len, ioaddr + TX_FIFO);
+	iowrite32(skb->len, ioaddr + TX_FIFO);
 	if (vp->bus_master) {
 		/* Set the bus-master controller to transfer the packet. */
 		int len = (skb->len + 3) & ~3;
-		outl(	vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len, PCI_DMA_TODEVICE),
+		iowrite32(	vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len, PCI_DMA_TODEVICE),
 				ioaddr + Wn7_MasterAddr);
-		outw(len, ioaddr + Wn7_MasterLen);
+		iowrite16(len, ioaddr + Wn7_MasterLen);
 		vp->tx_skb = skb;
-		outw(StartDMADown, ioaddr + EL3_CMD);
+		iowrite16(StartDMADown, ioaddr + EL3_CMD);
 		/* netif_wake_queue() will be called at the DMADone interrupt. */
 	} else {
 		/* ... and the packet rounded to a doubleword. */
-		outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
+		iowrite32_rep(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
 		dev_kfree_skb (skb);
-		if (inw(ioaddr + TxFree) > 1536) {
+		if (ioread16(ioaddr + TxFree) > 1536) {
 			netif_start_queue (dev);	/* AKPM: redundant? */
 		} else {
 			/* Interrupt us when the FIFO has room for max-sized packet. */
 			netif_stop_queue(dev);
-			outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
+			iowrite16(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
 		}
 	}
 
@@ -2189,7 +2220,7 @@
 		int tx_status;
 		int i = 32;
 
-		while (--i > 0	&&	(tx_status = inb(ioaddr + TxStatus)) > 0) {
+		while (--i > 0	&&	(tx_status = ioread8(ioaddr + TxStatus)) > 0) {
 			if (tx_status & 0x3C) {		/* A Tx-disabling error occurred.  */
 				if (vortex_debug > 2)
 				  printk(KERN_DEBUG "%s: Tx error, status %2.2x.\n",
@@ -2199,9 +2230,9 @@
 				if (tx_status & 0x30) {
 					issue_and_wait(dev, TxReset);
 				}
-				outw(TxEnable, ioaddr + EL3_CMD);
+				iowrite16(TxEnable, ioaddr + EL3_CMD);
 			}
-			outb(0x00, ioaddr + TxStatus); /* Pop the status stack. */
+			iowrite8(0x00, ioaddr + TxStatus); /* Pop the status stack. */
 		}
 	}
 	return 0;
@@ -2211,7 +2242,7 @@
 boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 	/* Calculate the next Tx descriptor entry. */
 	int entry = vp->cur_tx % TX_RING_SIZE;
 	struct boom_tx_desc *prev_entry = &vp->tx_ring[(vp->cur_tx-1) % TX_RING_SIZE];
@@ -2275,8 +2306,8 @@
 	/* Wait for the stall to complete. */
 	issue_and_wait(dev, DownStall);
 	prev_entry->next = cpu_to_le32(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc));
-	if (inl(ioaddr + DownListPtr) == 0) {
-		outl(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc), ioaddr + DownListPtr);
+	if (ioread32(ioaddr + DownListPtr) == 0) {
+		iowrite32(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc), ioaddr + DownListPtr);
 		vp->queued_packet++;
 	}
 
@@ -2291,7 +2322,7 @@
 		prev_entry->status &= cpu_to_le32(~TxIntrUploaded);
 #endif
 	}
-	outw(DownUnstall, ioaddr + EL3_CMD);
+	iowrite16(DownUnstall, ioaddr + EL3_CMD);
 	spin_unlock_irqrestore(&vp->lock, flags);
 	dev->trans_start = jiffies;
 	return 0;
@@ -2310,15 +2341,15 @@
 {
 	struct net_device *dev = dev_id;
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr;
+	void __iomem *ioaddr;
 	int status;
 	int work_done = max_interrupt_work;
 	int handled = 0;
 
-	ioaddr = dev->base_addr;
+	ioaddr = vp->ioaddr;
 	spin_lock(&vp->lock);
 
-	status = inw(ioaddr + EL3_STATUS);
+	status = ioread16(ioaddr + EL3_STATUS);
 
 	if (vortex_debug > 6)
 		printk("vortex_interrupt(). status=0x%4x\n", status);
@@ -2337,7 +2368,7 @@
 
 	if (vortex_debug > 4)
 		printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
-			   dev->name, status, inb(ioaddr + Timer));
+			   dev->name, status, ioread8(ioaddr + Timer));
 
 	do {
 		if (vortex_debug > 5)
@@ -2350,16 +2381,16 @@
 			if (vortex_debug > 5)
 				printk(KERN_DEBUG "	TX room bit was handled.\n");
 			/* There's room in the FIFO for a full-sized packet. */
-			outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
+			iowrite16(AckIntr | TxAvailable, ioaddr + EL3_CMD);
 			netif_wake_queue (dev);
 		}
 
 		if (status & DMADone) {
-			if (inw(ioaddr + Wn7_MasterStatus) & 0x1000) {
-				outw(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
+			if (ioread16(ioaddr + Wn7_MasterStatus) & 0x1000) {
+				iowrite16(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
 				pci_unmap_single(VORTEX_PCI(vp), vp->tx_skb_dma, (vp->tx_skb->len + 3) & ~3, PCI_DMA_TODEVICE);
 				dev_kfree_skb_irq(vp->tx_skb); /* Release the transferred buffer */
-				if (inw(ioaddr + TxFree) > 1536) {
+				if (ioread16(ioaddr + TxFree) > 1536) {
 					/*
 					 * AKPM: FIXME: I don't think we need this.  If the queue was stopped due to
 					 * insufficient FIFO room, the TxAvailable test will succeed and call
@@ -2367,7 +2398,7 @@
 					 */
 					netif_wake_queue(dev);
 				} else { /* Interrupt when FIFO has room for max-sized packet. */
-					outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
+					iowrite16(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
 					netif_stop_queue(dev);
 				}
 			}
@@ -2385,17 +2416,17 @@
 			/* Disable all pending interrupts. */
 			do {
 				vp->deferred |= status;
-				outw(SetStatusEnb | (~vp->deferred & vp->status_enable),
+				iowrite16(SetStatusEnb | (~vp->deferred & vp->status_enable),
 					 ioaddr + EL3_CMD);
-				outw(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
-			} while ((status = inw(ioaddr + EL3_CMD)) & IntLatch);
+				iowrite16(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
+			} while ((status = ioread16(ioaddr + EL3_CMD)) & IntLatch);
 			/* The timer will reenable interrupts. */
 			mod_timer(&vp->timer, jiffies + 1*HZ);
 			break;
 		}
 		/* Acknowledge the IRQ. */
-		outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
-	} while ((status = inw(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
+		iowrite16(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
+	} while ((status = ioread16(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
 
 	if (vortex_debug > 4)
 		printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
@@ -2415,11 +2446,11 @@
 {
 	struct net_device *dev = dev_id;
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr;
+	void __iomem *ioaddr;
 	int status;
 	int work_done = max_interrupt_work;
 
-	ioaddr = dev->base_addr;
+	ioaddr = vp->ioaddr;
 
 	/*
 	 * It seems dopey to put the spinlock this early, but we could race against vortex_tx_timeout
@@ -2427,7 +2458,7 @@
 	 */
 	spin_lock(&vp->lock);
 
-	status = inw(ioaddr + EL3_STATUS);
+	status = ioread16(ioaddr + EL3_STATUS);
 
 	if (vortex_debug > 6)
 		printk(KERN_DEBUG "boomerang_interrupt. status=0x%4x\n", status);
@@ -2448,13 +2479,13 @@
 
 	if (vortex_debug > 4)
 		printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
-			   dev->name, status, inb(ioaddr + Timer));
+			   dev->name, status, ioread8(ioaddr + Timer));
 	do {
 		if (vortex_debug > 5)
 				printk(KERN_DEBUG "%s: In interrupt loop, status %4.4x.\n",
 					   dev->name, status);
 		if (status & UpComplete) {
-			outw(AckIntr | UpComplete, ioaddr + EL3_CMD);
+			iowrite16(AckIntr | UpComplete, ioaddr + EL3_CMD);
 			if (vortex_debug > 5)
 				printk(KERN_DEBUG "boomerang_interrupt->boomerang_rx\n");
 			boomerang_rx(dev);
@@ -2463,11 +2494,11 @@
 		if (status & DownComplete) {
 			unsigned int dirty_tx = vp->dirty_tx;
 
-			outw(AckIntr | DownComplete, ioaddr + EL3_CMD);
+			iowrite16(AckIntr | DownComplete, ioaddr + EL3_CMD);
 			while (vp->cur_tx - dirty_tx > 0) {
 				int entry = dirty_tx % TX_RING_SIZE;
 #if 1	/* AKPM: the latter is faster, but cyclone-only */
-				if (inl(ioaddr + DownListPtr) ==
+				if (ioread32(ioaddr + DownListPtr) ==
 					vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc))
 					break;			/* It still hasn't been processed. */
 #else
@@ -2514,20 +2545,20 @@
 			/* Disable all pending interrupts. */
 			do {
 				vp->deferred |= status;
-				outw(SetStatusEnb | (~vp->deferred & vp->status_enable),
+				iowrite16(SetStatusEnb | (~vp->deferred & vp->status_enable),
 					 ioaddr + EL3_CMD);
-				outw(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
-			} while ((status = inw(ioaddr + EL3_CMD)) & IntLatch);
+				iowrite16(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
+			} while ((status = ioread16(ioaddr + EL3_CMD)) & IntLatch);
 			/* The timer will reenable interrupts. */
 			mod_timer(&vp->timer, jiffies + 1*HZ);
 			break;
 		}
 		/* Acknowledge the IRQ. */
-		outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
+		iowrite16(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
 		if (vp->cb_fn_base)			/* The PCMCIA people are idiots.  */
-			writel(0x8000, vp->cb_fn_base + 4);
+			iowrite32(0x8000, vp->cb_fn_base + 4);
 
-	} while ((status = inw(ioaddr + EL3_STATUS)) & IntLatch);
+	} while ((status = ioread16(ioaddr + EL3_STATUS)) & IntLatch);
 
 	if (vortex_debug > 4)
 		printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
@@ -2540,16 +2571,16 @@
 static int vortex_rx(struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 	int i;
 	short rx_status;
 
 	if (vortex_debug > 5)
 		printk(KERN_DEBUG "vortex_rx(): status %4.4x, rx_status %4.4x.\n",
-			   inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus));
-	while ((rx_status = inw(ioaddr + RxStatus)) > 0) {
+			   ioread16(ioaddr+EL3_STATUS), ioread16(ioaddr+RxStatus));
+	while ((rx_status = ioread16(ioaddr + RxStatus)) > 0) {
 		if (rx_status & 0x4000) { /* Error, update stats. */
-			unsigned char rx_error = inb(ioaddr + RxErrors);
+			unsigned char rx_error = ioread8(ioaddr + RxErrors);
 			if (vortex_debug > 2)
 				printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error);
 			vp->stats.rx_errors++;
@@ -2572,34 +2603,35 @@
 				skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
 				/* 'skb_put()' points to the start of sk_buff data area. */
 				if (vp->bus_master &&
-					! (inw(ioaddr + Wn7_MasterStatus) & 0x8000)) {
+					! (ioread16(ioaddr + Wn7_MasterStatus) & 0x8000)) {
 					dma_addr_t dma = pci_map_single(VORTEX_PCI(vp), skb_put(skb, pkt_len),
 									   pkt_len, PCI_DMA_FROMDEVICE);
-					outl(dma, ioaddr + Wn7_MasterAddr);
-					outw((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen);
-					outw(StartDMAUp, ioaddr + EL3_CMD);
-					while (inw(ioaddr + Wn7_MasterStatus) & 0x8000)
+					iowrite32(dma, ioaddr + Wn7_MasterAddr);
+					iowrite16((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen);
+					iowrite16(StartDMAUp, ioaddr + EL3_CMD);
+					while (ioread16(ioaddr + Wn7_MasterStatus) & 0x8000)
 						;
 					pci_unmap_single(VORTEX_PCI(vp), dma, pkt_len, PCI_DMA_FROMDEVICE);
 				} else {
-					insl(ioaddr + RX_FIFO, skb_put(skb, pkt_len),
-						 (pkt_len + 3) >> 2);
+					ioread32_rep(ioaddr + RX_FIFO,
+					             skb_put(skb, pkt_len),
+						     (pkt_len + 3) >> 2);
 				}
-				outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
+				iowrite16(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
 				skb->protocol = eth_type_trans(skb, dev);
 				netif_rx(skb);
 				dev->last_rx = jiffies;
 				vp->stats.rx_packets++;
 				/* Wait a limited time to go to next packet. */
 				for (i = 200; i >= 0; i--)
-					if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
+					if ( ! (ioread16(ioaddr + EL3_STATUS) & CmdInProgress))
 						break;
 				continue;
 			} else if (vortex_debug > 0)
 				printk(KERN_NOTICE "%s: No memory to allocate a sk_buff of "
 					   "size %d.\n", dev->name, pkt_len);
+			vp->stats.rx_dropped++;
 		}
-		vp->stats.rx_dropped++;
 		issue_and_wait(dev, RxDiscard);
 	}
 
@@ -2611,12 +2643,12 @@
 {
 	struct vortex_private *vp = netdev_priv(dev);
 	int entry = vp->cur_rx % RX_RING_SIZE;
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 	int rx_status;
 	int rx_work_limit = vp->dirty_rx + RX_RING_SIZE - vp->cur_rx;
 
 	if (vortex_debug > 5)
-		printk(KERN_DEBUG "boomerang_rx(): status %4.4x\n", inw(ioaddr+EL3_STATUS));
+		printk(KERN_DEBUG "boomerang_rx(): status %4.4x\n", ioread16(ioaddr+EL3_STATUS));
 
 	while ((rx_status = le32_to_cpu(vp->rx_ring[entry].status)) & RxDComplete){
 		if (--rx_work_limit < 0)
@@ -2699,7 +2731,7 @@
 			vp->rx_skbuff[entry] = skb;
 		}
 		vp->rx_ring[entry].status = 0;	/* Clear complete bit. */
-		outw(UpUnstall, ioaddr + EL3_CMD);
+		iowrite16(UpUnstall, ioaddr + EL3_CMD);
 	}
 	return 0;
 }
@@ -2728,7 +2760,7 @@
 vortex_down(struct net_device *dev, int final_down)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 
 	netif_stop_queue (dev);
 
@@ -2736,26 +2768,26 @@
 	del_timer_sync(&vp->timer);
 
 	/* Turn off statistics ASAP.  We update vp->stats below. */
-	outw(StatsDisable, ioaddr + EL3_CMD);
+	iowrite16(StatsDisable, ioaddr + EL3_CMD);
 
 	/* Disable the receiver and transmitter. */
-	outw(RxDisable, ioaddr + EL3_CMD);
-	outw(TxDisable, ioaddr + EL3_CMD);
+	iowrite16(RxDisable, ioaddr + EL3_CMD);
+	iowrite16(TxDisable, ioaddr + EL3_CMD);
 
 	/* Disable receiving 802.1q tagged frames */
 	set_8021q_mode(dev, 0);
 
 	if (dev->if_port == XCVR_10base2)
 		/* Turn off thinnet power.  Green! */
-		outw(StopCoax, ioaddr + EL3_CMD);
+		iowrite16(StopCoax, ioaddr + EL3_CMD);
 
-	outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
+	iowrite16(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
 
 	update_stats(ioaddr, dev);
 	if (vp->full_bus_master_rx)
-		outl(0, ioaddr + UpListPtr);
+		iowrite32(0, ioaddr + UpListPtr);
 	if (vp->full_bus_master_tx)
-		outl(0, ioaddr + DownListPtr);
+		iowrite32(0, ioaddr + DownListPtr);
 
 	if (final_down && VORTEX_PCI(vp)) {
 		vp->pm_state_valid = 1;
@@ -2768,7 +2800,7 @@
 vortex_close(struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 	int i;
 
 	if (netif_device_present(dev))
@@ -2776,17 +2808,18 @@
 
 	if (vortex_debug > 1) {
 		printk(KERN_DEBUG"%s: vortex_close() status %4.4x, Tx status %2.2x.\n",
-			   dev->name, inw(ioaddr + EL3_STATUS), inb(ioaddr + TxStatus));
+			   dev->name, ioread16(ioaddr + EL3_STATUS), ioread8(ioaddr + TxStatus));
 		printk(KERN_DEBUG "%s: vortex close stats: rx_nocopy %d rx_copy %d"
 			   " tx_queued %d Rx pre-checksummed %d.\n",
 			   dev->name, vp->rx_nocopy, vp->rx_copy, vp->queued_packet, vp->rx_csumhits);
 	}
 
 #if DO_ZEROCOPY
-	if (	vp->rx_csumhits &&
-			((vp->drv_flags & HAS_HWCKSM) == 0) &&
-			(hw_checksums[vp->card_idx] == -1)) {
-		printk(KERN_WARNING "%s supports hardware checksums, and we're not using them!\n", dev->name);
+	if (vp->rx_csumhits &&
+	    (vp->drv_flags & HAS_HWCKSM) == 0 &&
+	    (vp->card_idx >= MAX_UNITS || hw_checksums[vp->card_idx] == -1)) {
+			printk(KERN_WARNING "%s supports hardware checksums, and we're "
+						"not using them!\n", dev->name);
 	}
 #endif
 		
@@ -2830,18 +2863,18 @@
 {
 	if (vortex_debug > 0) {
 	struct vortex_private *vp = netdev_priv(dev);
-		long ioaddr = dev->base_addr;
+		void __iomem *ioaddr = vp->ioaddr;
 		
 		if (vp->full_bus_master_tx) {
 			int i;
-			int stalled = inl(ioaddr + PktStatus) & 0x04;	/* Possible racy. But it's only debug stuff */
+			int stalled = ioread32(ioaddr + PktStatus) & 0x04;	/* Possible racy. But it's only debug stuff */
 
 			printk(KERN_ERR "  Flags; bus-master %d, dirty %d(%d) current %d(%d)\n",
 					vp->full_bus_master_tx,
 					vp->dirty_tx, vp->dirty_tx % TX_RING_SIZE,
 					vp->cur_tx, vp->cur_tx % TX_RING_SIZE);
 			printk(KERN_ERR "  Transmit list %8.8x vs. %p.\n",
-				   inl(ioaddr + DownListPtr),
+				   ioread32(ioaddr + DownListPtr),
 				   &vp->tx_ring[vp->dirty_tx % TX_RING_SIZE]);
 			issue_and_wait(dev, DownStall);
 			for (i = 0; i < TX_RING_SIZE; i++) {
@@ -2855,7 +2888,7 @@
 					   le32_to_cpu(vp->tx_ring[i].status));
 			}
 			if (!stalled)
-				outw(DownUnstall, ioaddr + EL3_CMD);
+				iowrite16(DownUnstall, ioaddr + EL3_CMD);
 		}
 	}
 }
@@ -2863,11 +2896,12 @@
 static struct net_device_stats *vortex_get_stats(struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
+	void __iomem *ioaddr = vp->ioaddr;
 	unsigned long flags;
 
 	if (netif_device_present(dev)) {	/* AKPM: Used to be netif_running */
 		spin_lock_irqsave (&vp->lock, flags);
-		update_stats(dev->base_addr, dev);
+		update_stats(ioaddr, dev);
 		spin_unlock_irqrestore (&vp->lock, flags);
 	}
 	return &vp->stats;
@@ -2880,37 +2914,37 @@
 	table.  This is done by checking that the ASM (!) code generated uses
 	atomic updates with '+='.
 	*/
-static void update_stats(long ioaddr, struct net_device *dev)
+static void update_stats(void __iomem *ioaddr, struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	int old_window = inw(ioaddr + EL3_CMD);
+	int old_window = ioread16(ioaddr + EL3_CMD);
 
 	if (old_window == 0xffff)	/* Chip suspended or ejected. */
 		return;
 	/* Unlike the 3c5x9 we need not turn off stats updates while reading. */
 	/* Switch to the stats window, and read everything. */
 	EL3WINDOW(6);
-	vp->stats.tx_carrier_errors		+= inb(ioaddr + 0);
-	vp->stats.tx_heartbeat_errors		+= inb(ioaddr + 1);
-	vp->stats.collisions			+= inb(ioaddr + 3);
-	vp->stats.tx_window_errors		+= inb(ioaddr + 4);
-	vp->stats.rx_fifo_errors		+= inb(ioaddr + 5);
-	vp->stats.tx_packets			+= inb(ioaddr + 6);
-	vp->stats.tx_packets			+= (inb(ioaddr + 9)&0x30) << 4;
-	/* Rx packets	*/			inb(ioaddr + 7);   /* Must read to clear */
+	vp->stats.tx_carrier_errors		+= ioread8(ioaddr + 0);
+	vp->stats.tx_heartbeat_errors		+= ioread8(ioaddr + 1);
+	vp->stats.collisions			+= ioread8(ioaddr + 3);
+	vp->stats.tx_window_errors		+= ioread8(ioaddr + 4);
+	vp->stats.rx_fifo_errors		+= ioread8(ioaddr + 5);
+	vp->stats.tx_packets			+= ioread8(ioaddr + 6);
+	vp->stats.tx_packets			+= (ioread8(ioaddr + 9)&0x30) << 4;
+	/* Rx packets	*/			ioread8(ioaddr + 7);   /* Must read to clear */
 	/* Don't bother with register 9, an extension of registers 6&7.
 	   If we do use the 6&7 values the atomic update assumption above
 	   is invalid. */
-	vp->stats.rx_bytes 			+= inw(ioaddr + 10);
-	vp->stats.tx_bytes 			+= inw(ioaddr + 12);
+	vp->stats.rx_bytes 			+= ioread16(ioaddr + 10);
+	vp->stats.tx_bytes 			+= ioread16(ioaddr + 12);
 	/* Extra stats for get_ethtool_stats() */
-	vp->xstats.tx_multiple_collisions	+= inb(ioaddr + 2);
-	vp->xstats.tx_deferred			+= inb(ioaddr + 8);
+	vp->xstats.tx_multiple_collisions	+= ioread8(ioaddr + 2);
+	vp->xstats.tx_deferred			+= ioread8(ioaddr + 8);
 	EL3WINDOW(4);
-	vp->xstats.rx_bad_ssd			+= inb(ioaddr + 12);
+	vp->xstats.rx_bad_ssd			+= ioread8(ioaddr + 12);
 
 	{
-		u8 up = inb(ioaddr + 13);
+		u8 up = ioread8(ioaddr + 13);
 		vp->stats.rx_bytes += (up & 0x0f) << 16;
 		vp->stats.tx_bytes += (up & 0xf0) << 12;
 	}
@@ -2922,7 +2956,7 @@
 static int vortex_nway_reset(struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 	unsigned long flags;
 	int rc;
 
@@ -2936,7 +2970,7 @@
 static u32 vortex_get_link(struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 	unsigned long flags;
 	int rc;
 
@@ -2950,7 +2984,7 @@
 static int vortex_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 	unsigned long flags;
 	int rc;
 
@@ -2964,7 +2998,7 @@
 static int vortex_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 	unsigned long flags;
 	int rc;
 
@@ -2994,10 +3028,11 @@
 	struct ethtool_stats *stats, u64 *data)
 {
 	struct vortex_private *vp = netdev_priv(dev);
+	void __iomem *ioaddr = vp->ioaddr;
 	unsigned long flags;
 
 	spin_lock_irqsave(&vp->lock, flags);
-	update_stats(dev->base_addr, dev);
+	update_stats(ioaddr, dev);
 	spin_unlock_irqrestore(&vp->lock, flags);
 
 	data[0] = vp->xstats.tx_deferred;
@@ -3047,6 +3082,7 @@
 	.set_settings           = vortex_set_settings,
 	.get_link               = vortex_get_link,
 	.nway_reset             = vortex_nway_reset,
+	.get_perm_addr			= ethtool_op_get_perm_addr,
 };
 
 #ifdef CONFIG_PCI
@@ -3057,7 +3093,7 @@
 {
 	int err;
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 	unsigned long flags;
 	int state = 0;
 
@@ -3085,7 +3121,8 @@
    the chip has a very clean way to set the mode, unlike many others. */
 static void set_rx_mode(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
+	struct vortex_private *vp = netdev_priv(dev);
+	void __iomem *ioaddr = vp->ioaddr;
 	int new_mode;
 
 	if (dev->flags & IFF_PROMISC) {
@@ -3097,7 +3134,7 @@
 	} else
 		new_mode = SetRxFilter | RxStation | RxBroadcast;
 
-	outw(new_mode, ioaddr + EL3_CMD);
+	iowrite16(new_mode, ioaddr + EL3_CMD);
 }
 
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
@@ -3111,8 +3148,8 @@
 static void set_8021q_mode(struct net_device *dev, int enable)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
-	int old_window = inw(ioaddr + EL3_CMD);
+	void __iomem *ioaddr = vp->ioaddr;
+	int old_window = ioread16(ioaddr + EL3_CMD);
 	int mac_ctrl;
 
 	if ((vp->drv_flags&IS_CYCLONE) || (vp->drv_flags&IS_TORNADO)) {
@@ -3124,24 +3161,24 @@
 			max_pkt_size += 4;	/* 802.1Q VLAN tag */
 
 		EL3WINDOW(3);
-		outw(max_pkt_size, ioaddr+Wn3_MaxPktSize);
+		iowrite16(max_pkt_size, ioaddr+Wn3_MaxPktSize);
 
 		/* set VlanEtherType to let the hardware checksumming
 		   treat tagged frames correctly */
 		EL3WINDOW(7);
-		outw(VLAN_ETHER_TYPE, ioaddr+Wn7_VlanEtherType);
+		iowrite16(VLAN_ETHER_TYPE, ioaddr+Wn7_VlanEtherType);
 	} else {
 		/* on older cards we have to enable large frames */
 
 		vp->large_frames = dev->mtu > 1500 || enable;
 
 		EL3WINDOW(3);
-		mac_ctrl = inw(ioaddr+Wn3_MAC_Ctrl);
+		mac_ctrl = ioread16(ioaddr+Wn3_MAC_Ctrl);
 		if (vp->large_frames)
 			mac_ctrl |= 0x40;
 		else
 			mac_ctrl &= ~0x40;
-		outw(mac_ctrl, ioaddr+Wn3_MAC_Ctrl);
+		iowrite16(mac_ctrl, ioaddr+Wn3_MAC_Ctrl);
 	}
 
 	EL3WINDOW(old_window);
@@ -3163,7 +3200,7 @@
 /* The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
    met by back-to-back PCI I/O cycles, but we insert a delay to avoid
    "overclocking" issues. */
-#define mdio_delay() inl(mdio_addr)
+#define mdio_delay() ioread32(mdio_addr)
 
 #define MDIO_SHIFT_CLK	0x01
 #define MDIO_DIR_WRITE	0x04
@@ -3174,15 +3211,15 @@
 
 /* Generate the preamble required for initial synchronization and
    a few older transceivers. */
-static void mdio_sync(long ioaddr, int bits)
+static void mdio_sync(void __iomem *ioaddr, int bits)
 {
-	long mdio_addr = ioaddr + Wn4_PhysicalMgmt;
+	void __iomem *mdio_addr = ioaddr + Wn4_PhysicalMgmt;
 
 	/* Establish sync by sending at least 32 logic ones. */
 	while (-- bits >= 0) {
-		outw(MDIO_DATA_WRITE1, mdio_addr);
+		iowrite16(MDIO_DATA_WRITE1, mdio_addr);
 		mdio_delay();
-		outw(MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
+		iowrite16(MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
 		mdio_delay();
 	}
 }
@@ -3190,10 +3227,11 @@
 static int mdio_read(struct net_device *dev, int phy_id, int location)
 {
 	int i;
-	long ioaddr = dev->base_addr;
+	struct vortex_private *vp = netdev_priv(dev);
+	void __iomem *ioaddr = vp->ioaddr;
 	int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
 	unsigned int retval = 0;
-	long mdio_addr = ioaddr + Wn4_PhysicalMgmt;
+	void __iomem *mdio_addr = ioaddr + Wn4_PhysicalMgmt;
 
 	if (mii_preamble_required)
 		mdio_sync(ioaddr, 32);
@@ -3201,17 +3239,17 @@
 	/* Shift the read command bits out. */
 	for (i = 14; i >= 0; i--) {
 		int dataval = (read_cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
-		outw(dataval, mdio_addr);
+		iowrite16(dataval, mdio_addr);
 		mdio_delay();
-		outw(dataval | MDIO_SHIFT_CLK, mdio_addr);
+		iowrite16(dataval | MDIO_SHIFT_CLK, mdio_addr);
 		mdio_delay();
 	}
 	/* Read the two transition, 16 data, and wire-idle bits. */
 	for (i = 19; i > 0; i--) {
-		outw(MDIO_ENB_IN, mdio_addr);
+		iowrite16(MDIO_ENB_IN, mdio_addr);
 		mdio_delay();
-		retval = (retval << 1) | ((inw(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
-		outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
+		retval = (retval << 1) | ((ioread16(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
+		iowrite16(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
 		mdio_delay();
 	}
 	return retval & 0x20000 ? 0xffff : retval>>1 & 0xffff;
@@ -3219,9 +3257,10 @@
 
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
 {
-	long ioaddr = dev->base_addr;
+	struct vortex_private *vp = netdev_priv(dev);
+	void __iomem *ioaddr = vp->ioaddr;
 	int write_cmd = 0x50020000 | (phy_id << 23) | (location << 18) | value;
-	long mdio_addr = ioaddr + Wn4_PhysicalMgmt;
+	void __iomem *mdio_addr = ioaddr + Wn4_PhysicalMgmt;
 	int i;
 
 	if (mii_preamble_required)
@@ -3230,16 +3269,16 @@
 	/* Shift the command bits out. */
 	for (i = 31; i >= 0; i--) {
 		int dataval = (write_cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
-		outw(dataval, mdio_addr);
+		iowrite16(dataval, mdio_addr);
 		mdio_delay();
-		outw(dataval | MDIO_SHIFT_CLK, mdio_addr);
+		iowrite16(dataval | MDIO_SHIFT_CLK, mdio_addr);
 		mdio_delay();
 	}
 	/* Leave the interface idle. */
 	for (i = 1; i >= 0; i--) {
-		outw(MDIO_ENB_IN, mdio_addr);
+		iowrite16(MDIO_ENB_IN, mdio_addr);
 		mdio_delay();
-		outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
+		iowrite16(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
 		mdio_delay();
 	}
 	return;
@@ -3250,15 +3289,15 @@
 static void acpi_set_WOL(struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 
 	if (vp->enable_wol) {
 		/* Power up on: 1==Downloaded Filter, 2==Magic Packets, 4==Link Status. */
 		EL3WINDOW(7);
-		outw(2, ioaddr + 0x0c);
+		iowrite16(2, ioaddr + 0x0c);
 		/* The RxFilter must accept the WOL frames. */
-		outw(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD);
-		outw(RxEnable, ioaddr + EL3_CMD);
+		iowrite16(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD);
+		iowrite16(RxEnable, ioaddr + EL3_CMD);
 
 		pci_enable_wake(VORTEX_PCI(vp), 0, 1);
 
@@ -3280,10 +3319,9 @@
 
 	vp = netdev_priv(dev);
 
-	/* AKPM: FIXME: we should have
-	 *	if (vp->cb_fn_base) iounmap(vp->cb_fn_base);
-	 * here
-	 */
+	if (vp->cb_fn_base)
+		pci_iounmap(VORTEX_PCI(vp), vp->cb_fn_base);
+
 	unregister_netdev(dev);
 
 	if (VORTEX_PCI(vp)) {
@@ -3293,8 +3331,10 @@
 		pci_disable_device(VORTEX_PCI(vp));
 	}
 	/* Should really use issue_and_wait() here */
-	outw(TotalReset | ((vp->drv_flags & EEPROM_RESET) ? 0x04 : 0x14),
-	     dev->base_addr + EL3_CMD);
+	iowrite16(TotalReset | ((vp->drv_flags & EEPROM_RESET) ? 0x04 : 0x14),
+	     vp->ioaddr + EL3_CMD);
+
+	pci_iounmap(VORTEX_PCI(vp), vp->ioaddr);
 
 	pci_free_consistent(pdev,
 						sizeof(struct boom_rx_desc) * RX_RING_SIZE
@@ -3342,7 +3382,7 @@
 static void __exit vortex_eisa_cleanup (void)
 {
 	struct vortex_private *vp;
-	long ioaddr;
+	void __iomem *ioaddr;
 
 #ifdef CONFIG_EISA
 	/* Take care of the EISA devices */
@@ -3351,11 +3391,13 @@
 	
 	if (compaq_net_device) {
 		vp = compaq_net_device->priv;
-		ioaddr = compaq_net_device->base_addr;
+		ioaddr = ioport_map(compaq_net_device->base_addr,
+		                    VORTEX_TOTAL_SIZE);
 
 		unregister_netdev (compaq_net_device);
-		outw (TotalReset, ioaddr + EL3_CMD);
-		release_region (ioaddr, VORTEX_TOTAL_SIZE);
+		iowrite16 (TotalReset, ioaddr + EL3_CMD);
+		release_region(compaq_net_device->base_addr,
+		               VORTEX_TOTAL_SIZE);
 
 		free_netdev (compaq_net_device);
 	}
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 11d2523..8f46427 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -14,8 +14,8 @@
 
 #define DRV_MODULE_NAME		"bnx2"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"1.2.21"
-#define DRV_MODULE_RELDATE	"September 7, 2005"
+#define DRV_MODULE_VERSION	"1.4.30"
+#define DRV_MODULE_RELDATE	"October 11, 2005"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -26,7 +26,7 @@
 	"Broadcom NetXtreme II Gigabit Ethernet Driver " DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
 
 MODULE_AUTHOR("Michael Chan <mchan@broadcom.com>");
-MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706 Driver");
+MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708 Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_MODULE_VERSION);
 
@@ -41,6 +41,8 @@
 	NC370I,
 	BCM5706S,
 	NC370F,
+	BCM5708,
+	BCM5708S,
 } board_t;
 
 /* indexed by board_t, above */
@@ -52,6 +54,8 @@
 	{ "HP NC370i Multifunction Gigabit Server Adapter" },
 	{ "Broadcom NetXtreme II BCM5706 1000Base-SX" },
 	{ "HP NC370F Multifunction Gigabit Server Adapter" },
+	{ "Broadcom NetXtreme II BCM5708 1000Base-T" },
+	{ "Broadcom NetXtreme II BCM5708 1000Base-SX" },
 	};
 
 static struct pci_device_id bnx2_pci_tbl[] = {
@@ -61,48 +65,102 @@
 	  PCI_VENDOR_ID_HP, 0x3106, 0, 0, NC370I },
 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706 },
+	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5708,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5708 },
 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706S,
 	  PCI_VENDOR_ID_HP, 0x3102, 0, 0, NC370F },
 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706S,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706S },
+	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5708S,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5708S },
 	{ 0, }
 };
 
 static struct flash_spec flash_table[] =
 {
 	/* Slow EEPROM */
-	{0x00000000, 0x40030380, 0x009f0081, 0xa184a053, 0xaf000400,
+	{0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
 	 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
 	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
 	 "EEPROM - slow"},
-	/* Fast EEPROM */
-	{0x02000000, 0x62008380, 0x009f0081, 0xa184a053, 0xaf000400,
-	 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
-	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
-	 "EEPROM - fast"},
-	/* ATMEL AT45DB011B (buffered flash) */
-	{0x02000003, 0x6e008173, 0x00570081, 0x68848353, 0xaf000400,
-	 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
-	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
-	 "Buffered flash"},
-	/* Saifun SA25F005 (non-buffered flash) */
-       	/* strap, cfg1, & write1 need updates */
-	{0x01000003, 0x5f008081, 0x00050081, 0x03840253, 0xaf020406,
+	/* Expansion entry 0001 */
+	{0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
-	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
-	 "Non-buffered flash (64kB)"},
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+	 "Entry 0001"},
 	/* Saifun SA25F010 (non-buffered flash) */
 	/* strap, cfg1, & write1 need updates */
-	{0x00000001, 0x47008081, 0x00050081, 0x03840253, 0xaf020406,
+	{0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
 	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
 	 "Non-buffered flash (128kB)"},
 	/* Saifun SA25F020 (non-buffered flash) */
 	/* strap, cfg1, & write1 need updates */
-	{0x00000003, 0x4f008081, 0x00050081, 0x03840253, 0xaf020406,
+	{0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
 	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
 	 "Non-buffered flash (256kB)"},
+	/* Expansion entry 0100 */
+	{0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
+	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+	 "Entry 0100"},
+	/* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
+	{0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,        
+	 0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
+	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
+	 "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
+	/* Entry 0110: ST M45PE20 (non-buffered flash)*/
+	{0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
+	 0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
+	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
+	 "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
+	/* Saifun SA25F005 (non-buffered flash) */
+	/* strap, cfg1, & write1 need updates */
+	{0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
+	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
+	 "Non-buffered flash (64kB)"},
+	/* Fast EEPROM */
+	{0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
+	 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
+	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
+	 "EEPROM - fast"},
+	/* Expansion entry 1001 */
+	{0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
+	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+	 "Entry 1001"},
+	/* Expansion entry 1010 */
+	{0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
+	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+	 "Entry 1010"},
+	/* ATMEL AT45DB011B (buffered flash) */
+	{0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
+	 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
+	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
+	 "Buffered flash (128kB)"},
+	/* Expansion entry 1100 */
+	{0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
+	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+	 "Entry 1100"},
+	/* Expansion entry 1101 */
+	{0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
+	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+	 "Entry 1101"},
+	/* Ateml Expansion entry 1110 */
+	{0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
+	 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
+	 BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
+	 "Entry 1110 (Atmel)"},
+	/* ATMEL AT45DB021B (buffered flash) */
+	{0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
+	 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
+	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
+	 "Buffered flash (256kB)"},
 };
 
 MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl);
@@ -379,6 +437,62 @@
 }
 
 static void
+bnx2_report_fw_link(struct bnx2 *bp)
+{
+	u32 fw_link_status = 0;
+
+	if (bp->link_up) {
+		u32 bmsr;
+
+		switch (bp->line_speed) {
+		case SPEED_10:
+			if (bp->duplex == DUPLEX_HALF)
+				fw_link_status = BNX2_LINK_STATUS_10HALF;
+			else
+				fw_link_status = BNX2_LINK_STATUS_10FULL;
+			break;
+		case SPEED_100:
+			if (bp->duplex == DUPLEX_HALF)
+				fw_link_status = BNX2_LINK_STATUS_100HALF;
+			else
+				fw_link_status = BNX2_LINK_STATUS_100FULL;
+			break;
+		case SPEED_1000:
+			if (bp->duplex == DUPLEX_HALF)
+				fw_link_status = BNX2_LINK_STATUS_1000HALF;
+			else
+				fw_link_status = BNX2_LINK_STATUS_1000FULL;
+			break;
+		case SPEED_2500:
+			if (bp->duplex == DUPLEX_HALF)
+				fw_link_status = BNX2_LINK_STATUS_2500HALF;
+			else
+				fw_link_status = BNX2_LINK_STATUS_2500FULL;
+			break;
+		}
+
+		fw_link_status |= BNX2_LINK_STATUS_LINK_UP;
+
+		if (bp->autoneg) {
+			fw_link_status |= BNX2_LINK_STATUS_AN_ENABLED;
+
+			bnx2_read_phy(bp, MII_BMSR, &bmsr);
+			bnx2_read_phy(bp, MII_BMSR, &bmsr);
+
+			if (!(bmsr & BMSR_ANEGCOMPLETE) ||
+			    bp->phy_flags & PHY_PARALLEL_DETECT_FLAG)
+				fw_link_status |= BNX2_LINK_STATUS_PARALLEL_DET;
+			else
+				fw_link_status |= BNX2_LINK_STATUS_AN_COMPLETE;
+		}
+	}
+	else
+		fw_link_status = BNX2_LINK_STATUS_LINK_DOWN;
+
+	REG_WR_IND(bp, bp->shmem_base + BNX2_LINK_STATUS, fw_link_status);
+}
+
+static void
 bnx2_report_link(struct bnx2 *bp)
 {
 	if (bp->link_up) {
@@ -409,6 +523,8 @@
 		netif_carrier_off(bp->dev);
 		printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name);
 	}
+
+	bnx2_report_fw_link(bp);
 }
 
 static void
@@ -430,6 +546,18 @@
 		return;
 	}
 
+	if ((bp->phy_flags & PHY_SERDES_FLAG) &&
+	    (CHIP_NUM(bp) == CHIP_NUM_5708)) {
+		u32 val;
+
+		bnx2_read_phy(bp, BCM5708S_1000X_STAT1, &val);
+		if (val & BCM5708S_1000X_STAT1_TX_PAUSE)
+			bp->flow_ctrl |= FLOW_CTRL_TX;
+		if (val & BCM5708S_1000X_STAT1_RX_PAUSE)
+			bp->flow_ctrl |= FLOW_CTRL_RX;
+		return;
+	}
+
 	bnx2_read_phy(bp, MII_ADVERTISE, &local_adv);
 	bnx2_read_phy(bp, MII_LPA, &remote_adv);
 
@@ -476,7 +604,36 @@
 }
 
 static int
-bnx2_serdes_linkup(struct bnx2 *bp)
+bnx2_5708s_linkup(struct bnx2 *bp)
+{
+	u32 val;
+
+	bp->link_up = 1;
+	bnx2_read_phy(bp, BCM5708S_1000X_STAT1, &val);
+	switch (val & BCM5708S_1000X_STAT1_SPEED_MASK) {
+		case BCM5708S_1000X_STAT1_SPEED_10:
+			bp->line_speed = SPEED_10;
+			break;
+		case BCM5708S_1000X_STAT1_SPEED_100:
+			bp->line_speed = SPEED_100;
+			break;
+		case BCM5708S_1000X_STAT1_SPEED_1G:
+			bp->line_speed = SPEED_1000;
+			break;
+		case BCM5708S_1000X_STAT1_SPEED_2G5:
+			bp->line_speed = SPEED_2500;
+			break;
+	}
+	if (val & BCM5708S_1000X_STAT1_FD)
+		bp->duplex = DUPLEX_FULL;
+	else
+		bp->duplex = DUPLEX_HALF;
+
+	return 0;
+}
+
+static int
+bnx2_5706s_linkup(struct bnx2 *bp)
 {
 	u32 bmcr, local_adv, remote_adv, common;
 
@@ -593,13 +750,27 @@
 	val = REG_RD(bp, BNX2_EMAC_MODE);
 
 	val &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX |
-		BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK);
+		BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK |
+		BNX2_EMAC_MODE_25G);
 
 	if (bp->link_up) {
-		if (bp->line_speed != SPEED_1000)
-			val |= BNX2_EMAC_MODE_PORT_MII;
-		else
-			val |= BNX2_EMAC_MODE_PORT_GMII;
+		switch (bp->line_speed) {
+			case SPEED_10:
+				if (CHIP_NUM(bp) == CHIP_NUM_5708) {
+					val |= BNX2_EMAC_MODE_PORT_MII_10;
+					break;
+				}
+				/* fall through */
+			case SPEED_100:
+				val |= BNX2_EMAC_MODE_PORT_MII;
+				break;
+			case SPEED_2500:
+				val |= BNX2_EMAC_MODE_25G;
+				/* fall through */
+			case SPEED_1000:
+				val |= BNX2_EMAC_MODE_PORT_GMII;
+				break;
+		}
 	}
 	else {
 		val |= BNX2_EMAC_MODE_PORT_GMII;
@@ -662,7 +833,10 @@
 		bp->link_up = 1;
 
 		if (bp->phy_flags & PHY_SERDES_FLAG) {
-			bnx2_serdes_linkup(bp);
+			if (CHIP_NUM(bp) == CHIP_NUM_5706)
+				bnx2_5706s_linkup(bp);
+			else if (CHIP_NUM(bp) == CHIP_NUM_5708)
+				bnx2_5708s_linkup(bp);
 		}
 		else {
 			bnx2_copper_linkup(bp);
@@ -755,39 +929,61 @@
 static int
 bnx2_setup_serdes_phy(struct bnx2 *bp)
 {
-	u32 adv, bmcr;
+	u32 adv, bmcr, up1;
 	u32 new_adv = 0;
 
 	if (!(bp->autoneg & AUTONEG_SPEED)) {
 		u32 new_bmcr;
+		int force_link_down = 0;
+
+		if (CHIP_NUM(bp) == CHIP_NUM_5708) {
+			bnx2_read_phy(bp, BCM5708S_UP1, &up1);
+			if (up1 & BCM5708S_UP1_2G5) {
+				up1 &= ~BCM5708S_UP1_2G5;
+				bnx2_write_phy(bp, BCM5708S_UP1, up1);
+				force_link_down = 1;
+			}
+		}
+
+		bnx2_read_phy(bp, MII_ADVERTISE, &adv);
+		adv &= ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF);
 
 		bnx2_read_phy(bp, MII_BMCR, &bmcr);
 		new_bmcr = bmcr & ~BMCR_ANENABLE;
 		new_bmcr |= BMCR_SPEED1000;
 		if (bp->req_duplex == DUPLEX_FULL) {
+			adv |= ADVERTISE_1000XFULL;
 			new_bmcr |= BMCR_FULLDPLX;
 		}
 		else {
+			adv |= ADVERTISE_1000XHALF;
 			new_bmcr &= ~BMCR_FULLDPLX;
 		}
-		if (new_bmcr != bmcr) {
+		if ((new_bmcr != bmcr) || (force_link_down)) {
 			/* Force a link down visible on the other side */
 			if (bp->link_up) {
-				bnx2_read_phy(bp, MII_ADVERTISE, &adv);
-				adv &= ~(ADVERTISE_1000XFULL |
-					ADVERTISE_1000XHALF);
-				bnx2_write_phy(bp, MII_ADVERTISE, adv);
+				bnx2_write_phy(bp, MII_ADVERTISE, adv &
+					       ~(ADVERTISE_1000XFULL |
+						 ADVERTISE_1000XHALF));
 				bnx2_write_phy(bp, MII_BMCR, bmcr |
 					BMCR_ANRESTART | BMCR_ANENABLE);
 
 				bp->link_up = 0;
 				netif_carrier_off(bp->dev);
+				bnx2_write_phy(bp, MII_BMCR, new_bmcr);
 			}
+			bnx2_write_phy(bp, MII_ADVERTISE, adv);
 			bnx2_write_phy(bp, MII_BMCR, new_bmcr);
 		}
 		return 0;
 	}
 
+	if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) {
+		bnx2_read_phy(bp, BCM5708S_UP1, &up1);
+		up1 |= BCM5708S_UP1_2G5;
+		bnx2_write_phy(bp, BCM5708S_UP1, up1);
+	}
+
 	if (bp->advertising & ADVERTISED_1000baseT_Full)
 		new_adv |= ADVERTISE_1000XFULL;
 
@@ -952,7 +1148,60 @@
 }
 
 static int
-bnx2_init_serdes_phy(struct bnx2 *bp)
+bnx2_init_5708s_phy(struct bnx2 *bp)
+{
+	u32 val;
+
+	bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG3);
+	bnx2_write_phy(bp, BCM5708S_DIG_3_0, BCM5708S_DIG_3_0_USE_IEEE);
+	bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG);
+
+	bnx2_read_phy(bp, BCM5708S_1000X_CTL1, &val);
+	val |= BCM5708S_1000X_CTL1_FIBER_MODE | BCM5708S_1000X_CTL1_AUTODET_EN;
+	bnx2_write_phy(bp, BCM5708S_1000X_CTL1, val);
+
+	bnx2_read_phy(bp, BCM5708S_1000X_CTL2, &val);
+	val |= BCM5708S_1000X_CTL2_PLLEL_DET_EN;
+	bnx2_write_phy(bp, BCM5708S_1000X_CTL2, val);
+
+	if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) {
+		bnx2_read_phy(bp, BCM5708S_UP1, &val);
+		val |= BCM5708S_UP1_2G5;
+		bnx2_write_phy(bp, BCM5708S_UP1, val);
+	}
+
+	if ((CHIP_ID(bp) == CHIP_ID_5708_A0) ||
+	    (CHIP_ID(bp) == CHIP_ID_5708_B0)) {
+		/* increase tx signal amplitude */
+		bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
+			       BCM5708S_BLK_ADDR_TX_MISC);
+		bnx2_read_phy(bp, BCM5708S_TX_ACTL1, &val);
+		val &= ~BCM5708S_TX_ACTL1_DRIVER_VCM;
+		bnx2_write_phy(bp, BCM5708S_TX_ACTL1, val);
+		bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG);
+	}
+
+	val = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG) &
+	      BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK;
+
+	if (val) {
+		u32 is_backplane;
+
+		is_backplane = REG_RD_IND(bp, bp->shmem_base +
+					  BNX2_SHARED_HW_CFG_CONFIG);
+		if (is_backplane & BNX2_SHARED_HW_CFG_PHY_BACKPLANE) {
+			bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
+				       BCM5708S_BLK_ADDR_TX_MISC);
+			bnx2_write_phy(bp, BCM5708S_TX_ACTL3, val);
+			bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
+				       BCM5708S_BLK_ADDR_DIG);
+		}
+	}
+	return 0;
+}
+
+static int
+bnx2_init_5706s_phy(struct bnx2 *bp)
 {
 	bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG;
 
@@ -990,6 +1239,8 @@
 static int
 bnx2_init_copper_phy(struct bnx2 *bp)
 {
+	u32 val;
+
 	bp->phy_flags |= PHY_CRC_FIX_FLAG;
 
 	if (bp->phy_flags & PHY_CRC_FIX_FLAG) {
@@ -1004,8 +1255,6 @@
 	}
 
 	if (bp->dev->mtu > 1500) {
-		u32 val;
-
 		/* Set extended packet length bit */
 		bnx2_write_phy(bp, 0x18, 0x7);
 		bnx2_read_phy(bp, 0x18, &val);
@@ -1015,8 +1264,6 @@
 		bnx2_write_phy(bp, 0x10, val | 0x1);
 	}
 	else {
-		u32 val;
-
 		bnx2_write_phy(bp, 0x18, 0x7);
 		bnx2_read_phy(bp, 0x18, &val);
 		bnx2_write_phy(bp, 0x18, val & ~0x4007);
@@ -1025,6 +1272,10 @@
 		bnx2_write_phy(bp, 0x10, val & ~0x1);
 	}
 
+	/* ethernet@wirespeed */
+	bnx2_write_phy(bp, 0x18, 0x7007);
+	bnx2_read_phy(bp, 0x18, &val);
+	bnx2_write_phy(bp, 0x18, val | (1 << 15) | (1 << 4));
 	return 0;
 }
 
@@ -1048,7 +1299,10 @@
 	bp->phy_id |= val & 0xffff;
 
 	if (bp->phy_flags & PHY_SERDES_FLAG) {
-		rc = bnx2_init_serdes_phy(bp);
+		if (CHIP_NUM(bp) == CHIP_NUM_5706)
+			rc = bnx2_init_5706s_phy(bp);
+		else if (CHIP_NUM(bp) == CHIP_NUM_5708)
+			rc = bnx2_init_5708s_phy(bp);
 	}
 	else {
 		rc = bnx2_init_copper_phy(bp);
@@ -1084,13 +1338,13 @@
 	bp->fw_wr_seq++;
 	msg_data |= bp->fw_wr_seq;
 
-	REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_MB, msg_data);
+	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);
 
-		val = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_FW_MB);
+		val = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_MB);
 
 		if ((val & BNX2_FW_MSG_ACK) == (msg_data & BNX2_DRV_MSG_SEQ))
 			break;
@@ -1103,7 +1357,7 @@
 		msg_data &= ~BNX2_DRV_MSG_CODE;
 		msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT;
 
-		REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_MB, msg_data);
+		REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data);
 
 		bp->fw_timed_out = 1;
 
@@ -1279,10 +1533,11 @@
 static void
 bnx2_tx_int(struct bnx2 *bp)
 {
+	struct status_block *sblk = bp->status_blk;
 	u16 hw_cons, sw_cons, sw_ring_cons;
 	int tx_free_bd = 0;
 
-	hw_cons = bp->status_blk->status_tx_quick_consumer_index0;
+	hw_cons = bp->hw_tx_cons = sblk->status_tx_quick_consumer_index0;
 	if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) {
 		hw_cons++;
 	}
@@ -1337,7 +1592,9 @@
 
 		dev_kfree_skb_irq(skb);
 
-		hw_cons = bp->status_blk->status_tx_quick_consumer_index0;
+		hw_cons = bp->hw_tx_cons =
+			sblk->status_tx_quick_consumer_index0;
+
 		if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) {
 			hw_cons++;
 		}
@@ -1382,11 +1639,12 @@
 static int
 bnx2_rx_int(struct bnx2 *bp, int budget)
 {
+	struct status_block *sblk = bp->status_blk;
 	u16 hw_cons, sw_cons, sw_ring_cons, sw_prod, sw_ring_prod;
 	struct l2_fhdr *rx_hdr;
 	int rx_pkt = 0;
 
-	hw_cons = bp->status_blk->status_rx_quick_consumer_index0;
+	hw_cons = bp->hw_rx_cons = sblk->status_rx_quick_consumer_index0;
 	if ((hw_cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT) {
 		hw_cons++;
 	}
@@ -1506,6 +1764,15 @@
 
 		if ((rx_pkt == budget))
 			break;
+
+		/* Refresh hw_cons to see if there is new work */
+		if (sw_cons == hw_cons) {
+			hw_cons = bp->hw_rx_cons =
+				sblk->status_rx_quick_consumer_index0;
+			if ((hw_cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT)
+				hw_cons++;
+			rmb();
+		}
 	}
 	bp->rx_cons = sw_cons;
 	bp->rx_prod = sw_prod;
@@ -1573,15 +1840,27 @@
 	return IRQ_HANDLED;
 }
 
+static inline int
+bnx2_has_work(struct bnx2 *bp)
+{
+	struct status_block *sblk = bp->status_blk;
+
+	if ((sblk->status_rx_quick_consumer_index0 != bp->hw_rx_cons) ||
+	    (sblk->status_tx_quick_consumer_index0 != bp->hw_tx_cons))
+		return 1;
+
+	if (((sblk->status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) != 0) !=
+	    bp->link_up)
+		return 1;
+
+	return 0;
+}
+
 static int
 bnx2_poll(struct net_device *dev, int *budget)
 {
 	struct bnx2 *bp = dev->priv;
-	int rx_done = 1;
 
-	bp->last_status_idx = bp->status_blk->status_idx;
-
-	rmb();
 	if ((bp->status_blk->status_attn_bits &
 		STATUS_ATTN_BITS_LINK_STATE) !=
 		(bp->status_blk->status_attn_bits_ack &
@@ -1592,11 +1871,10 @@
 		spin_unlock(&bp->phy_lock);
 	}
 
-	if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_cons) {
+	if (bp->status_blk->status_tx_quick_consumer_index0 != bp->hw_tx_cons)
 		bnx2_tx_int(bp);
-	}
 
-	if (bp->status_blk->status_rx_quick_consumer_index0 != bp->rx_cons) {
+	if (bp->status_blk->status_rx_quick_consumer_index0 != bp->hw_rx_cons) {
 		int orig_budget = *budget;
 		int work_done;
 
@@ -1606,13 +1884,12 @@
 		work_done = bnx2_rx_int(bp, orig_budget);
 		*budget -= work_done;
 		dev->quota -= work_done;
-		
-		if (work_done >= orig_budget) {
-			rx_done = 0;
-		}
 	}
 	
-	if (rx_done) {
+	bp->last_status_idx = bp->status_blk->status_idx;
+	rmb();
+
+	if (!bnx2_has_work(bp)) {
 		netif_rx_complete(dev);
 		REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
 			BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
@@ -2383,21 +2660,27 @@
 
 		/* Flash interface has been reconfigured */
 		for (j = 0, flash = &flash_table[0]; j < entry_count;
-			j++, flash++) {
-
-			if (val == flash->config1) {
+		     j++, flash++) {
+			if ((val & FLASH_BACKUP_STRAP_MASK) ==
+			    (flash->config1 & FLASH_BACKUP_STRAP_MASK)) {
 				bp->flash_info = flash;
 				break;
 			}
 		}
 	}
 	else {
+		u32 mask;
 		/* Not yet been reconfigured */
 
+		if (val & (1 << 23))
+			mask = FLASH_BACKUP_STRAP_MASK;
+		else
+			mask = FLASH_STRAP_MASK;
+
 		for (j = 0, flash = &flash_table[0]; j < entry_count;
 			j++, flash++) {
 
-			if ((val & FLASH_STRAP_MASK) == flash->strapping) {
+			if ((val & mask) == (flash->strapping & mask)) {
 				bp->flash_info = flash;
 
 				/* Request access to the flash interface. */
@@ -2733,7 +3016,7 @@
 
 	/* Deposit a driver reset signature so the firmware knows that
 	 * this is a soft reset. */
-	REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_RESET_SIGNATURE,
+	REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_RESET_SIGNATURE,
 		   BNX2_DRV_RESET_SIGNATURE_MAGIC);
 
 	bp->fw_timed_out = 0;
@@ -2962,6 +3245,7 @@
 
 	bp->tx_prod = 0;
 	bp->tx_cons = 0;
+	bp->hw_tx_cons = 0;
 	bp->tx_prod_bseq = 0;
 	
 	val = BNX2_L2CTX_TYPE_TYPE_L2;
@@ -2994,6 +3278,7 @@
 
 	ring_prod = prod = bp->rx_prod = 0;
 	bp->rx_cons = 0;
+	bp->hw_rx_cons = 0;
 	bp->rx_prod_bseq = 0;
 		
 	rxbd = &bp->rx_desc_ring[0];
@@ -3079,7 +3364,7 @@
 		struct sw_bd *rx_buf = &bp->rx_buf_ring[i];
 		struct sk_buff *skb = rx_buf->skb;
 
-		if (skb == 0)
+		if (skb == NULL)
 			continue;
 
 		pci_unmap_single(bp->pdev, pci_unmap_addr(rx_buf, mapping),
@@ -3234,7 +3519,7 @@
 		{ 0x1408, 0, 0x01c00800, 0x00000000 },
 		{ 0x149c, 0, 0x8000ffff, 0x00000000 },
 		{ 0x14a8, 0, 0x00000000, 0x000001ff },
-		{ 0x14ac, 0, 0x4fffffff, 0x10000000 },
+		{ 0x14ac, 0, 0x0fffffff, 0x10000000 },
 		{ 0x14b0, 0, 0x00000002, 0x00000001 },
 		{ 0x14b8, 0, 0x00000000, 0x00000000 },
 		{ 0x14c0, 0, 0x00000000, 0x00000009 },
@@ -3577,7 +3862,7 @@
 		u32   len;
 	} mem_tbl[] = {
 		{ 0x60000,  0x4000 },
-		{ 0xa0000,  0x4000 },
+		{ 0xa0000,  0x3000 },
 		{ 0xe0000,  0x4000 },
 		{ 0x120000, 0x4000 },
 		{ 0x1a0000, 0x4000 },
@@ -3810,7 +4095,7 @@
 		goto bnx2_restart_timer;
 
 	msg = (u32) ++bp->fw_drv_pulse_wr_seq;
-	REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_PULSE_MB, msg);
+	REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB, msg);
 
 	if ((bp->phy_flags & PHY_SERDES_FLAG) &&
 	    (CHIP_NUM(bp) == CHIP_NUM_5706)) {
@@ -4264,7 +4549,8 @@
     		(unsigned long) (stats_blk->stat_Dot3StatsExcessiveCollisions +
 		stats_blk->stat_Dot3StatsLateCollisions);
 
-	if (CHIP_NUM(bp) == CHIP_NUM_5706)
+	if ((CHIP_NUM(bp) == CHIP_NUM_5706) ||
+	    (CHIP_ID(bp) == CHIP_ID_5708_A0))
 		net_stats->tx_carrier_errors = 0;
 	else {
 		net_stats->tx_carrier_errors =
@@ -4814,6 +5100,14 @@
 	4,4,4,4,4,
 };
 
+static u8 bnx2_5708_stats_len_arr[BNX2_NUM_STATS] = {
+	8,0,8,8,8,8,8,8,8,8,
+	4,4,4,4,4,4,4,4,4,4,
+	4,4,4,4,4,4,4,4,4,4,
+	4,4,4,4,4,4,4,4,4,4,
+	4,4,4,4,4,
+};
+
 #define BNX2_NUM_TESTS 6
 
 static struct {
@@ -4922,8 +5216,13 @@
 		return;
 	}
 
-	if (CHIP_NUM(bp) == CHIP_NUM_5706)
+	if ((CHIP_ID(bp) == CHIP_ID_5706_A0) ||
+	    (CHIP_ID(bp) == CHIP_ID_5706_A1) ||
+	    (CHIP_ID(bp) == CHIP_ID_5706_A2) ||
+	    (CHIP_ID(bp) == CHIP_ID_5708_A0))
 		stats_len_arr = bnx2_5706_stats_len_arr;
+	else
+		stats_len_arr = bnx2_5708_stats_len_arr;
 
 	for (i = 0; i < BNX2_NUM_STATS; i++) {
 		if (stats_len_arr[i] == 0) {
@@ -5205,8 +5504,6 @@
 
 	bp->chip_id = REG_RD(bp, BNX2_MISC_ID);
 
-	bp->phy_addr = 1;
-
 	/* Get bus information. */
 	reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS);
 	if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) {
@@ -5269,10 +5566,18 @@
 
 	bnx2_init_nvram(bp);
 
+	reg = REG_RD_IND(bp, BNX2_SHM_HDR_SIGNATURE);
+
+	if ((reg & BNX2_SHM_HDR_SIGNATURE_SIG_MASK) ==
+	    BNX2_SHM_HDR_SIGNATURE_SIG)
+		bp->shmem_base = REG_RD_IND(bp, BNX2_SHM_HDR_ADDR_0);
+	else
+		bp->shmem_base = HOST_VIEW_SHMEM_BASE;
+
 	/* Get the permanent MAC address.  First we need to make sure the
 	 * firmware is actually running.
 	 */
-	reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DEV_INFO_SIGNATURE);
+	reg = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_SIGNATURE);
 
 	if ((reg & BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
 	    BNX2_DEV_INFO_SIGNATURE_MAGIC) {
@@ -5281,14 +5586,13 @@
 		goto err_out_unmap;
 	}
 
-	bp->fw_ver = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE +
-				BNX2_DEV_INFO_BC_REV);
+	bp->fw_ver = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_BC_REV);
 
-	reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_MAC_UPPER);
+	reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_UPPER);
 	bp->mac_addr[0] = (u8) (reg >> 8);
 	bp->mac_addr[1] = (u8) reg;
 
-	reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_MAC_LOWER);
+	reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_LOWER);
 	bp->mac_addr[2] = (u8) (reg >> 24);
 	bp->mac_addr[3] = (u8) (reg >> 16);
 	bp->mac_addr[4] = (u8) (reg >> 8);
@@ -5316,10 +5620,19 @@
 	bp->timer_interval =  HZ;
 	bp->current_interval =  HZ;
 
+	bp->phy_addr = 1;
+
 	/* Disable WOL support if we are running on a SERDES chip. */
 	if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) {
 		bp->phy_flags |= PHY_SERDES_FLAG;
 		bp->flags |= NO_WOL_FLAG;
+		if (CHIP_NUM(bp) == CHIP_NUM_5708) {
+			bp->phy_addr = 2;
+			reg = REG_RD_IND(bp, bp->shmem_base +
+					 BNX2_SHARED_HW_CFG_CONFIG);
+			if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G)
+				bp->phy_flags |= PHY_2_5G_CAPABLE_FLAG;
+		}
 	}
 
 	if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
@@ -5339,8 +5652,7 @@
 	if (bp->phy_flags & PHY_SERDES_FLAG) {
 		bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg;
 
-		reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE +
-				 BNX2_PORT_HW_CFG_CONFIG);
+		reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG);
 		reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK;
 		if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) {
 			bp->autoneg = 0;
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 62857b6..76bb5f1 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -1449,8 +1449,9 @@
 #define BNX2_EMAC_MODE_PORT_NONE			 (0L<<2)
 #define BNX2_EMAC_MODE_PORT_MII				 (1L<<2)
 #define BNX2_EMAC_MODE_PORT_GMII			 (2L<<2)
-#define BNX2_EMAC_MODE_PORT_UNDEF			 (3L<<2)
+#define BNX2_EMAC_MODE_PORT_MII_10			 (3L<<2)
 #define BNX2_EMAC_MODE_MAC_LOOP				 (1L<<4)
+#define BNX2_EMAC_MODE_25G				 (1L<<5)
 #define BNX2_EMAC_MODE_TAGGED_MAC_CTL			 (1L<<7)
 #define BNX2_EMAC_MODE_TX_BURST				 (1L<<8)
 #define BNX2_EMAC_MODE_MAX_DEFER_DROP_ENA		 (1L<<9)
@@ -3714,6 +3715,15 @@
 #define BNX2_MCP_ROM					0x00150000
 #define BNX2_MCP_SCRATCH				0x00160000
 
+#define BNX2_SHM_HDR_SIGNATURE				BNX2_MCP_SCRATCH
+#define BNX2_SHM_HDR_SIGNATURE_SIG_MASK			 0xffff0000
+#define BNX2_SHM_HDR_SIGNATURE_SIG			 0x53530000
+#define BNX2_SHM_HDR_SIGNATURE_VER_MASK			 0x000000ff
+#define BNX2_SHM_HDR_SIGNATURE_VER_ONE			 0x00000001
+
+#define BNX2_SHM_HDR_ADDR_0				BNX2_MCP_SCRATCH + 4
+#define BNX2_SHM_HDR_ADDR_1				BNX2_MCP_SCRATCH + 8
+
 
 #define NUM_MC_HASH_REGISTERS   8
 
@@ -3724,6 +3734,53 @@
 #define PHY_ID(id)                                  ((id) & 0xfffffff0)
 #define PHY_REV_ID(id)                              ((id) & 0xf)
 
+/* 5708 Serdes PHY registers */
+
+#define BCM5708S_UP1				0xb
+
+#define BCM5708S_UP1_2G5			0x1
+
+#define BCM5708S_BLK_ADDR			0x1f
+
+#define BCM5708S_BLK_ADDR_DIG			0x0000
+#define BCM5708S_BLK_ADDR_DIG3			0x0002
+#define BCM5708S_BLK_ADDR_TX_MISC		0x0005
+
+/* Digital Block */
+#define BCM5708S_1000X_CTL1			0x10
+
+#define BCM5708S_1000X_CTL1_FIBER_MODE		0x0001
+#define BCM5708S_1000X_CTL1_AUTODET_EN		0x0010
+
+#define BCM5708S_1000X_CTL2			0x11
+
+#define BCM5708S_1000X_CTL2_PLLEL_DET_EN	0x0001
+
+#define BCM5708S_1000X_STAT1			0x14
+
+#define BCM5708S_1000X_STAT1_SGMII		0x0001
+#define BCM5708S_1000X_STAT1_LINK		0x0002
+#define BCM5708S_1000X_STAT1_FD			0x0004
+#define BCM5708S_1000X_STAT1_SPEED_MASK		0x0018
+#define BCM5708S_1000X_STAT1_SPEED_10		0x0000
+#define BCM5708S_1000X_STAT1_SPEED_100		0x0008
+#define BCM5708S_1000X_STAT1_SPEED_1G		0x0010
+#define BCM5708S_1000X_STAT1_SPEED_2G5		0x0018
+#define BCM5708S_1000X_STAT1_TX_PAUSE		0x0020
+#define BCM5708S_1000X_STAT1_RX_PAUSE		0x0040
+
+/* Digital3 Block */
+#define BCM5708S_DIG_3_0			0x10
+
+#define BCM5708S_DIG_3_0_USE_IEEE		0x0001
+
+/* Tx/Misc Block */
+#define BCM5708S_TX_ACTL1			0x15
+
+#define BCM5708S_TX_ACTL1_DRIVER_VCM		0x30
+
+#define BCM5708S_TX_ACTL3			0x17
+
 #define MIN_ETHERNET_PACKET_SIZE	60
 #define MAX_ETHERNET_PACKET_SIZE	1514
 #define MAX_ETHERNET_JUMBO_PACKET_SIZE	9014
@@ -3799,7 +3856,7 @@
 #define BUFFERED_FLASH_PHY_PAGE_SIZE		(1 << BUFFERED_FLASH_PAGE_BITS)
 #define BUFFERED_FLASH_BYTE_ADDR_MASK		(BUFFERED_FLASH_PHY_PAGE_SIZE-1)
 #define BUFFERED_FLASH_PAGE_SIZE		264
-#define BUFFERED_FLASH_TOTAL_SIZE		131072
+#define BUFFERED_FLASH_TOTAL_SIZE		0x21000
 
 #define SAIFUN_FLASH_PAGE_BITS			8
 #define SAIFUN_FLASH_PHY_PAGE_SIZE		(1 << SAIFUN_FLASH_PAGE_BITS)
@@ -3807,6 +3864,12 @@
 #define SAIFUN_FLASH_PAGE_SIZE			256
 #define SAIFUN_FLASH_BASE_TOTAL_SIZE		65536
 
+#define ST_MICRO_FLASH_PAGE_BITS		8
+#define ST_MICRO_FLASH_PHY_PAGE_SIZE		(1 << ST_MICRO_FLASH_PAGE_BITS)
+#define ST_MICRO_FLASH_BYTE_ADDR_MASK		(ST_MICRO_FLASH_PHY_PAGE_SIZE-1)
+#define ST_MICRO_FLASH_PAGE_SIZE		256
+#define ST_MICRO_FLASH_BASE_TOTAL_SIZE		65536
+
 #define NVRAM_TIMEOUT_COUNT			30000
 
 
@@ -3815,6 +3878,8 @@
 						 BNX2_NVM_CFG1_PROTECT_MODE | \
 						 BNX2_NVM_CFG1_FLASH_SIZE)
 
+#define FLASH_BACKUP_STRAP_MASK			(0xf << 26)
+
 struct flash_spec {
 	u32 strapping;
 	u32 config1;
@@ -3849,6 +3914,9 @@
 	u16			tx_cons;
 	int			tx_ring_size;
 
+	u16			hw_tx_cons;
+	u16			hw_rx_cons;
+
 #ifdef BCM_VLAN 
 	struct			vlan_group *vlgrp;
 #endif
@@ -3893,6 +3961,7 @@
 #define PHY_SERDES_FLAG			1
 #define PHY_CRC_FIX_FLAG		2
 #define PHY_PARALLEL_DETECT_FLAG	4
+#define PHY_2_5G_CAPABLE_FLAG		8
 #define PHY_INT_MODE_MASK_FLAG		0x300
 #define PHY_INT_MODE_AUTO_POLLING_FLAG	0x100
 #define PHY_INT_MODE_LINK_READY_FLAG	0x200
@@ -3901,6 +3970,7 @@
 	/* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
 #define CHIP_NUM(bp)			(((bp)->chip_id) & 0xffff0000)
 #define CHIP_NUM_5706			0x57060000
+#define CHIP_NUM_5708			0x57080000
 
 #define CHIP_REV(bp)			(((bp)->chip_id) & 0x0000f000)
 #define CHIP_REV_Ax			0x00000000
@@ -3913,6 +3983,9 @@
 #define CHIP_ID(bp)			(((bp)->chip_id) & 0xfffffff0)
 #define CHIP_ID_5706_A0			0x57060000
 #define CHIP_ID_5706_A1			0x57060010
+#define CHIP_ID_5706_A2			0x57060020
+#define CHIP_ID_5708_A0			0x57080000
+#define CHIP_ID_5708_B0			0x57081000
 
 #define CHIP_BOND_ID(bp)		(((bp)->chip_id) & 0xf)
 
@@ -3991,6 +4064,8 @@
 
 	u8			mac_addr[8];
 
+	u32			shmem_base;
+
 	u32			fw_ver;
 
 	int			pm_cap;
@@ -4130,14 +4205,46 @@
 #define BNX2_FW_MSG_STATUS_FAILURE		 0x00ff0000
 
 #define BNX2_LINK_STATUS			0x0000000c
+#define BNX2_LINK_STATUS_INIT_VALUE		 0xffffffff 
+#define BNX2_LINK_STATUS_LINK_UP		 0x1 
+#define BNX2_LINK_STATUS_LINK_DOWN		 0x0 
+#define BNX2_LINK_STATUS_SPEED_MASK		 0x1e
+#define BNX2_LINK_STATUS_AN_INCOMPLETE		 (0<<1) 
+#define BNX2_LINK_STATUS_10HALF			 (1<<1) 
+#define BNX2_LINK_STATUS_10FULL			 (2<<1) 
+#define BNX2_LINK_STATUS_100HALF		 (3<<1) 
+#define BNX2_LINK_STATUS_100BASE_T4		 (4<<1) 
+#define BNX2_LINK_STATUS_100FULL		 (5<<1) 
+#define BNX2_LINK_STATUS_1000HALF		 (6<<1) 
+#define BNX2_LINK_STATUS_1000FULL		 (7<<1) 
+#define BNX2_LINK_STATUS_2500HALF		 (8<<1) 
+#define BNX2_LINK_STATUS_2500FULL		 (9<<1) 
+#define BNX2_LINK_STATUS_AN_ENABLED		 (1<<5) 
+#define BNX2_LINK_STATUS_AN_COMPLETE		 (1<<6) 
+#define BNX2_LINK_STATUS_PARALLEL_DET		 (1<<7) 
+#define BNX2_LINK_STATUS_RESERVED		 (1<<8) 
+#define BNX2_LINK_STATUS_PARTNER_AD_1000FULL	 (1<<9) 
+#define BNX2_LINK_STATUS_PARTNER_AD_1000HALF	 (1<<10) 
+#define BNX2_LINK_STATUS_PARTNER_AD_100BT4	 (1<<11) 
+#define BNX2_LINK_STATUS_PARTNER_AD_100FULL	 (1<<12) 
+#define BNX2_LINK_STATUS_PARTNER_AD_100HALF	 (1<<13) 
+#define BNX2_LINK_STATUS_PARTNER_AD_10FULL	 (1<<14) 
+#define BNX2_LINK_STATUS_PARTNER_AD_10HALF	 (1<<15) 
+#define BNX2_LINK_STATUS_TX_FC_ENABLED		 (1<<16) 
+#define BNX2_LINK_STATUS_RX_FC_ENABLED		 (1<<17) 
+#define BNX2_LINK_STATUS_PARTNER_SYM_PAUSE_CAP	 (1<<18) 
+#define BNX2_LINK_STATUS_PARTNER_ASYM_PAUSE_CAP	 (1<<19) 
+#define BNX2_LINK_STATUS_SERDES_LINK		 (1<<20) 
+#define BNX2_LINK_STATUS_PARTNER_AD_2500FULL	 (1<<21) 
+#define BNX2_LINK_STATUS_PARTNER_AD_2500HALF	 (1<<22) 
 
 #define BNX2_DRV_PULSE_MB			0x00000010
-#define BNX2_DRV_PULSE_SEQ_MASK			 0x0000ffff
+#define BNX2_DRV_PULSE_SEQ_MASK			 0x00007fff
 
 /* Indicate to the firmware not to go into the
  * OS absent when it is not getting driver pulse.
  * This is used for debugging. */
-#define BNX2_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE	 0x00010000
+#define BNX2_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE	 0x00080000
 
 #define BNX2_DEV_INFO_SIGNATURE			0x00000020
 #define BNX2_DEV_INFO_SIGNATURE_MAGIC		 0x44564900
@@ -4160,6 +4267,8 @@
 #define BNX2_SHARED_HW_CFG_DESIGN_LOM		 0x1
 #define BNX2_SHARED_HW_CFG_PHY_COPPER		 0
 #define BNX2_SHARED_HW_CFG_PHY_FIBER		 0x2
+#define BNX2_SHARED_HW_CFG_PHY_2_5G		 0x20
+#define BNX2_SHARED_HW_CFG_PHY_BACKPLANE	 0x40
 #define BNX2_SHARED_HW_CFG_LED_MODE_SHIFT_BITS	 8
 #define BNX2_SHARED_HW_CFG_LED_MODE_MASK	 0x300
 #define BNX2_SHARED_HW_CFG_LED_MODE_MAC		 0
@@ -4173,9 +4282,11 @@
 
 #define BNX2_PORT_HW_CFG_MAC_LOWER		0x00000054
 #define BNX2_PORT_HW_CFG_CONFIG			0x00000058
+#define BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK	 0x0000ffff
 #define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK	 0x001f0000
 #define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_AN	 0x00000000
 #define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G	 0x00030000
+#define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_2_5G	 0x00040000
 
 #define BNX2_PORT_HW_CFG_IMD_MAC_A_UPPER	0x00000068
 #define BNX2_PORT_HW_CFG_IMD_MAC_A_LOWER	0x0000006c
diff --git a/drivers/net/bnx2_fw.h b/drivers/net/bnx2_fw.h
index 35f3a2a..ab07a49 100644
--- a/drivers/net/bnx2_fw.h
+++ b/drivers/net/bnx2_fw.h
@@ -14,24 +14,23 @@
  * accompanying it.
  */
 
-
-static int bnx2_COM_b06FwReleaseMajor = 0x0;
+static int bnx2_COM_b06FwReleaseMajor = 0x1;
 static int bnx2_COM_b06FwReleaseMinor = 0x0;
 static int bnx2_COM_b06FwReleaseFix = 0x0;
-static u32 bnx2_COM_b06FwStartAddr = 0x080004a0;
+static u32 bnx2_COM_b06FwStartAddr = 0x080008b4;
 static u32 bnx2_COM_b06FwTextAddr = 0x08000000;
-static int bnx2_COM_b06FwTextLen = 0x4594;
-static u32 bnx2_COM_b06FwDataAddr = 0x080045e0;
+static int bnx2_COM_b06FwTextLen = 0x57bc;
+static u32 bnx2_COM_b06FwDataAddr = 0x08005840;
 static int bnx2_COM_b06FwDataLen = 0x0;
-static u32 bnx2_COM_b06FwRodataAddr = 0x08004598;
-static int bnx2_COM_b06FwRodataLen = 0x18;
-static u32 bnx2_COM_b06FwBssAddr = 0x08004600;
+static u32 bnx2_COM_b06FwRodataAddr = 0x080057c0;
+static int bnx2_COM_b06FwRodataLen = 0x58;
+static u32 bnx2_COM_b06FwBssAddr = 0x08005860;
 static int bnx2_COM_b06FwBssLen = 0x88;
-static u32 bnx2_COM_b06FwSbssAddr = 0x080045e0;
+static u32 bnx2_COM_b06FwSbssAddr = 0x08005840;
 static int bnx2_COM_b06FwSbssLen = 0x1c;
-static u32 bnx2_COM_b06FwText[(0x4594/4) + 1] = {
-	0x0a000128, 0x00000000, 0x00000000, 0x0000000d, 0x636f6d20, 0x302e362e,
-	0x39000000, 0x00060902, 0x00000000, 0x00000003, 0x00000014, 0x00000032,
+static u32 bnx2_COM_b06FwText[(0x57bc/4) + 1] = {
+	0x0a00022d, 0x00000000, 0x00000000, 0x0000000d, 0x636f6d20, 0x322e352e,
+	0x38000000, 0x02050802, 0x00000000, 0x00000003, 0x00000014, 0x00000032,
 	0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
 	0x00000010, 0x000003e8, 0x0000ea60, 0x00000001, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -79,70 +78,117 @@
 	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, 0x244245e0, 0x3c030800, 0x24634688, 0xac400000,
-	0x0043202b, 0x1480fffd, 0x24420004, 0x3c1d0800, 0x37bd7ffc, 0x03a0f021,
-	0x3c100800, 0x261004a0, 0x3c1c0800, 0x279c45e0, 0x0e0001f2, 0x00000000,
-	0x0000000d, 0x27bdffe8, 0x3c1a8000, 0x3c020008, 0x0342d825, 0x3c036010,
-	0xafbf0010, 0x8c655000, 0x3c020800, 0x24470ac8, 0x3c040800, 0x24864600,
-	0x2402ff7f, 0x00a22824, 0x34a5380c, 0xac655000, 0x00002821, 0x24020037,
-	0x24030c80, 0xaf420008, 0xaf430024, 0xacc70000, 0x24a50001, 0x2ca20016,
-	0x1440fffc, 0x24c60004, 0x24844600, 0x3c020800, 0x24420ad4, 0x3c030800,
-	0x246309d4, 0xac820004, 0x3c020800, 0x24420618, 0x3c050800, 0x24a50ca0,
-	0xac82000c, 0x3c020800, 0x24423100, 0xac830008, 0x3c030800, 0x246325c8,
-	0xac820014, 0x3c020800, 0x24422b0c, 0xac830018, 0xac83001c, 0x3c030800,
-	0x24630adc, 0xac820024, 0x3c020800, 0x24423040, 0xac83002c, 0x3c030800,
-	0x24633060, 0xac820030, 0x3c020800, 0x24422f6c, 0xac830034, 0x3c030800,
-	0x24632c60, 0xac82003c, 0x3c020800, 0x24420b6c, 0xac850010, 0xac850020,
-	0xac830040, 0x0e000bd6, 0xac820050, 0x8fbf0010, 0x03e00008, 0x27bd0018,
-	0x27bdffe0, 0xafb00010, 0x27500100, 0xafbf0018, 0xafb10014, 0x9203000b,
-	0x24020003, 0x1462005b, 0x96110008, 0x32220001, 0x10400009, 0x27430080,
-	0x8e020000, 0x96040014, 0x000211c2, 0x00021040, 0x00621821, 0xa4640000,
-	0x0a0001cb, 0x3c020800, 0x3c020800, 0x8c430020, 0x1060002a, 0x3c030800,
-	0x0e001006, 0x00000000, 0x97420108, 0x8f850018, 0x9743010c, 0x3042003e,
-	0x00021400, 0x00621825, 0xaca30000, 0x8f840018, 0x8f420100, 0xac820004,
-	0x97430116, 0x9742010e, 0x8f840018, 0x00031c00, 0x00431025, 0xac820008,
-	0x97430110, 0x97440112, 0x8f850018, 0x00031c00, 0x00832025, 0xaca4000c,
-	0x97420114, 0x8f840018, 0x3042ffff, 0xac820010, 0x8f830018, 0xac600014,
-	0x8f820018, 0x3c030800, 0xac400018, 0x9462466e, 0x8f840018, 0x3c032000,
-	0x00431025, 0xac82001c, 0x0e001044, 0x24040001, 0x3c030800, 0x8c620040,
-	0x24420001, 0xac620040, 0x3c020800, 0x8c430044, 0x32240004, 0x24630001,
-	0x10800017, 0xac430044, 0x8f4202b8, 0x04430007, 0x8e020020, 0x3c040800,
-	0x8c830060, 0x24020001, 0x24630001, 0x0a0001ed, 0xac830060, 0x3c060800,
-	0x8cc4005c, 0xaf420280, 0x96030016, 0x00001021, 0xa7430284, 0x8e050004,
-	0x24840001, 0x3c031000, 0xaf450288, 0xaf4302b8, 0x0a0001ed, 0xacc4005c,
-	0x32220002, 0x0a0001ed, 0x0002102b, 0x3c026000, 0xac400808, 0x0000000d,
-	0x00001021, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020,
-	0x27bdffc8, 0xafbf0034, 0xafbe0030, 0xafb7002c, 0xafb60028, 0xafb50024,
-	0xafb40020, 0xafb3001c, 0xafb20018, 0xafb10014, 0x0e00013f, 0xafb00010,
-	0x24110020, 0x24150030, 0x2794000c, 0x27930008, 0x3c124000, 0x3c1e0800,
-	0x3c170800, 0x3c160800, 0x8f820004, 0x3c040800, 0x8c830020, 0x10430004,
-	0x00000000, 0xaf830004, 0x0e00110b, 0x00000000, 0x8f500000, 0x32020007,
-	0x1040fff5, 0x32020001, 0x1040002b, 0x32020002, 0x8f420100, 0xaf420020,
-	0x8f430104, 0xaf4300a8, 0x9342010b, 0x93630000, 0x306300ff, 0x10710005,
-	0x304400ff, 0x10750006, 0x2c820016, 0x0a000227, 0x00000000, 0xaf940000,
-	0x0a000228, 0x2c820016, 0xaf930000, 0x0a000228, 0x00000000, 0xaf800000,
-	0x14400005, 0x00041880, 0x0e0002b2, 0x00000000, 0x0a000234, 0x00000000,
-	0x3c020800, 0x24424600, 0x00621821, 0x8c620000, 0x0040f809, 0x00000000,
-	0x10400005, 0x8fc20034, 0x8f420104, 0x3c016020, 0xac220014, 0x8fc20034,
-	0xaf520138, 0x24420001, 0xafc20034, 0x32020002, 0x10400019, 0x32020004,
-	0x8f420140, 0xaf420020, 0x93630000, 0x306300ff, 0x10710005, 0x00000000,
-	0x10750006, 0x00000000, 0x0a000250, 0x00000000, 0xaf940000, 0x0a000251,
-	0x00000000, 0xaf930000, 0x0a000251, 0x00000000, 0xaf800000, 0x0e0008b9,
-	0x00000000, 0x8ee20038, 0xaf520178, 0x24420001, 0xaee20038, 0x32020004,
-	0x1040ffad, 0x00000000, 0x8f420180, 0xaf420020, 0x93630000, 0x306300ff,
-	0x10710005, 0x00000000, 0x10750006, 0x00000000, 0x0a00026a, 0x00000000,
-	0xaf940000, 0x0a00026b, 0x00000000, 0xaf930000, 0x0a00026b, 0x00000000,
-	0xaf800000, 0x93620000, 0x14510004, 0x8ec2003c, 0x0e000835, 0x00000000,
-	0x8ec2003c, 0xaf5201b8, 0x24420001, 0x0a000206, 0xaec2003c, 0x27bdffe8,
-	0xafbf0010, 0x97420108, 0x24033000, 0x30447000, 0x10830012, 0x28823001,
-	0x10400007, 0x24024000, 0x1080000b, 0x24022000, 0x1082001a, 0x24020001,
-	0x0a000299, 0x00000000, 0x1082000c, 0x24025000, 0x1082000e, 0x00000000,
-	0x0a000299, 0x00000000, 0x0000000d, 0x0a00029b, 0x00001021, 0x0e000300,
-	0x00000000, 0x0a00029b, 0x00001021, 0x0e00048f, 0x00000000, 0x0a00029b,
-	0x00001021, 0x0e000fdf, 0x00000000, 0x0a00029b, 0x00001021, 0x0000000d,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800, 0x24425840,
+	0x3c030800, 0x246358e8, 0xac400000, 0x0043202b, 0x1480fffd, 0x24420004,
+	0x3c1d0800, 0x37bd7ffc, 0x03a0f021, 0x3c100800, 0x261008b4, 0x3c1c0800,
+	0x279c5840, 0x0e0002f7, 0x00000000, 0x0000000d, 0x27bdffe8, 0x3c1a8000,
+	0x3c020008, 0x0342d825, 0x3c036010, 0xafbf0010, 0x8c655000, 0x3c020800,
+	0x24470f30, 0x3c040800, 0x24865860, 0x2402ff7f, 0x00a22824, 0x34a5380c,
+	0xac655000, 0x00002821, 0x24020037, 0x24030c80, 0xaf420008, 0xaf430024,
+	0xacc70000, 0x24a50001, 0x2ca20016, 0x1440fffc, 0x24c60004, 0x24845860,
+	0x3c020800, 0x24420f3c, 0x3c030800, 0x24630e2c, 0xac820004, 0x3c020800,
+	0x24420a2c, 0x3c050800, 0x24a51268, 0xac82000c, 0x3c020800, 0x244243dc,
+	0xac830008, 0x3c030800, 0x24633698, 0xac820014, 0x3c020800, 0x24423c24,
+	0xac830018, 0xac83001c, 0x3c030800, 0x24630f44, 0xac820024, 0x3c020800,
+	0x244243ac, 0xac83002c, 0x3c030800, 0x246343cc, 0xac820030, 0x3c020800,
+	0x244242f0, 0xac830034, 0x3c030800, 0x24633d78, 0xac82003c, 0x3c020800,
+	0x24420fd4, 0xac850010, 0xac850020, 0xac830040, 0x0e0010b7, 0xac820050,
+	0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe0, 0xafb00010, 0x27500100,
+	0xafbf0018, 0xafb10014, 0x9203000b, 0x24020003, 0x1462005b, 0x96110008,
+	0x32220001, 0x10400009, 0x27430080, 0x8e020000, 0x96040014, 0x000211c2,
+	0x00021040, 0x00621821, 0xa4640000, 0x0a0002d0, 0x3c020800, 0x3c020800,
+	0x8c430020, 0x1060002a, 0x3c030800, 0x0e00148e, 0x00000000, 0x97420108,
+	0x8f850018, 0x9743010c, 0x3042003e, 0x00021400, 0x00621825, 0xaca30000,
+	0x8f840018, 0x8f420100, 0xac820004, 0x97430116, 0x9742010e, 0x8f840018,
+	0x00031c00, 0x00431025, 0xac820008, 0x97430110, 0x97440112, 0x8f850018,
+	0x00031c00, 0x00832025, 0xaca4000c, 0x97420114, 0x8f840018, 0x3042ffff,
+	0xac820010, 0x8f830018, 0xac600014, 0x8f820018, 0x3c030800, 0xac400018,
+	0x946258ce, 0x8f840018, 0x3c032000, 0x00431025, 0xac82001c, 0x0e0014cc,
+	0x24040001, 0x3c030800, 0x8c620040, 0x24420001, 0xac620040, 0x3c020800,
+	0x8c430044, 0x32240004, 0x24630001, 0x10800017, 0xac430044, 0x8f4202b8,
+	0x04430007, 0x8e020020, 0x3c040800, 0x8c830060, 0x24020001, 0x24630001,
+	0x0a0002f2, 0xac830060, 0x3c060800, 0x8cc4005c, 0xaf420280, 0x96030016,
+	0x00001021, 0xa7430284, 0x8e050004, 0x24840001, 0x3c031000, 0xaf450288,
+	0xaf4302b8, 0x0a0002f2, 0xacc4005c, 0x32220002, 0x0a0002f2, 0x0002102b,
+	0x3c026000, 0xac400808, 0x0000000d, 0x00001021, 0x8fbf0018, 0x8fb10014,
+	0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffc8, 0xafbf0034, 0xafbe0030,
+	0xafb7002c, 0xafb60028, 0xafb50024, 0xafb40020, 0xafb3001c, 0xafb20018,
+	0xafb10014, 0x0e000244, 0xafb00010, 0x3c170800, 0x3c160800, 0x24110020,
+	0x24150030, 0x2794000c, 0x27930008, 0x3c124000, 0x3c1e0800, 0x8f820004,
+	0x3c040800, 0x8c830020, 0x10430005, 0x8ee200a4, 0xaf830004, 0x0e001593,
+	0x00000000, 0x8ee200a4, 0x8ec300a0, 0x10430004, 0x26c400a0, 0x94820002,
+	0xa742009e, 0xaee300a4, 0x8f500000, 0x32020007, 0x1040ffee, 0x32020001,
+	0x1040002c, 0x32020002, 0x8f420100, 0xaf420020, 0x8f430104, 0xaf4300a8,
+	0x9342010b, 0x93630000, 0x306300ff, 0x10710005, 0x304400ff, 0x10750006,
+	0x2c820016, 0x0a000333, 0x00000000, 0xaf940000, 0x0a000334, 0x2c820016,
+	0xaf930000, 0x0a000334, 0x00000000, 0xaf800000, 0x14400005, 0x00041880,
+	0x0e0003cc, 0x00000000, 0x0a000340, 0x00000000, 0x3c020800, 0x24425860,
+	0x00621821, 0x8c620000, 0x0040f809, 0x00000000, 0x10400005, 0x3c030800,
+	0x8f420104, 0x3c016020, 0xac220014, 0x3c030800, 0x8c620034, 0xaf520138,
+	0x24420001, 0xac620034, 0x32020002, 0x1040001a, 0x32020004, 0x8f420140,
+	0xaf420020, 0x93630000, 0x306300ff, 0x10710005, 0x00000000, 0x10750006,
+	0x00000000, 0x0a00035d, 0x00000000, 0xaf940000, 0x0a00035e, 0x00000000,
+	0xaf930000, 0x0a00035e, 0x00000000, 0xaf800000, 0x0e000c7b, 0x00000000,
+	0x3c040800, 0x8c820038, 0xaf520178, 0x24420001, 0xac820038, 0x32020004,
+	0x1040ffa4, 0x00000000, 0x8f420180, 0xaf420020, 0x93630000, 0x306300ff,
+	0x10710005, 0x00000000, 0x10750006, 0x00000000, 0x0a000378, 0x00000000,
+	0xaf940000, 0x0a000379, 0x00000000, 0xaf930000, 0x0a000379, 0x00000000,
+	0xaf800000, 0x8f430180, 0x24020f00, 0x14620005, 0x00000000, 0x8f420188,
+	0xa742009c, 0x0a000387, 0x8fc2003c, 0x93620000, 0x14510004, 0x8fc2003c,
+	0x0e000bad, 0x00000000, 0x8fc2003c, 0xaf5201b8, 0x24420001, 0x0a00030b,
+	0xafc2003c, 0x27bdffe8, 0xafbf0010, 0x97420108, 0x24033000, 0x30447000,
+	0x10830016, 0x28823001, 0x10400007, 0x24024000, 0x1080000b, 0x24022000,
+	0x1082000c, 0x00000000, 0x0a0003b3, 0x00000000, 0x10820010, 0x24025000,
+	0x10820012, 0x00000000, 0x0a0003b3, 0x00000000, 0x0000000d, 0x0a0003b5,
+	0x00001021, 0x0e000442, 0x00000000, 0x0a0003b6, 0x8fbf0010, 0x0e00041a,
+	0x00000000, 0x0a0003b5, 0x00001021, 0x0e000669, 0x00000000, 0x0a0003b5,
+	0x00001021, 0x0e001467, 0x00000000, 0x0a0003b5, 0x00001021, 0x0000000d,
 	0x00001021, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x93620000, 0x24030020,
-	0x304400ff, 0x10830005, 0x24020030, 0x10820007, 0x00000000, 0x0a0002af,
+	0x304400ff, 0x10830005, 0x24020030, 0x10820007, 0x00000000, 0x0a0003c9,
 	0x00000000, 0x2782000c, 0xaf820000, 0x03e00008, 0x00000000, 0x27820008,
 	0xaf820000, 0x03e00008, 0x00000000, 0xaf800000, 0x03e00008, 0x00000000,
 	0x0000000d, 0x03e00008, 0x00001021, 0x03e00008, 0x00001021, 0x27440100,
@@ -159,1000 +205,1716 @@
 	0x3c020006, 0x34420001, 0xaf420030, 0x00000000, 0x00000000, 0x00000000,
 	0x8f420000, 0x30420010, 0x1040fffd, 0x00001021, 0x03e00008, 0x00000000,
 	0x3c020800, 0x8c430020, 0x27bdffe8, 0xafb00010, 0x27500100, 0x1060001e,
-	0xafbf0014, 0x0e001006, 0x00000000, 0x8f830018, 0x8e020018, 0xac620000,
+	0xafbf0014, 0x0e00148e, 0x00000000, 0x8f830018, 0x8e020018, 0xac620000,
 	0x8f840018, 0x9602000c, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018,
 	0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 0xac400014, 0x8f840018,
-	0x3c026000, 0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x9464466e,
-	0x8f850018, 0x00021400, 0x00441025, 0x24040001, 0x0e001044, 0xaca2001c,
-	0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdffc8, 0xafb3001c,
-	0x00009821, 0xafb7002c, 0x0000b821, 0xafbe0030, 0x0000f021, 0xafb50024,
-	0x27550100, 0xafbf0034, 0xafb60028, 0xafb40020, 0xafb20018, 0xafb10014,
-	0xafb00010, 0x96a20008, 0x8f540100, 0x8eb20018, 0x30420001, 0x10400037,
-	0x02a0b021, 0x8f630054, 0x2642ffff, 0x00431023, 0x18400006, 0x00000000,
-	0x0000000d, 0x00000000, 0x24000128, 0x0a000372, 0x00002021, 0x8f62004c,
-	0x02421023, 0x18400028, 0x00002021, 0x93650120, 0x93640121, 0x3c030800,
-	0x8c62008c, 0x308400ff, 0x24420001, 0x30a500ff, 0x00803821, 0x1485000b,
-	0xac62008c, 0x3c040800, 0x8c830090, 0x24630001, 0xac830090, 0x93620122,
-	0x30420001, 0x00021023, 0x30420005, 0x0a000372, 0x34440004, 0x27660100,
-	0x00041080, 0x00c21021, 0x8c430000, 0x02431823, 0x04600004, 0x24820001,
-	0x30440007, 0x1485fff9, 0x00041080, 0x10870007, 0x3c030800, 0xa3640121,
-	0x8c620094, 0x24040005, 0x24420001, 0x0a000372, 0xac620094, 0x24040004,
-	0x00809821, 0x9362003f, 0x304400ff, 0x38830016, 0x2c630001, 0x38820010,
-	0x2c420001, 0x00621825, 0x1460000c, 0x24020001, 0x38830008, 0x2c630001,
-	0x38820014, 0x2c420001, 0x00621825, 0x14600005, 0x24020001, 0x24020012,
-	0x14820002, 0x00001021, 0x24020001, 0x50400007, 0x8eb10020, 0x8ea20020,
-	0x8f630040, 0x00408821, 0x00431023, 0x5c400001, 0x8f710040, 0x9343010b,
-	0x24020004, 0x54620005, 0x36730080, 0x96a20008, 0x36730002, 0x24170001,
-	0x305e0020, 0x2402fffb, 0x02628024, 0x1200002a, 0x3c030800, 0x8c620030,
-	0x02021024, 0x10400026, 0x3c020800, 0x8c430020, 0x10600024, 0x32620004,
-	0x0e001006, 0x00000000, 0x8f830018, 0x8f420100, 0xac620000, 0x8f840018,
-	0x02201821, 0x32620002, 0xac900004, 0x8f840018, 0x50400001, 0x8ec30014,
-	0xac830008, 0x8f830018, 0x8ec20020, 0xac62000c, 0x8f840018, 0x8f620040,
-	0xac820010, 0x8f830018, 0x8ec20018, 0xac620014, 0x8f840018, 0x3c026000,
-	0x8c434448, 0x3c020800, 0xac830018, 0x9443466e, 0x8f840018, 0x3c024010,
-	0x00621825, 0xac83001c, 0x0e001044, 0x24040001, 0x32620004, 0x10400076,
-	0x00003821, 0x3c029000, 0x34420001, 0x3c038000, 0x02821025, 0xa360007c,
-	0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620023,
-	0x30420080, 0x10400011, 0x00000000, 0x8f65005c, 0x8f63004c, 0x9764003c,
-	0x8f620064, 0x00a32823, 0x00852821, 0x00a2102b, 0x54400006, 0x3c023fff,
-	0x93620023, 0x3042007f, 0xa3620023, 0xaf720064, 0x3c023fff, 0x0a0003f1,
-	0x3442ffff, 0x8f62005c, 0x02421023, 0x04400011, 0x00000000, 0x8f65005c,
-	0x8f630064, 0x9764003c, 0x3c023fff, 0x3442ffff, 0xaf720064, 0x00a32823,
-	0x00852821, 0x0045102b, 0x10400004, 0x02451021, 0x3c053fff, 0x34a5ffff,
-	0x02451021, 0xaf62005c, 0x24070001, 0xaf72004c, 0x8f620054, 0x16420005,
+	0x3c026000, 0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x946458ce,
+	0x8f850018, 0x00021400, 0x00441025, 0x24040001, 0x0e0014cc, 0xaca2001c,
+	0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafb00010,
+	0x27500100, 0xafbf0014, 0x92020009, 0x14400003, 0x3c020800, 0x0a00046c,
+	0x24020001, 0x8c430020, 0x1060001f, 0x00001021, 0x0e00148e, 0x00000000,
+	0x8f830018, 0x8e020018, 0xac620000, 0x8f840018, 0x9602000c, 0xac820004,
+	0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
+	0x8f820018, 0xac400014, 0x8f840018, 0x3c026000, 0x8c434448, 0xac830018,
+	0x96020008, 0x3c030800, 0x946458ce, 0x8f850018, 0x00021400, 0x00441025,
+	0x24040001, 0x0e0014cc, 0xaca2001c, 0x00001021, 0x8fbf0014, 0x8fb00010,
+	0x03e00008, 0x27bd0018, 0x3c0b0800, 0x8d6808b0, 0x3c070800, 0x24e700b0,
+	0x00084900, 0x01271821, 0xac640000, 0x93620005, 0x97660008, 0x00e95021,
+	0x93630023, 0x9364003f, 0x25080001, 0x00021600, 0x00063400, 0x00461025,
+	0x00031a00, 0x00431025, 0x00822025, 0xad440004, 0x9362007e, 0x9366007f,
+	0x8f630178, 0x9364007a, 0x00021600, 0x00063400, 0x00461025, 0x00031a00,
+	0x00431025, 0x00822025, 0xad440008, 0x93620080, 0x9363007d, 0x3108007f,
+	0x01403821, 0xad6808b0, 0x00021600, 0x00031c00, 0x00431025, 0x00451025,
+	0x03e00008, 0xace2000c, 0x27bdffb8, 0xafb3002c, 0x00009821, 0xafbe0040,
+	0x0000f021, 0xafb50034, 0x27550100, 0xafbf0044, 0xafb7003c, 0xafb60038,
+	0xafb40030, 0xafb20028, 0xafb10024, 0xafb00020, 0xafa00010, 0xafa00014,
+	0x96a20008, 0x8f540100, 0x8eb10018, 0x30420001, 0x10400037, 0x02a0b821,
+	0x8f630054, 0x2622ffff, 0x00431023, 0x18400006, 0x00000000, 0x0000000d,
+	0x00000000, 0x2400015c, 0x0a0004e5, 0x00002021, 0x8f62004c, 0x02221023,
+	0x18400028, 0x00002021, 0x93650120, 0x93640121, 0x3c030800, 0x8c62008c,
+	0x308400ff, 0x24420001, 0x30a500ff, 0x00803821, 0x1485000b, 0xac62008c,
+	0x3c040800, 0x8c830090, 0x24630001, 0xac830090, 0x93620122, 0x30420001,
+	0x00021023, 0x30420005, 0x0a0004e5, 0x34440004, 0x27660100, 0x00041080,
+	0x00c21021, 0x8c430000, 0x02231823, 0x04600004, 0x24820001, 0x30440007,
+	0x1485fff9, 0x00041080, 0x10870007, 0x3c030800, 0xa3640121, 0x8c620094,
+	0x24040005, 0x24420001, 0x0a0004e5, 0xac620094, 0x24040004, 0x00809821,
+	0x9362003f, 0x304400ff, 0x38830016, 0x2c630001, 0x38820010, 0x2c420001,
+	0x00621825, 0x1460000c, 0x24020001, 0x38830008, 0x2c630001, 0x38820014,
+	0x2c420001, 0x00621825, 0x14600005, 0x24020001, 0x24020012, 0x14820002,
+	0x00001021, 0x24020001, 0x10400009, 0x00000000, 0x8ea20020, 0x8f630040,
+	0x0040b021, 0x00431023, 0x5c400010, 0x8f760040, 0x0a000511, 0x00000000,
+	0x9343010b, 0x24020004, 0x1462000a, 0x8eb60020, 0x8f630040, 0x3c021000,
+	0x00761823, 0x0043102a, 0x10400004, 0x00000000, 0x0000000d, 0x00000000,
+	0x240002fa, 0x9343010b, 0x24020004, 0x5462000b, 0x96a20008, 0x24020001,
+	0xafa20010, 0x96a20008, 0x24030001, 0xafa30018, 0x8eb2001c, 0x36730002,
+	0x30420020, 0x0a000526, 0xafa20014, 0x36730080, 0x30420002, 0x10400003,
+	0xafa00018, 0x0a000526, 0x8eb2001c, 0x8eb20014, 0x2402fffb, 0x02628024,
+	0x1200002a, 0x3c030800, 0x8c620030, 0x02021024, 0x10400026, 0x3c020800,
+	0x8c430020, 0x10600024, 0x32620004, 0x0e00148e, 0x00000000, 0x8f830018,
+	0x8f420100, 0xac620000, 0x8f840018, 0x02401821, 0x32620002, 0xac900004,
+	0x8f840018, 0x54400001, 0x02c01821, 0xac830008, 0x8f830018, 0x8ee20020,
+	0xac62000c, 0x8f840018, 0x8f620040, 0xac820010, 0x8f830018, 0x8ee20018,
+	0xac620014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800,
+	0xaca30018, 0x944358ce, 0x8f850018, 0x3c024010, 0x00621825, 0x0e0014cc,
+	0xaca3001c, 0x32620004, 0x10400063, 0x00003821, 0x3c029000, 0x34420001,
+	0x3c038000, 0x02821025, 0xa360007c, 0xaf420020, 0x8f420020, 0x00431024,
+	0x1440fffd, 0x00000000, 0x93620023, 0x30420080, 0x10400011, 0x00000000,
+	0x8f65005c, 0x8f63004c, 0x9764003c, 0x8f620064, 0x00a32823, 0x00852821,
+	0x00a2102b, 0x54400006, 0x3c023fff, 0x93620023, 0x3042007f, 0xa3620023,
+	0xaf710064, 0x3c023fff, 0x0a000580, 0x3442ffff, 0x8f62005c, 0x02221023,
+	0x04400011, 0x00000000, 0x8f65005c, 0x8f630064, 0x9764003c, 0x3c023fff,
+	0x3442ffff, 0xaf710064, 0x00a32823, 0x00852821, 0x0045102b, 0x10400004,
+	0x02251021, 0x3c053fff, 0x34a5ffff, 0x02251021, 0xaf62005c, 0x24070001,
+	0xaf71004c, 0x8f620054, 0x16220005, 0x00000000, 0x93620023, 0x30420040,
+	0x10400017, 0x24020001, 0x9762006a, 0x00022880, 0x50a00001, 0x24050001,
+	0x97630068, 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804,
+	0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b,
+	0x54600001, 0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021,
+	0xaf62000c, 0x93620082, 0x30420080, 0x50400001, 0xa3600081, 0x3c028000,
+	0x34420001, 0x02821025, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620004,
+	0x00000000, 0x0e0013c4, 0x00000000, 0x00403821, 0x54e00001, 0x241e0001,
+	0x8f700040, 0x8f620040, 0x14520003, 0x00521023, 0x0a0005bf, 0x00001021,
+	0x28420001, 0x10400041, 0x8fa20010, 0x0e000fae, 0x02402021, 0xaf720040,
+	0x9362003e, 0x30420001, 0x1440000b, 0x3c029000, 0x93620022, 0x24420001,
+	0xa3620022, 0x93630022, 0x3c020800, 0x8c440098, 0x0064182b, 0x14600027,
+	0x3c020800, 0x3c029000, 0x34420001, 0x02821025, 0xaf420020, 0x3c038000,
+	0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000,
+	0x34420001, 0xa362007d, 0x8f640074, 0x34630001, 0x02831825, 0xaf430020,
+	0x04810006, 0x3c038000, 0x02802021, 0x0e000470, 0x24050273, 0x0a0005f2,
+	0x24050001, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000,
+	0xaf5401c0, 0xa34201c4, 0xaf4301f8, 0x24050001, 0x24020001, 0xa7620012,
+	0xa3600022, 0x0a0005fe, 0x2ca20001, 0x9743007a, 0x9444002a, 0x00002821,
+	0x00641821, 0x3063fffe, 0xa7630012, 0x2ca20001, 0x00021023, 0x03c2f024,
+	0x8fa20010, 0x10400004, 0x8fa30014, 0x0e0013c1, 0x00000000, 0x8fa30014,
+	0x10600003, 0x00000000, 0x0e0010eb, 0x00000000, 0x13c0001f, 0x3c029000,
+	0x34420001, 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
+	0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074,
+	0x34630001, 0x02831825, 0xaf430020, 0x04810006, 0x3c038000, 0x02802021,
+	0x0e000470, 0x2405036c, 0x0a00062b, 0x8fa20018, 0x8f4201f8, 0x00431024,
+	0x1440fffd, 0x24020002, 0x3c031000, 0xaf5401c0, 0xa34201c4, 0xaf4301f8,
+	0x8fa20018, 0x5040002f, 0x96a20008, 0x8f620048, 0x8f630024, 0x00761821,
+	0xaf630048, 0x9764003c, 0x00501023, 0x0044102b, 0x10400025, 0x3c029000,
+	0x34420001, 0x3c040800, 0x8c830080, 0x8f450100, 0x3c068000, 0x24630001,
+	0x00a21025, 0xac830080, 0xaf420020, 0x8f420020, 0x00461024, 0x1440fffd,
+	0x00000000, 0x9362007d, 0x3c038000, 0x34420004, 0xa362007d, 0x8f640074,
+	0x34630001, 0x00a31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00a02021,
+	0x0e000470, 0x2405038a, 0x0a00065b, 0x96a20008, 0x8f4201f8, 0x00431024,
+	0x1440fffd, 0x24020002, 0x3c031000, 0xaf4501c0, 0xa34201c4, 0xaf4301f8,
+	0x96a20008, 0x8fbf0044, 0x8fbe0040, 0x8fb7003c, 0x8fb60038, 0x8fb50034,
+	0x8fb40030, 0x8fb3002c, 0x8fb20028, 0x8fb10024, 0x8fb00020, 0x00021042,
+	0x30420001, 0x03e00008, 0x27bd0048, 0x27bdffe0, 0xafbf0018, 0x97420108,
+	0x24030019, 0x304400ff, 0x10830065, 0x2882001a, 0x1040001a, 0x2882000a,
+	0x1040000f, 0x28820008, 0x10400040, 0x24020001, 0x1082003a, 0x28820002,
+	0x50400005, 0x24020006, 0x10800032, 0x3c026000, 0x0a0006fb, 0x00000000,
+	0x1082003d, 0x00000000, 0x0a0006fb, 0x00000000, 0x2402000b, 0x10820044,
+	0x2882000b, 0x1440004b, 0x2402000e, 0x10820045, 0x00000000, 0x0a0006fb,
+	0x00000000, 0x24020020, 0x10820062, 0x28820021, 0x1040000e, 0x2402001c,
+	0x1082004c, 0x2882001d, 0x10400005, 0x2402001b, 0x10820043, 0x00000000,
+	0x0a0006fb, 0x00000000, 0x2402001f, 0x10820050, 0x00000000, 0x0a0006fb,
+	0x00000000, 0x240200c1, 0x10820042, 0x288200c2, 0x10400005, 0x24020080,
+	0x10820021, 0x00000000, 0x0a0006fb, 0x00000000, 0x240200c2, 0x1082003d,
+	0x240200c9, 0x50820049, 0xafa00010, 0x0a0006fb, 0x00000000, 0x0e001163,
+	0xac400808, 0x0a0006fd, 0x8fbf0018, 0x3c026000, 0x8c444448, 0x3c030800,
+	0xac640064, 0x0e001163, 0x00000000, 0x3c026000, 0x8c444448, 0x3c030800,
+	0x0a0006fc, 0xac640068, 0x8f440100, 0x0e0006ff, 0x00000000, 0x3c026000,
+	0x8c444448, 0x3c030800, 0x0a0006fc, 0xac64006c, 0x0e001191, 0x00000000,
+	0x0a0006fd, 0x8fbf0018, 0x8f440100, 0x0e0011bb, 0x00000000, 0x0a0006fd,
+	0x8fbf0018, 0x0e001202, 0x00000000, 0x0a0006fd, 0x8fbf0018, 0x0000000d,
+	0x0a0006fd, 0x8fbf0018, 0x0e000826, 0x00000000, 0x0a0006fd, 0x8fbf0018,
+	0x8f440100, 0x0e001264, 0x00000000, 0x0a0006fd, 0x8fbf0018, 0x0e00134e,
+	0x00000000, 0x0a0006fd, 0x8fbf0018, 0x0e00087c, 0x27440100, 0x0a0006fd,
+	0x8fbf0018, 0x8f640040, 0x0e000fae, 0x00000000, 0x0a0006fd, 0x8fbf0018,
+	0x8f440100, 0x0e001059, 0x00000000, 0x0a0006fd, 0x8fbf0018, 0x0e001417,
+	0x00000000, 0x0a0006fd, 0x8fbf0018, 0xafa00014, 0x8f440100, 0x8f450118,
+	0x8f46011c, 0x0e001439, 0x8f470120, 0x0a0006fd, 0x8fbf0018, 0x0000000d,
+	0x8fbf0018, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0010, 0x9742010c,
+	0x1440005e, 0x00803821, 0x3c029000, 0x34420001, 0x00e21025, 0xaf420020,
+	0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620023,
+	0x30420010, 0x14400026, 0x3c030800, 0x8f630074, 0x3c027fff, 0x3442ffff,
+	0x00621824, 0xaf630074, 0x93620005, 0x34420001, 0xa3620005, 0x8f63004c,
+	0x8f620054, 0x10620021, 0x24040001, 0x9762006a, 0x00022880, 0x50a00001,
+	0x24050001, 0x97630068, 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821,
+	0x00852804, 0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050,
+	0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824,
+	0x00a21021, 0xaf62000c, 0x0a00073d, 0x24040001, 0x8c6200a8, 0x00002021,
+	0x24420001, 0xac6200a8, 0x0000000d, 0x00000000, 0x2400044d, 0x3c028000,
+	0x34420001, 0x00e21025, 0xaf420020, 0x1080001f, 0x3c029000, 0x34420001,
+	0x00e21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
+	0x00000000, 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074, 0x34630001,
+	0x00e31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00e02021, 0x0e000470,
+	0x24050455, 0x0a000761, 0x00000000, 0x8f4201f8, 0x00431024, 0x1440fffd,
+	0x24020002, 0x3c031000, 0xaf4701c0, 0xa34201c4, 0xaf4301f8, 0x0e001163,
+	0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffd8, 0xafbf0024,
+	0xafb40020, 0xafb3001c, 0xafb20018, 0xafb10014, 0xafb00010, 0x93630005,
+	0x00809821, 0x24020030, 0x30630030, 0x146200ac, 0x00a0a021, 0x3c020800,
+	0x8c430020, 0x106000a6, 0x00000000, 0x0e00148e, 0x00000000, 0x8f830018,
+	0xac730000, 0x936200c4, 0x30420002, 0x10400004, 0x24020001, 0x8f830018,
+	0x0a000784, 0x00000000, 0x8f830018, 0x24020003, 0xac620004, 0x8f6200dc,
+	0x8f630040, 0x00431023, 0x18400004, 0x00000000, 0x0000000d, 0x00000000,
+	0x24000509, 0x8f840018, 0x8f6200dc, 0xac820008, 0x8f830018, 0xac60000c,
+	0x8f820018, 0xac400010, 0x8f830018, 0x8f62004c, 0x3c100800, 0xac620014,
+	0x8f850018, 0x3c026000, 0x8c434448, 0x261258c0, 0x00002021, 0xaca30018,
+	0x9642000e, 0x8f850018, 0x3c034010, 0x00431025, 0x0e0014cc, 0xaca2001c,
+	0x8f830018, 0xac730000, 0x9362003e, 0x9363003f, 0x8f840018, 0x00021200,
+	0x00621825, 0xac830004, 0x93620081, 0x93630082, 0x8f840018, 0x00021600,
+	0x00031c00, 0x00431025, 0xac820008, 0x8f830018, 0x8f620040, 0xac62000c,
+	0x8f840018, 0x8f620048, 0xac820010, 0x8f71004c, 0x8f820018, 0xac510014,
+	0x8f620050, 0x8f850018, 0x00401821, 0x02221023, 0x5c400001, 0x02201821,
+	0x00002021, 0xaca30018, 0x9642000e, 0x8f850018, 0x3c03c00b, 0x00431025,
+	0x0e0014cc, 0xaca2001c, 0x8f620054, 0x8f840018, 0x00401821, 0x02221023,
+	0x5c400001, 0x02201821, 0xac830000, 0x8f840018, 0x8f630058, 0xac830004,
+	0x93620023, 0x30420010, 0x10400004, 0x00000000, 0x8f830018, 0x0a0007dd,
+	0x8f620148, 0x8f830018, 0x8f62005c, 0xac620008, 0x8f830018, 0x8f620060,
+	0xac62000c, 0x8f840018, 0x8f620064, 0xac820010, 0x97630068, 0x9762006a,
+	0x8f840018, 0x00031c00, 0x00431025, 0xac820014, 0x8f850018, 0x00002021,
+	0x2402ffff, 0x260358c0, 0xaca20018, 0x9462000e, 0x8f850018, 0x3c03c00c,
+	0x00431025, 0x0e0014cc, 0xaca2001c, 0x8f840018, 0x8f630018, 0xac830000,
+	0x936200c4, 0x30420002, 0x10400006, 0x00000000, 0x976200c8, 0x8f830018,
+	0x3042ffff, 0x0a000803, 0xac620004, 0x8f820018, 0xac400004, 0x8f830018,
+	0x8f62006c, 0xac620008, 0x8f840018, 0x8f6200dc, 0xac82000c, 0x8f830018,
+	0xac600010, 0x93620005, 0x8f830018, 0x00021600, 0x00541025, 0xac620014,
+	0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x260258c0, 0xaca30018,
+	0x9443000e, 0x8f850018, 0x3c02400d, 0x00621825, 0x0e0014cc, 0xaca3001c,
+	0x0e00122e, 0x02602021, 0x8fbf0024, 0x8fb40020, 0x8fb3001c, 0x8fb20018,
+	0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0028, 0x27bdffe0, 0xafb00010,
+	0x27500100, 0xafbf0018, 0xafb10014, 0x9603000c, 0x240200c1, 0x54620024,
+	0x8e040000, 0x3c029000, 0x8f450100, 0x34420001, 0x3c038000, 0x00a21025,
+	0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x9362007d,
+	0x3c038000, 0x34420004, 0xa362007d, 0x8f640074, 0x34630001, 0x00a31825,
+	0xaf430020, 0x04810006, 0x3c038000, 0x00a02021, 0x0e000470, 0x240505b2,
+	0x0a000878, 0x8fbf0018, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002,
+	0x3c031000, 0xaf4501c0, 0xa34201c4, 0xaf4301f8, 0x0a000878, 0x8fbf0018,
+	0x8f65004c, 0x24060001, 0x0e0012a3, 0x240705be, 0x3c020800, 0x8c430020,
+	0x9611000c, 0x1060001d, 0x8e100000, 0x0e00148e, 0x00000000, 0x8f820018,
+	0xac500000, 0x8f840018, 0x00111400, 0xac820004, 0x8f830018, 0xac600008,
+	0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f840018, 0x240205c1,
+	0xac820014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800,
+	0xaca30018, 0x944358ce, 0x8f850018, 0x3c024019, 0x00621825, 0x0e0014cc,
+	0xaca3001c, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020,
+	0x27bdffb0, 0xafb5003c, 0x0000a821, 0xafbe0048, 0x0000f021, 0xafb70044,
+	0x0000b821, 0xafb30034, 0x00009821, 0xafb60040, 0x0080b021, 0xafbf004c,
+	0xafb40038, 0xafb20030, 0xafb1002c, 0xafb00028, 0xafa00010, 0x8f620040,
+	0x8ec30014, 0x96d1000c, 0x00431023, 0x04410025, 0x8ed40000, 0x32220401,
+	0x1040030c, 0x3c029000, 0x34420001, 0x02821025, 0xaf420020, 0x3c038000,
+	0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000,
+	0x34420004, 0xa362007d, 0x8f640074, 0x34630001, 0x02831825, 0xaf430020,
+	0x04810006, 0x3c038000, 0x02802021, 0x0e000470, 0x24050664, 0x0a000ba2,
+	0x8fbf004c, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000,
+	0xaf5401c0, 0xa34201c4, 0xaf4301f8, 0x0a000ba2, 0x8fbf004c, 0x32220010,
+	0x1040006b, 0x00003021, 0x9362003f, 0x92c6000f, 0x304500ff, 0x24c3fff8,
+	0x2c62000f, 0x10400057, 0x3c020800, 0x244257c0, 0x00031880, 0x00621821,
+	0x8c640000, 0x00800008, 0x00000000, 0x38a20012, 0x0a000924, 0x0002a82b,
+	0x2402000e, 0x14a20004, 0x2402000c, 0x24150001, 0x0a000924, 0x24060010,
+	0x10a20049, 0x38a30010, 0x2c630001, 0x38a20016, 0x2c420001, 0x00621825,
+	0x1460004d, 0x0000a821, 0x24020014, 0x10a2004a, 0x00000000, 0x0000000d,
+	0x00000000, 0x2400069c, 0x0a000924, 0x0000a821, 0x24020016, 0x14a20005,
+	0x2402000c, 0x24150001, 0x24060010, 0x0a000924, 0x3231fffd, 0x10a20032,
+	0x38a30010, 0x2c630001, 0x38a2000e, 0x2c420001, 0x00621825, 0x14600036,
+	0x0000a821, 0x24020014, 0x14a20003, 0x24150001, 0x0a000924, 0x24060012,
+	0x0000000d, 0x00000000, 0x240006bc, 0x0a000924, 0x0000a821, 0x2402000e,
+	0x14a20004, 0x24020016, 0x24150001, 0x0a000924, 0x3231fffb, 0x14a20004,
+	0x24020014, 0x24150001, 0x0a000924, 0x3231fffd, 0x54a20013, 0x92c2000e,
+	0x24150001, 0x24060012, 0x0a000924, 0x3231fffd, 0x2402000c, 0x54a2000c,
+	0x92c2000e, 0x92c3000e, 0x2402000a, 0x10620005, 0x24150001, 0x0000000d,
+	0x00000000, 0x240006e8, 0x24150001, 0x0a000924, 0x24060014, 0x92c2000e,
+	0x14a20003, 0x00000000, 0x0a000924, 0x24150001, 0x10a6ffc1, 0x24020012,
+	0x10a20005, 0x0000a821, 0x0000000d, 0x00000000, 0x24000704, 0x0000a821,
+	0x12a00022, 0x32220004, 0x10400002, 0x24020001, 0xafa20010, 0x32230102,
+	0x24020002, 0x1462000f, 0x00000000, 0x92c2000a, 0x30420020, 0x1440000b,
+	0x00000000, 0x8f630048, 0x8f620040, 0x14620004, 0x00000000, 0x8f620048,
+	0x24420001, 0xaf620048, 0x8f620040, 0x24420001, 0xaf620040, 0xa366003f,
+	0x38c30012, 0x2c630001, 0x38c20010, 0x2c420001, 0x00621825, 0x10600005,
+	0x3c030800, 0x8c620074, 0x24420001, 0x0e00140d, 0xac620074, 0x32220040,
+	0x32230020, 0xafa30020, 0x32230080, 0xafa30024, 0x32230001, 0xafa30018,
+	0x32230008, 0xafa3001c, 0x32230100, 0x104000c4, 0xafa30014, 0x8ec60010,
+	0x8f630054, 0x24c2ffff, 0x00431023, 0x18400006, 0x00000000, 0x0000000d,
+	0x00000000, 0x2400015c, 0x0a000989, 0x00009021, 0x8f62004c, 0x00c21023,
+	0x18400028, 0x00009021, 0x93650120, 0x93640121, 0x3c030800, 0x8c62008c,
+	0x308400ff, 0x24420001, 0x30a500ff, 0x00804021, 0x1485000b, 0xac62008c,
+	0x3c040800, 0x8c830090, 0x24630001, 0xac830090, 0x93620122, 0x30420001,
+	0x00021023, 0x30420005, 0x0a000989, 0x34520004, 0x27670100, 0x00041080,
+	0x00e21021, 0x8c430000, 0x00c31823, 0x04600004, 0x24820001, 0x30440007,
+	0x1485fff9, 0x00041080, 0x10880007, 0x3c030800, 0xa3640121, 0x8c620094,
+	0x24120005, 0x24420001, 0x0a000989, 0xac620094, 0x24120004, 0x32420001,
+	0x10400021, 0x3c020800, 0x8c430020, 0x8ed00000, 0x1060001c, 0x8ed30010,
+	0x0e00148e, 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x24020001,
+	0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018,
+	0xac600010, 0x8f820018, 0xac530014, 0x8f850018, 0x3c026000, 0x8c434448,
+	0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024010,
+	0x00621825, 0x0e0014cc, 0xaca3001c, 0x24130001, 0x32420004, 0x10400068,
+	0x00003821, 0x3c029000, 0x8ec60010, 0x34420001, 0x3c038000, 0x02821025,
+	0xa360007c, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000,
+	0x93620023, 0x30420080, 0x10400011, 0x00000000, 0x8f65005c, 0x8f63004c,
+	0x9764003c, 0x8f620064, 0x00a32823, 0x00852821, 0x00a2102b, 0x54400006,
+	0x3c023fff, 0x93620023, 0x3042007f, 0xa3620023, 0xaf660064, 0x3c023fff,
+	0x0a0009da, 0x3442ffff, 0x8f62005c, 0x00c21023, 0x04400011, 0x00000000,
+	0x8f65005c, 0x8f630064, 0x9764003c, 0x3c023fff, 0x3442ffff, 0xaf660064,
+	0x00a32823, 0x00852821, 0x0045102b, 0x10400004, 0x00c51021, 0x3c053fff,
+	0x34a5ffff, 0x00c51021, 0xaf62005c, 0x24070001, 0xaf66004c, 0x8fa20010,
+	0x10400003, 0x00000000, 0xaf660050, 0xaf660054, 0x8f620054, 0x14c20005,
 	0x00000000, 0x93620023, 0x30420040, 0x10400017, 0x24020001, 0x9762006a,
 	0x00022880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081, 0x3c020800,
 	0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021,
 	0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074,
-	0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, 0x3c028000, 0x34420001,
-	0x02821025, 0xa3600081, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620004,
-	0x00000000, 0x0e000f2a, 0x00000000, 0x00403821, 0x10e00017, 0x3c029000,
+	0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, 0x93620082, 0x30420080,
+	0x50400001, 0xa3600081, 0x3c028000, 0x34420001, 0x02821025, 0xaf420020,
+	0x9363007e, 0x9362007a, 0x10620005, 0x00e0b821, 0x0e0013c4, 0x00000000,
+	0x00403821, 0x00e0b821, 0x8fa30020, 0x10600009, 0x8fa20010, 0x8ec20018,
+	0xaf620018, 0x8ec3001c, 0xaf63001c, 0x8ec20020, 0x24170001, 0xaf620058,
+	0x8fa20010, 0x10400057, 0x8fa30024, 0x93620023, 0x30420040, 0x10400053,
+	0x00000000, 0x16600021, 0x3c120800, 0x8e420020, 0x8f70004c, 0x1040001e,
+	0x24130001, 0x0e00148e, 0x00000000, 0x8f820018, 0xac540000, 0x8f840018,
+	0x24020001, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c,
+	0x8f830018, 0xac600010, 0x8f820018, 0xac500014, 0x8f850018, 0x3c026000,
+	0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018,
+	0x3c024010, 0x00621825, 0xaca3001c, 0x0e0014cc, 0x24130001, 0x8e420020,
+	0x1040001c, 0x8ed00000, 0x0e00148e, 0x00000000, 0x8f820018, 0xac500000,
+	0x8f830018, 0xac600004, 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c,
+	0x8f820018, 0xac400010, 0x8f830018, 0x24020798, 0xac620014, 0x8f850018,
+	0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce,
+	0x8f850018, 0x3c024019, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x3c029000,
 	0x34420001, 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
-	0x1440fffd, 0x3c028000, 0x9363007d, 0x34420001, 0x3c048000, 0x02821025,
-	0xa363007d, 0xaf420020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002,
-	0x3c031000, 0xaf5401c0, 0xa34201c4, 0xaf4301f8, 0x8ea30014, 0x8f620040,
-	0x14430003, 0x00431023, 0x0a000443, 0x00001021, 0x28420001, 0x10400034,
-	0x00000000, 0x8f620040, 0xaf630040, 0x9362003e, 0x30420001, 0x1440000b,
-	0x3c029000, 0x93620022, 0x24420001, 0xa3620022, 0x93630022, 0x3c020800,
-	0x8c440098, 0x0064182b, 0x1460001e, 0x3c020800, 0x3c029000, 0x34420001,
+	0x1440fffd, 0x24020001, 0xaf62000c, 0x93630023, 0x3c028000, 0x34420001,
+	0x02821025, 0x306300bf, 0xa3630023, 0xaf420020, 0x8fa30024, 0x10600012,
+	0x8fa30018, 0x9362007c, 0x24420001, 0xa362007c, 0x9363007e, 0x9362007a,
+	0x1462000b, 0x8fa30018, 0x9362007c, 0x3c030800, 0x8c640024, 0x0044102b,
+	0x14400005, 0x8fa30018, 0x0e0013c4, 0x00000000, 0x02e2b825, 0x8fa30018,
+	0x3062ffff, 0x10400003, 0x32220200, 0x0a000a94, 0x241e0004, 0x10400003,
+	0x00000000, 0x241e0040, 0x24170001, 0x12a000d0, 0x32220002, 0x104000cf,
+	0x8fa2001c, 0x92c2000a, 0x30420002, 0x5040003b, 0x92c2000a, 0x93620023,
+	0x30420008, 0x54400037, 0x92c2000a, 0x3c020800, 0x8c430020, 0x10600023,
+	0x3c029000, 0x0e00148e, 0x00000000, 0x8f840018, 0x8ec30000, 0xac830000,
+	0x92c2000a, 0x8f830018, 0x00021600, 0xac620004, 0x8f840018, 0x8f620040,
+	0xac820008, 0x8f850018, 0x8f63004c, 0xaca3000c, 0x9362003f, 0x8f840018,
+	0x304200ff, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f850018,
+	0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018,
+	0x3c02401a, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x3c029000, 0x34420001,
 	0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
-	0x00000000, 0x3c038000, 0x9362007d, 0x34630001, 0x3c048000, 0x02831825,
-	0x34420001, 0xa362007d, 0xaf430020, 0x8f4201f8, 0x00441024, 0x1440fffd,
-	0x24020002, 0x3c031000, 0xaf5401c0, 0xa34201c4, 0x24020001, 0xaf4301f8,
-	0xa7620012, 0x0a000476, 0xa3600022, 0x9743007a, 0x9444002a, 0x00641821,
-	0x3063fffe, 0xa7630012, 0x0e000b68, 0x00000000, 0x12e00003, 0x00000000,
-	0x0e000f27, 0x00000000, 0x53c00004, 0x96a20008, 0x0e000c10, 0x00000000,
-	0x96a20008, 0x8fbf0034, 0x8fbe0030, 0x8fb7002c, 0x8fb60028, 0x8fb50024,
-	0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x00021042,
-	0x30420001, 0x03e00008, 0x27bd0038, 0x27bdffe8, 0xafbf0010, 0x97420108,
-	0x2403000b, 0x304400ff, 0x1083004e, 0x2882000c, 0x10400011, 0x24020006,
-	0x1082003e, 0x28820007, 0x10400007, 0x28820008, 0x1080002b, 0x24020001,
-	0x1082002e, 0x3c026000, 0x0a000504, 0x00000000, 0x14400061, 0x2882000a,
-	0x1440002b, 0x00000000, 0x0a0004ec, 0x00000000, 0x2402001c, 0x1082004e,
-	0x2882001d, 0x1040000e, 0x24020019, 0x10820041, 0x2882001a, 0x10400005,
-	0x2402000e, 0x10820036, 0x00000000, 0x0a000504, 0x00000000, 0x2402001b,
-	0x1082003c, 0x00000000, 0x0a000504, 0x00000000, 0x240200c1, 0x10820040,
-	0x288200c2, 0x10400005, 0x24020080, 0x1082001f, 0x00000000, 0x0a000504,
-	0x00000000, 0x240200c2, 0x1082003b, 0x00000000, 0x0a000504, 0x00000000,
-	0x3c026000, 0x0e000c7d, 0xac400808, 0x0a000506, 0x8fbf0010, 0x8c444448,
-	0x3c030800, 0xac640064, 0x0e000c7d, 0x00000000, 0x3c026000, 0x8c444448,
-	0x3c030800, 0x0a000505, 0xac640068, 0x8f440100, 0x0e000508, 0x00000000,
-	0x3c026000, 0x8c444448, 0x3c030800, 0x0a000505, 0xac64006c, 0x0e000cab,
-	0x00000000, 0x0a000506, 0x8fbf0010, 0x8f440100, 0x0e000cd5, 0x00000000,
-	0x0a000506, 0x8fbf0010, 0x0e000d1c, 0x00000000, 0x0a000506, 0x8fbf0010,
-	0x0000000d, 0x0a000506, 0x8fbf0010, 0x0e0005d7, 0x00000000, 0x0a000506,
-	0x8fbf0010, 0x8f440100, 0x0e000d7e, 0x00000000, 0x0a000506, 0x8fbf0010,
-	0x0e000e95, 0x00000000, 0x0a000506, 0x8fbf0010, 0x0e000626, 0x00000000,
-	0x0a000506, 0x8fbf0010, 0x0e000b68, 0x00000000, 0x0a000506, 0x8fbf0010,
-	0x0000000d, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0x3c029000,
-	0x34420001, 0xafb00010, 0x00808021, 0x02021025, 0x3c038000, 0xafbf0014,
-	0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620005,
-	0x34420001, 0xa3620005, 0x8f63004c, 0x8f620054, 0x10620019, 0x3c028000,
-	0x9762006a, 0x00022880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081,
-	0x3c020800, 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001,
-	0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021,
-	0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, 0x3c028000,
-	0x34420001, 0x02021025, 0x0e000c7d, 0xaf420020, 0x3c029000, 0x34420001,
-	0x3c038000, 0x02021025, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd,
-	0x3c028000, 0x9363007d, 0x34420001, 0x3c048000, 0x02021025, 0xa363007d,
-	0xaf420020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x8fbf0014, 0xaf5001c0,
-	0x8fb00010, 0x24020002, 0x3c031000, 0xa34201c4, 0xaf4301f8, 0x03e00008,
-	0x27bd0018, 0x27bdffd8, 0xafbf0020, 0xafb3001c, 0xafb20018, 0xafb10014,
-	0xafb00010, 0x93630005, 0x00809021, 0x24020030, 0x30630030, 0x14620072,
-	0x00a09821, 0x3c020800, 0x8c430020, 0x1060006c, 0x00000000, 0x0e001006,
-	0x00000000, 0x8f820018, 0xac520000, 0x9363003e, 0x9362003f, 0x8f840018,
-	0x00031a00, 0x00431025, 0xac820004, 0x93630081, 0x93620082, 0x8f850018,
-	0x00031e00, 0x00021400, 0x00621825, 0xaca30008, 0x8f840018, 0x8f620040,
-	0xac82000c, 0x8f830018, 0x8f620048, 0xac620010, 0x8f840018, 0x8f62004c,
-	0x3c110800, 0xac820014, 0x8f830018, 0x8f620050, 0x26304660, 0x00002021,
-	0xac620018, 0x9602000e, 0x8f850018, 0x3c03c00b, 0x00431025, 0x0e001044,
-	0xaca2001c, 0x8f830018, 0x8f620054, 0xac620000, 0x8f840018, 0x8f620058,
-	0xac820004, 0x8f830018, 0x8f62005c, 0xac620008, 0x8f840018, 0x8f620060,
-	0xac82000c, 0x8f850018, 0x8f620064, 0xaca20010, 0x97630068, 0x9762006a,
-	0x8f840018, 0x00031c00, 0x00431025, 0xac820014, 0x8f830018, 0x00002021,
-	0xac600018, 0x9602000e, 0x8f850018, 0x3c03c00c, 0x00431025, 0x0e001044,
-	0xaca2001c, 0x8f840018, 0x8f630018, 0xac830000, 0x936200c4, 0x30420002,
-	0x10400006, 0x00000000, 0x976200c8, 0x8f830018, 0x3042ffff, 0x0a0005b5,
-	0xac620004, 0x8f820018, 0xac400004, 0x8f830018, 0x8f62006c, 0xac620008,
-	0x8f840018, 0x8f6200dc, 0xac82000c, 0x8f830018, 0xac600010, 0x93620005,
-	0x8f830018, 0x00021600, 0x00531025, 0xac620014, 0x8f850018, 0x3c026000,
-	0x8c434448, 0x24040001, 0x26224660, 0xaca30018, 0x9443000e, 0x8f850018,
-	0x3c02400d, 0x00621825, 0x0e001044, 0xaca3001c, 0x0e000d48, 0x02402021,
-	0x8fbf0020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008,
-	0x27bd0028, 0x27bdffe0, 0xafb00010, 0x27500100, 0xafbf0018, 0xafb10014,
-	0x9603000c, 0x240200c1, 0x5462001d, 0x8e040000, 0x3c029000, 0x8f440100,
-	0x34420001, 0x3c038000, 0x00821025, 0xaf420020, 0x8f420020, 0x00431024,
-	0x1440fffd, 0x00000000, 0x3c038000, 0x9362007d, 0x34630001, 0x3c058000,
-	0x00831825, 0x34420004, 0xa362007d, 0xaf430020, 0x8f4201f8, 0x00451024,
-	0x1440fffd, 0x24020002, 0x3c031000, 0xaf4401c0, 0xa34201c4, 0xaf4301f8,
-	0x0a000622, 0x8fbf0018, 0x8f65004c, 0x24060001, 0x0e000db5, 0x2407049f,
-	0x3c020800, 0x8c430020, 0x9611000c, 0x1060001d, 0x8e100000, 0x0e001006,
-	0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x00111400, 0xac820004,
-	0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
-	0x8f840018, 0x240204a2, 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448,
-	0x24040001, 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c024019,
-	0x00621825, 0x0e001044, 0xaca3001c, 0x8fbf0018, 0x8fb10014, 0x8fb00010,
-	0x03e00008, 0x27bd0020, 0x27bdffb0, 0xafb1002c, 0x27510100, 0xafbf004c,
-	0xafbe0048, 0xafb70044, 0xafb60040, 0xafb5003c, 0xafb40038, 0xafb30034,
-	0xafb20030, 0xafb00028, 0x8e350000, 0x9634000c, 0x3c026000, 0x8c434448,
-	0x0000f021, 0xaf630170, 0x8f620040, 0x8e230014, 0x0000b821, 0x00431023,
-	0x044001ec, 0x0000b021, 0x32820010, 0x1040002e, 0x3c026000, 0x9363003f,
-	0x9222000e, 0x10430006, 0x2402000c, 0x9223000f, 0x10620003, 0x24020014,
-	0x14620025, 0x3c026000, 0x32820004, 0x10400007, 0x241e0001, 0x8f620050,
-	0x24420001, 0xaf620050, 0x8f630054, 0x24630001, 0xaf630054, 0x32830102,
-	0x24020002, 0x5462000d, 0x9222000f, 0x8f620040, 0x24420001, 0xaf620040,
-	0x8f630048, 0x8f620040, 0x24630001, 0x54620005, 0x9222000f, 0x8f620048,
-	0x24420001, 0xaf620048, 0x9222000f, 0xa362003f, 0x9223000f, 0x24020012,
-	0x14620007, 0x3c026000, 0x3c030800, 0x8c620074, 0x24420001, 0x0e000f6e,
-	0xac620074, 0x3c026000, 0x8c434448, 0x32820040, 0xaf630174, 0x32830020,
-	0xafa30010, 0x32830080, 0xafa30014, 0x32830001, 0xafa3001c, 0x32830008,
-	0xafa30020, 0x32830100, 0x104000bb, 0xafa30018, 0x8e260010, 0x8f630054,
-	0x24c2ffff, 0x00431023, 0x18400006, 0x00000000, 0x0000000d, 0x00000000,
-	0x24000128, 0x0a0006b2, 0x00009021, 0x8f62004c, 0x00c21023, 0x18400028,
-	0x00009021, 0x93650120, 0x93640121, 0x3c030800, 0x8c62008c, 0x308400ff,
-	0x24420001, 0x30a500ff, 0x00804021, 0x1485000b, 0xac62008c, 0x3c040800,
-	0x8c830090, 0x24630001, 0xac830090, 0x93620122, 0x30420001, 0x00021023,
-	0x30420005, 0x0a0006b2, 0x34520004, 0x27670100, 0x00041080, 0x00e21021,
-	0x8c430000, 0x00c31823, 0x04600004, 0x24820001, 0x30440007, 0x1485fff9,
-	0x00041080, 0x10880007, 0x3c030800, 0xa3640121, 0x8c620094, 0x24120005,
-	0x24420001, 0x0a0006b2, 0xac620094, 0x24120004, 0x32420001, 0x10400020,
-	0x3c020800, 0x8c430020, 0x8e300000, 0x1060001c, 0x8e330010, 0x0e001006,
-	0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x24020001, 0xac820004,
-	0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
-	0x8f820018, 0xac530014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001,
-	0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c024010, 0x00621825,
-	0x0e001044, 0xaca3001c, 0x32420004, 0x10400060, 0x00003821, 0x3c029000,
-	0x8e260010, 0x34420001, 0x3c038000, 0x02a21025, 0xa360007c, 0xaf420020,
-	0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620023, 0x30420080,
-	0x10400011, 0x00000000, 0x8f65005c, 0x8f63004c, 0x9764003c, 0x8f620064,
-	0x00a32823, 0x00852821, 0x00a2102b, 0x54400006, 0x3c023fff, 0x93620023,
-	0x3042007f, 0xa3620023, 0xaf660064, 0x3c023fff, 0x0a000702, 0x3442ffff,
-	0x8f62005c, 0x00c21023, 0x04400011, 0x00000000, 0x8f65005c, 0x8f630064,
-	0x9764003c, 0x3c023fff, 0x3442ffff, 0xaf660064, 0x00a32823, 0x00852821,
-	0x0045102b, 0x10400004, 0x00c51021, 0x3c053fff, 0x34a5ffff, 0x00c51021,
-	0xaf62005c, 0x24070001, 0xaf66004c, 0x8f620054, 0x14c20005, 0x00000000,
-	0x93620023, 0x30420040, 0x10400017, 0x24020001, 0x9762006a, 0x00022880,
-	0x50a00001, 0x24050001, 0x97630068, 0x93640081, 0x3c020800, 0x8c46004c,
-	0x00652821, 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800,
-	0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074, 0x2403fffe,
-	0x00832824, 0x00a21021, 0xaf62000c, 0x3c028000, 0x34420001, 0x02a21025,
-	0xa3600081, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620005, 0x00e0b021,
-	0x0e000f2a, 0x00000000, 0x00403821, 0x00e0b021, 0x8fa20010, 0x10400008,
-	0x00000000, 0x8e220018, 0xaf620018, 0x8e23001c, 0xaf63001c, 0x8e220020,
-	0x24160001, 0xaf620058, 0x13c00036, 0x32820004, 0x10400035, 0x8fa30014,
-	0x93620023, 0x30420040, 0x10400031, 0x3c020800, 0x8c430020, 0x1060001c,
-	0x8e300000, 0x0e001006, 0x00000000, 0x8f820018, 0xac500000, 0x8f830018,
-	0xac600004, 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c, 0x8f820018,
-	0xac400010, 0x8f830018, 0x24020587, 0xac620014, 0x8f850018, 0x3c026000,
-	0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018,
-	0x3c024019, 0x00621825, 0x0e001044, 0xaca3001c, 0x3c029000, 0x34420001,
-	0x02a21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
-	0x24020001, 0xaf62000c, 0x93630023, 0x3c028000, 0x34420001, 0x02a21025,
-	0x306300bf, 0xa3630023, 0xaf420020, 0x8fa30014, 0x10600012, 0x8fa3001c,
-	0x9362007c, 0x24420001, 0xa362007c, 0x9363007e, 0x9362007a, 0x1462000b,
-	0x8fa3001c, 0x9362007c, 0x3c030800, 0x8c640024, 0x0044102b, 0x14400005,
-	0x8fa3001c, 0x0e000f2a, 0x00000000, 0x02c2b025, 0x8fa3001c, 0x3062ffff,
-	0x10400003, 0x32820200, 0x0a000793, 0x24170004, 0x10400003, 0x00000000,
-	0x24170040, 0x24160001, 0x13c0005d, 0x32820002, 0x1040005c, 0x8fa20020,
-	0x9222000a, 0x30420020, 0x10400033, 0x3c100800, 0x93620023, 0x30420040,
-	0x1040002f, 0x8e020020, 0x1040001e, 0x3c029000, 0x0e001006, 0x00000000,
-	0x8f820018, 0xac550000, 0x8f840018, 0x3c02008d, 0xac820004, 0x8f830018,
-	0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f840018,
-	0x240205bf, 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001,
-	0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c024019, 0x00621825,
-	0x0e001044, 0xaca3001c, 0x3c029000, 0x34420001, 0x02a21025, 0xaf420020,
-	0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93630023,
-	0x3c028000, 0x34420001, 0x02a21025, 0x306300bf, 0xa3630023, 0xaf420020,
-	0x8e020020, 0x10400023, 0x8fa20020, 0x0e001006, 0x00000000, 0x8f840018,
-	0x8e230000, 0xac830000, 0x9222000a, 0x8f830018, 0x00021600, 0xac620004,
-	0x8f840018, 0x8f620040, 0xac820008, 0x8f850018, 0x8f63004c, 0xaca3000c,
-	0x9362003f, 0x8f840018, 0x304200ff, 0xac820010, 0x8f830018, 0x3c026000,
-	0xac600014, 0x8f850018, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018,
-	0x9443466e, 0x8f850018, 0x3c02401a, 0x00621825, 0x0e001044, 0xaca3001c,
-	0x8fa20020, 0x1040000e, 0x8fa20018, 0x9222000a, 0xa3620082, 0x56e00005,
-	0x36f70008, 0x8fa30018, 0x10600004, 0x00000000, 0x36f70008, 0x0a000801,
-	0x24160001, 0x0e000de1, 0x02a02021, 0x8fa20018, 0x10400003, 0x00000000,
-	0x36f70010, 0x24160001, 0x12c00019, 0x3c029000, 0x34420001, 0x02a21025,
-	0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000,
-	0x3c038000, 0x9362007d, 0x34630001, 0x3c048000, 0x02a31825, 0x02e21025,
-	0xa362007d, 0xaf430020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002,
-	0x3c031000, 0xaf5501c0, 0xa34201c4, 0xaf4301f8, 0x9363003f, 0x24020012,
-	0x14620004, 0x3c026000, 0x0e000f6e, 0x00000000, 0x3c026000, 0x8c434448,
-	0xaf630178, 0x8fbf004c, 0x8fbe0048, 0x8fb70044, 0x8fb60040, 0x8fb5003c,
+	0x00000000, 0x93630023, 0x3c028000, 0x34420001, 0x02821025, 0x34630008,
+	0xa3630023, 0xaf420020, 0x92c2000a, 0x30420020, 0x1040008e, 0x8fa2001c,
+	0x93620023, 0x30420001, 0x14400035, 0x3c020800, 0x8c430020, 0x10600023,
+	0x3c029000, 0x0e00148e, 0x00000000, 0x8f840018, 0x8ec30000, 0xac830000,
+	0x92c2000a, 0x8f830018, 0x00021600, 0xac620004, 0x8f840018, 0x8f620040,
+	0xac820008, 0x8f850018, 0x8f63004c, 0xaca3000c, 0x9362003f, 0x8f840018,
+	0x304200ff, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f850018,
+	0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018,
+	0x3c02401a, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x3c029000, 0x34420001,
+	0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
+	0x00000000, 0x93630023, 0x3c028000, 0x34420001, 0x02821025, 0x34630001,
+	0xa3630023, 0xaf420020, 0x93620023, 0x30420040, 0x10400052, 0x8fa2001c,
+	0x16600020, 0x3c120800, 0x8e420020, 0x8f70004c, 0x1040003c, 0x3c029000,
+	0x0e00148e, 0x00000000, 0x8f820018, 0xac540000, 0x8f840018, 0x24020001,
+	0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018,
+	0xac600010, 0x8f820018, 0xac500014, 0x8f850018, 0x3c026000, 0x8c434448,
+	0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024010,
+	0x00621825, 0x0e0014cc, 0xaca3001c, 0x8e420020, 0x1040001e, 0x3c029000,
+	0x0e00148e, 0x00000000, 0x8f820018, 0xac540000, 0x8f840018, 0x3c02008d,
+	0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018,
+	0xac600010, 0x8f840018, 0x240207ee, 0xac820014, 0x8f850018, 0x3c026000,
+	0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018,
+	0x3c024019, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x3c029000, 0x34420001,
+	0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
+	0x00000000, 0x93630023, 0x3c028000, 0x34420001, 0x02821025, 0x306300bf,
+	0xa3630023, 0xaf420020, 0x8fa2001c, 0x1040000e, 0x8fa20014, 0x92c2000a,
+	0xa3620082, 0x57c00005, 0x37de0008, 0x8fa30014, 0x10600004, 0x00000000,
+	0x37de0008, 0x0a000b75, 0x24170001, 0x0e0012cf, 0x02802021, 0x8fa20014,
+	0x10400003, 0x00000000, 0x37de0010, 0x24170001, 0x12e00020, 0x3c029000,
+	0x34420001, 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
+	0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0x03c21025, 0xa362007d,
+	0x8f640074, 0x34630001, 0x02831825, 0xaf430020, 0x04810006, 0x3c038000,
+	0x02802021, 0x0e000470, 0x2405082a, 0x0a000b9b, 0x00000000, 0x8f4201f8,
+	0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf5401c0, 0xa34201c4,
+	0xaf4301f8, 0x9363003f, 0x24020012, 0x14620004, 0x8fbf004c, 0x0e00140d,
+	0x00000000, 0x8fbf004c, 0x8fbe0048, 0x8fb70044, 0x8fb60040, 0x8fb5003c,
 	0x8fb40038, 0x8fb30034, 0x8fb20030, 0x8fb1002c, 0x8fb00028, 0x03e00008,
 	0x27bd0050, 0x27bdffe8, 0xafbf0014, 0xafb00010, 0x8f500180, 0x97420184,
 	0x30420200, 0x14400015, 0x00000000, 0x8f430188, 0x3c02ff00, 0x00621824,
 	0x3c020200, 0x10620031, 0x0043102b, 0x14400007, 0x3c020300, 0x1060000b,
-	0x3c020100, 0x1062000d, 0x00000000, 0x0a0008b4, 0x00000000, 0x10620027,
-	0x3c020400, 0x1062003e, 0x02002021, 0x0a0008b4, 0x00000000, 0x0e000e1e,
-	0x02002021, 0x0a0008b6, 0x8fbf0014, 0x93620005, 0x30420020, 0x1440005e,
+	0x3c020100, 0x1062000d, 0x00000000, 0x0a000c2c, 0x00000000, 0x10620027,
+	0x3c020400, 0x1062003e, 0x02002021, 0x0a000c2c, 0x00000000, 0x0e000c31,
+	0x02002021, 0x0a000c2e, 0x8fbf0014, 0x93620005, 0x30420020, 0x1440005e,
 	0x8fbf0014, 0x3c029000, 0x34420001, 0x02021025, 0xaf420020, 0x3c038000,
 	0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620005, 0x3c038000,
 	0x34630001, 0x02031825, 0x34420020, 0xa3620005, 0xaf430020, 0x93620005,
-	0x30420020, 0x14400003, 0x02002021, 0x0000000d, 0x02002021, 0x0e000553,
-	0x24055854, 0x0a0008b6, 0x8fbf0014, 0x93620005, 0x30420001, 0x1040003f,
+	0x30420020, 0x14400003, 0x02002021, 0x0000000d, 0x02002021, 0x0e000766,
+	0x24055854, 0x0a000c2e, 0x8fbf0014, 0x93620005, 0x30420001, 0x1040003f,
 	0x3c029000, 0x34420001, 0x02021025, 0xaf420020, 0x3c038000, 0x8f420020,
-	0x00431024, 0x1440fffd, 0x00000000, 0x93620005, 0x3c048000, 0x3c030800,
-	0x304200fe, 0xa3620005, 0x8c620020, 0x34840001, 0x02042025, 0xaf440020,
-	0x1040002d, 0x8fbf0014, 0x0a000894, 0x00000000, 0x00002821, 0x00003021,
-	0x0e000f78, 0x240706a4, 0x3c020800, 0x8c430020, 0x10600023, 0x8fbf0014,
-	0x0e001006, 0x00000000, 0x8f820018, 0xac500000, 0x93630082, 0x9362003f,
+	0x00431024, 0x1440fffd, 0x00000000, 0x93620023, 0x34420004, 0xa3620023,
+	0x93630005, 0x3c048000, 0x3c020800, 0x306300fe, 0xa3630005, 0x8c430020,
+	0x34840001, 0x02042025, 0x0a000c0a, 0xaf440020, 0x00002821, 0x00003021,
+	0x0e000fb1, 0x240708d9, 0x3c020800, 0x8c430020, 0x10600023, 0x8fbf0014,
+	0x0e00148e, 0x00000000, 0x8f820018, 0xac500000, 0x93630082, 0x9362003f,
 	0x8f840018, 0x00031a00, 0x00431025, 0xac820004, 0x8f830018, 0xac600008,
 	0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 0xac400014,
 	0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018,
-	0x9443466e, 0x8f850018, 0x3c02400a, 0x00621825, 0x0e001044, 0xaca3001c,
-	0x0a0008b6, 0x8fbf0014, 0x0000000d, 0x8fbf0014, 0x8fb00010, 0x03e00008,
-	0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x93420148, 0x2444ffff, 0x2c830005,
-	0x10600047, 0x3c020800, 0x24424598, 0x00041880, 0x00621821, 0x8c640000,
-	0x00800008, 0x00000000, 0x8f430144, 0x8f62000c, 0x14620006, 0x24020001,
-	0xaf62000c, 0x0e000909, 0x00000000, 0x0a000907, 0x8fbf0010, 0x8f62000c,
-	0x0a000900, 0x00000000, 0x97630010, 0x8f420144, 0x14430006, 0x24020001,
-	0xa7620010, 0x0e000eeb, 0x00000000, 0x0a000907, 0x8fbf0010, 0x97620010,
-	0x0a000900, 0x00000000, 0x97630012, 0x8f420144, 0x14430006, 0x24020001,
-	0xa7620012, 0x0e000f06, 0x00000000, 0x0a000907, 0x8fbf0010, 0x97620012,
-	0x0a000900, 0x00000000, 0x97630014, 0x8f420144, 0x14430006, 0x24020001,
-	0xa7620014, 0x0e000f21, 0x00000000, 0x0a000907, 0x8fbf0010, 0x97620014,
-	0x0a000900, 0x00000000, 0x97630016, 0x8f420144, 0x14430006, 0x24020001,
-	0xa7620016, 0x0e000f24, 0x00000000, 0x0a000907, 0x8fbf0010, 0x97620016,
-	0x14400006, 0x8fbf0010, 0x3c030800, 0x8c620070, 0x24420001, 0xac620070,
-	0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x93620081,
-	0x3c030800, 0x8c640048, 0x0044102b, 0x14400028, 0x3c029000, 0x8f460140,
-	0x34420001, 0x3c038000, 0x00c21025, 0xaf420020, 0x8f420020, 0x00431024,
-	0x1440fffd, 0x3c048000, 0x34840001, 0x3c059000, 0x34a50001, 0x3c078000,
-	0x24020012, 0x24030080, 0x00c42025, 0x00c52825, 0xa362003f, 0xa3630082,
-	0xaf440020, 0xaf450020, 0x8f420020, 0x00471024, 0x1440fffd, 0x3c038000,
-	0x9362007d, 0x34630001, 0x3c048000, 0x00c31825, 0x34420020, 0xa362007d,
-	0xaf430020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002, 0x3c031000,
-	0x0a00096d, 0xaf4601c0, 0x93620081, 0x24420001, 0x0e000f2a, 0xa3620081,
-	0x9763006a, 0x00032880, 0x14a00002, 0x00403821, 0x24050001, 0x97630068,
+	0x944358ce, 0x8f850018, 0x3c02400a, 0x00621825, 0x0e0014cc, 0xaca3001c,
+	0x0a000c2e, 0x8fbf0014, 0x0000000d, 0x8fbf0014, 0x8fb00010, 0x03e00008,
+	0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x8f420188, 0x00803021, 0x93640000,
+	0x24030020, 0x00021402, 0x10830008, 0x304500ff, 0x3c036018, 0x8c625000,
+	0x34420400, 0xac625000, 0x0000000d, 0x00000000, 0x24000955, 0x9363003f,
+	0x24020012, 0x14620023, 0x3c029000, 0x34420001, 0x3c038000, 0x00c21025,
+	0xaf650178, 0xa365007a, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd,
+	0x00000000, 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074, 0x34630001,
+	0x00c31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00c02021, 0x0e000470,
+	0x24050963, 0x0a000c79, 0x8fbf0010, 0x8f4201f8, 0x00431024, 0x1440fffd,
+	0x24020002, 0x3c031000, 0xaf4601c0, 0xa34201c4, 0xaf4301f8, 0x0a000c79,
+	0x8fbf0010, 0x9362007e, 0x1445000e, 0x00000000, 0x8f620178, 0x1045000b,
+	0x00000000, 0x8f820000, 0xaf650178, 0x8f660178, 0x8f440180, 0x8f65004c,
+	0x8c430000, 0x0060f809, 0x30c600ff, 0x0a000c79, 0x8fbf0010, 0xaf650178,
+	0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x93630000,
+	0x24020020, 0x10620005, 0x00000000, 0x93630000, 0x24020030, 0x1462004d,
+	0x8fbf0010, 0x93420148, 0x2444ffff, 0x2c830005, 0x10600047, 0x3c020800,
+	0x24425800, 0x00041880, 0x00621821, 0x8c640000, 0x00800008, 0x00000000,
+	0x8f430144, 0x8f62000c, 0x14620006, 0x24020001, 0xaf62000c, 0x0e000d59,
+	0x00000000, 0x0a000cd1, 0x8fbf0010, 0x8f62000c, 0x0a000cca, 0x00000000,
+	0x97630010, 0x8f420144, 0x14430006, 0x24020001, 0xa7620010, 0x0e00137a,
+	0x00000000, 0x0a000cd1, 0x8fbf0010, 0x97620010, 0x0a000cca, 0x00000000,
+	0x97630012, 0x8f420144, 0x14430006, 0x24020001, 0xa7620012, 0x0e001395,
+	0x00000000, 0x0a000cd1, 0x8fbf0010, 0x97620012, 0x0a000cca, 0x00000000,
+	0x97630014, 0x8f420144, 0x14430006, 0x24020001, 0xa7620014, 0x0e0013bb,
+	0x00000000, 0x0a000cd1, 0x8fbf0010, 0x97620014, 0x0a000cca, 0x00000000,
+	0x97630016, 0x8f420144, 0x14430006, 0x24020001, 0xa7620016, 0x0e0013be,
+	0x00000000, 0x0a000cd1, 0x8fbf0010, 0x97620016, 0x14400006, 0x8fbf0010,
+	0x3c030800, 0x8c620070, 0x24420001, 0xac620070, 0x8fbf0010, 0x03e00008,
+	0x27bd0018, 0x27bdffe0, 0x3c029000, 0xafbf001c, 0xafb20018, 0xafb10014,
+	0xafb00010, 0x8f500140, 0x34420001, 0x3c038000, 0x02021025, 0xaf420020,
+	0x8f420020, 0x00431024, 0x1440fffd, 0x24020012, 0x24030080, 0xa362003f,
+	0xa3630082, 0x93620023, 0x30420040, 0x10400007, 0x00008821, 0x93620023,
+	0x24110001, 0x304200bf, 0xa3620023, 0x0a000cf0, 0x3c028000, 0x3c028000,
+	0x34420001, 0x3c039000, 0x34630001, 0x3c048000, 0x02021025, 0x02031825,
+	0xaf420020, 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd, 0x00000000,
+	0x9362007d, 0x3c038000, 0x34420020, 0xa362007d, 0x8f640074, 0x34630001,
+	0x02031825, 0xaf430020, 0x04810006, 0x3c038000, 0x02002021, 0x0e000470,
+	0x24050a63, 0x0a000d13, 0x00000000, 0x8f4201f8, 0x00431024, 0x1440fffd,
+	0x24020002, 0x3c031000, 0xaf5001c0, 0xa34201c4, 0xaf4301f8, 0x1220003f,
+	0x3c120800, 0x8e420020, 0x8f71004c, 0x1040003c, 0x8fbf001c, 0x0e00148e,
+	0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x24020001, 0xac820004,
+	0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
+	0x8f820018, 0xac510014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001,
+	0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024010, 0x00621825,
+	0x0e0014cc, 0xaca3001c, 0x8e420020, 0x1040001e, 0x8fbf001c, 0x0e00148e,
+	0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x3c02008d, 0xac820004,
+	0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
+	0x8f840018, 0x24020a6a, 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448,
+	0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024019,
+	0x00621825, 0x0e0014cc, 0xaca3001c, 0x8fbf001c, 0x8fb20018, 0x8fb10014,
+	0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0010, 0x93620081,
+	0x3c030800, 0x8c640048, 0x0044102b, 0x14400005, 0x00000000, 0x0e000cd3,
+	0x00000000, 0x0a000da4, 0x8fbf0010, 0x93620081, 0x24420001, 0x0e0013c4,
+	0xa3620081, 0x9763006a, 0x00032880, 0x14a00002, 0x00403821, 0x24050001,
+	0x97630068, 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804,
+	0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b,
+	0x54600001, 0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021,
+	0xaf62000c, 0x10e00021, 0x3c029000, 0x8f450140, 0x34420001, 0x3c038000,
+	0x00a21025, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000,
+	0x9362007d, 0x3c038000, 0x34420004, 0xa362007d, 0x8f640074, 0x34630001,
+	0x00a31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00a02021, 0x0e000470,
+	0x24050a92, 0x0a000da4, 0x8fbf0010, 0x8f4201f8, 0x00431024, 0x1440fffd,
+	0x24020002, 0x3c031000, 0xaf4501c0, 0xa34201c4, 0xaf4301f8, 0x8fbf0010,
+	0x03e00008, 0x27bd0018, 0x27bdffd8, 0xafb3001c, 0x27530100, 0xafbf0024,
+	0xafb40020, 0xafb20018, 0xafb10014, 0xafb00010, 0x96620008, 0x3c140800,
+	0x8f520100, 0x30420001, 0x104000da, 0x00000000, 0x8e700018, 0x8f630054,
+	0x2602ffff, 0x00431023, 0x18400006, 0x00000000, 0x0000000d, 0x00000000,
+	0x2400015c, 0x0a000dea, 0x00008821, 0x8f62004c, 0x02021023, 0x18400028,
+	0x00008821, 0x93650120, 0x93640121, 0x3c030800, 0x8c62008c, 0x308400ff,
+	0x24420001, 0x30a500ff, 0x00803821, 0x1485000b, 0xac62008c, 0x3c040800,
+	0x8c830090, 0x24630001, 0xac830090, 0x93620122, 0x30420001, 0x00021023,
+	0x30420005, 0x0a000dea, 0x34510004, 0x27660100, 0x00041080, 0x00c21021,
+	0x8c430000, 0x02031823, 0x04600004, 0x24820001, 0x30440007, 0x1485fff9,
+	0x00041080, 0x10870007, 0x3c030800, 0xa3640121, 0x8c620094, 0x24110005,
+	0x24420001, 0x0a000dea, 0xac620094, 0x24110004, 0x32220001, 0x1040001e,
+	0x8e820020, 0x1040001d, 0x32220004, 0x0e00148e, 0x00000000, 0x8f820018,
+	0xac520000, 0x8f840018, 0x24020001, 0xac820004, 0x8f830018, 0xac600008,
+	0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 0xac500014,
+	0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018,
+	0x944358ce, 0x8f850018, 0x3c024010, 0x00621825, 0x0e0014cc, 0xaca3001c,
+	0x32220004, 0x10400081, 0x00003821, 0x3c029000, 0x34420001, 0x3c038000,
+	0x02421025, 0xa360007c, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd,
+	0x00000000, 0x93620023, 0x30420080, 0x10400011, 0x00000000, 0x8f65005c,
+	0x8f63004c, 0x9764003c, 0x8f620064, 0x00a32823, 0x00852821, 0x00a2102b,
+	0x54400006, 0x3c023fff, 0x93620023, 0x3042007f, 0xa3620023, 0xaf700064,
+	0x3c023fff, 0x0a000e37, 0x3442ffff, 0x8f62005c, 0x02021023, 0x04400011,
+	0x00000000, 0x8f65005c, 0x8f630064, 0x9764003c, 0x3c023fff, 0x3442ffff,
+	0xaf700064, 0x00a32823, 0x00852821, 0x0045102b, 0x10400004, 0x02051021,
+	0x3c053fff, 0x34a5ffff, 0x02051021, 0xaf62005c, 0x24070001, 0xaf70004c,
+	0x8f620054, 0x16020005, 0x00000000, 0x93620023, 0x30420040, 0x10400017,
+	0x24020001, 0x9762006a, 0x00022880, 0x50a00001, 0x24050001, 0x97630068,
 	0x93640081, 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b,
 	0x54400001, 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001,
 	0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c,
-	0x10e0001a, 0x3c029000, 0x8f440140, 0x34420001, 0x3c038000, 0x00821025,
-	0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000,
-	0x9362007d, 0x34630001, 0x3c058000, 0x00831825, 0x34420004, 0xa362007d,
-	0xaf430020, 0x8f4201f8, 0x00451024, 0x1440fffd, 0x24020002, 0x3c031000,
-	0xaf4401c0, 0xa34201c4, 0xaf4301f8, 0x8fbf0010, 0x03e00008, 0x27bd0018,
-	0x27bdffd8, 0xafb3001c, 0x27530100, 0xafbf0024, 0xafb40020, 0xafb20018,
-	0xafb10014, 0xafb00010, 0x96620008, 0x3c140800, 0x8f520100, 0x30420001,
-	0x104000cf, 0x00000000, 0x8e700018, 0x8f630054, 0x2602ffff, 0x00431023,
-	0x18400006, 0x00000000, 0x0000000d, 0x00000000, 0x24000128, 0x0a0009b6,
-	0x00008821, 0x8f62004c, 0x02021023, 0x18400028, 0x00008821, 0x93650120,
-	0x93640121, 0x3c030800, 0x8c62008c, 0x308400ff, 0x24420001, 0x30a500ff,
-	0x00803821, 0x1485000b, 0xac62008c, 0x3c040800, 0x8c830090, 0x24630001,
-	0xac830090, 0x93620122, 0x30420001, 0x00021023, 0x30420005, 0x0a0009b6,
-	0x34510004, 0x27660100, 0x00041080, 0x00c21021, 0x8c430000, 0x02031823,
-	0x04600004, 0x24820001, 0x30440007, 0x1485fff9, 0x00041080, 0x10870007,
-	0x3c030800, 0xa3640121, 0x8c620094, 0x24110005, 0x24420001, 0x0a0009b6,
-	0xac620094, 0x24110004, 0x32220001, 0x1040001e, 0x8e820020, 0x1040001d,
-	0x32220004, 0x0e001006, 0x00000000, 0x8f820018, 0xac520000, 0x8f840018,
-	0x24020001, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c,
-	0x8f830018, 0xac600010, 0x8f820018, 0xac500014, 0x8f850018, 0x3c026000,
-	0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018,
-	0x3c024010, 0x00621825, 0x0e001044, 0xaca3001c, 0x32220004, 0x10400076,
-	0x00003821, 0x3c029000, 0x34420001, 0x3c038000, 0x02421025, 0xa360007c,
-	0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620023,
-	0x30420080, 0x10400011, 0x00000000, 0x8f65005c, 0x8f63004c, 0x9764003c,
-	0x8f620064, 0x00a32823, 0x00852821, 0x00a2102b, 0x54400006, 0x3c023fff,
-	0x93620023, 0x3042007f, 0xa3620023, 0xaf700064, 0x3c023fff, 0x0a000a03,
-	0x3442ffff, 0x8f62005c, 0x02021023, 0x04400011, 0x00000000, 0x8f65005c,
-	0x8f630064, 0x9764003c, 0x3c023fff, 0x3442ffff, 0xaf700064, 0x00a32823,
-	0x00852821, 0x0045102b, 0x10400004, 0x02051021, 0x3c053fff, 0x34a5ffff,
-	0x02051021, 0xaf62005c, 0x24070001, 0xaf70004c, 0x8f620054, 0x16020005,
-	0x00000000, 0x93620023, 0x30420040, 0x10400017, 0x24020001, 0x9762006a,
-	0x00022880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081, 0x3c020800,
-	0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021,
-	0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074,
-	0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, 0x3c028000, 0x34420001,
-	0x02421025, 0xa3600081, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620004,
-	0x00000000, 0x0e000f2a, 0x00000000, 0x00403821, 0x10e00017, 0x3c029000,
+	0x93620082, 0x30420080, 0x50400001, 0xa3600081, 0x3c028000, 0x34420001,
+	0x02421025, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620004, 0x00000000,
+	0x0e0013c4, 0x00000000, 0x00403821, 0x10e0001f, 0x3c029000, 0x34420001,
+	0x02421025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
+	0x00000000, 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074, 0x34630001,
+	0x02431825, 0xaf430020, 0x04810006, 0x3c038000, 0x02402021, 0x0e000470,
+	0x24050b3d, 0x0a000e8d, 0x00000000, 0x8f4201f8, 0x00431024, 0x1440fffd,
+	0x24020002, 0x3c031000, 0xaf5201c0, 0xa34201c4, 0xaf4301f8, 0x9342010b,
+	0x9343010b, 0x8e820020, 0x27500100, 0x38630006, 0x10400029, 0x2c710001,
+	0x0e00148e, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018,
+	0x96020008, 0xac820004, 0x8f830018, 0x8e020014, 0xac620008, 0x8f850018,
+	0x3c026000, 0x8c434448, 0xaca3000c, 0x8f840018, 0x96020012, 0xac820010,
+	0x8f850018, 0x8e030020, 0xaca30014, 0x9602000c, 0x9603000e, 0x8f840018,
+	0x00021400, 0x00431025, 0xac820018, 0x12200005, 0x3c020800, 0x944358ce,
+	0x8f840018, 0x0a000eb8, 0x3c024013, 0x944358ce, 0x8f840018, 0x3c024014,
+	0x00621825, 0xac83001c, 0x0e0014cc, 0x24040001, 0x8e700014, 0x8f620040,
+	0x14500003, 0x00501023, 0x0a000ec3, 0x00001021, 0x28420001, 0x1040003a,
+	0x00000000, 0x0e000fae, 0x02002021, 0xaf700040, 0x9362003e, 0x30420001,
+	0x1440000b, 0x3c029000, 0x93620022, 0x24420001, 0xa3620022, 0x93630022,
+	0x3c020800, 0x8c440098, 0x0064182b, 0x14600025, 0x3c020800, 0x3c029000,
 	0x34420001, 0x02421025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
-	0x1440fffd, 0x3c028000, 0x9363007d, 0x34420001, 0x3c048000, 0x02421025,
-	0xa363007d, 0xaf420020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002,
-	0x3c031000, 0xaf5201c0, 0xa34201c4, 0xaf4301f8, 0x9342010b, 0x8e830020,
-	0x27500100, 0x38420006, 0x10600029, 0x2c510001, 0x0e001006, 0x00000000,
-	0x8f830018, 0x8e020000, 0xac620000, 0x8f840018, 0x96020008, 0xac820004,
-	0x8f830018, 0x8e020014, 0xac620008, 0x8f850018, 0x3c026000, 0x8c434448,
-	0xaca3000c, 0x8f840018, 0x96020012, 0xac820010, 0x8f850018, 0x8e030020,
-	0xaca30014, 0x9602000c, 0x9603000e, 0x8f840018, 0x00021400, 0x00431025,
-	0xac820018, 0x12200005, 0x3c020800, 0x9443466e, 0x8f840018, 0x0a000a78,
-	0x3c024013, 0x9443466e, 0x8f840018, 0x3c024014, 0x00621825, 0xac83001c,
-	0x0e001044, 0x24040001, 0x8e630014, 0x8f620040, 0x14430003, 0x00431023,
-	0x0a000a83, 0x00001021, 0x28420001, 0x10400034, 0x00000000, 0x8f620040,
-	0xaf630040, 0x9362003e, 0x30420001, 0x1440000b, 0x3c029000, 0x93620022,
-	0x24420001, 0xa3620022, 0x93630022, 0x3c020800, 0x8c440098, 0x0064182b,
-	0x1460001e, 0x3c020800, 0x3c029000, 0x34420001, 0x02421025, 0xaf420020,
-	0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000,
-	0x9362007d, 0x34630001, 0x3c048000, 0x02431825, 0x34420001, 0xa362007d,
-	0xaf430020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002, 0x3c031000,
-	0xaf5201c0, 0xa34201c4, 0x24020001, 0xaf4301f8, 0xa7620012, 0x0a000ab6,
-	0xa3600022, 0x9743007a, 0x9444002a, 0x00641821, 0x3063fffe, 0xa7630012,
-	0x0e000b68, 0x00000000, 0x97420108, 0x8fbf0024, 0x8fb40020, 0x8fb3001c,
-	0x8fb20018, 0x8fb10014, 0x8fb00010, 0x00021042, 0x30420001, 0x03e00008,
-	0x27bd0028, 0x27bdffe0, 0xafb20018, 0x3c120800, 0x8e420020, 0xafb00010,
-	0x27500100, 0xafbf001c, 0x10400046, 0xafb10014, 0x0e001006, 0x00000000,
-	0x8f840018, 0x8e020000, 0xac820000, 0x936300b1, 0x936200c5, 0x8f850018,
-	0x00031e00, 0x00021400, 0x34420100, 0x00621825, 0xaca30004, 0x8f840018,
-	0x8e02001c, 0xac820008, 0x8f830018, 0x8f620048, 0xac62000c, 0x8f840018,
-	0x96020012, 0xac820010, 0x8f830018, 0x8f620040, 0x24040001, 0xac620014,
-	0x8f850018, 0x3c026000, 0x8c434448, 0x3c020800, 0x24514660, 0xaca30018,
-	0x9623000e, 0x8f850018, 0x3c024016, 0x00621825, 0x0e001044, 0xaca3001c,
-	0x96030008, 0x30630010, 0x1060001c, 0x8e420020, 0x1040001a, 0x8e100000,
-	0x0e001006, 0x00000000, 0x8f820018, 0xac500000, 0x8f830018, 0xac600004,
-	0x8f820018, 0xac400008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010,
-	0x8f830018, 0xac600014, 0x8f850018, 0x3c036000, 0x8c634448, 0x24040001,
-	0xaca30018, 0x9622000e, 0x8f850018, 0x3c034015, 0x00431025, 0x0e001044,
-	0xaca2001c, 0x00001021, 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010,
-	0x03e00008, 0x27bd0020, 0x27bdffe0, 0xafb20018, 0x3c120800, 0x8e420020,
-	0xafb00010, 0x27500100, 0xafbf001c, 0x10400041, 0xafb10014, 0x0e001006,
-	0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018, 0x24020100,
-	0xac820004, 0x8f830018, 0x8e02001c, 0xac620008, 0x8f840018, 0x8e020018,
-	0xac82000c, 0x8f830018, 0x96020012, 0xac620010, 0x8f840018, 0x96020008,
-	0xac820014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800,
-	0x24514660, 0xaca30018, 0x9623000e, 0x8f850018, 0x3c024017, 0x00621825,
-	0x0e001044, 0xaca3001c, 0x96030008, 0x30630010, 0x1060001c, 0x8e420020,
-	0x1040001a, 0x8e100000, 0x0e001006, 0x00000000, 0x8f820018, 0xac500000,
+	0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0x34420001, 0xa362007d,
+	0x8f640074, 0x34630001, 0x02431825, 0xaf430020, 0x04810006, 0x3c038000,
+	0x02402021, 0x0e000470, 0x24050273, 0x0a000ef6, 0x24020001, 0x8f4201f8,
+	0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf5201c0, 0xa34201c4,
+	0xaf4301f8, 0x24020001, 0xa7620012, 0x0a000efe, 0xa3600022, 0x9743007a,
+	0x9444002a, 0x00641821, 0x3063fffe, 0xa7630012, 0x97420108, 0x8fbf0024,
+	0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x00021042,
+	0x30420001, 0x03e00008, 0x27bd0028, 0x27bdffe0, 0xafb20018, 0x3c120800,
+	0x8e420020, 0xafb00010, 0x27500100, 0xafbf001c, 0x10400046, 0xafb10014,
+	0x0e00148e, 0x00000000, 0x8f840018, 0x8e020000, 0xac820000, 0x936300b1,
+	0x936200c5, 0x8f850018, 0x00031e00, 0x00021400, 0x34420100, 0x00621825,
+	0xaca30004, 0x8f840018, 0x8e02001c, 0xac820008, 0x8f830018, 0x8f620048,
+	0xac62000c, 0x8f840018, 0x96020012, 0xac820010, 0x8f830018, 0x8f620040,
+	0x24040001, 0xac620014, 0x8f850018, 0x3c026000, 0x8c434448, 0x3c020800,
+	0x245158c0, 0xaca30018, 0x9623000e, 0x8f850018, 0x3c024016, 0x00621825,
+	0x0e0014cc, 0xaca3001c, 0x96030008, 0x30630010, 0x1060001c, 0x8e420020,
+	0x1040001a, 0x8e100000, 0x0e00148e, 0x00000000, 0x8f820018, 0xac500000,
 	0x8f830018, 0xac600004, 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c,
 	0x8f820018, 0xac400010, 0x8f830018, 0xac600014, 0x8f850018, 0x3c036000,
 	0x8c634448, 0x24040001, 0xaca30018, 0x9622000e, 0x8f850018, 0x3c034015,
-	0x00431025, 0x0e001044, 0xaca2001c, 0x00001021, 0x8fbf001c, 0x8fb20018,
-	0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0010,
-	0x936200c4, 0x30420002, 0x10400019, 0x00000000, 0x936200c5, 0x936300b1,
-	0x00431023, 0x304400ff, 0x30830080, 0x10600004, 0x00000000, 0x0000000d,
-	0x00000000, 0x24000a6a, 0x93620004, 0x00441023, 0x304400ff, 0x30830080,
-	0x10600004, 0x2482ffff, 0x8f650024, 0x0a000b82, 0x00000000, 0x00022b00,
-	0x8f620024, 0x0045102b, 0x10400002, 0x00000000, 0x8f650024, 0x8f620048,
-	0x8f630040, 0x00431823, 0x0065202b, 0x10800004, 0x00000000, 0x8f620040,
-	0x00451021, 0xaf620048, 0x9762003c, 0x0062102b, 0x10400041, 0x8fbf0010,
-	0x10a0003f, 0x3c029000, 0x34420001, 0x3c040800, 0x8c830080, 0x8f450100,
-	0x3c068000, 0x24630001, 0x00a21025, 0xac830080, 0xaf420020, 0x8f420020,
-	0x00461024, 0x1440fffd, 0x3c038000, 0x9362007d, 0x34630001, 0x3c048000,
-	0x00a31825, 0x34420004, 0xa362007d, 0xaf430020, 0x8f4201f8, 0x00441024,
-	0x1440fffd, 0x24020002, 0x3c030800, 0xaf4501c0, 0xa34201c4, 0x8c640020,
-	0x3c021000, 0xaf4201f8, 0x1080001f, 0x8fbf0010, 0x0e001006, 0x00000000,
-	0x8f830018, 0x8f420100, 0xac620000, 0x8f840018, 0x8f620040, 0xac820004,
-	0x8f850018, 0x8f620048, 0xaca20008, 0x8f830018, 0xac60000c, 0x8f820018,
-	0xac400010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018, 0x8c434448,
-	0x3c020800, 0xac830018, 0x9443466e, 0x8f840018, 0x3c0240c2, 0x00621825,
-	0xac83001c, 0x0e001044, 0x24040001, 0x8fbf0010, 0x03e00008, 0x27bd0018,
-	0x3c020800, 0x24423958, 0xaf82000c, 0x03e00008, 0x00000000, 0x27bdffe8,
-	0xafb00010, 0x27500100, 0xafbf0014, 0x8e02001c, 0x14400003, 0x3c020800,
-	0x0000000d, 0x3c020800, 0x8c430020, 0x10600026, 0x00001021, 0x0e001006,
-	0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018, 0x8e02001c,
-	0xac820004, 0x8f830018, 0xac600008, 0x8f840018, 0x8e020018, 0xac82000c,
-	0x8f850018, 0x96020012, 0xaca20010, 0x8f830018, 0x3c106000, 0xac600014,
-	0x8f840018, 0x8e024448, 0x3c030800, 0xac820018, 0x9462466e, 0x8f840018,
-	0x3c034012, 0x00431025, 0xac82001c, 0x0e001044, 0x24040001, 0x8e036800,
-	0x00001021, 0x3c040001, 0x00641825, 0xae036800, 0x0a000c0d, 0x8fbf0014,
-	0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c020800, 0x97430078,
-	0x9444002e, 0x00001021, 0x00641821, 0x3063fffe, 0x03e00008, 0xa7630010,
-	0x27450100, 0x8f640048, 0x8ca30018, 0x00641023, 0x18400021, 0x00000000,
-	0xaf630048, 0x8f620040, 0x9763003c, 0x00821023, 0x0043102a, 0x1040001a,
-	0x3c029000, 0x8ca40000, 0x34420001, 0x3c038000, 0x00821025, 0xaf420020,
-	0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000, 0x9362007d,
-	0x34630001, 0x3c058000, 0x00831825, 0x34420004, 0xa362007d, 0xaf430020,
-	0x8f4201f8, 0x00451024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4401c0,
-	0xa34201c4, 0xaf4301f8, 0x03e00008, 0x00001021, 0x8f420100, 0x34420001,
-	0xaf4200a4, 0x03e00008, 0x00001021, 0x27bdffe0, 0xafbf0018, 0xafb10014,
-	0xafb00010, 0x9362007e, 0x30d000ff, 0x16020029, 0x00808821, 0x93620080,
-	0x16020026, 0x00000000, 0x9362007f, 0x16020023, 0x00000000, 0x9362007a,
-	0x16020004, 0x00000000, 0x0000000d, 0x00000000, 0x24000771, 0x0e000f49,
-	0x00000000, 0x3c039000, 0x34630001, 0x3c048000, 0x02231825, 0xa370007a,
-	0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd, 0x3c028000, 0x9363007d,
-	0x34420001, 0x3c048000, 0x02221025, 0xa363007d, 0xaf420020, 0x8f4201f8,
-	0x00441024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf5101c0, 0xa34201c4,
-	0xaf4301f8, 0x0a000c79, 0x8fbf0018, 0x0000000d, 0x00000000, 0x24000781,
-	0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3c020800,
+	0x00431025, 0x0e0014cc, 0xaca2001c, 0x00001021, 0x8fbf001c, 0x8fb20018,
+	0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe0, 0xafb20018,
+	0x3c120800, 0x8e420020, 0xafb00010, 0x27500100, 0xafbf001c, 0x10400041,
+	0xafb10014, 0x0e00148e, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000,
+	0x8f840018, 0x24020100, 0xac820004, 0x8f830018, 0x8e02001c, 0xac620008,
+	0x8f840018, 0x8e020018, 0xac82000c, 0x8f830018, 0x96020012, 0xac620010,
+	0x8f840018, 0x96020008, 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448,
+	0x24040001, 0x3c020800, 0x245158c0, 0xaca30018, 0x9623000e, 0x8f850018,
+	0x3c024017, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x96030008, 0x30630010,
+	0x1060001c, 0x8e420020, 0x1040001a, 0x8e100000, 0x0e00148e, 0x00000000,
+	0x8f820018, 0xac500000, 0x8f830018, 0xac600004, 0x8f820018, 0xac400008,
+	0x8f830018, 0xac60000c, 0x8f820018, 0xac400010, 0x8f830018, 0xac600014,
+	0x8f850018, 0x3c036000, 0x8c634448, 0x24040001, 0xaca30018, 0x9622000e,
+	0x8f850018, 0x3c034015, 0x00431025, 0x0e0014cc, 0xaca2001c, 0x00001021,
+	0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020,
+	0x27bdfff0, 0x03e00008, 0x27bd0010, 0x27bdffd0, 0xafb10014, 0x00808821,
+	0xafb40020, 0x00c0a021, 0xafbf0028, 0xafb50024, 0xafb3001c, 0xafb20018,
+	0xafb00010, 0x93620023, 0x00e0a821, 0x30420040, 0x1040003e, 0x30b3ffff,
+	0x3c120800, 0x8e420020, 0x1040003a, 0x8f70004c, 0x0e00148e, 0x00000000,
+	0x8f820018, 0xac510000, 0x8f840018, 0x24020001, 0xac820004, 0x8f830018,
+	0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018,
+	0x24040001, 0xac500014, 0x8f850018, 0x3c026000, 0x8c434448, 0x3c020800,
+	0x245058c0, 0xaca30018, 0x9603000e, 0x8f850018, 0x3c024010, 0x00621825,
+	0x0e0014cc, 0xaca3001c, 0x8e430020, 0x1060001b, 0x00000000, 0x0e00148e,
+	0x00000000, 0x8f820018, 0xac510000, 0x8f840018, 0x3c02008d, 0xac820004,
+	0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
+	0x8f820018, 0xac550014, 0x8f850018, 0x3c036000, 0x8c634448, 0x24040001,
+	0xaca30018, 0x9602000e, 0x8f850018, 0x3c034019, 0x00431025, 0x0e0014cc,
+	0xaca2001c, 0x93620023, 0x30420020, 0x14400003, 0x3c120800, 0x1280003f,
+	0x3c029000, 0x8e420020, 0x8f70004c, 0x1040003b, 0x3c029000, 0x0e00148e,
+	0x00000000, 0x8f820018, 0xac510000, 0x8f840018, 0x24020001, 0xac820004,
+	0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
+	0x8f820018, 0x24040001, 0xac500014, 0x8f850018, 0x3c026000, 0x8c434448,
+	0x3c020800, 0x245058c0, 0xaca30018, 0x9603000e, 0x8f850018, 0x3c024010,
+	0x00621825, 0x0e0014cc, 0xaca3001c, 0x8e430020, 0x1060001c, 0x3c029000,
+	0x0e00148e, 0x00000000, 0x8f820018, 0xac510000, 0x8f840018, 0x00131400,
+	0xac820004, 0x8f830018, 0xac750008, 0x8f820018, 0xac40000c, 0x8f830018,
+	0xac600010, 0x8f820018, 0xac400014, 0x8f850018, 0x3c036000, 0x8c634448,
+	0x24040001, 0xaca30018, 0x9602000e, 0x8f850018, 0x3c03401b, 0x00431025,
+	0x0e0014cc, 0xaca2001c, 0x3c029000, 0x34420001, 0x02221025, 0xaf420020,
+	0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93630023,
+	0x3c028000, 0x34420001, 0x02221025, 0x8fbf0028, 0x8fb50024, 0x8fb40020,
+	0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x3063009f, 0xa3630023,
+	0xaf420020, 0x03e00008, 0x27bd0030, 0x27bdffe0, 0xafb10014, 0x27510100,
+	0x3c029000, 0x34420001, 0xafb00010, 0x00808021, 0x02021025, 0x3c038000,
+	0xafbf0018, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000,
+	0xa7600008, 0x8f63005c, 0x3c028000, 0x34420001, 0xaf630148, 0x8f640050,
+	0x02021025, 0x3c039000, 0xaf64017c, 0xaf420020, 0x8f450100, 0x34630001,
+	0x3c048000, 0x00a31825, 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd,
+	0x00000000, 0x9362007d, 0x3c038000, 0x34420001, 0xa362007d, 0x8f640074,
+	0x34630001, 0x00a31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00a02021,
+	0x0e000470, 0x24050de5, 0x0a001093, 0x3c020800, 0x8f4201f8, 0x00431024,
+	0x1440fffd, 0x24020002, 0x3c031000, 0xaf4501c0, 0xa34201c4, 0xaf4301f8,
+	0x3c020800, 0x8c430020, 0x1060001e, 0x8fbf0018, 0x0e00148e, 0x00000000,
+	0x8f830018, 0xac700000, 0x9622000c, 0x8f840018, 0x00021400, 0xac820004,
+	0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
+	0x8f820018, 0xac400014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001,
+	0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c02401f, 0x00621825,
+	0x0e0014cc, 0xaca3001c, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008,
+	0x27bd0020, 0x3c020800, 0x24424c3c, 0xaf82000c, 0x03e00008, 0x00000000,
+	0x27bdffe8, 0xafb00010, 0x27500100, 0xafbf0014, 0x8e02001c, 0x14400003,
+	0x3c020800, 0x0000000d, 0x3c020800, 0x8c430020, 0x10600020, 0x00001021,
+	0x0e00148e, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018,
+	0x8e02001c, 0xac820004, 0x8f830018, 0xac600008, 0x8f840018, 0x8e020018,
+	0xac82000c, 0x8f850018, 0x96020012, 0xaca20010, 0x8f830018, 0x3c026000,
+	0xac600014, 0x8f840018, 0x8c434448, 0x3c020800, 0xac830018, 0x944358ce,
+	0x8f840018, 0x3c024012, 0x00621825, 0xac83001c, 0x0e0014cc, 0x24040001,
+	0x00001021, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c020800,
+	0x97430078, 0x9444002e, 0x00001021, 0x00641821, 0x3063fffe, 0x03e00008,
+	0xa7630010, 0x27bdfff0, 0x00001021, 0x03e00008, 0x27bd0010, 0x8f420100,
+	0x34420001, 0xaf4200a4, 0x03e00008, 0x00001021, 0x27bdffe0, 0xafbf0018,
+	0xafb10014, 0xafb00010, 0x9362007e, 0x30d000ff, 0x16020031, 0x00808821,
+	0x8f620178, 0x1602002e, 0x00000000, 0x9362007f, 0x1602002b, 0x00000000,
+	0x9362007a, 0x16020004, 0x00000000, 0x0000000d, 0x00000000, 0x240009d2,
+	0x0e0013e6, 0x00000000, 0x3c039000, 0x34630001, 0x3c048000, 0x02231825,
+	0xa370007a, 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd, 0x00000000,
+	0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074, 0x34630001, 0x02231825,
+	0xaf430020, 0x04810006, 0x3c038000, 0x02202021, 0x0e000470, 0x240509dd,
+	0x0a001138, 0x8fbf0018, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002,
+	0x3c031000, 0xaf5101c0, 0xa34201c4, 0xaf4301f8, 0x0a001138, 0x8fbf0018,
+	0x0000000d, 0x00000000, 0x240009e2, 0x8fbf0018, 0x8fb10014, 0x8fb00010,
+	0x03e00008, 0x27bd0020, 0x27bdffe8, 0x30a500ff, 0x3c029000, 0x34420001,
+	0x00803821, 0x00e21025, 0x3c038000, 0xafbf0010, 0xaf420020, 0x8f420020,
+	0x00431024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0x00a21025,
+	0xa362007d, 0x8f640074, 0x34630001, 0x00e31825, 0xaf430020, 0x04810006,
+	0x3c038000, 0x00e02021, 0x0e000470, 0x00c02821, 0x0a001161, 0x8fbf0010,
+	0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4701c0,
+	0xa34201c4, 0xaf4301f8, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x3c020800,
 	0x8c430020, 0x27bdffe8, 0xafb00010, 0x27500100, 0x10600024, 0xafbf0014,
-	0x0e001006, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018,
+	0x0e00148e, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018,
 	0x8e020004, 0xac820004, 0x8f830018, 0x8e020018, 0xac620008, 0x8f840018,
 	0x8e03001c, 0xac83000c, 0x9602000c, 0x9203000a, 0x8f840018, 0x00021400,
 	0x00431025, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018,
-	0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x9464466e, 0x8f850018,
-	0x00021400, 0x00441025, 0x24040001, 0x0e001044, 0xaca2001c, 0x8fbf0014,
+	0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x946458ce, 0x8f850018,
+	0x00021400, 0x00441025, 0x24040001, 0x0e0014cc, 0xaca2001c, 0x8fbf0014,
 	0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe8,
-	0xafb00010, 0x27500100, 0x10600020, 0xafbf0014, 0x0e001006, 0x00000000,
+	0xafb00010, 0x27500100, 0x10600020, 0xafbf0014, 0x0e00148e, 0x00000000,
 	0x8f820018, 0xac400000, 0x8f830018, 0xac600004, 0x8f820018, 0xac400008,
 	0x8f830018, 0xac60000c, 0x9602000c, 0x9603000e, 0x8f840018, 0x00021400,
 	0x00431025, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018,
-	0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x9464466e, 0x8f850018,
-	0x00021400, 0x00441025, 0x24040001, 0x0e001044, 0xaca2001c, 0x8fbf0014,
+	0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x946458ce, 0x8f850018,
+	0x00021400, 0x00441025, 0x24040001, 0x0e0014cc, 0xaca2001c, 0x8fbf0014,
 	0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafb00010, 0x27500100,
 	0xafbf0014, 0x9602000c, 0x10400024, 0x00802821, 0x3c020800, 0x8c430020,
-	0x1060003a, 0x8fbf0014, 0x0e001006, 0x00000000, 0x8f840018, 0x8e030000,
+	0x1060003a, 0x8fbf0014, 0x0e00148e, 0x00000000, 0x8f840018, 0x8e030000,
 	0xac830000, 0x9602000c, 0x8f840018, 0x00021400, 0xac820004, 0x8f830018,
 	0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018,
 	0xac400014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800,
-	0xaca30018, 0x9443466e, 0x8f850018, 0x3c02400b, 0x00621825, 0x0e001044,
-	0xaca3001c, 0x0a000d19, 0x8fbf0014, 0x93620005, 0x30420010, 0x14400015,
+	0xaca30018, 0x944358ce, 0x8f850018, 0x3c02400b, 0x00621825, 0x0e0014cc,
+	0xaca3001c, 0x0a0011ff, 0x8fbf0014, 0x93620005, 0x30420010, 0x14400015,
 	0x3c029000, 0x34420001, 0x00a21025, 0xaf420020, 0x3c038000, 0x8f420020,
 	0x00431024, 0x1440fffd, 0x00000000, 0x3c038000, 0x93620005, 0x34630001,
-	0x00a02021, 0x00a31825, 0x24055852, 0x34420010, 0xa3620005, 0x0e000553,
-	0xaf430020, 0x0a000d19, 0x8fbf0014, 0x0000000d, 0x8fbf0014, 0x8fb00010,
+	0x00a02021, 0x00a31825, 0x24055852, 0x34420010, 0xa3620005, 0x0e000766,
+	0xaf430020, 0x0a0011ff, 0x8fbf0014, 0x0000000d, 0x8fbf0014, 0x8fb00010,
 	0x03e00008, 0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe8, 0xafb00010,
-	0x27500100, 0x10600022, 0xafbf0014, 0x0e001006, 0x00000000, 0x8f840018,
+	0x27500100, 0x10600022, 0xafbf0014, 0x0e00148e, 0x00000000, 0x8f840018,
 	0x8e020004, 0xac820000, 0x9603000c, 0x9762002c, 0x8f840018, 0x00031c00,
 	0x00431025, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c,
 	0x8f830018, 0xac600010, 0x8f820018, 0xac400014, 0x8f850018, 0x3c026000,
-	0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018,
-	0x3c02400e, 0x00621825, 0x0e001044, 0xaca3001c, 0x0e000d48, 0x8e040000,
+	0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018,
+	0x3c02400e, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x0e00122e, 0x8e040000,
 	0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c038000, 0x8f420278,
 	0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf440240, 0xa3420244,
 	0x03e00008, 0xaf430278, 0x3c020800, 0x8c430020, 0x27bdffe0, 0xafb10014,
 	0x00808821, 0xafb20018, 0x00c09021, 0xafb00010, 0x30b0ffff, 0x1060001c,
-	0xafbf001c, 0x0e001006, 0x00000000, 0x8f820018, 0xac510000, 0x8f840018,
+	0xafbf001c, 0x0e00148e, 0x00000000, 0x8f820018, 0xac510000, 0x8f840018,
 	0x00101400, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c,
 	0x8f830018, 0xac600010, 0x8f820018, 0xac520014, 0x8f840018, 0x3c026000,
-	0x8c434448, 0x3c020800, 0xac830018, 0x9443466e, 0x8f840018, 0x3c024019,
-	0x00621825, 0xac83001c, 0x0e001044, 0x24040001, 0x8fbf001c, 0x8fb20018,
+	0x8c434448, 0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c024019,
+	0x00621825, 0xac83001c, 0x0e0014cc, 0x24040001, 0x8fbf001c, 0x8fb20018,
 	0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0x27450100,
-	0xafbf0010, 0x94a3000c, 0x240200c1, 0x14620029, 0x00803021, 0x3c029000,
+	0xafbf0010, 0x94a3000c, 0x240200c1, 0x14620031, 0x00803021, 0x3c029000,
 	0x34420001, 0x00c21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
 	0x1440fffd, 0x3c028000, 0x34420001, 0x3c049000, 0x34840001, 0x3c058000,
 	0x24030012, 0x00c21025, 0x00c42025, 0xa363003f, 0xaf420020, 0xaf440020,
-	0x8f420020, 0x00451024, 0x1440fffd, 0x3c038000, 0x9362007d, 0x34630001,
-	0x3c048000, 0x00c31825, 0x34420020, 0xa362007d, 0xaf430020, 0x8f4201f8,
-	0x00441024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4601c0, 0xa34201c4,
-	0xaf4301f8, 0x0a000db3, 0x8fbf0010, 0x00c02021, 0x94a5000c, 0x24060001,
-	0x0e000f78, 0x240706d8, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x3c020800,
-	0x8c430020, 0x27bdffe0, 0xafb00010, 0x00808021, 0xafb20018, 0x00a09021,
-	0xafb10014, 0x30d100ff, 0x1060001c, 0xafbf001c, 0x0e001006, 0x00000000,
-	0x8f820018, 0xac500000, 0x8f840018, 0x24020001, 0xac820004, 0x8f830018,
-	0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018,
-	0xac520014, 0x8f840018, 0x3c026000, 0x8c434448, 0x3c020800, 0xac830018,
-	0x9443466e, 0x8f840018, 0x3c024010, 0x00621825, 0xac83001c, 0x0e001044,
-	0x02202021, 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008,
-	0x27bd0020, 0x27bdffe8, 0xafbf0014, 0xafb00010, 0x93620005, 0x30420001,
-	0x10400033, 0x00808021, 0x3c029000, 0x34420001, 0x02021025, 0xaf420020,
-	0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620005,
-	0x3c048000, 0x3c030800, 0x304200fe, 0xa3620005, 0x8c620020, 0x34840001,
-	0x02042025, 0xaf440020, 0x10400020, 0x8fbf0014, 0x0e001006, 0x00000000,
-	0x8f820018, 0xac500000, 0x93630082, 0x9362003f, 0x8f840018, 0x00031a00,
-	0x00431025, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c,
-	0x8f830018, 0xac600010, 0x8f820018, 0xac400014, 0x8f840018, 0x3c026000,
-	0x8c434448, 0x3c020800, 0xac830018, 0x9443466e, 0x8f840018, 0x3c02400a,
-	0x00621825, 0xac83001c, 0x0e001044, 0x24040001, 0x8fbf0014, 0x8fb00010,
-	0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x8f420188, 0x00803021,
-	0x9364003f, 0x24030012, 0x00021402, 0x1483001c, 0x304500ff, 0x3c029000,
-	0x34420001, 0x3c038000, 0x00c21025, 0xa3650080, 0xa365007a, 0xaf420020,
-	0x8f420020, 0x00431024, 0x1440fffd, 0x3c028000, 0x9363007d, 0x34420001,
-	0x3c048000, 0x00c21025, 0xa363007d, 0xaf420020, 0x8f4201f8, 0x00441024,
-	0x1440fffd, 0x24020002, 0x3c031000, 0xaf4601c0, 0xa34201c4, 0xaf4301f8,
-	0x0a000e54, 0x8fbf0010, 0x9362007e, 0x1445000e, 0x00000000, 0x93620080,
-	0x1045000b, 0x00000000, 0xa3650080, 0x8f820000, 0x93660080, 0x8f440180,
-	0x8f65004c, 0x8c430000, 0x0060f809, 0x00000000, 0x0a000e54, 0x8fbf0010,
-	0xa3650080, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x3c020800, 0x8c430020,
-	0x27bdffe0, 0xafb10014, 0x00808821, 0xafb20018, 0x00a09021, 0xafb00010,
-	0x30d000ff, 0x1060002f, 0xafbf001c, 0x0e001006, 0x00000000, 0x8f820018,
-	0xac510000, 0x8f830018, 0xac700004, 0x8f820018, 0xac520008, 0x8f830018,
-	0xac60000c, 0x8f820018, 0xac400010, 0x9763006a, 0x00032880, 0x50a00001,
-	0x24050001, 0x97630068, 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821,
-	0x00852804, 0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050,
-	0x00c4182b, 0x54600001, 0x00c02021, 0x8f830018, 0x2402fffe, 0x00822824,
-	0x3c026000, 0xac650014, 0x8f840018, 0x8c434448, 0x3c020800, 0xac830018,
-	0x9443466e, 0x8f840018, 0x3c024011, 0x00621825, 0xac83001c, 0x0e001044,
-	0x24040001, 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008,
-	0x27bd0020, 0x27bdffe8, 0xafbf0014, 0xafb00010, 0x8f440100, 0x27500100,
-	0x8f650050, 0x0e000c45, 0x9206001b, 0x3c020800, 0x8c430020, 0x1060001d,
-	0x8e100018, 0x0e001006, 0x00000000, 0x8f840018, 0x8f420100, 0xac820000,
-	0x8f830018, 0xac700004, 0x8f840018, 0x8f620050, 0xac820008, 0x8f830018,
-	0xac60000c, 0x8f820018, 0xac400010, 0x8f830018, 0x3c026000, 0xac600014,
-	0x8f850018, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e,
-	0x8f850018, 0x3c02401c, 0x00621825, 0x0e001044, 0xaca3001c, 0x8fbf0014,
-	0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c029000, 0x8f460140, 0x34420001,
-	0x3c038000, 0x00c21025, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd,
-	0x3c048000, 0x34840001, 0x3c059000, 0x34a50001, 0x3c078000, 0x24020012,
-	0x24030080, 0x00c42025, 0x00c52825, 0xa362003f, 0xa3630082, 0xaf440020,
-	0xaf450020, 0x8f420020, 0x00471024, 0x1440fffd, 0x3c038000, 0x9362007d,
-	0x34630001, 0x3c048000, 0x00c31825, 0x34420020, 0xa362007d, 0xaf430020,
-	0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4601c0,
-	0xa34201c4, 0x03e00008, 0xaf4301f8, 0x8f430238, 0x3c020800, 0x04610013,
-	0x8c44009c, 0x2406fffe, 0x3c050800, 0x3c038000, 0x2484ffff, 0x14800009,
-	0x00000000, 0x97420078, 0x8ca3007c, 0x24420001, 0x00461024, 0x24630001,
-	0xa7620010, 0x03e00008, 0xaca3007c, 0x8f420238, 0x00431024, 0x1440fff3,
-	0x2484ffff, 0x8f420140, 0x3c031000, 0xaf420200, 0x03e00008, 0xaf430238,
-	0x3c029000, 0x8f440140, 0x34420001, 0x3c038000, 0x00821025, 0xaf420020,
-	0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000, 0x9362007d,
-	0x34630001, 0x3c058000, 0x00831825, 0x34420001, 0xa362007d, 0xaf430020,
-	0x8f4201f8, 0x00451024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4401c0,
-	0xa34201c4, 0x03e00008, 0xaf4301f8, 0x0000000d, 0x03e00008, 0x00000000,
-	0x0000000d, 0x03e00008, 0x00000000, 0x24020001, 0x03e00008, 0xa7620010,
-	0x9362003f, 0x304400ff, 0x3883000e, 0x2c630001, 0x38820010, 0x2c420001,
-	0x00621825, 0x14600003, 0x24020012, 0x14820003, 0x00000000, 0x03e00008,
-	0x00001021, 0x9363007e, 0x9362007a, 0x14620006, 0x00000000, 0x9363007e,
-	0x24020001, 0x24630001, 0x03e00008, 0xa363007e, 0x9363007e, 0x93620080,
-	0x14620004, 0x24020001, 0xa362000b, 0x03e00008, 0x24020001, 0x03e00008,
-	0x00001021, 0x9362000b, 0x10400021, 0x00001021, 0xa360000b, 0x9362003f,
-	0x304400ff, 0x3883000e, 0x2c630001, 0x38820010, 0x2c420001, 0x00621825,
-	0x14600015, 0x00001821, 0x24020012, 0x10820012, 0x00000000, 0x9363007e,
-	0x9362007a, 0x14620007, 0x00000000, 0x9362007e, 0x24030001, 0x24420001,
-	0xa362007e, 0x03e00008, 0x00601021, 0x9363007e, 0x93620080, 0x14620004,
-	0x00001821, 0x24020001, 0xa362000b, 0x24030001, 0x03e00008, 0x00601021,
-	0x03e00008, 0x00000000, 0x24040001, 0xaf64000c, 0x8f6300dc, 0x8f6200cc,
-	0x50620001, 0xa7640010, 0xa7640012, 0xa7640014, 0x03e00008, 0xa7640016,
-	0x27bdffd8, 0xafb00010, 0x00808021, 0xafb3001c, 0x00c09821, 0xafbf0020,
-	0xafb20018, 0xafb10014, 0x93620023, 0x00e09021, 0x30420040, 0x10400020,
-	0x30b1ffff, 0x3c020800, 0x8c430020, 0x1060001c, 0x00000000, 0x0e001006,
-	0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x3c02008d, 0xac820004,
-	0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
-	0x8f820018, 0xac520014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001,
-	0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c024019, 0x00621825,
-	0x0e001044, 0xaca3001c, 0x93620023, 0x30420020, 0x14400003, 0x3c020800,
-	0x52600020, 0x3c029000, 0x8c430020, 0x1060001d, 0x3c029000, 0x0e001006,
-	0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x00111400, 0xac820004,
-	0x8f830018, 0xac720008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
-	0x8f820018, 0xac400014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001,
-	0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c02401b, 0x00621825,
-	0x0e001044, 0xaca3001c, 0x3c029000, 0x34420001, 0x02021025, 0xaf420020,
-	0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93630023,
-	0x3c028000, 0x34420001, 0x02021025, 0x8fbf0020, 0x8fb3001c, 0x8fb20018,
-	0x8fb10014, 0x8fb00010, 0x3063009f, 0xa3630023, 0xaf420020, 0x03e00008,
-	0x27bd0028, 0x3c020800, 0x8c430020, 0x27bdffe8, 0xafb00010, 0x27500100,
-	0x1060001d, 0xafbf0014, 0x0e001006, 0x00000000, 0x8f830018, 0x8e020004,
-	0xac620000, 0x8f840018, 0x8e020018, 0xac820004, 0x8f850018, 0x8e020000,
-	0xaca20008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010, 0x8f830018,
-	0xac600014, 0x8f820018, 0xac400018, 0x96030008, 0x3c020800, 0x9444466e,
-	0x8f850018, 0x00031c00, 0x00641825, 0x24040001, 0x0e001044, 0xaca3001c,
-	0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c060800, 0x24c54660,
-	0x3c02000a, 0x03421821, 0x94640006, 0x94a2000a, 0x00441023, 0x00021400,
-	0x00021c03, 0x04610006, 0xa4a40006, 0x0000000d, 0x00000000, 0x2400005a,
-	0x0a00101b, 0x24020001, 0x8f820014, 0x0062102b, 0x14400002, 0x00001021,
-	0x24020001, 0x304200ff, 0x1040001c, 0x274a0400, 0x3c07000a, 0x3c020800,
-	0x24454660, 0x94a9000a, 0x8f880014, 0x03471021, 0x94430006, 0x00402021,
-	0xa4a30006, 0x94820006, 0xa4a20006, 0x01221023, 0x00021400, 0x00021403,
-	0x04410006, 0x0048102b, 0x0000000d, 0x00000000, 0x2400005a, 0x0a001036,
-	0x24020001, 0x14400002, 0x00001021, 0x24020001, 0x304200ff, 0x1440ffec,
-	0x03471021, 0x24c44660, 0x8c820010, 0xaf420038, 0x8c830014, 0x3c020005,
-	0xaf43003c, 0xaf420030, 0xaf800010, 0xaf8a0018, 0x03e00008, 0x00000000,
-	0x27bdffe0, 0x8f820010, 0x8f850018, 0x3c070800, 0x24e84660, 0xafbf001c,
-	0xafb20018, 0xafb10014, 0xafb00010, 0x9503000a, 0x8d060014, 0x00009021,
-	0x309000ff, 0x00e08821, 0x24420001, 0x24a50020, 0x24630001, 0xaf820010,
-	0xaf850018, 0xa503000a, 0x24c30020, 0x3c028000, 0x04c10007, 0xad030014,
-	0x00621024, 0x14400005, 0x26224660, 0x8d020010, 0x24420001, 0xad020010,
-	0x26224660, 0x9444000a, 0x94450018, 0x0010102b, 0x00a41826, 0x2c630001,
-	0x00621825, 0x1060001c, 0x3c030006, 0x8f820010, 0x24120001, 0x00021140,
-	0x00431025, 0xaf420030, 0x00000000, 0x00000000, 0x00000000, 0x27450400,
-	0x8f420000, 0x30420010, 0x1040fffd, 0x26224660, 0x9444000a, 0x94430018,
-	0xaf800010, 0xaf850018, 0x14830012, 0x26274660, 0x0e0010d2, 0x00000000,
-	0x1600000e, 0x26274660, 0x0e001006, 0x00000000, 0x0a00108f, 0x26274660,
-	0x00041c00, 0x00031c03, 0x00051400, 0x00021403, 0x00621823, 0x18600002,
-	0x3c026000, 0xac400808, 0x26274660, 0x94e2000e, 0x94e3000c, 0x24420001,
-	0xa4e2000e, 0x3042ffff, 0x50430001, 0xa4e0000e, 0x12000005, 0x3c02000a,
-	0x94e2000a, 0xa74200a2, 0x0a0010cc, 0x02401021, 0x03421821, 0x94640006,
-	0x94e2000a, 0x00441023, 0x00021400, 0x00021c03, 0x04610006, 0xa4e40006,
-	0x0000000d, 0x00000000, 0x2400005a, 0x0a0010ae, 0x24020001, 0x8f820014,
-	0x0062102b, 0x14400002, 0x00001021, 0x24020001, 0x304200ff, 0x1040001b,
-	0x3c020800, 0x3c06000a, 0x24454660, 0x94a8000a, 0x8f870014, 0x03461021,
-	0x94430006, 0x00402021, 0xa4a30006, 0x94820006, 0xa4a20006, 0x01021023,
-	0x00021400, 0x00021403, 0x04410006, 0x0047102b, 0x0000000d, 0x00000000,
-	0x2400005a, 0x0a0010c8, 0x24020001, 0x14400002, 0x00001021, 0x24020001,
-	0x304200ff, 0x1440ffec, 0x03461021, 0x02401021, 0x8fbf001c, 0x8fb20018,
-	0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3c020800, 0x24454660,
-	0x94a3001a, 0x8ca40024, 0x00403021, 0x000318c0, 0x00832021, 0xaf44003c,
-	0x8ca20020, 0xaf420038, 0x3c020050, 0x34420008, 0xaf420030, 0x00000000,
-	0x00000000, 0x00000000, 0x8f420000, 0x30420020, 0x1040fffd, 0x00000000,
-	0x8f430400, 0x24c64660, 0xacc30010, 0x8f420404, 0x3c030020, 0xacc20014,
-	0xaf430030, 0x94c40018, 0x94c3001c, 0x94c2001a, 0x94c5001e, 0x00832021,
-	0x24420001, 0xa4c2001a, 0x3042ffff, 0x14450002, 0xa4c40018, 0xa4c0001a,
-	0x03e00008, 0x00000000, 0x8f820010, 0x3c030006, 0x00021140, 0x00431025,
-	0xaf420030, 0x00000000, 0x00000000, 0x00000000, 0x27430400, 0x8f420000,
-	0x30420010, 0x1040fffd, 0x00000000, 0xaf800010, 0xaf830018, 0x03e00008,
-	0x00000000, 0x27bdffe8, 0xafb00010, 0x3c100800, 0x26104660, 0x3c05000a,
-	0x02002021, 0x03452821, 0xafbf0014, 0x0e001128, 0x2406000a, 0x96020002,
-	0x9603001e, 0x3042000f, 0x24420003, 0x00431804, 0x24027fff, 0x0043102b,
-	0xaf830014, 0x10400004, 0x00000000, 0x0000000d, 0x00000000, 0x24000043,
-	0x0e0010d2, 0x00000000, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018,
-	0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000,
-	0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a001137, 0x00a01021,
-	0xac860000, 0x24840004, 0x00a01021, 0x1440fffc, 0x24a5ffff, 0x03e00008,
-	0x00000000, 0x3c036000, 0x8c642b7c, 0x3c036010, 0x8c6553fc, 0x00041582,
-	0x00042302, 0x308403ff, 0x00052d82, 0x00441026, 0x0002102b, 0x0005282b,
-	0x00451025, 0x1440000d, 0x3c020050, 0x34420004, 0xaf400038, 0xaf40003c,
-	0xaf420030, 0x00000000, 0x00000000, 0x8f420000, 0x30420020, 0x1040fffd,
-	0x3c020020, 0xaf420030, 0x0000000d, 0x03e00008, 0x00000000, 0x3c020050,
-	0x34420004, 0xaf440038, 0xaf45003c, 0xaf420030, 0x00000000, 0x00000000,
-	0x8f420000, 0x30420020, 0x1040fffd, 0x3c020020, 0xaf420030, 0x03e00008,
-	0x00000000, 0x00000000 };
+	0x8f420020, 0x00451024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000,
+	0x34420020, 0xa362007d, 0x8f640074, 0x34630001, 0x00c31825, 0xaf430020,
+	0x04810006, 0x3c038000, 0x00c02021, 0x0e000470, 0x24050906, 0x0a0012a1,
+	0x8fbf0010, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000,
+	0xaf4601c0, 0xa34201c4, 0xaf4301f8, 0x0a0012a1, 0x8fbf0010, 0x00c02021,
+	0x94a5000c, 0x24060001, 0x0e000fb1, 0x2407090e, 0x8fbf0010, 0x03e00008,
+	0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe0, 0xafb00010, 0x00808021,
+	0xafb20018, 0x00a09021, 0xafb10014, 0x30d100ff, 0x1060001c, 0xafbf001c,
+	0x0e00148e, 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x24020001,
+	0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018,
+	0xac600010, 0x8f820018, 0xac520014, 0x8f840018, 0x3c026000, 0x8c434448,
+	0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c024010, 0x00621825,
+	0xac83001c, 0x0e0014cc, 0x02202021, 0x8fbf001c, 0x8fb20018, 0x8fb10014,
+	0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0014, 0xafb00010,
+	0x93620005, 0x30420001, 0x10400036, 0x00808021, 0x3c029000, 0x34420001,
+	0x02021025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
+	0x00000000, 0x93620023, 0x34420004, 0xa3620023, 0x93630005, 0x3c048000,
+	0x3c020800, 0x306300fe, 0xa3630005, 0x8c430020, 0x34840001, 0x02042025,
+	0xaf440020, 0x10600020, 0x8fbf0014, 0x0e00148e, 0x00000000, 0x8f820018,
+	0xac500000, 0x93630082, 0x9362003f, 0x8f840018, 0x00031a00, 0x00431025,
+	0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018,
+	0xac600010, 0x8f820018, 0xac400014, 0x8f840018, 0x3c026000, 0x8c434448,
+	0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c02400a, 0x00621825,
+	0xac83001c, 0x0e0014cc, 0x24040001, 0x8fbf0014, 0x8fb00010, 0x03e00008,
+	0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe0, 0xafb10014, 0x00808821,
+	0xafb20018, 0x00a09021, 0xafb00010, 0x30d000ff, 0x1060002f, 0xafbf001c,
+	0x0e00148e, 0x00000000, 0x8f820018, 0xac510000, 0x8f830018, 0xac700004,
+	0x8f820018, 0xac520008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010,
+	0x9763006a, 0x00032880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081,
+	0x3c020800, 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001,
+	0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021,
+	0x8f830018, 0x2402fffe, 0x00822824, 0x3c026000, 0xac650014, 0x8f840018,
+	0x8c434448, 0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c024011,
+	0x00621825, 0xac83001c, 0x0e0014cc, 0x24040001, 0x8fbf001c, 0x8fb20018,
+	0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0014,
+	0xafb00010, 0x8f440100, 0x27500100, 0x8f650050, 0x0e0010fc, 0x9206001b,
+	0x3c020800, 0x8c430020, 0x1060001d, 0x8e100018, 0x0e00148e, 0x00000000,
+	0x8f840018, 0x8f420100, 0xac820000, 0x8f830018, 0xac700004, 0x8f840018,
+	0x8f620050, 0xac820008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010,
+	0x8f830018, 0x3c026000, 0xac600014, 0x8f850018, 0x8c434448, 0x24040001,
+	0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c02401c, 0x00621825,
+	0x0e0014cc, 0xaca3001c, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018,
+	0x8f430238, 0x3c020800, 0x04610013, 0x8c44009c, 0x2406fffe, 0x3c050800,
+	0x3c038000, 0x2484ffff, 0x14800009, 0x00000000, 0x97420078, 0x8ca3007c,
+	0x24420001, 0x00461024, 0x24630001, 0xa7620010, 0x03e00008, 0xaca3007c,
+	0x8f420238, 0x00431024, 0x1440fff3, 0x2484ffff, 0x8f420140, 0x3c031000,
+	0xaf420200, 0x03e00008, 0xaf430238, 0x27bdffe8, 0x3c029000, 0xafbf0010,
+	0x8f450140, 0x34420001, 0x3c038000, 0x00a21025, 0xaf420020, 0x8f420020,
+	0x00431024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0x34420001,
+	0xa362007d, 0x8f640074, 0x34630001, 0x00a31825, 0xaf430020, 0x04810006,
+	0x3c038000, 0x00a02021, 0x0e000470, 0x24050ac7, 0x0a0013b9, 0x8fbf0010,
+	0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4501c0,
+	0xa34201c4, 0xaf4301f8, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x0000000d,
+	0x03e00008, 0x00000000, 0x0000000d, 0x03e00008, 0x00000000, 0x24020001,
+	0x03e00008, 0xa7620010, 0x9362003f, 0x304400ff, 0x3883000e, 0x2c630001,
+	0x38820010, 0x2c420001, 0x00621825, 0x14600003, 0x24020012, 0x14820003,
+	0x00000000, 0x03e00008, 0x00001021, 0x9363007e, 0x9362007a, 0x14620006,
+	0x00000000, 0x9363007e, 0x24020001, 0x24630001, 0x03e00008, 0xa363007e,
+	0x9362007e, 0x8f630178, 0x304200ff, 0x14430006, 0x00000000, 0x9363000b,
+	0x24020001, 0x24630001, 0x03e00008, 0xa363000b, 0x03e00008, 0x00001021,
+	0x9362000b, 0x10400023, 0x00001021, 0xa360000b, 0x9362003f, 0x304400ff,
+	0x3883000e, 0x2c630001, 0x38820010, 0x2c420001, 0x00621825, 0x14600017,
+	0x00001821, 0x24020012, 0x10820014, 0x00000000, 0x9363007e, 0x9362007a,
+	0x14620007, 0x00000000, 0x9362007e, 0x24030001, 0x24420001, 0xa362007e,
+	0x03e00008, 0x00601021, 0x9362007e, 0x8f630178, 0x304200ff, 0x14430005,
+	0x00001821, 0x9362000b, 0x24030001, 0x24420001, 0xa362000b, 0x03e00008,
+	0x00601021, 0x03e00008, 0x00000000, 0x24040001, 0xaf64000c, 0x8f6300dc,
+	0x8f6200cc, 0x50620001, 0xa7640010, 0xa7640012, 0xa7640014, 0x03e00008,
+	0xa7640016, 0x3c020800, 0x8c430020, 0x27bdffe8, 0x1060001b, 0xafbf0010,
+	0x0e00148e, 0x00000000, 0x8f820018, 0xac400000, 0x8f830018, 0xac600004,
+	0x8f820018, 0xac400008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010,
+	0x8f830018, 0x3c026000, 0xac600014, 0x8f840018, 0x8c434448, 0x3c020800,
+	0xac830018, 0x944358ce, 0x8f840018, 0x3c024020, 0x00621825, 0xac83001c,
+	0x0e0014cc, 0x24040001, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x3c020800,
+	0x8c430020, 0x27bdffe0, 0xafb00010, 0x00a08021, 0xafb10014, 0x00c08821,
+	0xafb20018, 0x00e09021, 0x1060001e, 0xafbf001c, 0x0e00148e, 0x00000000,
+	0x8f840018, 0x8f420100, 0xac820000, 0x8f830018, 0xac700004, 0x8f820018,
+	0xac510008, 0x8f830018, 0xac72000c, 0x8f840018, 0x8fa20030, 0xac820010,
+	0x8f830018, 0x8fa20034, 0xac620014, 0x8f840018, 0x3c026000, 0x8c434448,
+	0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c0240c9, 0x00621825,
+	0xac83001c, 0x0e0014cc, 0x24040001, 0x8fbf001c, 0x8fb20018, 0x8fb10014,
+	0x8fb00010, 0x03e00008, 0x27bd0020, 0x3c020800, 0x8c430020, 0x27bdffe8,
+	0xafb00010, 0x27500100, 0x1060001d, 0xafbf0014, 0x0e00148e, 0x00000000,
+	0x8f830018, 0x8e020004, 0xac620000, 0x8f840018, 0x8e020018, 0xac820004,
+	0x8f850018, 0x8e020000, 0xaca20008, 0x8f830018, 0xac60000c, 0x8f820018,
+	0xac400010, 0x8f830018, 0xac600014, 0x8f820018, 0xac400018, 0x96030008,
+	0x3c020800, 0x944458ce, 0x8f850018, 0x00031c00, 0x00641825, 0x24040001,
+	0x0e0014cc, 0xaca3001c, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018,
+	0x3c060800, 0x24c558c0, 0x3c02000a, 0x03421821, 0x94640006, 0x94a2000a,
+	0x00441023, 0x00021400, 0x00021c03, 0x04610006, 0xa4a40006, 0x0000000d,
+	0x00000000, 0x2400005a, 0x0a0014a3, 0x24020001, 0x8f820014, 0x0062102b,
+	0x14400002, 0x00001021, 0x24020001, 0x304200ff, 0x1040001c, 0x274a0400,
+	0x3c07000a, 0x3c020800, 0x244558c0, 0x94a9000a, 0x8f880014, 0x03471021,
+	0x94430006, 0x00402021, 0xa4a30006, 0x94820006, 0xa4a20006, 0x01221023,
+	0x00021400, 0x00021403, 0x04410006, 0x0048102b, 0x0000000d, 0x00000000,
+	0x2400005a, 0x0a0014be, 0x24020001, 0x14400002, 0x00001021, 0x24020001,
+	0x304200ff, 0x1440ffec, 0x03471021, 0x24c458c0, 0x8c820010, 0xaf420038,
+	0x8c830014, 0x3c020005, 0xaf43003c, 0xaf420030, 0xaf800010, 0xaf8a0018,
+	0x03e00008, 0x00000000, 0x27bdffe0, 0x8f820010, 0x8f850018, 0x3c070800,
+	0x24e858c0, 0xafbf001c, 0xafb20018, 0xafb10014, 0xafb00010, 0x9503000a,
+	0x8d060014, 0x00009021, 0x309000ff, 0x00e08821, 0x24420001, 0x24a50020,
+	0x24630001, 0xaf820010, 0xaf850018, 0xa503000a, 0x24c30020, 0x3c028000,
+	0x04c10007, 0xad030014, 0x00621024, 0x14400005, 0x262258c0, 0x8d020010,
+	0x24420001, 0xad020010, 0x262258c0, 0x9444000a, 0x94450018, 0x0010102b,
+	0x00a41826, 0x2c630001, 0x00621825, 0x1060001c, 0x3c030006, 0x8f820010,
+	0x24120001, 0x00021140, 0x00431025, 0xaf420030, 0x00000000, 0x00000000,
+	0x00000000, 0x27450400, 0x8f420000, 0x30420010, 0x1040fffd, 0x262258c0,
+	0x9444000a, 0x94430018, 0xaf800010, 0xaf850018, 0x14830012, 0x262758c0,
+	0x0e00155a, 0x00000000, 0x1600000e, 0x262758c0, 0x0e00148e, 0x00000000,
+	0x0a001517, 0x262758c0, 0x00041c00, 0x00031c03, 0x00051400, 0x00021403,
+	0x00621823, 0x18600002, 0x3c026000, 0xac400808, 0x262758c0, 0x94e2000e,
+	0x94e3000c, 0x24420001, 0xa4e2000e, 0x3042ffff, 0x50430001, 0xa4e0000e,
+	0x12000005, 0x3c02000a, 0x94e2000a, 0xa74200a2, 0x0a001554, 0x02401021,
+	0x03421821, 0x94640006, 0x94e2000a, 0x00441023, 0x00021400, 0x00021c03,
+	0x04610006, 0xa4e40006, 0x0000000d, 0x00000000, 0x2400005a, 0x0a001536,
+	0x24020001, 0x8f820014, 0x0062102b, 0x14400002, 0x00001021, 0x24020001,
+	0x304200ff, 0x1040001b, 0x3c020800, 0x3c06000a, 0x244558c0, 0x94a8000a,
+	0x8f870014, 0x03461021, 0x94430006, 0x00402021, 0xa4a30006, 0x94820006,
+	0xa4a20006, 0x01021023, 0x00021400, 0x00021403, 0x04410006, 0x0047102b,
+	0x0000000d, 0x00000000, 0x2400005a, 0x0a001550, 0x24020001, 0x14400002,
+	0x00001021, 0x24020001, 0x304200ff, 0x1440ffec, 0x03461021, 0x02401021,
+	0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020,
+	0x3c020800, 0x244558c0, 0x94a3001a, 0x8ca40024, 0x00403021, 0x000318c0,
+	0x00832021, 0xaf44003c, 0x8ca20020, 0xaf420038, 0x3c020050, 0x34420008,
+	0xaf420030, 0x00000000, 0x00000000, 0x00000000, 0x8f420000, 0x30420020,
+	0x1040fffd, 0x00000000, 0x8f430400, 0x24c658c0, 0xacc30010, 0x8f420404,
+	0x3c030020, 0xacc20014, 0xaf430030, 0x94c40018, 0x94c3001c, 0x94c2001a,
+	0x94c5001e, 0x00832021, 0x24420001, 0xa4c2001a, 0x3042ffff, 0x14450002,
+	0xa4c40018, 0xa4c0001a, 0x03e00008, 0x00000000, 0x8f820010, 0x3c030006,
+	0x00021140, 0x00431025, 0xaf420030, 0x00000000, 0x00000000, 0x00000000,
+	0x27430400, 0x8f420000, 0x30420010, 0x1040fffd, 0x00000000, 0xaf800010,
+	0xaf830018, 0x03e00008, 0x00000000, 0x27bdffe8, 0xafb00010, 0x3c100800,
+	0x261058c0, 0x3c05000a, 0x02002021, 0x03452821, 0xafbf0014, 0x0e0015b0,
+	0x2406000a, 0x96020002, 0x9603001e, 0x3042000f, 0x24420003, 0x00431804,
+	0x24027fff, 0x0043102b, 0xaf830014, 0x10400004, 0x00000000, 0x0000000d,
+	0x00000000, 0x24000043, 0x0e00155a, 0x00000000, 0x8fbf0014, 0x8fb00010,
+	0x03e00008, 0x27bd0018, 0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff,
+	0x24a50004, 0xac820000, 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000,
+	0x0a0015c1, 0x00a01021, 0xac860000, 0x00000000, 0x00000000, 0x24840004,
+	0x00a01021, 0x1440fffa, 0x24a5ffff, 0x03e00008, 0x00000000, 0x3c036000,
+	0x8c642b7c, 0x3c036010, 0x8c6553fc, 0x00041582, 0x00042302, 0x308403ff,
+	0x00052d82, 0x00441026, 0x0002102b, 0x0005282b, 0x00451025, 0x1440000d,
+	0x3c020050, 0x34420004, 0xaf400038, 0xaf40003c, 0xaf420030, 0x00000000,
+	0x00000000, 0x8f420000, 0x30420020, 0x1040fffd, 0x3c020020, 0xaf420030,
+	0x0000000d, 0x03e00008, 0x00000000, 0x3c020050, 0x34420004, 0xaf440038,
+	0xaf45003c, 0xaf420030, 0x00000000, 0x00000000, 0x8f420000, 0x30420020,
+	0x1040fffd, 0x3c020020, 0xaf420030, 0x03e00008, 0x00000000, 0x00000000};
 
-static u32 bnx2_COM_b06FwData[(0x0/4) + 1] = { 0x00000000 };
-static u32 bnx2_COM_b06FwRodata[(0x18/4) + 1] = {
-	0x08002318, 0x08002348, 0x08002378, 0x080023a8, 0x080023d8, 0x00000000,
-	0x00000000 };
+static u32 bnx2_COM_b06FwData[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_COM_b06FwRodata[(0x58/4) + 1] = {
+	0x08002428, 0x0800245c, 0x0800245c, 0x0800245c, 0x0800245c, 0x0800245c,
+	0x08002380, 0x0800245c, 0x080023e4, 0x0800245c, 0x0800231c, 0x0800245c,
+	0x0800245c, 0x0800245c, 0x08002328, 0x00000000, 0x08003240, 0x08003270,
+	0x080032a0, 0x080032d0, 0x08003300, 0x00000000, 0x00000000 };
+static u32 bnx2_COM_b06FwBss[(0x88/4) + 1] = { 0x0 };
+static u32 bnx2_COM_b06FwSbss[(0x1c/4) + 1] = { 0x0 };
 
-static u32 bnx2_COM_b06FwBss[(0x88/4) + 1] = { 0x00000000 };
-static u32 bnx2_COM_b06FwSbss[(0x1c/4) + 1] = { 0x00000000 };
-
-static int bnx2_RXP_b06FwReleaseMajor = 0x0;
+static int bnx2_RXP_b06FwReleaseMajor = 0x1;
 static int bnx2_RXP_b06FwReleaseMinor = 0x0;
 static int bnx2_RXP_b06FwReleaseFix = 0x0;
-static u32 bnx2_RXP_b06FwStartAddr = 0x08000060;
+static u32 bnx2_RXP_b06FwStartAddr = 0x08003104;
 static u32 bnx2_RXP_b06FwTextAddr = 0x08000000;
-static int bnx2_RXP_b06FwTextLen = 0x20b8;
-static u32 bnx2_RXP_b06FwDataAddr = 0x080020e0;
+static int bnx2_RXP_b06FwTextLen = 0x562c;
+static u32 bnx2_RXP_b06FwDataAddr = 0x08005660;
 static int bnx2_RXP_b06FwDataLen = 0x0;
 static u32 bnx2_RXP_b06FwRodataAddr = 0x00000000;
 static int bnx2_RXP_b06FwRodataLen = 0x0;
-static u32 bnx2_RXP_b06FwBssAddr = 0x08002100;
-static int bnx2_RXP_b06FwBssLen = 0x239c;
-static u32 bnx2_RXP_b06FwSbssAddr = 0x080020e0;
-static int bnx2_RXP_b06FwSbssLen = 0x14;
-
-static u32 bnx2_RXP_b06FwText[(0x20b8/4) + 1] = {
-	0x0a000018, 0x00000000, 0x00000000, 0x0000000d, 0x72787020, 0x302e362e,
-	0x39000000, 0x00060903, 0x00000000, 0x0000000d, 0x00000000, 0x00000000,
+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,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
-	0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800,
-	0x244220e0, 0x3c030800, 0x2463449c, 0xac400000, 0x0043202b, 0x1480fffd,
-	0x24420004, 0x3c1d0800, 0x37bd3ffc, 0x03a0f021, 0x3c100800, 0x26100060,
-	0x3c1c0800, 0x279c20e0, 0x0e000329, 0x00000000, 0x0000000d, 0x8f870008,
-	0x2ce20080, 0x10400018, 0x3c030800, 0x24633490, 0x8f460100, 0x00072140,
-	0x00831021, 0xac460000, 0x8f450104, 0x00641021, 0xac450004, 0x8f460108,
-	0xac460008, 0x8f45010c, 0xac45000c, 0x8f460114, 0xac460010, 0x8f450118,
-	0xac450014, 0x8f460124, 0xac460018, 0x8f450128, 0x00641821, 0x24e20001,
-	0xaf820008, 0xac65001c, 0x03e00008, 0x00000000, 0x00804021, 0x8f830000,
-	0x24070001, 0x3c020001, 0x00621024, 0x10400037, 0x00603021, 0x9742010e,
-	0x3c038000, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003,
-	0xa342018b, 0x8f840004, 0x24020080, 0x24030002, 0xaf420180, 0xa743018c,
-	0x10800005, 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000069, 0x00021400,
-	0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c,
-	0x24020003, 0x30838000, 0x1060000d, 0xa7420188, 0x93420116, 0x304200fc,
-	0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600005, 0x00000000,
-	0x3c02ffff, 0x34427fff, 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c,
-	0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6,
-	0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x30c21000,
-	0x1040000f, 0x00000000, 0x9742010c, 0x3042fc00, 0x5440000b, 0x24070005,
-	0x3c021000, 0x00c21024, 0x10400007, 0x3c030dff, 0x3463ffff, 0x3c020e00,
-	0x00c21024, 0x0062182b, 0x54600001, 0x24070005, 0x8f82000c, 0x30434000,
-	0x10600016, 0x00404821, 0x3c020f00, 0x00c21024, 0x14400012, 0x00000000,
-	0x93420116, 0x34424000, 0x03421821, 0x94650002, 0x2ca21389, 0x1040000b,
-	0x3c020800, 0x24422100, 0x00051942, 0x00031880, 0x00621821, 0x30a5001f,
-	0x8c640000, 0x24020001, 0x00a21004, 0x00822024, 0x01044025, 0x11000037,
-	0x3c021000, 0x9742010e, 0x34e60002, 0x3c038000, 0x24420004, 0x3045ffff,
-	0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x8f840004,
-	0x24020180, 0x24030002, 0xaf420180, 0xa743018c, 0x10800005, 0xa745018e,
-	0x9743011c, 0x9742011e, 0x0a0000cd, 0x00021400, 0x9743011e, 0x9742011c,
-	0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c, 0x30828000, 0x1040000c,
-	0xa7460188, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000,
-	0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf82000c,
-	0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff,
-	0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x03e00008,
-	0x00001021, 0x00c21024, 0x104000ba, 0x3c020800, 0x8c430030, 0x1060003e,
-	0x31224000, 0x1040003c, 0x3c030f00, 0x00c31824, 0x3c020100, 0x0043102b,
-	0x14400038, 0x3c030800, 0x9742010e, 0x34e60002, 0x3c038000, 0x24420004,
-	0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b,
-	0x8f840004, 0x24020080, 0x24030002, 0xaf420180, 0xa743018c, 0x10800005,
-	0xa745018e, 0x9743011c, 0x9742011e, 0x0a000110, 0x00021400, 0x9743011e,
-	0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c, 0x30828000,
-	0x1040000c, 0xa7460188, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004,
-	0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024,
-	0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00,
-	0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8,
-	0x03e00008, 0x00001021, 0x3c030800, 0x8c620024, 0x30420008, 0x1040003d,
-	0x34e80002, 0x3c020f00, 0x00c21024, 0x5440003a, 0x3107ffff, 0x9742010c,
-	0x30420200, 0x50400036, 0x3107ffff, 0x9742010e, 0x30e6fffb, 0x3c038000,
-	0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003,
-	0xa342018b, 0x8f840004, 0x24020180, 0x24030002, 0xaf420180, 0xa743018c,
-	0x10800005, 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000153, 0x00021400,
-	0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c,
-	0x30828000, 0x1040000c, 0xa7460188, 0x93420116, 0x304200fc, 0x005a1021,
-	0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
-	0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff,
-	0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
-	0xaf4201b8, 0x3107ffff, 0x8f820000, 0x3c068000, 0x9743010e, 0x00021442,
-	0x30440780, 0x24630004, 0x3065ffff, 0x8f4201b8, 0x00461024, 0x1440fffd,
-	0x24020003, 0xa342018b, 0x8f830004, 0x24020002, 0xaf440180, 0xa742018c,
-	0x10600005, 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000189, 0x00021400,
-	0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c,
-	0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021,
-	0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
-	0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff,
-	0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
-	0xaf4201b8, 0x03e00008, 0x00001021, 0x8f424000, 0x30420100, 0x104000ef,
-	0x3c020800, 0x8c440024, 0x24030001, 0x14830036, 0x00404021, 0x9742010e,
-	0x34e50002, 0x3c038000, 0x24420004, 0x3044ffff, 0x8f4201b8, 0x00431024,
-	0x1440fffd, 0x24020003, 0xa342018b, 0x8f830004, 0x24020002, 0xaf400180,
-	0xa742018c, 0x10600005, 0xa744018e, 0x9743011c, 0x9742011e, 0x0a0001c6,
-	0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8,
-	0x8f84000c, 0x30828000, 0x1040000c, 0xa7450188, 0x93420116, 0x304200fc,
-	0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff,
-	0x34427fff, 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 0x30820001, 0x10400035,
-	0x30e90004, 0x9742010e, 0x30e6fffb, 0x3c038000, 0x24420004, 0x3044ffff,
-	0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x8f830004,
-	0x24020002, 0xaf400180, 0xa742018c, 0x10600005, 0xa744018e, 0x9743011c,
-	0x9742011e, 0x0a0001fe, 0x00021400, 0x9743011e, 0x9742011c, 0x00021400,
-	0x00621825, 0xaf4301a8, 0x8f84000c, 0x30828000, 0x1040000c, 0xa7470188,
-	0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff,
-	0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf82000c, 0x9782000e,
-	0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825,
-	0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x30c7ffff, 0x8d020024,
-	0x30420004, 0x10400037, 0x8d020024, 0x9742010e, 0x30e6fffb, 0x3c038000,
-	0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003,
-	0xa342018b, 0x8f840004, 0x24020100, 0x24030002, 0xaf420180, 0xa743018c,
-	0x10800005, 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000237, 0x00021400,
-	0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c,
+	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,
 	0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
-	0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff,
+	0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104, 0x3042bfff,
 	0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
-	0xaf4201b8, 0x30c7ffff, 0x8d020024, 0x30420008, 0x10400034, 0x00000000,
-	0x9742010e, 0x3c038000, 0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024,
-	0x1440fffd, 0x24020003, 0xa342018b, 0x8f840004, 0x24020180, 0x24030002,
-	0xaf420180, 0xa743018c, 0x10800005, 0xa745018e, 0x9743011c, 0x9742011e,
-	0x0a00026f, 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825,
-	0xaf4301a8, 0x8f84000c, 0x30828000, 0x1040000c, 0xa7470188, 0x93420116,
+	0xaf4201b8, 0x03e00008, 0x00001021, 0x00c21024, 0x104000e3, 0x3c020800,
+	0x8c430030, 0x10600040, 0x31024000, 0x1040003e, 0x3c030f00, 0x00c31824,
+	0x3c020100, 0x0043102b, 0x1440003a, 0x3c030800, 0x9742010e, 0x34e70002,
+	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,
+	0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff,
+	0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf820010, 0x97820012,
+	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,
+	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,
+	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, 0xaf82000c, 0x9782000e, 0x9743010c,
+	0x3c02ffff, 0x34427fff, 0x00821024, 0xaf820010, 0x97820012, 0x9743010c,
 	0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6,
-	0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x15200046, 0x00001021, 0x3c038000,
-	0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, 0x24032000, 0xa342018b,
-	0xa7430188, 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x3c030800,
-	0x8c620024, 0x30420001, 0x10400035, 0x00001021, 0x9742010e, 0x34e50002,
-	0x3c038000, 0x24420004, 0x3044ffff, 0x8f4201b8, 0x00431024, 0x1440fffd,
-	0x24020003, 0xa342018b, 0x8f830004, 0x24020002, 0xaf400180, 0xa742018c,
-	0x10600005, 0xa744018e, 0x9743011c, 0x9742011e, 0x0a0002b5, 0x00021400,
-	0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c,
-	0x30828000, 0x1040000c, 0xa7450188, 0x93420116, 0x304200fc, 0x005a1021,
-	0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
-	0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff,
-	0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
-	0xaf4201b8, 0x00001021, 0x03e00008, 0x00000000, 0x27bdffe0, 0xafbf0018,
-	0xafb10014, 0xafb00010, 0x8f420140, 0xaf420020, 0x8f430148, 0x3c027000,
-	0x00621824, 0x3c024000, 0x1062000c, 0x0043102b, 0x14400006, 0x3c025000,
-	0x3c023000, 0x1062000b, 0x3c024000, 0x0a00031f, 0x00000000, 0x10620034,
-	0x3c024000, 0x0a00031f, 0x00000000, 0x0e00067c, 0x00000000, 0x0a00031f,
+	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,
+	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,
+	0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff,
+	0x34427fff, 0x00821024, 0xaf820010, 0x97820012, 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,
+	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, 0x0a00030a, 0x3c038000, 0x12020007, 0x00000000, 0x0a000317,
-	0x00000000, 0x0e000423, 0x00000000, 0x0a000308, 0x00402021, 0x0e000435,
+	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, 0x0a00031f, 0x3c024000, 0x0000000d,
-	0x00000000, 0x240001c3, 0x0a00031f, 0x3c024000, 0x0e0007f7, 0x00000000,
-	0x3c024000, 0xaf420178, 0x00000000, 0x8fbf0018, 0x8fb10014, 0x8fb00010,
-	0x03e00008, 0x27bd0020, 0x24020800, 0x03e00008, 0xaf4201b8, 0x27bdffe8,
-	0x3c04600c, 0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f,
-	0x3c106000, 0x00431024, 0x3442380c, 0x24030003, 0xac825000, 0x3c040008,
-	0xaf430008, 0x8e020808, 0x3c030800, 0xac600020, 0x3042fff0, 0x2c420001,
-	0xaf820004, 0x0e000819, 0x0344d825, 0x0e000781, 0x00000000, 0x3c020400,
-	0x3442000c, 0x3c03ffff, 0x34630806, 0xae021948, 0xae03194c, 0x8e021980,
-	0x34420200, 0xae021980, 0x8f500000, 0x32020003, 0x1040fffd, 0x32020001,
-	0x10400004, 0x32020002, 0x0e0003bd, 0x00000000, 0x32020002, 0x1040fff6,
-	0x00000000, 0x0e0002d4, 0x00000000, 0x0a00034a, 0x00000000, 0x27bdffe8,
-	0x3c04600c, 0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f,
-	0x3c106000, 0x00431024, 0x3442380c, 0x24030003, 0xac825000, 0x3c040008,
-	0xaf430008, 0x8e020808, 0x3c030800, 0xac600020, 0x3042fff0, 0x2c420001,
-	0xaf820004, 0x0e000819, 0x0344d825, 0x0e000781, 0x00000000, 0x3c020400,
-	0x3442000c, 0x3c03ffff, 0x34630806, 0xae021948, 0xae03194c, 0x8e021980,
-	0x8fbf0014, 0x34420200, 0xae021980, 0x8fb00010, 0x03e00008, 0x27bd0018,
-	0x30a5ffff, 0x30c6ffff, 0x30e7ffff, 0x3c038000, 0x8f4201b8, 0x00431024,
-	0x1440fffd, 0x24020003, 0xa342018b, 0x8f830004, 0xaf440180, 0xa745018c,
-	0x10600005, 0xa746018e, 0x9743011c, 0x9742011e, 0x0a000393, 0x00021400,
-	0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c,
+	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, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff,
+	0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104, 0x3042bfff,
 	0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
-	0xaf4201b8, 0x03e00008, 0x00000000, 0x3c038000, 0x8f4201b8, 0x00431024,
-	0x1440fffd, 0x24020002, 0x24032000, 0xa342018b, 0xa7430188, 0x3c021000,
-	0xaf4201b8, 0x03e00008, 0x00000000, 0x27bdffe8, 0xafbf0010, 0x8f460128,
-	0xaf460020, 0x8f420104, 0x8f450100, 0x24030800, 0x3c040010, 0xaf820000,
-	0x00441024, 0xaf85000c, 0xaf4301b8, 0x14400005, 0x3c02001f, 0x3c030800,
-	0x8c620020, 0x0a0003d5, 0x00002021, 0x3442ff00, 0x14c20009, 0x2402bfff,
-	0x3c030800, 0x8c620020, 0x24040001, 0x24420001, 0x0e00004c, 0xac620020,
-	0x0a0003e4, 0x00000000, 0x00a21024, 0x14400006, 0x00000000, 0xaf400048,
-	0x0e000448, 0xaf400040, 0x0a0003e4, 0x00000000, 0x0e000783, 0x00000000,
-	0x10400005, 0x3c024000, 0x8f430124, 0x3c026020, 0xac430014, 0x3c024000,
-	0xaf420138, 0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe0,
+	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, 0x0a00040e, 0x3c038000, 0x12020007,
-	0x00000000, 0x0a00041b, 0x00000000, 0x0e000423, 0x00000000, 0x0a00040c,
-	0x00402021, 0x0e000435, 0x00000000, 0x00402021, 0x36053000, 0x3c038000,
+	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, 0x0a00041f,
-	0x8fbf0018, 0x0000000d, 0x00000000, 0x240001c3, 0x8fbf0018, 0x8fb10014,
+	0xa6240010, 0x8f420144, 0x3c031000, 0xae220024, 0xaf4301b8, 0x0a00111b,
+	0x8fbf0018, 0x0000000d, 0x00000000, 0x24000295, 0x8fbf0018, 0x8fb10014,
 	0x8fb00010, 0x03e00008, 0x27bd0020, 0x3084ffff, 0x2c821389, 0x1040000d,
-	0x00001021, 0x3c030800, 0x24632100, 0x00042942, 0x00052880, 0x00a32821,
+	0x00001021, 0x3c030800, 0x24635680, 0x00042942, 0x00052880, 0x00a32821,
 	0x3086001f, 0x8ca40000, 0x24030001, 0x00c31804, 0x00832025, 0x03e00008,
 	0xaca40000, 0x03e00008, 0x24020091, 0x3084ffff, 0x2c821389, 0x1040000e,
-	0x00001021, 0x3c030800, 0x24632100, 0x00042942, 0x00052880, 0x00a32821,
+	0x00001021, 0x3c030800, 0x24635680, 0x00042942, 0x00052880, 0x00a32821,
 	0x3086001f, 0x24030001, 0x8ca40000, 0x00c31804, 0x00031827, 0x00832024,
-	0x03e00008, 0xaca40000, 0x03e00008, 0x24020091, 0x27bdffb0, 0x3c026000,
-	0xafbf0048, 0x8c434448, 0xaf630140, 0x93620005, 0x30420001, 0x14400005,
-	0x00000000, 0x0e0007ed, 0x00000000, 0x0a00067a, 0x8fbf0048, 0x93420116,
-	0x93430112, 0x8f430104, 0x3c040020, 0x34424000, 0x00641824, 0x1060000d,
-	0x03426021, 0x8f430128, 0x27420180, 0xac430000, 0x8f650040, 0x24040008,
-	0x240340c1, 0xa4430008, 0x24030002, 0xa043000b, 0x3c031000, 0x0a000563,
-	0xa044000a, 0x8f420104, 0x3c030040, 0x00431024, 0x10400007, 0x00000000,
-	0x8f430128, 0x27420180, 0xac430000, 0x8f650040, 0x0a00055c, 0x24040010,
-	0xaf400048, 0xaf400054, 0xaf400040, 0x8f630048, 0x8f620040, 0x00624823,
-	0x05210004, 0x00000000, 0x0000000d, 0x00000000, 0x24000132, 0x9742011a,
-	0x3046ffff, 0x10c00004, 0x8d880004, 0x01061021, 0x0a000487, 0x2445ffff,
-	0x01002821, 0x918a000d, 0xa7a00020, 0xafa00028, 0x9364003f, 0x3c026000,
-	0x8c434448, 0x308700ff, 0x31420004, 0x10400033, 0xaf630144, 0x24090012,
-	0x14e90006, 0x3c040800, 0x8c830028, 0x24020001, 0x24630001, 0x0a00054e,
-	0xac830028, 0x8f620044, 0x15020012, 0x97a20020, 0x27a60010, 0x27450180,
-	0x3442001a, 0xa7a20020, 0x8f630040, 0x3c048000, 0x24020020, 0xa3a70022,
-	0xa3a90023, 0xa3a2001a, 0xafa30028, 0x8f4201b8, 0x00441024, 0x1440fffd,
-	0x00000000, 0x0a000533, 0x00000000, 0x8f620044, 0x01021023, 0x0440009e,
-	0x24020001, 0x8f620048, 0x01021023, 0x0441009a, 0x24020001, 0x97a20020,
-	0x27a60010, 0x34420001, 0xa7a20020, 0x8f630040, 0x27450180, 0x3c048000,
-	0xafa30028, 0x8f4201b8, 0x00441024, 0x1440fffd, 0x00000000, 0x0a000533,
-	0x00000000, 0x3c026000, 0x8c424448, 0xaf620148, 0x8f630040, 0x00685823,
-	0x19600013, 0x00cb102a, 0x54400007, 0x314a00fe, 0x5566000c, 0x010b4021,
-	0x31420001, 0x54400009, 0x010b4021, 0x314a00fe, 0x24020001, 0xa7a20020,
-	0x8f630040, 0x00c05821, 0x00003021, 0x0a0004dd, 0xafa30028, 0x00cb1023,
-	0x0a0004dd, 0x3046ffff, 0x00005821, 0x8f620048, 0x2442ffff, 0x00a21823,
-	0x18600019, 0x0066102a, 0x14400013, 0x24020001, 0xa7a20020, 0x8f630040,
-	0xafa30028, 0x8f620040, 0x55020005, 0x27a60010, 0x55200003, 0x27a60010,
-	0x0a0004f6, 0x00c01821, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024,
-	0x1440fffd, 0x00000000, 0x0a000533, 0x00000000, 0x8f650048, 0x00c31023,
-	0x3046ffff, 0x314a00f6, 0x3c046000, 0x8c824448, 0x31430002, 0x1060001e,
-	0xaf62014c, 0x8f620044, 0x1502000e, 0x97a20020, 0x27a60010, 0x34420200,
-	0xa7a20020, 0x8f630040, 0x27450180, 0x3c048000, 0xafa30028, 0x8f4201b8,
-	0x00441024, 0x1440fffd, 0x00000000, 0x0a000533, 0x00000000, 0x27a60010,
-	0x34420001, 0xa7a20020, 0x8f630040, 0x27450180, 0x3c048000, 0xafa30028,
-	0x8f4201b8, 0x00441024, 0x1440fffd, 0x00000000, 0x0a000533, 0x00000000,
-	0x3c026000, 0x8c424448, 0x31430010, 0xaf620150, 0x54600003, 0x8d890008,
-	0x0a00054e, 0x24020001, 0x8f630054, 0x2522ffff, 0x00431023, 0x1840002a,
-	0x24020001, 0x27a60010, 0xa7a20020, 0x8f630040, 0x27450180, 0x3c048000,
-	0xafa30028, 0x8f4201b8, 0x00441024, 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, 0x0a00067a, 0x8fbf0048,
-	0x3c026000, 0x8c424448, 0x31430020, 0x10600019, 0xaf620154, 0x8f430128,
-	0x27420180, 0xac430000, 0x8f650040, 0x24040004, 0x240340c1, 0xa4430008,
-	0x24030002, 0xa044000a, 0x24040008, 0xa043000b, 0x3c031000, 0xa4440010,
-	0xa0400012, 0xa0400013, 0xac400014, 0xac400024, 0xac400028, 0xac40002c,
-	0xac450018, 0x0e0007ed, 0xaf4301b8, 0x0a00067a, 0x8fbf0048, 0x8f430104,
-	0x8c824448, 0x38e3000a, 0x2c630001, 0xaf620158, 0x38e2000c, 0x2c420001,
-	0x00621825, 0x14600003, 0x2402000e, 0x14e2002a, 0x00000000, 0x50c00008,
-	0x9584000e, 0x10c00004, 0xa7a60040, 0x01061021, 0x0a000583, 0x2445ffff,
-	0x01002821, 0x9584000e, 0x93630035, 0x8f62004c, 0x00642004, 0x00892021,
-	0x00821023, 0x1840001f, 0x3c026000, 0x8f620018, 0x01021023, 0x1c40000f,
-	0x97a20020, 0x8f620018, 0x15020018, 0x3c026000, 0x8f62001c, 0x01221023,
-	0x1c400008, 0x97a20020, 0x8f62001c, 0x15220011, 0x3c026000, 0x8f620058,
-	0x00821023, 0x1840000c, 0x97a20020, 0xafa50028, 0xafa80034, 0xafa90038,
-	0xafa4003c, 0x34420020, 0x0a0005a8, 0xa7a20020, 0x8f680040, 0x00003021,
-	0x8f640058, 0x01002821, 0x3c026000, 0x8c434448, 0xaf63015c, 0x8f62004c,
-	0x01221023, 0x18400009, 0x00000000, 0x8f620054, 0x01221023, 0x1c400005,
-	0x97a20020, 0xafa50028, 0xafa90024, 0x0a0005c3, 0x34420040, 0x9742011a,
-	0x1440000c, 0x24020014, 0x8f620058, 0x14820009, 0x24020014, 0x8f63004c,
-	0x8f620054, 0x10620004, 0x97a20020, 0xafa50028, 0x34420080, 0xa7a20020,
-	0x24020014, 0x10e2000a, 0x28e20015, 0x10400005, 0x2402000c, 0x10e20006,
-	0x3c026000, 0x0a000600, 0x00000000, 0x24020016, 0x14e20031, 0x3c026000,
-	0x8f620054, 0x24420001, 0x1522002d, 0x3c026000, 0x24020014, 0x10e2001e,
-	0x28e20015, 0x10400005, 0x2402000c, 0x10e20008, 0x3c026000, 0x0a000600,
-	0x00000000, 0x24020016, 0x10e2000c, 0x97a20020, 0x0a000600, 0x3c026000,
-	0x97a30020, 0x2402000e, 0xafa50028, 0xa3a70022, 0xa3a20023, 0xafa90024,
-	0x34630054, 0x0a0005ff, 0xa7a30020, 0x24030010, 0x24040002, 0xafa50028,
-	0xa3a70022, 0xa3a30023, 0xa3a4001a, 0xafa90024, 0x0a0005fe, 0x3442005d,
-	0x97a20020, 0x24030012, 0x24040002, 0xafa50028, 0xa3a70022, 0xa3a30023,
-	0xa3a4001a, 0xafa90024, 0x3042fffe, 0x3442005c, 0xa7a20020, 0x3c026000,
-	0x8c434448, 0x31420001, 0xaf630160, 0x1040002c, 0x2402000c, 0x10e20014,
-	0x28e2000d, 0x10400005, 0x2402000a, 0x10e20008, 0x97a20020, 0x0a000631,
-	0x3c026000, 0x2402000e, 0x10e20018, 0x3c026000, 0x0a000631, 0x00000000,
-	0x24030008, 0x24040002, 0xafa50028, 0xa3a70022, 0xa3a30023, 0xa3a4001a,
-	0x0a00062f, 0x34420013, 0x97a30020, 0x30620004, 0x1440000b, 0x97a20020,
-	0x3462001b, 0xa7a20020, 0x24020016, 0x24030002, 0xafa50028, 0xa3a70022,
-	0xa3a20023, 0x0a000630, 0xa3a3001a, 0x97a20020, 0x24030010, 0x24040002,
-	0xafa50028, 0xa3a70022, 0xa3a30023, 0xa3a4001a, 0x3442001b, 0xa7a20020,
-	0x3c026000, 0x8c434448, 0x31420009, 0x0002102b, 0x00021023, 0x30420007,
-	0x34440003, 0xaf630164, 0x10c00016, 0x24030800, 0x8f820010, 0x27450180,
-	0x24420001, 0xaf820010, 0x24020004, 0xaf4301b8, 0xa4a40008, 0xa0a2000b,
-	0x93440120, 0x3c031000, 0xa4a6000e, 0xaca90024, 0xaca80028, 0x008b2021,
-	0xa4a4000c, 0xaf4301b8, 0x97a20020, 0x00003021, 0x3042ffbf, 0x0a000650,
-	0xa7a20020, 0x24060001, 0x3c026000, 0x8c434448, 0xaf630168, 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, 0x3c026000, 0x8c434448, 0x00c01021,
-	0xaf63016c, 0x8fbf0048, 0x03e00008, 0x27bd0050, 0x8f460140, 0x8f470148,
-	0x3c028000, 0x00e24024, 0x00072c02, 0x30a300ff, 0x2402000b, 0x1062008f,
-	0x27440180, 0x2862000c, 0x10400011, 0x24020006, 0x1062005a, 0x28620007,
-	0x10400007, 0x24020008, 0x10600024, 0x24020001, 0x10620037, 0x00000000,
-	0x0a00077e, 0x00000000, 0x106200a9, 0x24020009, 0x106200bb, 0x00071c02,
-	0x0a00077e, 0x00000000, 0x2402001b, 0x106200c7, 0x2862001c, 0x10400007,
-	0x2402000e, 0x106200b1, 0x24020019, 0x106200c2, 0x00071c02, 0x0a00077e,
-	0x00000000, 0x24020080, 0x10620060, 0x28620081, 0x10400005, 0x2402001c,
-	0x10620094, 0x00071c02, 0x0a00077e, 0x00000000, 0x240200c2, 0x106200c5,
-	0x00a01821, 0x0a00077e, 0x00000000, 0x00a01821, 0x3c058000, 0x8f4201b8,
-	0x00451024, 0x1440fffd, 0x24020001, 0xa4830008, 0x24030002, 0xac860000,
-	0xac800004, 0xa082000a, 0xa083000b, 0xa4870010, 0x8f430144, 0x3c021000,
+	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,
+	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, 0xa0434490, 0x24424490,
-	0xac460008, 0x8f430144, 0x03e00008, 0xac430004, 0x3c058000, 0x8f4201b8,
-	0x00451024, 0x1440fffd, 0x24020002, 0xac800000, 0xac860004, 0xa4830008,
-	0xa082000a, 0xa082000b, 0xa4870010, 0xac800024, 0x8f420144, 0x3c031000,
-	0xac820028, 0x3c026000, 0xaf4301b8, 0x03e00008, 0xac400808, 0x00a01821,
-	0x3c080800, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x00000000,
-	0xac860000, 0x91024490, 0x00002821, 0x10400002, 0x25064490, 0x8cc50008,
-	0xac850004, 0xa4830008, 0x91034490, 0x24020002, 0xa082000b, 0xa4870010,
-	0x34630001, 0xa083000a, 0x8f420144, 0xac820024, 0x91034490, 0x10600002,
-	0x00001021, 0x8cc20004, 0xac820028, 0x3c021000, 0xaf4201b8, 0x3c026000,
-	0xa1004490, 0x03e00008, 0xac400808, 0x00a01821, 0x3c058000, 0x8f4201b8,
-	0x00451024, 0x1440fffd, 0x24020002, 0xa082000b, 0xa4830008, 0xa4870010,
-	0x8f420144, 0x3c031000, 0xa4820012, 0x03e00008, 0xaf4301b8, 0x30e2ffff,
-	0x14400028, 0x00071c02, 0x93620005, 0x30420004, 0x14400020, 0x3c029000,
-	0x34420001, 0x00c21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
-	0x1440fffd, 0x00000000, 0x93620005, 0x3c038000, 0x34630001, 0x00c31825,
-	0x34420004, 0xa3620005, 0xaf430020, 0x93620005, 0x30420004, 0x14400003,
-	0x3c038000, 0x0000000d, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd,
-	0x24020005, 0x3c031000, 0xac860000, 0xa082000b, 0xaf4301b8, 0x0a00073d,
-	0x00071c02, 0x0000000d, 0x03e00008, 0x00000000, 0x00071c02, 0x3c058000,
-	0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020001, 0xa4830008, 0x24030002,
-	0xac860000, 0xac800004, 0xa082000a, 0xa083000b, 0xa4870010, 0x8f430144,
-	0x3c021000, 0xac800028, 0xac830024, 0x03e00008, 0xaf4201b8, 0x00071c02,
-	0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020002, 0xac800000,
-	0xac860004, 0xa4830008, 0xa082000a, 0xa082000b, 0xa4870010, 0xac800024,
-	0x8f420144, 0x3c031000, 0xac820028, 0x03e00008, 0xaf4301b8, 0x00071c02,
-	0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020001, 0xa4830008,
-	0x24030002, 0xa082000a, 0x3c021000, 0xac860000, 0xac800004, 0xa083000b,
-	0xa4870010, 0xac800024, 0xac800028, 0x03e00008, 0xaf4201b8, 0x3c058000,
-	0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020002, 0xac860000, 0xac800004,
-	0xa4830008, 0xa080000a, 0x0a000748, 0xa082000b, 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, 0x3c029000, 0x34420001, 0x00822025, 0xaf440020, 0x3c038000,
-	0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x03e00008, 0x00000000,
-	0x3c028000, 0x34420001, 0x00822025, 0x03e00008, 0xaf440020, 0x8f430128,
-	0x27420180, 0xac430000, 0x8f650040, 0x240340c1, 0xa4430008, 0x24030002,
-	0xa044000a, 0x24040008, 0xa043000b, 0x3c031000, 0xa4440010, 0xa0400012,
-	0xa0400013, 0xac400014, 0xac400024, 0xac400028, 0xac40002c, 0xac450018,
-	0x03e00008, 0xaf4301b8, 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, 0x0e000326, 0x00000000, 0x00002021,
-	0x0e00004c, 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, 0x0a000816, 0xa0a2000a, 0xa0a0000a,
-	0x3c021000, 0x03e00008, 0xaf4201b8, 0x03e00008, 0x00001021, 0x10c00007,
-	0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000, 0x14c0fffb,
-	0x24840004, 0x03e00008, 0x00000000, 0x0a00082a, 0x00a01021, 0xac860000,
-	0x24840004, 0x00a01021, 0x1440fffc, 0x24a5ffff, 0x03e00008, 0x00000000,
-	0x00000000 }; 
+	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 };
 
-static u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x00000000 };
-static u32 bnx2_RXP_b06FwRodata[(0x0/4) + 1] = { 0x00000000 };
-static u32 bnx2_RXP_b06FwBss[(0x239c/4) + 1] = { 0x00000000 };
-static u32 bnx2_RXP_b06FwSbss[(0x14/4) + 1] = { 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_rv2p_proc1[] = {
 	0x00000008, 0xac000001, 0x0000000c, 0x2f800001, 0x00000010, 0x213f0004,
@@ -1536,249 +2298,453 @@
 	0x0000000c, 0x29520000, 0x00000018, 0x80000002, 0x0000000c, 0x29800000,
 	0x00000018, 0x00570000 };
 
-static int bnx2_TPAT_b06FwReleaseMajor = 0x0;
+static int bnx2_TPAT_b06FwReleaseMajor = 0x1;
 static int bnx2_TPAT_b06FwReleaseMinor = 0x0;
 static int bnx2_TPAT_b06FwReleaseFix = 0x0;
-static u32 bnx2_TPAT_b06FwStartAddr = 0x08000858;
+static u32 bnx2_TPAT_b06FwStartAddr = 0x08000860;
 static u32 bnx2_TPAT_b06FwTextAddr = 0x08000800;
-static int bnx2_TPAT_b06FwTextLen = 0x1314;
-static u32 bnx2_TPAT_b06FwDataAddr = 0x08001b40;
+static int bnx2_TPAT_b06FwTextLen = 0x122c;
+static u32 bnx2_TPAT_b06FwDataAddr = 0x08001a60;
 static int bnx2_TPAT_b06FwDataLen = 0x0;
 static u32 bnx2_TPAT_b06FwRodataAddr = 0x00000000;
 static int bnx2_TPAT_b06FwRodataLen = 0x0;
-static u32 bnx2_TPAT_b06FwBssAddr = 0x08001b90;
-static int bnx2_TPAT_b06FwBssLen = 0x80;
-static u32 bnx2_TPAT_b06FwSbssAddr = 0x08001b40;
-static int bnx2_TPAT_b06FwSbssLen = 0x48;
-
-static u32 bnx2_TPAT_b06FwText[(0x1314/4) + 1] = {
-	0x0a000216, 0x00000000, 0x00000000, 0x0000000d, 0x74706174, 0x20302e36,
-	0x2e390000, 0x00060901, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+static u32 bnx2_TPAT_b06FwBssAddr = 0x08001aa0;
+static int bnx2_TPAT_b06FwBssLen = 0x250;
+static u32 bnx2_TPAT_b06FwSbssAddr = 0x08001a60;
+static int bnx2_TPAT_b06FwSbssLen = 0x34;
+static u32 bnx2_TPAT_b06FwText[(0x122c/4) + 1] = {
+	0x0a000218, 0x00000000, 0x00000000, 0x0000000d, 0x74706174, 0x20322e35,
+	0x2e313100, 0x02050b01, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
-	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x10000003,
-	0x00000000, 0x0000000d, 0x0000000d, 0x3c020800, 0x24421b40, 0x3c030800,
-	0x24631c10, 0xac400000, 0x0043202b, 0x1480fffd, 0x24420004, 0x3c1d0800,
-	0x37bd3ffc, 0x03a0f021, 0x3c100800, 0x26100858, 0x3c1c0800, 0x279c1b40,
-	0x0e00051f, 0x00000000, 0x0000000d, 0x8f820024, 0x27bdffe8, 0xafbf0014,
-	0x10400004, 0xafb00010, 0x0000000d, 0x00000000, 0x2400015f, 0x8f82001c,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800,
+	0x24421a60, 0x3c030800, 0x24631cf0, 0xac400000, 0x0043202b, 0x1480fffd,
+	0x24420004, 0x3c1d0800, 0x37bd2ffc, 0x03a0f021, 0x3c100800, 0x26100860,
+	0x3c1c0800, 0x279c1a60, 0x0e000546, 0x00000000, 0x0000000d, 0x8f820010,
 	0x8c450008, 0x24030800, 0xaf430178, 0x97430104, 0x3c020008, 0xaf420140,
-	0x8f820034, 0x30420001, 0x10400006, 0x3070ffff, 0x24020002, 0x2603fffe,
-	0xa7420146, 0x0a000246, 0xa7430148, 0xa7400146, 0x8f850034, 0x30a20020,
-	0x0002102b, 0x00021023, 0x30460009, 0x30a30c00, 0x24020400, 0x14620002,
-	0x34c40001, 0x34c40005, 0xa744014a, 0x3c020800, 0x8c440820, 0x3c030048,
-	0x24020002, 0x00832025, 0x30a30006, 0x1062000d, 0x2c620003, 0x50400005,
-	0x24020004, 0x10600012, 0x3c020001, 0x0a000271, 0x00000000, 0x10620007,
-	0x24020006, 0x1462000f, 0x3c020111, 0x0a000269, 0x00821025, 0x0a000268,
-	0x3c020101, 0x3c020011, 0x00821025, 0x24030001, 0xaf421000, 0xaf830030,
-	0x0a000271, 0x00000000, 0x00821025, 0xaf421000, 0xaf800030, 0x00000000,
-	0x00000000, 0x00000000, 0x00000000, 0x8f830030, 0x1060003f, 0x3c048000,
-	0x8f421000, 0x00441024, 0x1040fffd, 0x00000000, 0x10600039, 0x00000000,
-	0x8f421000, 0x3c030020, 0x00431024, 0x10400034, 0x00000000, 0x97421014,
-	0x14400031, 0x00000000, 0x97421008, 0x8f84001c, 0x24420006, 0x00024082,
-	0x00081880, 0x00643821, 0x8ce50000, 0x30430003, 0x30420001, 0x10400004,
-	0x00000000, 0x0000000d, 0x0a0002b0, 0x00081080, 0x5460000f, 0x30a5ffff,
-	0x3c06ffff, 0x00a62824, 0x0005182b, 0x00a61026, 0x0002102b, 0x00621824,
-	0x10600004, 0x00000000, 0x0000000d, 0x00000000, 0x240001fc, 0x8ce20000,
-	0x0a0002af, 0x00462825, 0x0005182b, 0x38a2ffff, 0x0002102b, 0x00621824,
-	0x10600004, 0x00000000, 0x0000000d, 0x00000000, 0x24000206, 0x8ce20000,
-	0x3445ffff, 0x00081080, 0x00441021, 0x3c030800, 0xac450000, 0x8c620840,
-	0x24420001, 0xac620840, 0x8f820008, 0x10400003, 0x00000000, 0x0e000660,
-	0x00000000, 0x8f840028, 0x02002821, 0x24820008, 0x30421fff, 0x24434000,
-	0x0343d821, 0x30a30007, 0xaf840018, 0xaf820028, 0xaf420084, 0x10600002,
-	0x24a20007, 0x3045fff8, 0x8f820044, 0x8f840004, 0x00451821, 0xaf82002c,
-	0x0064102b, 0xaf830044, 0x14400002, 0x00641023, 0xaf820044, 0x8f840044,
-	0x34028000, 0x8fbf0014, 0x8fb00010, 0x00821021, 0x03421821, 0x3c021000,
-	0xaf83001c, 0xaf440080, 0xaf420178, 0x03e00008, 0x27bd0018, 0x8f820024,
-	0x27bdffe8, 0xafbf0014, 0x10400004, 0xafb00010, 0x0000000d, 0x00000000,
-	0x24000249, 0x8f85001c, 0x24020001, 0xaf820024, 0x8ca70008, 0xa3800023,
-	0x8f620004, 0x3c100800, 0x26041b90, 0x00021402, 0xa3820010, 0x304600ff,
-	0x24c60005, 0x0e00064a, 0x00063082, 0x8f640004, 0x8f430108, 0x3c021000,
-	0x00621824, 0xa7840020, 0x10600008, 0x00000000, 0x97420104, 0x93830023,
-	0x2442ffec, 0x34630002, 0xa3830023, 0x0a000304, 0x3045ffff, 0x97420104,
-	0x2442fff0, 0x3045ffff, 0x8f620004, 0x3042ffff, 0x2c420013, 0x14400004,
-	0x00000000, 0x93820023, 0x34420001, 0xa3820023, 0x93830023, 0x24020001,
-	0x10620009, 0x28620002, 0x14400014, 0x24020002, 0x10620012, 0x24020003,
-	0x1062000a, 0x00000000, 0x0a000325, 0x00000000, 0x8f82001c, 0x8c43000c,
-	0x3c04ffff, 0x00641824, 0x00651825, 0x0a000325, 0xac43000c, 0x8f82001c,
-	0x8c430010, 0x3c04ffff, 0x00641824, 0x00651825, 0xac430010, 0x8f620004,
-	0x3042ffff, 0x24420002, 0x00021083, 0xa3820038, 0x304500ff, 0x8f82001c,
-	0x3c04ffff, 0x00052880, 0x00a22821, 0x8ca70000, 0x97820020, 0x97430104,
-	0x00e42024, 0x24420002, 0x00621823, 0x00833825, 0xaca70000, 0x93840038,
-	0x26061b90, 0x00041080, 0x00461021, 0x90430000, 0x3063000f, 0x00832021,
-	0xa3840022, 0x308200ff, 0x3c04fff6, 0x24420003, 0x00021080, 0x00461021,
-	0x8c450000, 0x93830022, 0x8f82001c, 0x3484ffff, 0x00a43824, 0x00031880,
-	0x00621821, 0xaf850000, 0xac67000c, 0x93820022, 0x93830022, 0x8f84001c,
-	0x24420003, 0x00021080, 0x00461021, 0x24630004, 0x00031880, 0xac470000,
-	0x93820022, 0x00661821, 0x94670002, 0x00021080, 0x00441021, 0xac670000,
-	0x24030010, 0xac470010, 0xa7430140, 0x24030002, 0xa7400142, 0xa7400144,
-	0xa7430146, 0x97420104, 0x8f840034, 0x24030001, 0x2442fffe, 0x30840006,
-	0xa7420148, 0x24020002, 0xa743014a, 0x1082000d, 0x2c820003, 0x10400005,
-	0x24020004, 0x10800011, 0x3c020009, 0x0a000383, 0x00000000, 0x10820007,
-	0x24020006, 0x1482000d, 0x3c020119, 0x0a00037d, 0x24030001, 0x0a00037c,
-	0x3c020109, 0x3c020019, 0x24030001, 0xaf421000, 0xaf830030, 0x0a000383,
-	0x00000000, 0xaf421000, 0xaf800030, 0x00000000, 0x00000000, 0x00000000,
-	0x00000000, 0x93820010, 0x24030008, 0x8f840030, 0x24420002, 0x30420007,
-	0x00621823, 0x30630007, 0xaf83000c, 0x10800005, 0x3c038000, 0x8f421000,
-	0x00431024, 0x1040fffd, 0x00000000, 0x8f820028, 0xaf820018, 0x24420010,
-	0x30421fff, 0xaf820028, 0xaf420084, 0x97430104, 0x24424000, 0x0342d821,
-	0x3063ffff, 0x30620007, 0x10400002, 0x24620007, 0x3043fff8, 0x8f820044,
-	0x8f840004, 0x00431821, 0xaf82002c, 0x0064102b, 0xaf830044, 0x14400002,
-	0x00641023, 0xaf820044, 0x8f840044, 0x34028000, 0x8fbf0014, 0x8fb00010,
-	0x00821021, 0x03421821, 0x3c021000, 0xaf83001c, 0xaf440080, 0xaf420178,
-	0x03e00008, 0x27bd0018, 0x8f820024, 0x27bdffe8, 0xafbf0014, 0x14400004,
-	0xafb00010, 0x0000000d, 0x00000000, 0x240002db, 0x8f620004, 0x04410009,
-	0x3c050800, 0x93820022, 0x8f830000, 0x24a41b90, 0xaf800024, 0x24420003,
-	0x00021080, 0x00441021, 0xac430000, 0x93820038, 0x24a51b90, 0x93860010,
-	0x3c040001, 0x27700008, 0x24420001, 0x00021080, 0x00451021, 0x8c430000,
-	0x24c60005, 0x00063082, 0x00641821, 0x02002021, 0x0e00064a, 0xac430000,
-	0x93840022, 0x3c057fff, 0x8f620004, 0x00042080, 0x00902021, 0x8c830004,
-	0x34a5ffff, 0x00451024, 0x00621821, 0xac830004, 0x93850038, 0x3c07ffff,
-	0x93840010, 0x00052880, 0x00b02821, 0x8ca30000, 0x97420104, 0x97860020,
-	0x00671824, 0x00441021, 0x00461023, 0x3042ffff, 0x00621825, 0xaca30000,
-	0x93830023, 0x24020001, 0x10620009, 0x28620002, 0x1440001a, 0x24020002,
-	0x10620018, 0x24020003, 0x1062000d, 0x00000000, 0x0a000411, 0x00000000,
-	0x93820010, 0x97430104, 0x8e04000c, 0x00621821, 0x2463fff2, 0x3063ffff,
-	0x00872024, 0x00832025, 0x0a000411, 0xae04000c, 0x93820010, 0x97430104,
-	0x8e040010, 0x00621821, 0x2463ffee, 0x3063ffff, 0x00872024, 0x00832025,
-	0xae040010, 0x9783000e, 0x8f840034, 0x2402000a, 0xa7420140, 0xa7430142,
-	0x93820010, 0xa7420144, 0xa7400146, 0x97430104, 0x30840006, 0x24020001,
-	0xa7430148, 0xa742014a, 0x24020002, 0x1082000d, 0x2c820003, 0x10400005,
-	0x24020004, 0x10800011, 0x3c020041, 0x0a000437, 0x00000000, 0x10820007,
-	0x24020006, 0x1482000d, 0x3c020151, 0x0a000431, 0x24030001, 0x0a000430,
-	0x3c020141, 0x3c020051, 0x24030001, 0xaf421000, 0xaf830030, 0x0a000437,
-	0x00000000, 0xaf421000, 0xaf800030, 0x00000000, 0x00000000, 0x00000000,
-	0x00000000, 0x8f820030, 0x93840010, 0x8f850028, 0x10400005, 0x3c038000,
-	0x8f421000, 0x00431024, 0x1040fffd, 0x00000000, 0x2483000a, 0x30620007,
-	0x10400002, 0x24620007, 0x304303f8, 0x00a31021, 0x30421fff, 0xaf850018,
-	0xaf820028, 0xaf420084, 0x97430104, 0x24424000, 0x0342d821, 0x3063ffff,
-	0x30620007, 0x10400002, 0x24620007, 0x3043fff8, 0x8f820044, 0x8f840004,
-	0x00431821, 0xaf82002c, 0x0064102b, 0xaf830044, 0x14400002, 0x00641023,
-	0xaf820044, 0x8f840044, 0x34028000, 0x8fbf0014, 0x8fb00010, 0x00821021,
-	0x03421821, 0x3c021000, 0xaf83001c, 0xaf440080, 0xaf420178, 0x03e00008,
-	0x27bd0018, 0x3c026000, 0x8c444448, 0x3c030800, 0xac64082c, 0x8f620000,
-	0x97430104, 0x3c048000, 0x3046ffff, 0x3067ffff, 0x8f420178, 0x00441024,
-	0x1440fffd, 0x2402000a, 0x30c30007, 0xa7420140, 0x24020008, 0x00431023,
-	0x30420007, 0x24c3fffe, 0xa7420142, 0xa7430144, 0xa7400146, 0xa7470148,
-	0x8f420108, 0x3c036000, 0x8f850034, 0x30420020, 0x0002102b, 0x00021023,
-	0x30420009, 0x34420001, 0xa742014a, 0x8c644448, 0x3c020800, 0x30a50006,
-	0xac440830, 0x24020002, 0x10a2000d, 0x2ca20003, 0x10400005, 0x24020004,
-	0x10a00011, 0x3c020041, 0x0a0004a8, 0x00000000, 0x10a20007, 0x24020006,
-	0x14a2000d, 0x3c020151, 0x0a0004a2, 0x24030001, 0x0a0004a1, 0x3c020141,
-	0x3c020051, 0x24030001, 0xaf421000, 0xaf830030, 0x0a0004a8, 0x00000000,
-	0xaf421000, 0xaf800030, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
-	0x8f820030, 0x24c30008, 0x10400006, 0x30e6ffff, 0x3c048000, 0x8f421000,
-	0x00441024, 0x1040fffd, 0x00000000, 0x3c026000, 0x8c444448, 0x3065ffff,
-	0x3c020800, 0x30a30007, 0x10600003, 0xac440834, 0x24a20007, 0x3045fff8,
-	0x8f840028, 0x00851021, 0x30421fff, 0x24434000, 0x0343d821, 0x30c30007,
-	0xaf840018, 0xaf820028, 0xaf420084, 0x10600002, 0x24c20007, 0x3046fff8,
-	0x8f820044, 0x8f840004, 0x00461821, 0xaf82002c, 0x0064102b, 0xaf830044,
-	0x14400002, 0x00641023, 0xaf820044, 0x8f840044, 0x34028000, 0x3c030800,
-	0x8c650844, 0x00821021, 0x03421821, 0xaf83001c, 0xaf440080, 0x10a00006,
-	0x2402000e, 0x93830043, 0x14620004, 0x3c021000, 0x2402043f, 0xa7420148,
-	0x3c021000, 0x3c036000, 0xaf420178, 0x8c644448, 0x3c020800, 0x03e00008,
-	0xac440838, 0x8f820034, 0x30424000, 0x10400005, 0x24020800, 0x0000000d,
-	0x00000000, 0x24000405, 0x24020800, 0xaf420178, 0x97440104, 0x3c030008,
-	0xaf430140, 0x8f820034, 0x30420001, 0x10400006, 0x3085ffff, 0x24020002,
-	0x24a3fffe, 0xa7420146, 0x0a0004ff, 0xa7430148, 0xa7400146, 0x8f840028,
-	0x2402000d, 0xa742014a, 0x24830008, 0x30631fff, 0x24624000, 0x0342d821,
-	0x30a20007, 0xaf840018, 0xaf830028, 0xaf430084, 0x10400002, 0x24a20007,
-	0x3045fff8, 0x8f820044, 0x8f840004, 0x00451821, 0xaf82002c, 0x0064102b,
-	0xaf830044, 0x14400002, 0x00641023, 0xaf820044, 0x8f840044, 0x34028000,
-	0x00821021, 0x03421821, 0x3c021000, 0xaf83001c, 0xaf440080, 0x03e00008,
-	0xaf420178, 0x27bdffe8, 0x3c046008, 0xafbf0014, 0xafb00010, 0x8c825000,
-	0x3c1a8000, 0x2403ff7f, 0x375b4000, 0x00431024, 0x3442380c, 0xac825000,
-	0x8f430008, 0x3c100800, 0x37428000, 0x34630001, 0xaf430008, 0xaf82001c,
-	0x3c02601c, 0xaf800028, 0xaf400080, 0xaf400084, 0x8c450008, 0x3c036000,
-	0x8c620808, 0x3c040800, 0x3c030080, 0xac830820, 0x3042fff0, 0x38420010,
-	0x2c420001, 0xaf850004, 0xaf820008, 0x0e00062f, 0x00000000, 0x8f420000,
-	0x30420001, 0x1040fffb, 0x00000000, 0x8f440108, 0x30822000, 0xaf840034,
-	0x10400004, 0x8e02083c, 0x24420001, 0x0a00059d, 0xae02083c, 0x30820200,
-	0x10400027, 0x00000000, 0x97420104, 0x1040001c, 0x30824000, 0x14400005,
-	0x00000000, 0x0e00022d, 0x00000000, 0x0a000592, 0x00000000, 0x8f620008,
-	0x8f630000, 0x24020030, 0x00031e02, 0x306300f0, 0x10620007, 0x28620031,
-	0x14400031, 0x24020040, 0x10620007, 0x00000000, 0x0a000592, 0x00000000,
-	0x0e0002dd, 0x00000000, 0x0a000592, 0x00000000, 0x0e0003b8, 0x00000000,
-	0x0a000592, 0x00000000, 0x30820040, 0x1440002d, 0x00000000, 0x0000000d,
-	0x00000000, 0x240004a6, 0x0a00059d, 0x00000000, 0x8f430100, 0x24020d00,
-	0x1462000f, 0x30820006, 0x97420104, 0x10400005, 0x30820040, 0x0e0004e9,
-	0x00000000, 0x0a000592, 0x00000000, 0x1440001b, 0x00000000, 0x0000000d,
-	0x00000000, 0x240004b8, 0x0a00059d, 0x00000000, 0x1040000e, 0x30821000,
-	0x10400005, 0x00000000, 0x0e00065d, 0x00000000, 0x0a000592, 0x00000000,
-	0x0e00046b, 0x00000000, 0x8f820040, 0x24420001, 0xaf820040, 0x0a00059d,
-	0x00000000, 0x30820040, 0x14400004, 0x00000000, 0x0000000d, 0x00000000,
-	0x240004cf, 0x8f420138, 0x3c034000, 0x00431025, 0xaf420138, 0x0a00053f,
-	0x00000000, 0x3c046008, 0x8c835000, 0x3c1a8000, 0x2402ff7f, 0x375b4000,
-	0x00621824, 0x3463380c, 0xac835000, 0x8f420008, 0x3c056000, 0x3c03601c,
-	0x34420001, 0xaf420008, 0x37428000, 0xaf800028, 0xaf82001c, 0xaf400080,
-	0xaf400084, 0x8c660008, 0x8ca20808, 0x3c040800, 0x3c030080, 0xac830820,
-	0x3042fff0, 0x38420010, 0x2c420001, 0xaf860004, 0xaf820008, 0x03e00008,
-	0x00000000, 0x3084ffff, 0x30820007, 0x10400002, 0x24820007, 0x3044fff8,
-	0x8f820028, 0x00441821, 0x30631fff, 0x24644000, 0x0344d821, 0xaf820018,
-	0xaf830028, 0x03e00008, 0xaf430084, 0x3084ffff, 0x30820007, 0x10400002,
-	0x24820007, 0x3044fff8, 0x8f820044, 0x8f830004, 0x00442021, 0xaf82002c,
-	0x0083102b, 0xaf840044, 0x14400002, 0x00831023, 0xaf820044, 0x8f820044,
-	0x34038000, 0x00431821, 0x03432021, 0xaf84001c, 0x03e00008, 0xaf420080,
-	0x8f830034, 0x24020002, 0x30630006, 0x1062000d, 0x2c620003, 0x50400005,
-	0x24020004, 0x10600012, 0x3c020001, 0x0a000601, 0x00000000, 0x10620007,
-	0x24020006, 0x1462000f, 0x3c020111, 0x0a0005f9, 0x00821025, 0x0a0005f8,
-	0x3c020101, 0x3c020011, 0x00821025, 0x24030001, 0xaf421000, 0xaf830030,
-	0x0a000601, 0x00000000, 0x00821025, 0xaf421000, 0xaf800030, 0x00000000,
-	0x00000000, 0x00000000, 0x03e00008, 0x00000000, 0x8f820030, 0x10400005,
-	0x3c038000, 0x8f421000, 0x00431024, 0x1040fffd, 0x00000000, 0x03e00008,
-	0x00000000, 0x8f820034, 0x27bdffe8, 0x30424000, 0x14400005, 0xafbf0010,
-	0x0e00022d, 0x00000000, 0x0a00062d, 0x8fbf0010, 0x8f620008, 0x8f630000,
-	0x24020030, 0x00031e02, 0x306300f0, 0x10620008, 0x28620031, 0x1440000d,
-	0x8fbf0010, 0x24020040, 0x10620007, 0x00000000, 0x0a00062d, 0x00000000,
-	0x0e0002dd, 0x00000000, 0x0a00062d, 0x8fbf0010, 0x0e0003b8, 0x00000000,
-	0x8fbf0010, 0x03e00008, 0x27bd0018, 0x8f84003c, 0x1080000f, 0x3c026000,
-	0x8c430c3c, 0x30630fff, 0xaf830014, 0x14600011, 0x3082000f, 0x10400005,
-	0x308200f0, 0x10400003, 0x30820f00, 0x14400006, 0x00000000, 0x0000000d,
-	0x00000000, 0x2400050e, 0x03e00008, 0x00000000, 0x0000000d, 0x00000000,
-	0x24000513, 0x03e00008, 0x00000000, 0xaf83003c, 0x03e00008, 0x00000000,
-	0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000,
-	0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a000659, 0x00a01021,
-	0xac860000, 0x24840004, 0x00a01021, 0x1440fffc, 0x24a5ffff, 0x03e00008,
-	0x00000000, 0x0000000d, 0x03e00008, 0x00000000, 0x3c040800, 0x8c82084c,
-	0x54400007, 0xac80084c, 0x8f820034, 0x24030400, 0x30420c00, 0x1443005b,
-	0x00000000, 0xac80084c, 0x0000000d, 0x00000000, 0x2400003c, 0x3c026000,
-	0x8c444448, 0x3c030800, 0xac640850, 0x24000043, 0x97420104, 0x3045ffff,
-	0x000530c2, 0x24a2007f, 0x000239c2, 0x2400004e, 0x3c046020, 0x24030020,
-	0xac830000, 0x8c820000, 0x30420020, 0x10400005, 0x3c036020, 0x8c620000,
-	0x30420020, 0x1440fffd, 0x00000000, 0x3c026020, 0x8c430010, 0x24040001,
-	0x0087102b, 0x30ea007f, 0x24abfffe, 0x10400010, 0x00034240, 0x3c056020,
-	0x24090020, 0xaca90000, 0x8ca20000, 0x30420020, 0x10400006, 0x24840001,
-	0x3c036020, 0x8c620000, 0x30420020, 0x1440fffd, 0x00000000, 0x0087102b,
-	0x1440fff4, 0x00000000, 0x8f85001c, 0x3c026020, 0x8c430010, 0x3c046020,
-	0x34848000, 0x006a1825, 0x01034025, 0x2400006b, 0x10c0000b, 0x00000000,
-	0x8ca30000, 0x24a50004, 0x8ca20000, 0x24a50004, 0x24c6ffff, 0xac820000,
-	0x24840004, 0xac830000, 0x14c0fff7, 0x24840004, 0x24000077, 0x3c020007,
-	0x34427700, 0x3c036000, 0xac6223c8, 0xac6b23cc, 0xac6823e4, 0x24000086,
-	0x3c046000, 0x3c038000, 0x8c8223f8, 0x00431024, 0x1440fffd, 0x3c021000,
-	0x3c056000, 0x24030019, 0xaca223f8, 0xa743014a, 0x8ca44448, 0x3c020800,
-	0xac440854, 0x03e00008, 0x00000000, 0x00000000 };
+	0x8f820024, 0x30420001, 0x10400007, 0x3069ffff, 0x24020002, 0x2523fffe,
+	0xa7420146, 0xa7430148, 0x0a000242, 0x3c020800, 0xa7400146, 0x3c020800,
+	0x8c43083c, 0x1460000e, 0x24020f00, 0x8f820024, 0x30430020, 0x0003182b,
+	0x00031823, 0x30650009, 0x30420c00, 0x24030400, 0x14430002, 0x34a40001,
+	0x34a40005, 0xa744014a, 0x0a000264, 0x3c020800, 0x8f830014, 0x14620008,
+	0x00000000, 0x8f820024, 0x30420020, 0x0002102b, 0x00021023, 0x3042000d,
+	0x0a000262, 0x34420005, 0x8f820024, 0x30420020, 0x0002102b, 0x00021023,
+	0x30420009, 0x34420001, 0xa742014a, 0x3c020800, 0x8c430820, 0x8f840024,
+	0x3c020048, 0x00621825, 0x30840006, 0x24020002, 0x1082000d, 0x2c820003,
+	0x50400005, 0x24020004, 0x10800012, 0x3c020001, 0x0a000284, 0x00000000,
+	0x10820007, 0x24020006, 0x1482000f, 0x3c020111, 0x0a00027c, 0x00621025,
+	0x0a00027b, 0x3c020101, 0x3c020011, 0x00621025, 0x24030001, 0xaf421000,
+	0xaf830020, 0x0a000284, 0x00000000, 0x00621025, 0xaf421000, 0xaf800020,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8f830020, 0x1060003f,
+	0x3c048000, 0x8f421000, 0x00441024, 0x1040fffd, 0x00000000, 0x10600039,
+	0x00000000, 0x8f421000, 0x3c030020, 0x00431024, 0x10400034, 0x00000000,
+	0x97421014, 0x14400031, 0x00000000, 0x97421008, 0x8f840010, 0x24420006,
+	0x00024082, 0x00081880, 0x00643821, 0x8ce50000, 0x30430003, 0x30420001,
+	0x10400004, 0x00000000, 0x0000000d, 0x0a0002c3, 0x00081080, 0x5460000f,
+	0x30a5ffff, 0x3c06ffff, 0x00a62824, 0x0005182b, 0x00a61026, 0x0002102b,
+	0x00621824, 0x10600004, 0x00000000, 0x0000000d, 0x00000000, 0x240001fb,
+	0x8ce20000, 0x0a0002c2, 0x00462825, 0x0005182b, 0x38a2ffff, 0x0002102b,
+	0x00621824, 0x10600004, 0x00000000, 0x0000000d, 0x00000000, 0x24000205,
+	0x8ce20000, 0x3445ffff, 0x00081080, 0x00441021, 0x3c030800, 0xac450000,
+	0x8c620830, 0x24420001, 0xac620830, 0x8f840018, 0x01202821, 0x24820008,
+	0x30421fff, 0x24434000, 0x0343d821, 0x30a30007, 0xaf84000c, 0xaf820018,
+	0xaf420084, 0x10600002, 0x24a20007, 0x3045fff8, 0x8f820030, 0x8f840000,
+	0x00451821, 0xaf82001c, 0x0064102b, 0xaf830030, 0x14400002, 0x00641023,
+	0xaf820030, 0x8f840030, 0x34028000, 0x00821021, 0x03421821, 0x3c021000,
+	0xaf830010, 0xaf440080, 0x03e00008, 0xaf420178, 0x8f830024, 0x27bdffe0,
+	0xafbf0018, 0xafb10014, 0x30620200, 0x14400004, 0xafb00010, 0x0000000d,
+	0x00000000, 0x24000242, 0x00031a82, 0x30630003, 0x000310c0, 0x00431021,
+	0x00021080, 0x00431021, 0x00021080, 0x3c030800, 0x24631aa0, 0x00438821,
+	0x8e240000, 0x10800004, 0x00000000, 0x0000000d, 0x00000000, 0x2400024d,
+	0x8f850010, 0x24020001, 0xae220000, 0x8ca70008, 0xa2200007, 0x8f620004,
+	0x26300014, 0x02002021, 0x00021402, 0xa2220004, 0x304600ff, 0x24c60005,
+	0x0e000673, 0x00063082, 0x8f620004, 0xa6220008, 0x8f430108, 0x3c021000,
+	0x00621824, 0x10600008, 0x00000000, 0x97420104, 0x92230007, 0x2442ffec,
+	0x3045ffff, 0x34630002, 0x0a000321, 0xa2230007, 0x97420104, 0x2442fff0,
+	0x3045ffff, 0x8f620004, 0x3042ffff, 0x2c420013, 0x54400005, 0x92230007,
+	0x92220007, 0x34420001, 0xa2220007, 0x92230007, 0x24020001, 0x10620009,
+	0x28620002, 0x14400014, 0x24020002, 0x10620012, 0x24020003, 0x1062000a,
+	0x00000000, 0x0a000342, 0x00000000, 0x8f820010, 0x8c43000c, 0x3c04ffff,
+	0x00641824, 0x00651825, 0x0a000342, 0xac43000c, 0x8f820010, 0x8c430010,
+	0x3c04ffff, 0x00641824, 0x00651825, 0xac430010, 0x8f620004, 0x3042ffff,
+	0x24420002, 0x00021083, 0xa2220005, 0x304500ff, 0x8f820010, 0x3c04ffff,
+	0x00052880, 0x00a22821, 0x8ca70000, 0x96220008, 0x97430104, 0x00e42024,
+	0x24420002, 0x00621823, 0x00833825, 0xaca70000, 0x92240005, 0x00041080,
+	0x02021021, 0x90430000, 0x3c05fff6, 0x34a5ffff, 0x3063000f, 0x00832021,
+	0xa2240006, 0x308200ff, 0x24420003, 0x00021080, 0x02021021, 0x8c460000,
+	0x308300ff, 0x8f820010, 0x3c04ff3f, 0x00031880, 0x00c53824, 0x00621821,
+	0xae26000c, 0xac67000c, 0x8e22000c, 0x92230006, 0x3484ffff, 0x00441024,
+	0x24630003, 0x00031880, 0x02031821, 0x00e42024, 0xae22000c, 0xac640000,
+	0x92220006, 0x24420004, 0x00021080, 0x02021021, 0x94470002, 0xac470000,
+	0x92230006, 0x8f820010, 0x00031880, 0x00621821, 0x24020010, 0xac670010,
+	0x24030002, 0xa7420140, 0xa7400142, 0xa7400144, 0xa7430146, 0x97420104,
+	0x24030001, 0x2442fffe, 0xa7420148, 0xa743014a, 0x8f820024, 0x24030002,
+	0x30440006, 0x1083000d, 0x2c820003, 0x10400005, 0x24020004, 0x10800011,
+	0x3c020009, 0x0a0003a5, 0x00000000, 0x10820007, 0x24020006, 0x1482000d,
+	0x3c020119, 0x0a00039f, 0x24030001, 0x0a00039e, 0x3c020109, 0x3c020019,
+	0x24030001, 0xaf421000, 0xaf830020, 0x0a0003a5, 0x00000000, 0xaf421000,
+	0xaf800020, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x92220004,
+	0x24030008, 0x8f840020, 0x24420002, 0x30420007, 0x00621823, 0x30630007,
+	0x10800006, 0xae230010, 0x3c038000, 0x8f421000, 0x00431024, 0x1040fffd,
+	0x00000000, 0x8f820018, 0xaf82000c, 0x24420010, 0x30421fff, 0xaf820018,
+	0xaf420084, 0x97430104, 0x24424000, 0x0342d821, 0x3063ffff, 0x30620007,
+	0x10400002, 0x24620007, 0x3043fff8, 0x8f820030, 0x8f840000, 0x00431821,
+	0xaf82001c, 0x0064102b, 0xaf830030, 0x14400002, 0x00641023, 0xaf820030,
+	0x8f840030, 0x34028000, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x00821021,
+	0x03421821, 0x3c021000, 0xaf830010, 0xaf440080, 0xaf420178, 0x03e00008,
+	0x27bd0020, 0x8f830024, 0x27bdffe0, 0xafbf0018, 0xafb10014, 0x30620200,
+	0x14400004, 0xafb00010, 0x0000000d, 0x00000000, 0x240002e4, 0x00031a82,
+	0x30630003, 0x000310c0, 0x00431021, 0x00021080, 0x00431021, 0x00021080,
+	0x3c030800, 0x24631aa0, 0x00438021, 0x8e040000, 0x14800004, 0x00000000,
+	0x0000000d, 0x00000000, 0x240002e9, 0x8f620004, 0x04410008, 0x26050014,
+	0x92020006, 0x8e03000c, 0x24420003, 0x00021080, 0x00a21021, 0xac430000,
+	0xae000000, 0x92020005, 0x24420001, 0x00021080, 0x00a21021, 0x8c430000,
+	0x3c040001, 0x00641821, 0xac430000, 0x92060004, 0x27710008, 0x02202021,
+	0x24c60005, 0x0e000673, 0x00063082, 0x92040006, 0x3c057fff, 0x8f620004,
+	0x00042080, 0x00912021, 0x8c830004, 0x34a5ffff, 0x00451024, 0x00621821,
+	0xac830004, 0x92050005, 0x3c07ffff, 0x92040004, 0x00052880, 0x00b12821,
+	0x8ca30000, 0x97420104, 0x96060008, 0x00671824, 0x00441021, 0x00461023,
+	0x3042ffff, 0x00621825, 0xaca30000, 0x92030007, 0x24020001, 0x1062000a,
+	0x28620002, 0x1440001d, 0x2402000a, 0x24020002, 0x10620019, 0x24020003,
+	0x1062000e, 0x2402000a, 0x0a000447, 0x00000000, 0x92020004, 0x97430104,
+	0x8e24000c, 0x00621821, 0x2463fff2, 0x3063ffff, 0x00872024, 0x00832025,
+	0xae24000c, 0x0a000447, 0x2402000a, 0x92020004, 0x97430104, 0x8e240010,
+	0x00621821, 0x2463ffee, 0x3063ffff, 0x00872024, 0x00832025, 0xae240010,
+	0x2402000a, 0xa7420140, 0x96030012, 0x8f840024, 0xa7430142, 0x92020004,
+	0xa7420144, 0xa7400146, 0x97430104, 0x30840006, 0x24020001, 0xa7430148,
+	0xa742014a, 0x24020002, 0x1082000d, 0x2c820003, 0x10400005, 0x24020004,
+	0x10800011, 0x3c020041, 0x0a00046c, 0x00000000, 0x10820007, 0x24020006,
+	0x1482000d, 0x3c020151, 0x0a000466, 0x24030001, 0x0a000465, 0x3c020141,
+	0x3c020051, 0x24030001, 0xaf421000, 0xaf830020, 0x0a00046c, 0x00000000,
+	0xaf421000, 0xaf800020, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x8f820020, 0x8f840018, 0x10400006, 0x92030004, 0x3c058000, 0x8f421000,
+	0x00451024, 0x1040fffd, 0x00000000, 0x2463000a, 0x30620007, 0x10400002,
+	0x24620007, 0x304303f8, 0x00831021, 0x30421fff, 0xaf84000c, 0xaf820018,
+	0xaf420084, 0x97430104, 0x24424000, 0x0342d821, 0x3063ffff, 0x30620007,
+	0x10400002, 0x24620007, 0x3043fff8, 0x8f820030, 0x8f840000, 0x00431821,
+	0xaf82001c, 0x0064102b, 0xaf830030, 0x14400002, 0x00641023, 0xaf820030,
+	0x8f840030, 0x34028000, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x00821021,
+	0x03421821, 0x3c021000, 0xaf830010, 0xaf440080, 0xaf420178, 0x03e00008,
+	0x27bd0020, 0x8f620000, 0x97430104, 0x3c048000, 0x3045ffff, 0x3066ffff,
+	0x8f420178, 0x00441024, 0x1440fffd, 0x2402000a, 0x30a30007, 0xa7420140,
+	0x24020008, 0x00431023, 0x30420007, 0x24a3fffe, 0xa7420142, 0xa7430144,
+	0xa7400146, 0xa7460148, 0x8f420108, 0x8f830024, 0x30420020, 0x0002102b,
+	0x00021023, 0x30420009, 0x34420001, 0x30630006, 0xa742014a, 0x24020002,
+	0x1062000d, 0x2c620003, 0x10400005, 0x24020004, 0x10600011, 0x3c020041,
+	0x0a0004d6, 0x00000000, 0x10620007, 0x24020006, 0x1462000d, 0x3c020151,
+	0x0a0004d0, 0x24030001, 0x0a0004cf, 0x3c020141, 0x3c020051, 0x24030001,
+	0xaf421000, 0xaf830020, 0x0a0004d6, 0x00000000, 0xaf421000, 0xaf800020,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8f820020, 0x24a30008,
+	0x8f850018, 0x10400006, 0x30c6ffff, 0x3c048000, 0x8f421000, 0x00441024,
+	0x1040fffd, 0x00000000, 0x3063ffff, 0x30620007, 0x10400002, 0x24620007,
+	0x3043fff8, 0x00a31021, 0x30421fff, 0x24434000, 0x0343d821, 0x00c02021,
+	0x30830007, 0xaf85000c, 0xaf820018, 0xaf420084, 0x10600002, 0x24820007,
+	0x3044fff8, 0x8f820030, 0x8f850000, 0x00441821, 0xaf82001c, 0x0065102b,
+	0xaf830030, 0x14400002, 0x00651023, 0xaf820030, 0x8f840030, 0x34028000,
+	0x3c030800, 0x8c650834, 0x00821021, 0x03421821, 0xaf830010, 0xaf440080,
+	0x10a00006, 0x2402000e, 0x9383002f, 0x14620004, 0x3c021000, 0x2402043f,
+	0xa7420148, 0x3c021000, 0x03e00008, 0xaf420178, 0x8f820024, 0x30424000,
+	0x10400005, 0x24020800, 0x0000000d, 0x00000000, 0x2400040e, 0x24020800,
+	0xaf420178, 0x97440104, 0x3c030008, 0xaf430140, 0x8f820024, 0x30420001,
+	0x10400006, 0x3085ffff, 0x24020002, 0x24a3fffe, 0xa7420146, 0x0a000526,
+	0xa7430148, 0xa7400146, 0x8f840018, 0x2402000d, 0xa742014a, 0x24830008,
+	0x30631fff, 0x24624000, 0x0342d821, 0x30a20007, 0xaf84000c, 0xaf830018,
+	0xaf430084, 0x10400002, 0x24a20007, 0x3045fff8, 0x8f820030, 0x8f840000,
+	0x00451821, 0xaf82001c, 0x0064102b, 0xaf830030, 0x14400002, 0x00641023,
+	0xaf820030, 0x8f840030, 0x34028000, 0x00821021, 0x03421821, 0x3c021000,
+	0xaf830010, 0xaf440080, 0x03e00008, 0xaf420178, 0x27bdffe8, 0x3c046008,
+	0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f, 0x375b4000,
+	0x00431024, 0x3442380c, 0xac825000, 0x8f430008, 0x3c100800, 0x37428000,
+	0x34630001, 0xaf430008, 0xaf820010, 0x3c02601c, 0xaf800018, 0xaf400080,
+	0xaf400084, 0x8c450008, 0x3c036000, 0x8c620808, 0x3c040800, 0x3c030080,
+	0xac830820, 0x3042fff0, 0x38420010, 0x2c420001, 0xaf850000, 0xaf820004,
+	0x0e000658, 0x00000000, 0x8f420000, 0x30420001, 0x1040fffb, 0x00000000,
+	0x8f430108, 0x8f440100, 0x30622000, 0xaf830024, 0xaf840014, 0x10400004,
+	0x8e02082c, 0x24420001, 0x0a0005c6, 0xae02082c, 0x30620200, 0x14400003,
+	0x24020f00, 0x14820027, 0x24020d00, 0x97420104, 0x1040001c, 0x30624000,
+	0x14400005, 0x00000000, 0x0e00022f, 0x00000000, 0x0a0005bb, 0x00000000,
+	0x8f620008, 0x8f630000, 0x24020030, 0x00031e02, 0x306300f0, 0x10620007,
+	0x28620031, 0x1440002f, 0x24020040, 0x10620007, 0x00000000, 0x0a0005bb,
+	0x00000000, 0x0e0002e8, 0x00000000, 0x0a0005bb, 0x00000000, 0x0e0003db,
+	0x00000000, 0x0a0005bb, 0x00000000, 0x30620040, 0x1440002b, 0x00000000,
+	0x0000000d, 0x00000000, 0x240004b2, 0x0a0005c6, 0x00000000, 0x1482000f,
+	0x30620006, 0x97420104, 0x10400005, 0x30620040, 0x0e000510, 0x00000000,
+	0x0a0005bb, 0x00000000, 0x1440001b, 0x00000000, 0x0000000d, 0x00000000,
+	0x240004c4, 0x0a0005c6, 0x00000000, 0x1040000e, 0x30621000, 0x10400005,
+	0x00000000, 0x0e000688, 0x00000000, 0x0a0005bb, 0x00000000, 0x0e0004a1,
+	0x00000000, 0x8f82002c, 0x24420001, 0xaf82002c, 0x0a0005c6, 0x00000000,
+	0x30620040, 0x14400004, 0x00000000, 0x0000000d, 0x00000000, 0x240004db,
+	0x8f420138, 0x3c034000, 0x00431025, 0xaf420138, 0x0a000566, 0x00000000,
+	0x3c046008, 0x8c835000, 0x3c1a8000, 0x2402ff7f, 0x375b4000, 0x00621824,
+	0x3463380c, 0xac835000, 0x8f420008, 0x3c056000, 0x3c03601c, 0x34420001,
+	0xaf420008, 0x37428000, 0xaf800018, 0xaf820010, 0xaf400080, 0xaf400084,
+	0x8c660008, 0x8ca20808, 0x3c040800, 0x3c030080, 0xac830820, 0x3042fff0,
+	0x38420010, 0x2c420001, 0xaf860000, 0xaf820004, 0x03e00008, 0x00000000,
+	0x3084ffff, 0x30820007, 0x10400002, 0x24820007, 0x3044fff8, 0x8f820018,
+	0x00441821, 0x30631fff, 0x24644000, 0x0344d821, 0xaf82000c, 0xaf830018,
+	0x03e00008, 0xaf430084, 0x3084ffff, 0x30820007, 0x10400002, 0x24820007,
+	0x3044fff8, 0x8f820030, 0x8f830000, 0x00442021, 0xaf82001c, 0x0083102b,
+	0xaf840030, 0x14400002, 0x00831023, 0xaf820030, 0x8f820030, 0x34038000,
+	0x00431821, 0x03432021, 0xaf840010, 0x03e00008, 0xaf420080, 0x8f830024,
+	0x24020002, 0x30630006, 0x1062000d, 0x2c620003, 0x50400005, 0x24020004,
+	0x10600012, 0x3c020001, 0x0a00062a, 0x00000000, 0x10620007, 0x24020006,
+	0x1462000f, 0x3c020111, 0x0a000622, 0x00821025, 0x0a000621, 0x3c020101,
+	0x3c020011, 0x00821025, 0x24030001, 0xaf421000, 0xaf830020, 0x0a00062a,
+	0x00000000, 0x00821025, 0xaf421000, 0xaf800020, 0x00000000, 0x00000000,
+	0x00000000, 0x03e00008, 0x00000000, 0x8f820020, 0x10400005, 0x3c038000,
+	0x8f421000, 0x00431024, 0x1040fffd, 0x00000000, 0x03e00008, 0x00000000,
+	0x8f820024, 0x27bdffe8, 0x30424000, 0x14400005, 0xafbf0010, 0x0e00022f,
+	0x00000000, 0x0a000656, 0x8fbf0010, 0x8f620008, 0x8f630000, 0x24020030,
+	0x00031e02, 0x306300f0, 0x10620008, 0x28620031, 0x1440000d, 0x8fbf0010,
+	0x24020040, 0x10620007, 0x00000000, 0x0a000656, 0x00000000, 0x0e0002e8,
+	0x00000000, 0x0a000656, 0x8fbf0010, 0x0e0003db, 0x00000000, 0x8fbf0010,
+	0x03e00008, 0x27bd0018, 0x8f840028, 0x1080000f, 0x3c026000, 0x8c430c3c,
+	0x30630fff, 0xaf830008, 0x14600011, 0x3082000f, 0x10400005, 0x308200f0,
+	0x10400003, 0x30820f00, 0x14400006, 0x00000000, 0x0000000d, 0x00000000,
+	0x2400051a, 0x03e00008, 0x00000000, 0x0000000d, 0x00000000, 0x2400051f,
+	0x03e00008, 0x00000000, 0xaf830028, 0x03e00008, 0x00000000, 0x10c00007,
+	0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000, 0x14c0fffb,
+	0x24840004, 0x03e00008, 0x00000000, 0x0a000684, 0x00a01021, 0xac860000,
+	0x00000000, 0x00000000, 0x24840004, 0x00a01021, 0x1440fffa, 0x24a5ffff,
+	0x03e00008, 0x00000000, 0x0000000d, 0x03e00008, 0x00000000, 0x00000000};
 
-static u32 bnx2_TPAT_b06FwData[(0x0/4) + 1] = { 0x00000000 };
-static u32 bnx2_TPAT_b06FwRodata[(0x0/4) + 1] = { 0x00000000 };
-static u32 bnx2_TPAT_b06FwBss[(0x80/4) + 1] = { 0x00000000 };
-static u32 bnx2_TPAT_b06FwSbss[(0x48/4) + 1] = { 0x00000000 };
+static u32 bnx2_TPAT_b06FwData[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_TPAT_b06FwRodata[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_TPAT_b06FwBss[(0x250/4) + 1] = { 0x0 };
+static u32 bnx2_TPAT_b06FwSbss[(0x34/4) + 1] = { 0x0 };
 
-static int bnx2_TXP_b06FwReleaseMajor = 0x0;
+static int bnx2_TXP_b06FwReleaseMajor = 0x1;
 static int bnx2_TXP_b06FwReleaseMinor = 0x0;
 static int bnx2_TXP_b06FwReleaseFix = 0x0;
-static u32 bnx2_TXP_b06FwStartAddr = 0x08002090;
+static u32 bnx2_TXP_b06FwStartAddr = 0x080034b0;
 static u32 bnx2_TXP_b06FwTextAddr = 0x08000000;
-static int bnx2_TXP_b06FwTextLen = 0x3ffc;
-static u32 bnx2_TXP_b06FwDataAddr = 0x08004020;
+static int bnx2_TXP_b06FwTextLen = 0x5748;
+static u32 bnx2_TXP_b06FwDataAddr = 0x08005760;
 static int bnx2_TXP_b06FwDataLen = 0x0;
 static u32 bnx2_TXP_b06FwRodataAddr = 0x00000000;
 static int bnx2_TXP_b06FwRodataLen = 0x0;
-static u32 bnx2_TXP_b06FwBssAddr = 0x08004060;
-static int bnx2_TXP_b06FwBssLen = 0x194;
-static u32 bnx2_TXP_b06FwSbssAddr = 0x08004020;
-static int bnx2_TXP_b06FwSbssLen = 0x34;
-static u32 bnx2_TXP_b06FwText[(0x3ffc/4) + 1] = {
-	0x0a000824, 0x00000000, 0x00000000, 0x0000000d, 0x74787020, 0x302e362e,
-	0x39000000, 0x00060900, 0x0000000a, 0x000003e8, 0x0000ea60, 0x00000000,
+static u32 bnx2_TXP_b06FwBssAddr = 0x080057a0;
+static int bnx2_TXP_b06FwBssLen = 0x1c4;
+static u32 bnx2_TXP_b06FwSbssAddr = 0x08005760;
+static int bnx2_TXP_b06FwSbssLen = 0x38;
+static u32 bnx2_TXP_b06FwText[(0x5748/4) + 1] = {
+	0x0a000d2c, 0x00000000, 0x00000000, 0x0000000d, 0x74787020, 0x322e352e,
+	0x38000000, 0x02050800, 0x0000000a, 0x000003e8, 0x0000ea60, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
@@ -2124,55 +3090,57 @@
 	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, 0x24424020, 0x3c030800, 0x246341f4, 0xac400000,
-	0x0043202b, 0x1480fffd, 0x24420004, 0x3c1d0800, 0x37bd7ffc, 0x03a0f021,
-	0x3c100800, 0x26102090, 0x3c1c0800, 0x279c4020, 0x0e000a0e, 0x00000000,
-	0x0000000d, 0x8f840014, 0x27bdffe8, 0xafb00010, 0x8f460104, 0x8f830008,
-	0x8c8500ac, 0xaf430080, 0x948200a8, 0xa7420e10, 0x948300aa, 0xa7430e12,
-	0x8c8200ac, 0xaf420e18, 0x97430e10, 0xa7430e14, 0x97420e12, 0xa7420e16,
-	0x8f430e18, 0x00005021, 0x00c53023, 0x10c001a3, 0xaf430e1c, 0x240f0800,
-	0x3c0e1000, 0x2419fff8, 0x24100010, 0x3c188100, 0x93620008, 0x10400009,
-	0x00000000, 0x97620010, 0x00c2102b, 0x14400005, 0x00000000, 0x97620010,
-	0x3042ffff, 0x0a000862, 0xaf420e00, 0xaf460e00, 0x8f420000, 0x30420008,
-	0x1040fffd, 0x00000000, 0x97420e08, 0x8f450e04, 0x3044ffff, 0x30820001,
-	0x14400005, 0x00000000, 0x14a00005, 0x3083a040, 0x0a0009e6, 0x00000000,
-	0x0000000d, 0x3083a040, 0x24020040, 0x14620049, 0x3082a000, 0x8f87000c,
-	0x30880036, 0x30890008, 0xaf4f0178, 0x00e01821, 0x9742008a, 0x00431023,
-	0x2442ffff, 0x30421fff, 0x2c420008, 0x1440fffa, 0x00000000, 0x8f830018,
-	0x00a05021, 0x00c53023, 0x24e24000, 0x03422821, 0x306b00ff, 0x24630001,
-	0xaf830018, 0x93840012, 0x000b1400, 0x3c030100, 0x00431025, 0xaca20000,
-	0x8f820018, 0x30840007, 0x00042240, 0x34870001, 0x00e83825, 0x1120000f,
-	0xaca20004, 0x97430e0a, 0x8f84000c, 0x00ee3825, 0x2402000e, 0x00781825,
-	0xaf430160, 0x25430006, 0x24840008, 0x30841fff, 0xa742015a, 0xa7430158,
-	0xaf84000c, 0x0a0008a9, 0x00000000, 0x8f83000c, 0x25420002, 0xa7420158,
-	0x24630008, 0x30631fff, 0xaf83000c, 0x54c0000c, 0x8f420e14, 0x97420e10,
-	0x97430e12, 0x8f840014, 0x00021400, 0x00621825, 0xac8300a8, 0x8f850014,
-	0x8f420e18, 0x34e70040, 0xaca200ac, 0x8f420e14, 0x8f430e1c, 0xaf420144,
-	0xaf430148, 0xa34b0152, 0xaf470154, 0x0a0009f1, 0xaf4e0178, 0x10400128,
-	0x00000000, 0x97620010, 0x00a2102b, 0x10400003, 0x30820040, 0x10400122,
-	0x00000000, 0xafa60008, 0xa7840010, 0xaf850004, 0x93620008, 0x1440005e,
-	0x27ac0008, 0xaf60000c, 0x97820010, 0x30424000, 0x10400002, 0x2403000e,
-	0x24030016, 0xa363000a, 0x24034007, 0xaf630014, 0x93820012, 0x8f630014,
-	0x30420007, 0x00021240, 0x00621825, 0xaf630014, 0x97820010, 0x8f630014,
-	0x30420010, 0x00621825, 0xaf630014, 0x97820010, 0x30420008, 0x5040000e,
-	0x00002821, 0x8f620014, 0x004e1025, 0xaf620014, 0x97430e0a, 0x2402000e,
-	0x00781825, 0xaf630004, 0xa3620002, 0x9363000a, 0x3405fffc, 0x24630004,
-	0x0a0008f2, 0xa363000a, 0xaf600004, 0xa3600002, 0x97820010, 0x9363000a,
-	0x30421f00, 0x00021182, 0x24420028, 0x00621821, 0xa3630009, 0x97420e0c,
-	0xa7620010, 0x93630009, 0x24020008, 0x24630002, 0x30630007, 0x00431023,
-	0x30420007, 0xa362000b, 0x93640009, 0x97620010, 0x8f890004, 0x97830010,
-	0x00441021, 0x00a21021, 0x30630040, 0x10600006, 0x3045ffff, 0x15250005,
-	0x0125102b, 0x3c068000, 0x0a000925, 0x00005821, 0x0125102b, 0x144000c8,
-	0x00005021, 0x97420e14, 0xa7420e10, 0x97430e16, 0xa7430e12, 0x8f420e1c,
-	0xaf420e18, 0xaf450e00, 0x8f420000, 0x30420008, 0x1040fffd, 0x00000000,
-	0x97420e08, 0x00a04821, 0xa7820010, 0x8f430e04, 0x00003021, 0x240b0001,
-	0xaf830004, 0x97620010, 0x0a000936, 0x304dffff, 0x8f890004, 0x97820010,
-	0x30420040, 0x10400004, 0x01206821, 0x3c068000, 0x0a000936, 0x00005821,
-	0x97630010, 0x8f820004, 0x144300a7, 0x00005021, 0x00003021, 0x240b0001,
+	0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800,
+	0x24425760, 0x3c030800, 0x24635964, 0xac400000, 0x0043202b, 0x1480fffd,
+	0x24420004, 0x3c1d0800, 0x37bd7ffc, 0x03a0f021, 0x3c100800, 0x261034b0,
+	0x3c1c0800, 0x279c5760, 0x0e000f5b, 0x00000000, 0x0000000d, 0x8f840014,
+	0x27bdffe8, 0xafb10014, 0xafb00010, 0x8f460104, 0x8f830008, 0x8c8500ac,
+	0xaf430080, 0x948200a8, 0xa7420e10, 0x948300aa, 0xa7430e12, 0x8c8200ac,
+	0xaf420e18, 0x97430e10, 0xa7430e14, 0x97420e12, 0x00008021, 0xa7420e16,
+	0x8f430e18, 0x00006021, 0x00c53023, 0xaf430e1c, 0x10c001a2, 0x2d820001,
+	0x3c0e1000, 0x2419fff8, 0x24110010, 0x240f0f00, 0x3c188100, 0x93620008,
+	0x10400009, 0x00000000, 0x97620010, 0x00c2102b, 0x14400005, 0x00000000,
+	0x97620010, 0x3042ffff, 0x0a000d6d, 0xaf420e00, 0xaf460e00, 0x8f420000,
+	0x30420008, 0x1040fffd, 0x00000000, 0x97420e08, 0x8f450e04, 0x3044ffff,
+	0x30820001, 0x14400005, 0x00000000, 0x14a00005, 0x3083a040, 0x0a000f34,
+	0x00000000, 0x0000000d, 0x3083a040, 0x24020040, 0x1462004f, 0x3082a000,
+	0x308a0036, 0x8f88000c, 0x30890008, 0x24020800, 0xaf420178, 0x01001821,
+	0x9742008a, 0x00431023, 0x2442ffff, 0x30421fff, 0x2c420008, 0x1440fffa,
+	0x00a06021, 0x8f820018, 0x00cc3023, 0x24070001, 0x8f830008, 0x304b00ff,
+	0x24420001, 0xaf820018, 0x25024000, 0x106f0005, 0x03422021, 0x93820012,
+	0x30420007, 0x00021240, 0x34470001, 0x000b1400, 0x3c030100, 0x00431025,
+	0xac820000, 0x8f830018, 0x00ea3825, 0x1120000f, 0xac830004, 0x97430e0a,
+	0x8f84000c, 0x00ee3825, 0x2402000e, 0x00781825, 0xaf430160, 0x25830006,
+	0x24840008, 0x30841fff, 0xa742015a, 0xa7430158, 0xaf84000c, 0x0a000db7,
+	0x00000000, 0x8f83000c, 0x25820002, 0xa7420158, 0x24630008, 0x30631fff,
+	0xaf83000c, 0x54c0000f, 0x8f420e14, 0x8f820008, 0x504f0002, 0x24100001,
+	0x34e70040, 0x97420e10, 0x97430e12, 0x8f850014, 0x00021400, 0x00621825,
+	0xaca300a8, 0x8f840014, 0x8f420e18, 0xac8200ac, 0x8f420e14, 0x8f430e1c,
+	0xaf420144, 0xaf430148, 0xa34b0152, 0xaf470154, 0x0a000efb, 0xaf4e0178,
+	0x10400165, 0x00000000, 0x93620008, 0x50400008, 0xafa60008, 0x97620010,
+	0x00a2102b, 0x10400003, 0x30820040, 0x1040015c, 0x00000000, 0xafa60008,
+	0xa7840010, 0xaf850004, 0x93620008, 0x1440005f, 0x27ac0008, 0xaf60000c,
+	0x97820010, 0x30424000, 0x10400002, 0x2403000e, 0x24030016, 0xa363000a,
+	0x24034007, 0xaf630014, 0x93820012, 0x8f630014, 0x30420007, 0x00021240,
+	0x00621825, 0xaf630014, 0x97820010, 0x8f630014, 0x30420010, 0x00621825,
+	0xaf630014, 0x97820010, 0x30420008, 0x5040000e, 0x00002821, 0x8f620014,
+	0x004e1025, 0xaf620014, 0x97430e0a, 0x2402000e, 0x00781825, 0xaf630004,
+	0xa3620002, 0x9363000a, 0x3405fffc, 0x24630004, 0x0a000e06, 0xa363000a,
+	0xaf600004, 0xa3600002, 0x97820010, 0x9363000a, 0x30421f00, 0x00021182,
+	0x24420028, 0x00621821, 0xa3630009, 0x97420e0c, 0xa7620010, 0x93630009,
+	0x24020008, 0x24630002, 0x30630007, 0x00431023, 0x30420007, 0xa362000b,
+	0x93640009, 0x97620010, 0x8f890004, 0x97830010, 0x00441021, 0x00a21021,
+	0x30630040, 0x10600007, 0x3045ffff, 0x00a9102b, 0x14400005, 0x0125102b,
+	0x3c068000, 0x0a000e3a, 0x00005821, 0x0125102b, 0x544000c7, 0x00006021,
+	0x97420e14, 0xa7420e10, 0x97430e16, 0xa7430e12, 0x8f420e1c, 0xaf420e18,
+	0xaf450e00, 0x8f420000, 0x30420008, 0x1040fffd, 0x00000000, 0x97420e08,
+	0x00a04821, 0xa7820010, 0x8f430e04, 0x00003021, 0x240b0001, 0xaf830004,
+	0x97620010, 0x0a000e4c, 0x304dffff, 0x8f890004, 0x97820010, 0x30420040,
+	0x10400004, 0x01206821, 0x3c068000, 0x0a000e4c, 0x00005821, 0x97630010,
+	0x8f820004, 0x10430003, 0x00003021, 0x0a000eee, 0x00006021, 0x240b0001,
 	0x8d820000, 0x00491023, 0x1440000d, 0xad820000, 0x8f620014, 0x34420040,
 	0xaf620014, 0x97430e10, 0x97420e12, 0x8f840014, 0x00031c00, 0x00431025,
-	0xac8200a8, 0x8f830014, 0x8f420e18, 0xac6200ac, 0x93620008, 0x1440003f,
+	0xac8200a8, 0x8f830014, 0x8f420e18, 0xac6200ac, 0x93620008, 0x1440003e,
 	0x00000000, 0x25260002, 0x8f84000c, 0x9743008a, 0x3063ffff, 0xafa30000,
 	0x8fa20000, 0x00441023, 0x2442ffff, 0x30421fff, 0x2c420010, 0x1440fff7,
 	0x00000000, 0x8f82000c, 0x8f830018, 0x00021082, 0x00021080, 0x24424000,
@@ -2180,289 +3148,320 @@
 	0x3c033200, 0x00431025, 0xaca20000, 0x93630009, 0x9362000a, 0x00031c00,
 	0x00431025, 0xaca20004, 0x8f830018, 0xaca30008, 0x97820010, 0x30420008,
 	0x10400002, 0x00c04021, 0x25280006, 0x97430e14, 0x93640002, 0x8f450e1c,
-	0x8f660004, 0x8f670014, 0xaf4f0178, 0x3063ffff, 0xa7430144, 0x97420e16,
-	0xa7420146, 0xaf450148, 0xa34a0152, 0x8f82000c, 0x308400ff, 0xa744015a,
-	0xaf460160, 0xa7480158, 0xaf470154, 0xaf4e0178, 0x00501021, 0x30421fff,
-	0xaf82000c, 0x0a0009c5, 0x8d820000, 0x93620009, 0x9363000b, 0x8f85000c,
-	0x2463000a, 0x00435021, 0x25440007, 0x00992024, 0x9743008a, 0x3063ffff,
-	0xafa30000, 0x8fa20000, 0x00451023, 0x2442ffff, 0x30421fff, 0x0044102b,
-	0x1440fff7, 0x00000000, 0x8f82000c, 0x8f840018, 0x00021082, 0x00021080,
-	0x24424000, 0x03422821, 0x00804021, 0x24840001, 0xaf840018, 0x93630009,
-	0x310200ff, 0x00022400, 0x3c024100, 0x24630002, 0x00621825, 0x00832025,
-	0xaca40000, 0x8f62000c, 0x00461025, 0xaca20004, 0x97430e14, 0x93640002,
-	0x8f450e1c, 0x8f660004, 0x8f670014, 0xaf4f0178, 0x3063ffff, 0xa7430144,
-	0x97420e16, 0x308400ff, 0xa7420146, 0xaf450148, 0xa3480152, 0x8f83000c,
-	0x25420007, 0x00591024, 0xa744015a, 0xaf460160, 0xa7490158, 0xaf470154,
-	0xaf4e0178, 0x00621821, 0x30631fff, 0xaf83000c, 0x8d820000, 0x14400005,
-	0x00000000, 0x8f620014, 0x2403ffbf, 0x00431024, 0xaf620014, 0x8f62000c,
-	0x004d1021, 0xaf62000c, 0x93630008, 0x14600008, 0x00000000, 0x11600006,
-	0x00000000, 0x8f630014, 0x3c02efff, 0x3442fffe, 0x00621824, 0xaf630014,
-	0xa36b0008, 0x01205021, 0x15400016, 0x8fa60008, 0x97420e14, 0x97430e16,
-	0x8f850014, 0x00021400, 0x00621825, 0xaca300a8, 0x8f840014, 0x8f420e1c,
-	0x0a0009f3, 0xac8200ac, 0x97420e14, 0x97430e16, 0x8f840014, 0x00021400,
-	0x00621825, 0xac8300a8, 0x8f850014, 0x8f420e1c, 0x00005021, 0x0a0009f3,
-	0xaca200ac, 0x14c0fe64, 0x00000000, 0x55400018, 0x8fb00010, 0x3c038000,
-	0x8f420178, 0x00431024, 0x1440fffd, 0x00000000, 0x97430e14, 0x8f440e1c,
-	0x24020800, 0xaf420178, 0x3063ffff, 0xa7430144, 0x97420e16, 0x3c031000,
-	0xa7420146, 0x24020240, 0xaf440148, 0xa3400152, 0xa740015a, 0xaf400160,
-	0xa7400158, 0xaf420154, 0xaf430178, 0x8fb00010, 0x03e00008, 0x27bd0018,
-	0x27bdffd8, 0x3c1a8000, 0x3c0420ff, 0x3484fffd, 0x3c020008, 0x03421821,
-	0xafbf0020, 0xafb3001c, 0xafb20018, 0xafb10014, 0xafb00010, 0xaf830014,
-	0xaf440e00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
-	0x3c0200ff, 0x3442fffd, 0x3c046004, 0xaf420e00, 0x8c835000, 0x24130d00,
-	0x3c120800, 0x3c114000, 0x2402ff7f, 0x00621824, 0x3463380c, 0x24020009,
-	0xac835000, 0xaf420008, 0xaf800018, 0xaf80000c, 0x0e000fa1, 0x00000000,
-	0x0e000a96, 0x00000000, 0x3c020800, 0x24504080, 0x8f420000, 0x30420001,
-	0x1040fffd, 0x00000000, 0x8f440100, 0xaf840008, 0xaf440020, 0x93430108,
-	0xa3830012, 0x93820012, 0x30420001, 0x10400008, 0x00000000, 0x93820012,
-	0x30420006, 0x00021100, 0x0e00083b, 0x0050d821, 0x0a000a52, 0x00000000,
-	0x14930005, 0x00000000, 0x0e00083b, 0x265b4100, 0x0a000a52, 0x00000000,
-	0x0e000ba3, 0x00000000, 0xaf510138, 0x0a000a36, 0x00000000, 0x27bdfff8,
-	0x3084ffff, 0x24820007, 0x3044fff8, 0x8f85000c, 0x9743008a, 0x3063ffff,
-	0xafa30000, 0x8fa20000, 0x00451023, 0x2442ffff, 0x30421fff, 0x0044102b,
-	0x1440fff7, 0x00000000, 0x8f82000c, 0x00021082, 0x00021080, 0x24424000,
-	0x03421021, 0x03e00008, 0x27bd0008, 0x3084ffff, 0x8f82000c, 0x24840007,
-	0x3084fff8, 0x00441021, 0x30421fff, 0xaf82000c, 0x03e00008, 0x00000000,
-	0x27bdffe8, 0x3c1a8000, 0x3c0420ff, 0x3484fffd, 0x3c020008, 0x03421821,
-	0xafbf0010, 0xaf830014, 0xaf440e00, 0x00000000, 0x00000000, 0x00000000,
-	0x00000000, 0x00000000, 0x3c0200ff, 0x3442fffd, 0x3c046004, 0xaf420e00,
-	0x8c825000, 0x2403ff7f, 0x00431024, 0x3442380c, 0x24030009, 0xac825000,
-	0xaf430008, 0xaf800018, 0xaf80000c, 0x0e000fa1, 0x00000000, 0x0e000a96,
-	0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0x3c02000a,
-	0x03421821, 0x3c040800, 0x24844120, 0x24050018, 0xafbf0010, 0xaf830024,
-	0x0e000fad, 0x00003021, 0x3c050800, 0x3c020800, 0x24423d60, 0xaca24180,
-	0x24a54180, 0x3c020800, 0x24423e18, 0x3c030800, 0x24633e2c, 0x3c040800,
-	0xaca20004, 0x3c020800, 0x24423d68, 0xaca30008, 0xac824190, 0x24844190,
-	0x3c020800, 0x24423da4, 0x3c070800, 0x24e73de4, 0x3c060800, 0x24c63e40,
-	0x3c050800, 0x24a52b28, 0x3c030800, 0xac820004, 0x3c020800, 0x24423e48,
-	0xac870008, 0xac86000c, 0xac850010, 0xac6241b0, 0x246341b0, 0x8fbf0010,
-	0x3c020800, 0x24423e60, 0xac620004, 0xac670008, 0xac66000c, 0xac650010,
-	0x03e00008, 0x27bd0018, 0x27bdffc8, 0x3c020800, 0x24424120, 0xafbf0030,
-	0xafb3002c, 0xafb20028, 0xafb10024, 0xafb00020, 0x90470021, 0x8c510008,
-	0x8c45001c, 0x8f900020, 0x3c060800, 0x3c038000, 0x8f420178, 0x00431024,
-	0x1440fffd, 0x8cc2414c, 0x24c3414c, 0x2473ffd4, 0xaf420144, 0x8e620030,
-	0x30b22000, 0xaf420148, 0x3c021000, 0xaf50014c, 0xa3470152, 0xa7510158,
-	0xaf450154, 0xaf420178, 0x12400004, 0x3c030800, 0x8c620030, 0x24420001,
-	0xac620030, 0x93420109, 0x9344010a, 0x00111c00, 0xafa30018, 0x00071a00,
-	0xafa50014, 0x8cc5414c, 0x00021600, 0x00042400, 0x00441025, 0x00431025,
-	0xafa20010, 0x8f440100, 0x8e660030, 0x0e000fe1, 0x02003821, 0x1640000e,
-	0x8fbf0030, 0x8f820000, 0x8e630030, 0x8c44017c, 0x02031823, 0x00711823,
-	0x00641823, 0x2c630002, 0x14600006, 0x8fb3002c, 0x0000000d, 0x00000000,
-	0x240000ca, 0x8fbf0030, 0x8fb3002c, 0x8fb20028, 0x8fb10024, 0x8fb00020,
-	0x03e00008, 0x27bd0038, 0x974309da, 0x00804021, 0xad030000, 0x8f4209dc,
-	0xad020004, 0x8f4309e0, 0xad030008, 0x934409d9, 0x24020001, 0x30840003,
-	0x1082001f, 0x30a900ff, 0x28820002, 0x10400005, 0x24020002, 0x10800009,
-	0x3c0a0800, 0x0a000b64, 0x93420934, 0x1082000b, 0x24020003, 0x10820026,
-	0x3c0a0800, 0x0a000b64, 0x93420934, 0x974209e4, 0x00021400, 0x34420800,
-	0xad02000c, 0x0a000b63, 0x25080010, 0x974209e4, 0x00021400, 0x34428100,
-	0xad02000c, 0x974309e8, 0x3c0a0800, 0x00031c00, 0x34630800, 0xad030010,
-	0x0a000b63, 0x25080014, 0x974409e4, 0x3c050800, 0x24a24120, 0x94430018,
-	0x94460010, 0x9447000c, 0x00a05021, 0x24020800, 0xad000010, 0xad020014,
-	0x00042400, 0x00661821, 0x00671823, 0x2463fff2, 0x00832025, 0xad04000c,
-	0x0a000b63, 0x25080018, 0x974209e4, 0x3c050800, 0x00021400, 0x34428100,
-	0xad02000c, 0x974409e8, 0x24a24120, 0x94430018, 0x94460010, 0x9447000c,
-	0x00a05021, 0x24020800, 0xad000014, 0xad020018, 0x00042400, 0x00661821,
-	0x00671823, 0x2463ffee, 0x00832025, 0xad040010, 0x2508001c, 0x93420934,
-	0x93450921, 0x3c074000, 0x25444120, 0x94830014, 0x94860010, 0x00021082,
-	0x00021600, 0x00052c00, 0x00a72825, 0x00451025, 0x00661821, 0x00431025,
-	0xad020000, 0x97830028, 0x974209ea, 0x00621821, 0x00031c00, 0xad030004,
-	0x97820028, 0x24420001, 0x30427fff, 0xa7820028, 0x93430920, 0x3c020006,
-	0x00031e00, 0x00621825, 0xad030008, 0x8f42092c, 0xad02000c, 0x8f430930,
-	0xad030010, 0x8f440938, 0x25080014, 0xad040000, 0x8f820020, 0x11200004,
-	0xad020004, 0x8f420940, 0x0a000b8d, 0x2442ffff, 0x8f420940, 0xad020008,
-	0x8f440948, 0x8f420940, 0x93430936, 0x00822823, 0x00652806, 0x3402ffff,
-	0x0045102b, 0x54400001, 0x3405ffff, 0x93420937, 0x25444120, 0x90830020,
-	0xad000010, 0x00021700, 0x34630010, 0x00031c00, 0x00431025, 0x00451025,
-	0xad02000c, 0x03e00008, 0x25020014, 0x27bdffb0, 0x3c020008, 0x03421821,
-	0xafbf004c, 0xafbe0048, 0xafb70044, 0xafb60040, 0xafb5003c, 0xafb40038,
-	0xafb30034, 0xafb20030, 0xafb1002c, 0xafb00028, 0xaf830000, 0x24020040,
-	0xaf420814, 0xaf400810, 0x8f420944, 0x8f430950, 0x8f440954, 0x8f45095c,
-	0xaf820030, 0xaf830020, 0xaf84001c, 0xaf85002c, 0x93430900, 0x24020020,
-	0x10620005, 0x24020030, 0x10620022, 0x3c030800, 0x0a000bf1, 0x8c62002c,
-	0x24020088, 0xaf420818, 0x3c020800, 0x24424180, 0xafa20020, 0x93430109,
-	0x3c020800, 0x10600009, 0x24574190, 0x3c026000, 0x24030100, 0xac43081c,
-	0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x2400031d, 0x9342010a,
-	0x30420080, 0x1440001c, 0x00000000, 0x3c026000, 0x24030100, 0xac43081c,
-	0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x24000324, 0x0a000bf4,
-	0x00000000, 0x93430109, 0x3063007f, 0x00031140, 0x000318c0, 0x00431021,
-	0x24430088, 0xaf430818, 0x0000000d, 0x3c020800, 0x244241d0, 0x3c030800,
-	0x247741e0, 0x0a000bf4, 0xafa20020, 0x24420001, 0x0a000f4c, 0xac62002c,
-	0x8f840000, 0x8f850020, 0x24020800, 0xaf420178, 0x8f4209a4, 0x8c83017c,
-	0x00a21023, 0x00431023, 0x2c420002, 0x14400004, 0x00000000, 0x0000000d,
-	0x00000000, 0x24000349, 0x8f420104, 0x8f430988, 0x00431023, 0x58400005,
-	0x8f4209a0, 0x0000000d, 0x00000000, 0x2400034d, 0x8f4209a0, 0x3c100800,
-	0xae02414c, 0x8f4309a4, 0x2604414c, 0x2491ffd4, 0xae230030, 0x8f420104,
-	0xae250024, 0x00431023, 0xac82ffd4, 0x8fa30020, 0x8c620000, 0x0040f809,
+	0x8f660004, 0x8f670014, 0x3063ffff, 0xa7430144, 0x97420e16, 0xa7420146,
+	0xaf450148, 0xa34a0152, 0x8f82000c, 0x308400ff, 0xa744015a, 0xaf460160,
+	0xa7480158, 0xaf470154, 0xaf4e0178, 0x00511021, 0x30421fff, 0xaf82000c,
+	0x0a000ed9, 0x8d820000, 0x93620009, 0x9363000b, 0x8f85000c, 0x2463000a,
+	0x00435021, 0x25440007, 0x00992024, 0x9743008a, 0x3063ffff, 0xafa30000,
+	0x8fa20000, 0x00451023, 0x2442ffff, 0x30421fff, 0x0044102b, 0x1440fff7,
+	0x00000000, 0x8f82000c, 0x8f840018, 0x00021082, 0x00021080, 0x24424000,
+	0x03422821, 0x00804021, 0x24840001, 0xaf840018, 0x93630009, 0x310200ff,
+	0x00022400, 0x3c024100, 0x24630002, 0x00621825, 0x00832025, 0xaca40000,
+	0x8f62000c, 0x00461025, 0xaca20004, 0x97430e14, 0x93640002, 0x8f450e1c,
+	0x8f660004, 0x8f670014, 0x3063ffff, 0xa7430144, 0x97420e16, 0x308400ff,
+	0xa7420146, 0xaf450148, 0xa3480152, 0x8f83000c, 0x25420007, 0x00591024,
+	0xa744015a, 0xaf460160, 0xa7490158, 0xaf470154, 0xaf4e0178, 0x00621821,
+	0x30631fff, 0xaf83000c, 0x8d820000, 0x14400005, 0x00000000, 0x8f620014,
+	0x2403ffbf, 0x00431024, 0xaf620014, 0x8f62000c, 0x004d1021, 0xaf62000c,
+	0x93630008, 0x14600008, 0x00000000, 0x11600006, 0x00000000, 0x8f630014,
+	0x3c02efff, 0x3442fffe, 0x00621824, 0xaf630014, 0xa36b0008, 0x01206021,
+	0x1580000c, 0x8fa60008, 0x97420e14, 0x97430e16, 0x8f850014, 0x00021400,
+	0x00621825, 0xaca300a8, 0x8f840014, 0x8f420e1c, 0xac8200ac, 0x0a000efd,
+	0x2d820001, 0x14c0fe65, 0x2d820001, 0x00501025, 0x10400058, 0x24020f00,
+	0x8f830008, 0x14620023, 0x3c048000, 0x11800009, 0x3c038000, 0x97420e08,
+	0x30420040, 0x14400005, 0x00000000, 0x0000000d, 0x00000000, 0x2400032c,
+	0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x00000000, 0x97420e10,
+	0x3c030500, 0x00431025, 0xaf42014c, 0x97430e14, 0xa7430144, 0x97420e16,
+	0xa7420146, 0x8f430e1c, 0x24022000, 0xaf430148, 0x3c031000, 0xa3400152,
+	0xa740015a, 0xaf400160, 0xa7400158, 0xaf420154, 0xaf430178, 0x8f830008,
+	0x3c048000, 0x8f420178, 0x00441024, 0x1440fffd, 0x24020f00, 0x10620016,
+	0x00000000, 0x97420e14, 0xa7420144, 0x97430e16, 0xa7430146, 0x8f420e1c,
+	0x3c031000, 0xaf420148, 0x0a000f51, 0x24020240, 0x97420e14, 0x97430e16,
+	0x8f840014, 0x00021400, 0x00621825, 0xac8300a8, 0x8f850014, 0x8f420e1c,
+	0x00006021, 0xaca200ac, 0x0a000efd, 0x2d820001, 0xaf40014c, 0x11800007,
+	0x00000000, 0x97420e10, 0xa7420144, 0x97430e12, 0xa7430146, 0x0a000f4e,
+	0x8f420e18, 0x97420e14, 0xa7420144, 0x97430e16, 0xa7430146, 0x8f420e1c,
+	0xaf420148, 0x24020040, 0x3c031000, 0xa3400152, 0xa740015a, 0xaf400160,
+	0xa7400158, 0xaf420154, 0xaf430178, 0x8fb10014, 0x8fb00010, 0x03e00008,
+	0x27bd0018, 0x27bdffd0, 0x3c1a8000, 0x3c0420ff, 0x3484fffd, 0x3c020008,
+	0x03421821, 0xafbf002c, 0xafb60028, 0xafb50024, 0xafb40020, 0xafb3001c,
+	0xafb20018, 0xafb10014, 0xafb00010, 0xaf830014, 0xaf440e00, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3c0200ff, 0x3442fffd,
+	0x3c046004, 0xaf420e00, 0x8c835000, 0x24160800, 0x24150d00, 0x3c140800,
+	0x24130f00, 0x3c120800, 0x3c114000, 0x2402ff7f, 0x00621824, 0x3463380c,
+	0x24020009, 0xac835000, 0xaf420008, 0xaf800018, 0xaf80000c, 0x0e001559,
+	0x00000000, 0x0e000ff0, 0x00000000, 0x3c020800, 0x245057c0, 0x8f420000,
+	0x30420001, 0x1040fffd, 0x00000000, 0x8f440100, 0xaf840008, 0xaf440020,
+	0xaf560178, 0x93430108, 0xa3830012, 0x93820012, 0x30420001, 0x10400008,
+	0x00000000, 0x93820012, 0x30420006, 0x00021100, 0x0e000d43, 0x0050d821,
+	0x0a000fac, 0x00000000, 0x14950005, 0x00000000, 0x0e000d43, 0x269b5840,
+	0x0a000fac, 0x00000000, 0x14930005, 0x00000000, 0x0e000d43, 0x265b5860,
+	0x0a000fac, 0x00000000, 0x0e0010ea, 0x00000000, 0xaf510138, 0x0a000f89,
+	0x00000000, 0x27bdfff8, 0x3084ffff, 0x24820007, 0x3044fff8, 0x8f85000c,
+	0x9743008a, 0x3063ffff, 0xafa30000, 0x8fa20000, 0x00451023, 0x2442ffff,
+	0x30421fff, 0x0044102b, 0x1440fff7, 0x00000000, 0x8f82000c, 0x00021082,
+	0x00021080, 0x24424000, 0x03421021, 0x03e00008, 0x27bd0008, 0x3084ffff,
+	0x8f82000c, 0x24840007, 0x3084fff8, 0x00441021, 0x30421fff, 0xaf82000c,
+	0x03e00008, 0x00000000, 0x27bdffe8, 0x3c1a8000, 0x3c0420ff, 0x3484fffd,
+	0x3c020008, 0x03421821, 0xafbf0010, 0xaf830014, 0xaf440e00, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3c0200ff, 0x3442fffd,
+	0x3c046004, 0xaf420e00, 0x8c825000, 0x2403ff7f, 0x00431024, 0x3442380c,
+	0x24030009, 0xac825000, 0xaf430008, 0xaf800018, 0xaf80000c, 0x0e001559,
+	0x00000000, 0x0e000ff0, 0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018,
+	0x27bdffe8, 0x3c02000a, 0x03421821, 0x3c040800, 0x24845880, 0x24050019,
+	0xafbf0010, 0xaf830024, 0x0e001565, 0x00003021, 0x3c050800, 0x3c020800,
+	0x24425330, 0xaca258e8, 0x24a558e8, 0x3c020800, 0x244254f8, 0x3c030800,
+	0x2463550c, 0x3c040800, 0xaca20004, 0x3c020800, 0x24425338, 0xaca30008,
+	0xac825900, 0x24845900, 0x3c020800, 0x244253c4, 0x3c070800, 0x24e75404,
+	0x3c060800, 0x24c65520, 0x3c050800, 0x24a55438, 0x3c030800, 0xac820004,
+	0x3c020800, 0x24425528, 0xac870008, 0xac86000c, 0xac850010, 0xac625920,
+	0x24635920, 0x8fbf0010, 0x3c020800, 0x24425540, 0xac620004, 0x3c020800,
+	0xac670008, 0xac66000c, 0xac650010, 0xac400048, 0x03e00008, 0x27bd0018,
+	0x974309da, 0x00804021, 0xad030000, 0x8f4209dc, 0xad020004, 0x8f4309e0,
+	0xad030008, 0x934409d9, 0x24020001, 0x30840003, 0x1082001f, 0x30a900ff,
+	0x28820002, 0x10400005, 0x24020002, 0x10800009, 0x3c0a0800, 0x0a001078,
+	0x93420934, 0x1082000b, 0x24020003, 0x10820026, 0x3c0a0800, 0x0a001078,
+	0x93420934, 0x974209e4, 0x00021400, 0x34420800, 0xad02000c, 0x0a001077,
+	0x25080010, 0x974209e4, 0x00021400, 0x34428100, 0xad02000c, 0x974309e8,
+	0x3c0a0800, 0x00031c00, 0x34630800, 0xad030010, 0x0a001077, 0x25080014,
+	0x974409e4, 0x3c050800, 0x24a25880, 0x9443001c, 0x94460014, 0x94470010,
+	0x00a05021, 0x24020800, 0xad000010, 0xad020014, 0x00042400, 0x00661821,
+	0x00671823, 0x2463fff2, 0x00832025, 0xad04000c, 0x0a001077, 0x25080018,
+	0x974209e4, 0x3c050800, 0x00021400, 0x34428100, 0xad02000c, 0x974409e8,
+	0x24a25880, 0x9443001c, 0x94460014, 0x94470010, 0x00a05021, 0x24020800,
+	0xad000014, 0xad020018, 0x00042400, 0x00661821, 0x00671823, 0x2463ffee,
+	0x00832025, 0xad040010, 0x2508001c, 0x93420934, 0x93450921, 0x3c074000,
+	0x25445880, 0x94830018, 0x94860014, 0x00021082, 0x00021600, 0x00052c00,
+	0x00a72825, 0x00451025, 0x00661821, 0x00431025, 0xad020000, 0x9783002c,
+	0x974209ea, 0x00621821, 0x00031c00, 0xad030004, 0x9782002c, 0x24420001,
+	0x30427fff, 0xa782002c, 0x93430920, 0x3c020006, 0x00031e00, 0x00621825,
+	0xad030008, 0x8f42092c, 0xad02000c, 0x8f430930, 0xad030010, 0x8f440938,
+	0x25080014, 0xad040000, 0x8f820020, 0x11200004, 0xad020004, 0x8f420940,
+	0x0a0010a1, 0x2442ffff, 0x8f420940, 0xad020008, 0x8f440948, 0x8f420940,
+	0x93430936, 0x00823023, 0x00663006, 0x3402ffff, 0x0046102b, 0x54400001,
+	0x3406ffff, 0x93420937, 0x25445880, 0x90830024, 0xad000010, 0x00021700,
+	0x34630010, 0x00031c00, 0x00431025, 0x00461025, 0xad02000c, 0x8c830008,
+	0x14600031, 0x25080014, 0x3c020800, 0x8c430048, 0x1060002d, 0x00000000,
+	0x9342010b, 0xad020000, 0x8f830000, 0x8c6200b0, 0xad020004, 0x8f830000,
+	0x8c6200b4, 0xad020008, 0x8f830000, 0x8c6200c0, 0xad02000c, 0x8f830000,
+	0x8c6200c4, 0xad020010, 0x8f830000, 0x8c6200c8, 0xad020014, 0x8f830000,
+	0x8c6200cc, 0xad020018, 0x8f830000, 0x8c6200e0, 0xad02001c, 0x8f830000,
+	0x8c6200e8, 0xad020020, 0x8f830000, 0x8c6200f0, 0x3c04600e, 0xad020024,
+	0x8c8200d0, 0xad020028, 0x8c8300d4, 0xad03002c, 0x8f820028, 0x3c046012,
+	0xad020030, 0x8c8200a8, 0xad020034, 0x8c8300ac, 0x3c026000, 0xad030038,
+	0x8c434448, 0xad03003c, 0x03e00008, 0x01001021, 0x27bdffa8, 0x3c020008,
+	0x03423021, 0xafbf0054, 0xafbe0050, 0xafb7004c, 0xafb60048, 0xafb50044,
+	0xafb40040, 0xafb3003c, 0xafb20038, 0xafb10034, 0xafb00030, 0xaf860000,
+	0x24020040, 0xaf420814, 0xaf400810, 0x8f420944, 0x8f430950, 0x8f440954,
+	0x8f45095c, 0xaf820034, 0xaf830020, 0xaf84001c, 0xaf850030, 0x90c20000,
+	0x24030020, 0x304400ff, 0x10830005, 0x24020030, 0x10820022, 0x3c030800,
+	0x0a001139, 0x8c62002c, 0x24020088, 0xaf420818, 0x3c020800, 0x244258e8,
+	0xafa20020, 0x93430109, 0x3c020800, 0x10600009, 0x24575900, 0x3c026000,
+	0x24030100, 0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000,
+	0x24000376, 0x9342010a, 0x30420080, 0x14400021, 0x24020800, 0x3c026000,
+	0x24030100, 0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000,
+	0x2400037d, 0x0a001141, 0x24020800, 0x93430109, 0x3063007f, 0x00031140,
+	0x000318c0, 0x00431021, 0x24430088, 0xaf430818, 0x0000000d, 0x3c020800,
+	0x24425940, 0x3c030800, 0x24775950, 0x0a001140, 0xafa20020, 0x24420001,
+	0xac62002c, 0x0000000d, 0x00000000, 0x24000395, 0x0a0014c1, 0x8fbf0054,
+	0x24020800, 0xaf420178, 0x8f450104, 0x8f420988, 0x00a21023, 0x58400005,
+	0x8f4309a0, 0x0000000d, 0x00000000, 0x240003b1, 0x8f4309a0, 0x3c100800,
+	0xae0358b0, 0x8f4209a4, 0x8f830020, 0x260458b0, 0x2491ffd0, 0xae220034,
+	0x00a21023, 0xae230028, 0xac82ffd0, 0x8fa30020, 0x8c620000, 0x0040f809,
 	0x0200b021, 0x00409021, 0x32440010, 0x32420002, 0x10400007, 0xafa40024,
-	0x8e22001c, 0x32500040, 0x2403ffbf, 0x00431024, 0x0a000f13, 0xae22001c,
-	0x32420020, 0x10400002, 0x3c020800, 0x245741b0, 0x32420001, 0x14400007,
-	0x00000000, 0x8f820008, 0xaf420080, 0x8ec3414c, 0xaf430e10, 0x8e220030,
+	0x8e220020, 0x32530040, 0x2403ffbf, 0x00431024, 0x0a001493, 0xae220020,
+	0x32420020, 0x10400002, 0x3c020800, 0x24575920, 0x32420001, 0x14400007,
+	0x00000000, 0x8f820008, 0xaf420080, 0x8ec358b0, 0xaf430e10, 0x8e220034,
 	0xaf420e18, 0x9343010b, 0x93420905, 0x30420008, 0x1040003c, 0x307400ff,
 	0x8f820000, 0x8c430074, 0x0460000a, 0x00000000, 0x3c026000, 0x24030100,
-	0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x24000384,
-	0x8f820000, 0x9044007b, 0x9343010a, 0x14830027, 0x32500040, 0x24072000,
-	0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec2414c,
-	0x26c4414c, 0x2484ffd4, 0xaf420144, 0x8c820030, 0x3c030100, 0xaf420148,
-	0x24020047, 0xaf43014c, 0x00001821, 0xa3420152, 0x3c021000, 0xa7430158,
-	0xaf470154, 0xaf420178, 0x8ec5414c, 0x8d230030, 0x8c860030, 0x24630001,
-	0xad230030, 0x93420109, 0x9343010a, 0xafa70014, 0xafa00018, 0x00021600,
-	0x00031c00, 0x00431025, 0x34424700, 0xafa20010, 0x8f440100, 0x0e000fe1,
-	0x3c070100, 0x3c030800, 0x24624120, 0x0a000d01, 0x8c43001c, 0x32820002,
-	0x10400047, 0x3c039000, 0x34630001, 0x8f820008, 0x32500040, 0x3c048000,
-	0x00431025, 0xaf420020, 0x8f420020, 0x00441024, 0x1440fffd, 0x00000000,
-	0x8f830000, 0x90620005, 0x3c058000, 0x34420008, 0xa0620005, 0x8f860000,
-	0x34a50001, 0x8f840008, 0x8cc20074, 0x3c038000, 0x00852025, 0x00431025,
-	0xacc20074, 0xaf440020, 0x90c3007b, 0x9342010a, 0x14620028, 0x3c040800,
-	0x24072000, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd,
-	0x8ec2414c, 0x26c4414c, 0x2484ffd4, 0xaf420144, 0x8c820030, 0x3c030100,
-	0xaf420148, 0x24020046, 0xaf43014c, 0x00001821, 0xa3420152, 0x3c021000,
-	0xa7430158, 0xaf470154, 0xaf420178, 0x8ec5414c, 0x8d230030, 0x8c860030,
-	0x24630001, 0xad230030, 0x93420109, 0x9343010a, 0xafa70014, 0xafa00018,
-	0x00021600, 0x00031c00, 0x00431025, 0x34424600, 0xafa20010, 0x8f440100,
-	0x0e000fe1, 0x3c070100, 0x3c040800, 0x24824120, 0x0a000d01, 0x8c43001c,
-	0x93420108, 0x30420010, 0x50400050, 0x9343093f, 0x8f860000, 0x90c3007f,
-	0x90c2007e, 0x90c40080, 0x306800ff, 0x00021600, 0x00081c00, 0x00431025,
-	0x00042200, 0x90c3007a, 0x90c5000a, 0x00441025, 0x11050028, 0x00623825,
-	0xa0c8000a, 0x24086000, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024,
-	0x1440fffd, 0x8ec2414c, 0x26c4414c, 0x2484ffd4, 0xaf420144, 0x8c820030,
-	0x00001821, 0xaf420148, 0x24020052, 0xaf47014c, 0xa3420152, 0x3c021000,
-	0xa7430158, 0xaf480154, 0xaf420178, 0x8ec5414c, 0x8d230030, 0x8c860030,
-	0x24630001, 0xad230030, 0x93420109, 0x9343010a, 0xafa80014, 0xafa00018,
-	0x00021600, 0x00031c00, 0x00431025, 0x34425200, 0xafa20010, 0x0e000fe1,
-	0x8f440100, 0x0a000cfb, 0x00000000, 0x3c026000, 0x24030100, 0xac43081c,
-	0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x240003cd, 0x16800009,
-	0x3c040800, 0x3c030800, 0x24624120, 0x8c43001c, 0x32500040, 0x2404ffbf,
-	0x00641824, 0x0a000f13, 0xac43001c, 0x8c824120, 0x10400005, 0x3c030800,
-	0x8c620034, 0xac804120, 0x24420001, 0xac620034, 0x9343093f, 0x24020012,
-	0x1462000f, 0x329e0038, 0x17c0000c, 0x3c030800, 0x8f830000, 0x8c62004c,
-	0xac62005c, 0x3c020800, 0x24444120, 0x8c82001c, 0x32500040, 0x2403ffbf,
-	0x00431024, 0x0a000f13, 0xac82001c, 0xac604120, 0x97420908, 0x000211c0,
+	0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x240003ed,
+	0x8f820000, 0x9044007b, 0x9343010a, 0x14830027, 0x32530040, 0x00003821,
+	0x24052000, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd,
+	0x8ec258b0, 0x26c458b0, 0x2484ffd0, 0xaf420144, 0x8c820034, 0x3c030100,
+	0xaf420148, 0x24020047, 0xaf43014c, 0xa3420152, 0x8d230030, 0x3c021000,
+	0xa7470158, 0xaf450154, 0xaf420178, 0x8c860034, 0x24630001, 0xad230030,
+	0x9342010a, 0x3c030047, 0xafa50014, 0x00021600, 0x00431025, 0x00471025,
+	0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100, 0x8f450104, 0x0e00159b,
+	0x3c070100, 0x3c050800, 0x24a25880, 0x0a001250, 0x8c430020, 0x32820002,
+	0x10400050, 0x00000000, 0x0e0015b9, 0x32530040, 0x3c039000, 0x34630001,
+	0x8f820008, 0x3c048000, 0x00431025, 0xaf420020, 0x8f420020, 0x00441024,
+	0x1440fffd, 0x00000000, 0x8f830000, 0x90620005, 0x34420008, 0xa0620005,
+	0x8f840000, 0x8c820074, 0x3c038000, 0x00431025, 0xac820074, 0x90830000,
+	0x24020020, 0x10620004, 0x00000000, 0x0000000d, 0x00000000, 0x2400040b,
+	0x8f830008, 0x3c028000, 0x34420001, 0x00621825, 0xaf430020, 0x9084007b,
+	0x9342010a, 0x14820028, 0x3c030800, 0x00003821, 0x24052000, 0x3c090800,
+	0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec258b0, 0x26c458b0,
+	0x2484ffd0, 0xaf420144, 0x8c820034, 0x3c030100, 0xaf420148, 0x24020046,
+	0xaf43014c, 0xa3420152, 0x8d230030, 0x3c021000, 0xa7470158, 0xaf450154,
+	0xaf420178, 0x8c860034, 0x24630001, 0xad230030, 0x9342010a, 0x3c030046,
+	0xafa50014, 0x00021600, 0x00431025, 0x00471025, 0xafa20010, 0x9343010b,
+	0xafa30018, 0x8f440100, 0x8f450104, 0x0e00159b, 0x3c070100, 0x3c030800,
+	0x24625880, 0x0a001250, 0x8c430020, 0x93420108, 0x30420010, 0x50400056,
+	0x9343093f, 0x8f860000, 0x90c2007f, 0x8cc30178, 0x304800ff, 0x15030004,
+	0x00000000, 0x0000000d, 0x00000000, 0x24000425, 0x90c2007e, 0x90c40080,
+	0x00081c00, 0x00021600, 0x00431025, 0x00042200, 0x90c3007a, 0x90c5000a,
+	0x00441025, 0x11050028, 0x00623825, 0xa0c8000a, 0x00004021, 0x24056000,
+	0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec258b0,
+	0x26c458b0, 0x2484ffd0, 0xaf420144, 0x8c820034, 0xaf420148, 0x24020052,
+	0xaf47014c, 0xa3420152, 0x8d230030, 0x3c021000, 0xa7480158, 0xaf450154,
+	0xaf420178, 0x8c860034, 0x24630001, 0xad230030, 0x9342010a, 0x3c030052,
+	0xafa50014, 0x00021600, 0x00431025, 0x00481025, 0xafa20010, 0x9343010b,
+	0xafa30018, 0x8f440100, 0x0e00159b, 0x8f450104, 0x0a00124a, 0x00000000,
+	0x3c026000, 0x24030100, 0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d,
+	0x00000000, 0x2400043e, 0x16800009, 0x3c050800, 0x3c040800, 0x24825880,
+	0x8c430020, 0x32530040, 0x2404ffbf, 0x00641824, 0x0a001493, 0xac430020,
+	0x8ca25880, 0x10400005, 0x3c030800, 0x8c620034, 0xaca05880, 0x24420001,
+	0xac620034, 0x9343093f, 0x24020012, 0x5462000e, 0x97420908, 0x32820038,
+	0x14400009, 0x3c030800, 0x8f830000, 0x8c62004c, 0xac62005c, 0x3c020800,
+	0x24445880, 0x8c820020, 0x0a001285, 0x32530040, 0xac605880, 0x97420908,
+	0x5440001c, 0x97420908, 0x3c039000, 0x34630001, 0x8f820008, 0x32530040,
+	0x3c048000, 0x00431025, 0xaf420020, 0x8f420020, 0x00441024, 0x1440fffd,
+	0x3c028000, 0x8f840000, 0x8f850008, 0x8c830050, 0x34420001, 0x00a22825,
+	0xaf830020, 0xac830070, 0xac83005c, 0xaf450020, 0x3c050800, 0x24a45880,
+	0x8c820020, 0x2403ffbf, 0x00431024, 0x0a001493, 0xac820020, 0x000211c0,
 	0xaf420024, 0x97420908, 0x3c030080, 0x34630003, 0x000211c0, 0xaf42080c,
-	0xaf43081c, 0x974209ec, 0x8f4309a4, 0xa7820028, 0x3c020800, 0x24444120,
-	0xac830028, 0x93420937, 0x93430934, 0x00021080, 0x00621821, 0xa4830014,
-	0x934209d8, 0x00621821, 0xa4830016, 0x934209d8, 0x93430934, 0x00809821,
-	0x00431021, 0x24420010, 0xa4820012, 0x0000a821, 0x24020006, 0x13c00003,
-	0xae62001c, 0x0a000d82, 0x24120008, 0x8f420958, 0x8f830020, 0x8f84002c,
-	0x00431023, 0x00832023, 0x04800003, 0xae620004, 0x04410003, 0x0082102b,
-	0x0a000d4e, 0xae600004, 0x54400001, 0xae640004, 0x8ee20000, 0x0040f809,
-	0x00000000, 0x00409021, 0x32420001, 0x5440001e, 0x8ee20004, 0x8e630008,
-	0x1060002b, 0x3c02c000, 0x00621025, 0xaf420e00, 0x8f420000, 0x30420008,
-	0x1040fffd, 0x00000000, 0x97420e08, 0xa7820010, 0x8f430e04, 0x8e620008,
-	0xaf830004, 0x8f840004, 0x0044102b, 0x1040000b, 0x24150001, 0x24020100,
-	0x3c016000, 0xac22081c, 0x3c020001, 0x3c016000, 0xac22081c, 0x0000000d,
-	0x00000000, 0x24000449, 0x24150001, 0x8ee20004, 0x0040f809, 0x00000000,
-	0x02429025, 0x32420002, 0x5040001d, 0x8f470940, 0x12a00006, 0x8ec2414c,
-	0x8f830000, 0xac6200a8, 0x8f840000, 0x8e620030, 0xac8200ac, 0x32420004,
-	0x50400013, 0x8f470940, 0x3c020800, 0x3283007d, 0x106000fe, 0x245741b0,
-	0x32820001, 0x50400006, 0x36520002, 0x8f830030, 0x8f420940, 0x106200f7,
-	0x00000000, 0x36520002, 0x24020008, 0xa660000c, 0xa662000e, 0xae600008,
-	0xa2600020, 0x8f470940, 0x3c030800, 0x24684120, 0x8d020028, 0x8d050008,
-	0x9504000c, 0x9506000a, 0x95030022, 0x00451021, 0x00862021, 0x00641821,
-	0xaf870030, 0xad020028, 0x32820030, 0x10400006, 0xa5030010, 0x91020020,
-	0x32910040, 0x34420004, 0x0a000dd4, 0xa1020020, 0x93420923, 0x30420040,
+	0xaf43081c, 0x974209ec, 0x8f4309a4, 0xa782002c, 0x3c020800, 0x24445880,
+	0xac83002c, 0x93420937, 0x93430934, 0x00021080, 0x00621821, 0xa4830018,
+	0x934209d8, 0x32850038, 0xafa50028, 0x00621821, 0xa483001a, 0x934209d8,
+	0x93430934, 0x3c1e0800, 0x00809821, 0x00431021, 0x24420010, 0xa4820016,
+	0x24020006, 0xae620020, 0x8fa20028, 0x10400003, 0x0000a821, 0x0a0012f0,
+	0x24120008, 0x8f420958, 0x8f830020, 0x8f840030, 0x00431023, 0x00832023,
+	0x04800003, 0xae620004, 0x04410003, 0x0082102b, 0x0a0012bc, 0xae600004,
+	0x54400001, 0xae640004, 0x8ee20000, 0x0040f809, 0x00000000, 0x00409021,
+	0x32420001, 0x5440001e, 0x8ee20004, 0x8e630008, 0x1060002b, 0x3c02c000,
+	0x00621025, 0xaf420e00, 0x8f420000, 0x30420008, 0x1040fffd, 0x00000000,
+	0x97420e08, 0xa7820010, 0x8f430e04, 0x8e620008, 0xaf830004, 0x8f840004,
+	0x0044102b, 0x1040000b, 0x24150001, 0x24020100, 0x3c016000, 0xac22081c,
+	0x3c020001, 0x3c016000, 0xac22081c, 0x0000000d, 0x00000000, 0x240004cd,
+	0x24150001, 0x8ee20004, 0x0040f809, 0x00000000, 0x02429025, 0x32420002,
+	0x5040001d, 0x8f470940, 0x12a00006, 0x8ec258b0, 0x8f830000, 0xac6200a8,
+	0x8f840000, 0x8e620034, 0xac8200ac, 0x32420004, 0x50400013, 0x8f470940,
+	0x3c020800, 0x3283007d, 0x10600110, 0x24575920, 0x32820001, 0x50400006,
+	0x36520002, 0x8f830034, 0x8f420940, 0x10620109, 0x00000000, 0x36520002,
+	0x24020008, 0xa6600010, 0xa6620012, 0xae600008, 0xa2600024, 0x8f470940,
+	0x3c030800, 0x24685880, 0x8d02002c, 0x8d050008, 0x95040010, 0x9506000a,
+	0x95030026, 0x00451021, 0x00862021, 0x00641821, 0xaf870034, 0xad02002c,
+	0x32820030, 0x10400008, 0xa5030014, 0x91020024, 0x32910040, 0x34420004,
+	0xa1020024, 0xaf400048, 0x0a001345, 0x3c040800, 0x93420923, 0x30420002,
 	0x10400029, 0x32910040, 0x8f830000, 0x8f840020, 0x8c620084, 0x00441023,
-	0x0442000a, 0x3c039000, 0x95020010, 0x8c630084, 0x00821021, 0x00621823,
-	0x1c600004, 0x3c039000, 0x91020020, 0x34420001, 0xa1020020, 0x34630001,
+	0x0442000a, 0x3c039000, 0x95020014, 0x8c630084, 0x00821021, 0x00621823,
+	0x1c600004, 0x3c039000, 0x91020024, 0x34420001, 0xa1020024, 0x34630001,
 	0x8f820008, 0x32910040, 0x3c048000, 0x00431025, 0xaf420020, 0x8f420020,
 	0x00441024, 0x1440fffd, 0x00000000, 0x8f840000, 0x9083003f, 0x2402000a,
 	0x10620005, 0x2402000c, 0x9083003f, 0x24020008, 0x14620002, 0x24020014,
 	0xa082003f, 0x8f830008, 0x3c028000, 0x34420001, 0x00621825, 0xaf430020,
-	0x3c040800, 0x24904120, 0x9602000c, 0x96030016, 0x9604000e, 0x00431021,
-	0x00442021, 0x24840002, 0x3084ffff, 0x0e000a55, 0xa6020018, 0x8f850018,
-	0x00a01821, 0xa2030021, 0x8ee60008, 0x00402021, 0x24a50001, 0xaf850018,
-	0x00c0f809, 0x00000000, 0x00402021, 0x0e000b12, 0x02202821, 0x8ee3000c,
-	0x0060f809, 0x00402021, 0x96040018, 0x9602000e, 0x00822021, 0x24840002,
-	0x0e000a6b, 0x3084ffff, 0x3c030800, 0x8c624120, 0x8e030008, 0x3c040800,
-	0x00431023, 0x14400012, 0xac824120, 0x54600006, 0x8e02001c, 0x3243004a,
-	0x24020002, 0x14620005, 0x00000000, 0x8e02001c, 0x34420040, 0x0a000e0b,
-	0xae02001c, 0x52a00006, 0x36520002, 0x8e02002c, 0xaf420e10, 0x8e030030,
-	0xaf430e18, 0x36520002, 0x52a00008, 0x96670010, 0x8f830000, 0x8f420e10,
-	0xac6200a8, 0x8f840000, 0x8f420e18, 0xac8200ac, 0x96670010, 0x92680020,
-	0x24020040, 0xaf420814, 0x8f830020, 0x8f82001c, 0x00671821, 0x00621023,
-	0xaf830020, 0x58400005, 0x8f42095c, 0x8f820000, 0xaf83001c, 0xac430054,
-	0x8f42095c, 0x31030008, 0xaf82002c, 0x1060001a, 0x00000000, 0x8f840000,
-	0x90820120, 0x90830121, 0x304600ff, 0x00c31823, 0x30630007, 0x24020007,
-	0x1062000e, 0x00000000, 0x90820122, 0x304200fe, 0xa0820122, 0x8f850000,
-	0x00061880, 0x8f840020, 0x24a20100, 0x00431021, 0x24c30001, 0x30630007,
-	0xac440000, 0x0a000e40, 0xa0a30120, 0x90820122, 0x34420001, 0xa0820122,
-	0x14e00003, 0x31020001, 0x10400031, 0x32510002, 0x8f820000, 0x8c43000c,
-	0x30630001, 0x1060002c, 0x32510002, 0x3c029000, 0x8f830008, 0x34420001,
-	0x3c048000, 0x00621825, 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd,
-	0x00000000, 0x8f870000, 0x8ce2000c, 0x30420001, 0x10400018, 0x00000000,
-	0x94e2006a, 0x00022880, 0x50a00001, 0x24050001, 0x94e30068, 0x90e40081,
-	0x3c020800, 0x8c460024, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001,
-	0x00a03021, 0x3c020800, 0x8c440028, 0x00c4182b, 0x54600001, 0x00c02021,
-	0x8f430074, 0x2402fffe, 0x00822824, 0x00a31821, 0xace3000c, 0x8f830008,
-	0x3c028000, 0x34420001, 0x00621825, 0xaf430020, 0x8f830020, 0x3c020800,
-	0x24504120, 0xae030024, 0x8ee20010, 0x0040f809, 0x00000000, 0x12a00005,
-	0x00000000, 0x8f420e10, 0xae02002c, 0x8f430e18, 0xae030030, 0x1220feba,
-	0x0000a821, 0x8f870024, 0x97860028, 0x8f830000, 0x8f820030, 0x8f840020,
-	0x8f85001c, 0x32500040, 0xa4e6002c, 0xac620044, 0x32420008, 0xac640050,
-	0xac650054, 0x1040007a, 0x32820020, 0x10400027, 0x32910010, 0x24072000,
-	0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec2414c,
-	0x26c4414c, 0x2484ffd4, 0xaf420144, 0x8c820030, 0x3c030400, 0xaf420148,
-	0x24020041, 0xaf43014c, 0x00001821, 0xa3420152, 0x3c021000, 0xa7430158,
-	0xaf470154, 0xaf420178, 0x8ec5414c, 0x8d230030, 0x8c860030, 0x24630001,
-	0xad230030, 0x93420109, 0x9343010a, 0xafa70014, 0xafa00018, 0x00021600,
-	0x00031c00, 0x00431025, 0x34424100, 0xafa20010, 0x8f440100, 0x0e000fe1,
-	0x3c070400, 0x12200028, 0x24072000, 0x3c090800, 0x3c038000, 0x8f420178,
-	0x00431024, 0x1440fffd, 0x8ec2414c, 0x26c4414c, 0x2484ffd4, 0xaf420144,
-	0x8c820030, 0x3c030300, 0xaf420148, 0x2402004e, 0xaf43014c, 0x00001821,
-	0xa3420152, 0x3c021000, 0xa7430158, 0xaf470154, 0xaf420178, 0x8ec5414c,
-	0x8d230030, 0x8c860030, 0x24630001, 0xad230030, 0x93420109, 0x9343010a,
-	0xafa70014, 0xafa00018, 0x00021600, 0x00031c00, 0x00431025, 0x34424e00,
-	0xafa20010, 0x8f440100, 0x0e000fe1, 0x3c070300, 0x0a000f0b, 0x8fa30024,
-	0x32820008, 0x10400026, 0x3c090800, 0x24072000, 0x3c038000, 0x8f420178,
-	0x00431024, 0x1440fffd, 0x8ec2414c, 0x26c4414c, 0x2484ffd4, 0xaf420144,
-	0x8c820030, 0x3c030200, 0xaf420148, 0x2402004b, 0xaf43014c, 0x00001821,
-	0xa3420152, 0x3c021000, 0xa7430158, 0xaf470154, 0xaf420178, 0x8ec5414c,
-	0x8d230030, 0x8c860030, 0x24630001, 0xad230030, 0x93420109, 0x9343010a,
-	0xafa70014, 0xafa00018, 0x00021600, 0x00031c00, 0x00431025, 0x34424b00,
-	0xafa20010, 0x8f440100, 0x0e000fe1, 0x3c070200, 0x8fa30024, 0x14600004,
-	0x8fa40020, 0x32420010, 0x10400004, 0x00000000, 0x8c820004, 0x0040f809,
-	0x00000000, 0x12000006, 0x8fa30020, 0x8c620008, 0x0040f809, 0x00000000,
-	0x0a000f4d, 0x8fbf004c, 0x3c030800, 0x8c62413c, 0x30420040, 0x1440002f,
-	0x8fbf004c, 0x24040040, 0x8f910020, 0x3c038000, 0x8f420178, 0x00431024,
-	0x1440fffd, 0x8ec2414c, 0x26d0414c, 0x2610ffd4, 0xaf420144, 0x8e020030,
-	0x00001821, 0xaf420148, 0x24020049, 0xaf51014c, 0xa3420152, 0x3c021000,
-	0xa7430158, 0xaf440154, 0xaf420178, 0x8ec5414c, 0x8e060030, 0x93420109,
-	0x9343010a, 0xafa40014, 0xafa00018, 0x00021600, 0x00031c00, 0x00431025,
-	0x34424900, 0xafa20010, 0x8f440100, 0x0e000fe1, 0x02203821, 0x8f830000,
-	0x8e020030, 0x8c64017c, 0x02221023, 0x00441023, 0x2c420002, 0x14400005,
-	0x8fbf004c, 0x0000000d, 0x00000000, 0x240000ca, 0x8fbf004c, 0x8fbe0048,
-	0x8fb70044, 0x8fb60040, 0x8fb5003c, 0x8fb40038, 0x8fb30034, 0x8fb20030,
-	0x8fb1002c, 0x8fb00028, 0x03e00008, 0x27bd0050, 0x03e00008, 0x00001021,
-	0x3c030800, 0x24654120, 0x8ca40004, 0x8c634120, 0x0064102b, 0x54400001,
-	0x00602021, 0x9743093c, 0x0083102b, 0x54400001, 0x00801821, 0x00001021,
-	0xaca30008, 0x03e00008, 0xa4a00022, 0x8f850004, 0x97840010, 0x3c030800,
-	0x24634120, 0x24020008, 0xa462000e, 0x8f820004, 0xa460000c, 0x000420c2,
+	0x3c040800, 0x24865880, 0x94c20010, 0x94c3001a, 0x8cc40008, 0x00432821,
+	0x14800006, 0xa4c5001c, 0x3c020800, 0x8c430048, 0x10600002, 0x24a20040,
+	0xa4c2001c, 0x27d05880, 0x9604001c, 0x96020012, 0x00822021, 0x24840002,
+	0x0e000faf, 0x3084ffff, 0x8f850018, 0x00a01821, 0xa2030025, 0x8ee60008,
+	0x00402021, 0x24a50001, 0xaf850018, 0x00c0f809, 0x00000000, 0x00402021,
+	0x0e001026, 0x02202821, 0x8ee3000c, 0x0060f809, 0x00402021, 0x9604001c,
+	0x96020012, 0x00822021, 0x24840002, 0x0e000fc5, 0x3084ffff, 0x8fc25880,
+	0x8e030008, 0x00431023, 0x14400012, 0xafc25880, 0x54600006, 0x8e020020,
+	0x3243004a, 0x24020002, 0x14620005, 0x00000000, 0x8e020020, 0x34420040,
+	0x0a001382, 0xae020020, 0x52a00006, 0x36520002, 0x8e020030, 0xaf420e10,
+	0x8e030034, 0xaf430e18, 0x36520002, 0x52a00008, 0x96670014, 0x8f830000,
+	0x8f420e10, 0xac6200a8, 0x8f840000, 0x8f420e18, 0xac8200ac, 0x96670014,
+	0x92680024, 0x24020040, 0xaf420814, 0x8f830020, 0x8f82001c, 0x00671821,
+	0x00621023, 0xaf830020, 0x18400008, 0x00000000, 0x8f820000, 0xaf83001c,
+	0xac430054, 0x54e00005, 0xaf400040, 0x0a0013a0, 0x8f42095c, 0x54e00001,
+	0xaf400044, 0x8f42095c, 0x31030008, 0xaf820030, 0x1060001a, 0x00000000,
+	0x8f840000, 0x90820120, 0x90830121, 0x304600ff, 0x00c31823, 0x30630007,
+	0x24020007, 0x1062000e, 0x00000000, 0x90820122, 0x304200fe, 0xa0820122,
+	0x8f850000, 0x00061880, 0x8f840020, 0x24a20100, 0x00431021, 0x24c30001,
+	0x30630007, 0xac440000, 0x0a0013bd, 0xa0a30120, 0x90820122, 0x34420001,
+	0xa0820122, 0x14e00003, 0x31020001, 0x10400031, 0x32510002, 0x8f820000,
+	0x8c43000c, 0x30630001, 0x1060002c, 0x32510002, 0x3c029000, 0x8f830008,
+	0x34420001, 0x3c048000, 0x00621825, 0xaf430020, 0x8f420020, 0x00441024,
+	0x1440fffd, 0x00000000, 0x8f870000, 0x8ce2000c, 0x30420001, 0x10400018,
+	0x00000000, 0x94e2006a, 0x00022880, 0x50a00001, 0x24050001, 0x94e30068,
+	0x90e40081, 0x3c020800, 0x8c460024, 0x00652821, 0x00852804, 0x00c5102b,
+	0x54400001, 0x00a03021, 0x3c020800, 0x8c440028, 0x00c4182b, 0x54600001,
+	0x00c02021, 0x8f430074, 0x2402fffe, 0x00822824, 0x00a31821, 0xace3000c,
+	0x8f830008, 0x3c028000, 0x34420001, 0x00621825, 0xaf430020, 0x8f820020,
+	0x3c050800, 0x24b05880, 0xae020028, 0x8ee30010, 0x0060f809, 0x00000000,
+	0x8f820028, 0x24420001, 0xaf820028, 0x12a00005, 0xaf40004c, 0x8f420e10,
+	0xae020030, 0x8f430e18, 0xae030034, 0x1220fea7, 0x24020006, 0x8f870024,
+	0x9786002c, 0x8f830000, 0x8f820034, 0x8f840020, 0x8f85001c, 0x32530040,
+	0xa4e6002c, 0xac620044, 0x32420008, 0xac640050, 0xac650054, 0x1040007a,
+	0x32820020, 0x10400027, 0x32910010, 0x00003821, 0x24052000, 0x3c090800,
+	0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec258b0, 0x26c458b0,
+	0x2484ffd0, 0xaf420144, 0x8c820034, 0x3c030400, 0xaf420148, 0x24020041,
+	0xaf43014c, 0xa3420152, 0x8d230030, 0x3c021000, 0xa7470158, 0xaf450154,
+	0xaf420178, 0x8c860034, 0x24630001, 0xad230030, 0x9342010a, 0x3c030041,
+	0xafa50014, 0x00021600, 0x00431025, 0x00471025, 0xafa20010, 0x9343010b,
+	0xafa30018, 0x8f440100, 0x8f450104, 0x0e00159b, 0x3c070400, 0x12200028,
+	0x00003821, 0x24052000, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024,
+	0x1440fffd, 0x8ec258b0, 0x26c458b0, 0x2484ffd0, 0xaf420144, 0x8c820034,
+	0x3c030300, 0xaf420148, 0x2402004e, 0xaf43014c, 0xa3420152, 0x8d230030,
+	0x3c021000, 0xa7470158, 0xaf450154, 0xaf420178, 0x8c860034, 0x24630001,
+	0xad230030, 0x9342010a, 0x3c03004e, 0xafa50014, 0x00021600, 0x00431025,
+	0x00471025, 0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100, 0x8f450104,
+	0x0e00159b, 0x3c070300, 0x0a00148b, 0x8fa20024, 0x32820008, 0x10400026,
+	0x24052000, 0x00003821, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024,
+	0x1440fffd, 0x8ec258b0, 0x26c458b0, 0x2484ffd0, 0xaf420144, 0x8c820034,
+	0x3c030200, 0xaf420148, 0x2402004b, 0xaf43014c, 0xa3420152, 0x8d230030,
+	0x3c021000, 0xa7470158, 0xaf450154, 0xaf420178, 0x8c860034, 0x24630001,
+	0xad230030, 0x9342010a, 0x3c03004b, 0xafa50014, 0x00021600, 0x00431025,
+	0x00471025, 0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100, 0x8f450104,
+	0x0e00159b, 0x3c070200, 0x8fa20024, 0x14400004, 0x8fa30020, 0x32420010,
+	0x10400004, 0x00000000, 0x8c620004, 0x0040f809, 0x00000000, 0x12600006,
+	0x8fa40020, 0x8c820008, 0x0040f809, 0x00000000, 0x0a0014c1, 0x8fbf0054,
+	0x3c030800, 0x8c6258a0, 0x30420040, 0x14400023, 0x8fbf0054, 0x00002821,
+	0x24040040, 0x8f870020, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd,
+	0x8ec258b0, 0x26c358b0, 0x2463ffd0, 0xaf420144, 0x8c620034, 0xaf420148,
+	0x24020049, 0xaf47014c, 0xa3420152, 0x3c021000, 0xa7450158, 0xaf440154,
+	0xaf420178, 0x8c660034, 0x9342010a, 0x3c030049, 0xafa40014, 0x00021600,
+	0x00431025, 0x00451025, 0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100,
+	0x0e00159b, 0x8f450104, 0x8fbf0054, 0x8fbe0050, 0x8fb7004c, 0x8fb60048,
+	0x8fb50044, 0x8fb40040, 0x8fb3003c, 0x8fb20038, 0x8fb10034, 0x8fb00030,
+	0x03e00008, 0x27bd0058, 0x03e00008, 0x00001021, 0x3c020800, 0x24435880,
+	0x8c650004, 0x8c445880, 0x0085182b, 0x10600002, 0x00403021, 0x00802821,
+	0x9744093c, 0x00a4102b, 0x54400001, 0x00a02021, 0x93420923, 0x0004182b,
+	0x00021042, 0x30420001, 0x00431024, 0x1040000d, 0x24c25880, 0x8f850000,
+	0x8f830020, 0x8ca20084, 0x00431023, 0x04420007, 0x24c25880, 0x8ca20084,
+	0x00641821, 0x00431023, 0x28420001, 0x00822023, 0x24c25880, 0xac440008,
+	0xa4400026, 0x03e00008, 0x00001021, 0x8f850004, 0x97840010, 0x3c030800,
+	0x24635880, 0x24020008, 0xa4620012, 0x8f820004, 0xa4600010, 0x000420c2,
 	0x30840008, 0x2c420001, 0x00021023, 0x30420006, 0xac650008, 0x03e00008,
-	0xa0640020, 0x3c020800, 0x24424120, 0x90450021, 0x94430018, 0x3c021100,
+	0xa0640024, 0x3c020800, 0x24425880, 0x90450025, 0x9443001c, 0x3c021100,
 	0xac800004, 0x00052c00, 0x24630002, 0x00621825, 0x00a32825, 0x24820008,
-	0x03e00008, 0xac850000, 0x0000000d, 0x00000000, 0x2400016f, 0x03e00008,
-	0x00000000, 0x0000000d, 0x00000000, 0x2400017b, 0x03e00008, 0x00000000,
-	0x03e00008, 0x00000000, 0x3c020800, 0x24424120, 0xac400008, 0xa4400022,
-	0x03e00008, 0x24020001, 0x3c020800, 0x24424120, 0x24030008, 0xac400008,
-	0xa440000c, 0xa443000e, 0xa0400020, 0x03e00008, 0x24020004, 0x03e00008,
+	0x03e00008, 0xac850000, 0x27bdffd8, 0x3c020800, 0x24425880, 0xafbf0020,
+	0x90480025, 0x8c440008, 0x8c460020, 0x8f870020, 0x3c030800, 0x3c058000,
+	0x8f420178, 0x00451024, 0x1440fffd, 0x8c6258b0, 0x246358b0, 0x2469ffd0,
+	0xaf420144, 0x8d220034, 0x30c32000, 0xaf420148, 0x3c021000, 0xaf47014c,
+	0xa3480152, 0xa7440158, 0xaf460154, 0xaf420178, 0x10600004, 0x3c030800,
+	0x8c620030, 0x24420001, 0xac620030, 0x9342010a, 0x00081c00, 0x3084ffff,
+	0xafa60014, 0x00021600, 0x00431025, 0x00441025, 0xafa20010, 0x9343010b,
+	0xafa30018, 0x8f440100, 0x8f450104, 0x0e00159b, 0x8d260034, 0x8fbf0020,
+	0x03e00008, 0x27bd0028, 0x0000000d, 0x00000000, 0x2400019d, 0x03e00008,
+	0x00000000, 0x0000000d, 0x00000000, 0x240001a9, 0x03e00008, 0x00000000,
+	0x03e00008, 0x00000000, 0x3c020800, 0x24425880, 0xac400008, 0xa4400026,
+	0x03e00008, 0x24020001, 0x3c020800, 0x24425880, 0x24030008, 0xac400008,
+	0xa4400010, 0xa4430012, 0xa0400024, 0x03e00008, 0x24020004, 0x03e00008,
 	0x00001021, 0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004,
-	0xac820000, 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a000fb2,
-	0x00a01021, 0xac860000, 0x24840004, 0x00a01021, 0x1440fffc, 0x24a5ffff,
-	0x03e00008, 0x00000000, 0x3c0a0800, 0x8d490068, 0x3c050800, 0x24a51090,
-	0x00093140, 0x00c51021, 0xac440000, 0x8f440e04, 0x00a61021, 0xac440004,
-	0x97430e08, 0x97420e0c, 0x00a62021, 0x00031c00, 0x00431025, 0xac820008,
-	0x8f430e10, 0x00801021, 0xac43000c, 0x8f440e14, 0xac440010, 0x8f430e18,
-	0x3c0800ff, 0xac430014, 0x8f470e1c, 0x3508ffff, 0x25290001, 0xac470018,
-	0x3c070800, 0x8ce3006c, 0x9344010a, 0x3c026000, 0x24630001, 0xace3006c,
-	0x8c434448, 0x3129007f, 0x00a62821, 0xad490068, 0x00042600, 0x00681824,
-	0x00832025, 0x03e00008, 0xaca4001c, 0x8fac0010, 0x8fad0014, 0x8fae0018,
-	0x3c0b0800, 0x8d6a0060, 0x3c080800, 0x25080078, 0x000a4940, 0x01281021,
-	0x01091821, 0xac440000, 0x00601021, 0xac650004, 0xac460008, 0xac67000c,
-	0xac4c0010, 0xac6d0014, 0x3c036000, 0xac4e0018, 0x8c654448, 0x3c040800,
-	0x8c820064, 0x254a0001, 0x314a007f, 0x01094021, 0xad6a0060, 0x24420001,
-	0xac820064, 0x03e00008, 0xad05001c, 0x00000000 };
+	0xac820000, 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a00156c,
+	0x00a01021, 0xac860000, 0x00000000, 0x00000000, 0x24840004, 0x00a01021,
+	0x1440fffa, 0x24a5ffff, 0x03e00008, 0x00000000, 0x3c0a0800, 0x8d490068,
+	0x3c050800, 0x24a52098, 0x00093140, 0x00c51021, 0xac440000, 0x8f440e04,
+	0x00a61021, 0xac440004, 0x97430e08, 0x97420e0c, 0x00a62021, 0x00031c00,
+	0x00431025, 0xac820008, 0x8f430e10, 0x00801021, 0xac43000c, 0x8f440e14,
+	0xac440010, 0x8f430e18, 0x3c0800ff, 0xac430014, 0x8f470e1c, 0x3508ffff,
+	0x25290001, 0xac470018, 0x3c070800, 0x8ce3006c, 0x9344010a, 0x3c026000,
+	0x24630001, 0xace3006c, 0x8c434448, 0x3129007f, 0x00a62821, 0xad490068,
+	0x00042600, 0x00681824, 0x00832025, 0x03e00008, 0xaca4001c, 0x8fac0010,
+	0x8fad0014, 0x8fae0018, 0x3c0b0800, 0x8d6a0060, 0x3c080800, 0x25080080,
+	0x000a4940, 0x01281021, 0x01091821, 0xac440000, 0x00601021, 0xac650004,
+	0xac460008, 0xac67000c, 0xac4c0010, 0xac6d0014, 0x3c036000, 0xac4e0018,
+	0x8c654448, 0x3c040800, 0x8c820064, 0x254a0001, 0x314a00ff, 0x01094021,
+	0xad6a0060, 0x24420001, 0xac820064, 0x03e00008, 0xad05001c, 0x3c030800,
+	0x3c090800, 0x8d250070, 0x246330b0, 0x8f460100, 0x00053900, 0x00e31021,
+	0xac460000, 0x8f440104, 0x00671021, 0xac440004, 0x8f460108, 0x8f840014,
+	0x24a50001, 0xac460008, 0x8c880074, 0x3c060800, 0x8cc20074, 0x30a5003f,
+	0x00671821, 0xad250070, 0x24420001, 0xacc20074, 0x03e00008, 0xac68000c,
+	0x00000000 };
 
-static u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x00000000 };
-static u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x00000000 };
-static u32 bnx2_TXP_b06FwBss[(0x194/4) + 1] = { 0x00000000 };
-static u32 bnx2_TXP_b06FwSbss[(0x34/4) + 1] = { 0x00000000 };
-
+static u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_TXP_b06FwBss[(0x1c4/4) + 1] = { 0x0 };
+static u32 bnx2_TXP_b06FwSbss[(0x38/4) + 1] = { 0x0 };
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 9c7feae..8eae8ba 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -1739,7 +1739,7 @@
 	}
 }
 
-struct ethtool_ops e1000_ethtool_ops = {
+static struct ethtool_ops e1000_ethtool_ops = {
 	.get_settings           = e1000_get_settings,
 	.set_settings           = e1000_set_settings,
 	.get_drvinfo            = e1000_get_drvinfo,
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index 8fc876d..a267c52 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -68,6 +68,38 @@
 static int32_t e1000_set_phy_mode(struct e1000_hw *hw);
 static int32_t e1000_host_if_read_cookie(struct e1000_hw *hw, uint8_t *buffer);
 static uint8_t e1000_calculate_mng_checksum(char *buffer, uint32_t length);
+static uint8_t e1000_arc_subsystem_valid(struct e1000_hw *hw);
+static int32_t e1000_check_downshift(struct e1000_hw *hw);
+static int32_t e1000_check_polarity(struct e1000_hw *hw, uint16_t *polarity);
+static void e1000_clear_hw_cntrs(struct e1000_hw *hw);
+static void e1000_clear_vfta(struct e1000_hw *hw);
+static int32_t e1000_commit_shadow_ram(struct e1000_hw *hw);
+static int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw,
+						  boolean_t link_up);
+static int32_t e1000_config_fc_after_link_up(struct e1000_hw *hw);
+static int32_t e1000_detect_gig_phy(struct e1000_hw *hw);
+static int32_t e1000_get_auto_rd_done(struct e1000_hw *hw);
+static int32_t e1000_get_cable_length(struct e1000_hw *hw,
+				      uint16_t *min_length,
+				      uint16_t *max_length);
+static int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
+static int32_t e1000_get_phy_cfg_done(struct e1000_hw *hw);
+static int32_t e1000_id_led_init(struct e1000_hw * hw);
+static void e1000_init_rx_addrs(struct e1000_hw *hw);
+static boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw);
+static int32_t e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
+static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
+static int32_t e1000_read_eeprom_eerd(struct e1000_hw *hw, uint16_t offset,
+				      uint16_t words, uint16_t *data);
+static int32_t e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active);
+static int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
+static int32_t e1000_wait_autoneg(struct e1000_hw *hw);
+
+static void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset,
+			       uint32_t value);
+
+#define E1000_WRITE_REG_IO(a, reg, val) \
+	    e1000_write_reg_io((a), E1000_##reg, val)
 
 /* IGP cable length table */
 static const
@@ -2035,7 +2067,7 @@
  * based on the flow control negotiated by the PHY. In TBI mode, the TFCE
  * and RFCE bits will be automaticaly set to the negotiated flow control mode.
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_config_fc_after_link_up(struct e1000_hw *hw)
 {
     int32_t ret_val;
@@ -2537,7 +2569,7 @@
 *
 * hw - Struct containing variables accessed by shared code
 ******************************************************************************/
-int32_t
+static int32_t
 e1000_wait_autoneg(struct e1000_hw *hw)
 {
     int32_t ret_val;
@@ -3021,7 +3053,7 @@
 *
 * hw - Struct containing variables accessed by shared code
 ******************************************************************************/
-int32_t
+static int32_t
 e1000_detect_gig_phy(struct e1000_hw *hw)
 {
     int32_t phy_init_status, ret_val;
@@ -3121,7 +3153,7 @@
 * hw - Struct containing variables accessed by shared code
 * phy_info - PHY information structure
 ******************************************************************************/
-int32_t
+static int32_t
 e1000_phy_igp_get_info(struct e1000_hw *hw,
                        struct e1000_phy_info *phy_info)
 {
@@ -3195,7 +3227,7 @@
 * hw - Struct containing variables accessed by shared code
 * phy_info - PHY information structure
 ******************************************************************************/
-int32_t
+static int32_t
 e1000_phy_m88_get_info(struct e1000_hw *hw,
                        struct e1000_phy_info *phy_info)
 {
@@ -3905,7 +3937,7 @@
  * data - word read from the EEPROM
  * words - number of words to read
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_read_eeprom_eerd(struct e1000_hw *hw,
                   uint16_t offset,
                   uint16_t words,
@@ -3939,7 +3971,7 @@
  * data - word read from the EEPROM
  * words - number of words to read
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_write_eeprom_eewr(struct e1000_hw *hw,
                    uint16_t offset,
                    uint16_t words,
@@ -3976,7 +4008,7 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd)
 {
     uint32_t attempts = 100000;
@@ -4004,7 +4036,7 @@
 *
 * hw - Struct containing variables accessed by shared code
 ****************************************************************************/
-boolean_t
+static boolean_t
 e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw)
 {
     uint32_t eecd = 0;
@@ -4322,7 +4354,7 @@
  * data - word read from the EEPROM
  * words - number of words to read
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_commit_shadow_ram(struct e1000_hw *hw)
 {
     uint32_t attempts = 100000;
@@ -4453,7 +4485,7 @@
  * of the receive addresss registers. Clears the multicast table. Assumes
  * the receiver is in reset when the routine is called.
  *****************************************************************************/
-void
+static void
 e1000_init_rx_addrs(struct e1000_hw *hw)
 {
     uint32_t i;
@@ -4481,6 +4513,7 @@
     }
 }
 
+#if 0
 /******************************************************************************
  * Updates the MAC's list of multicast addresses.
  *
@@ -4564,6 +4597,7 @@
     }
     DEBUGOUT("MC Update Complete\n");
 }
+#endif  /*  0  */
 
 /******************************************************************************
  * Hashes an address to determine its location in the multicast table
@@ -4705,7 +4739,7 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void
+static void
 e1000_clear_vfta(struct e1000_hw *hw)
 {
     uint32_t offset;
@@ -4735,7 +4769,7 @@
     }
 }
 
-int32_t
+static int32_t
 e1000_id_led_init(struct e1000_hw * hw)
 {
     uint32_t ledctl;
@@ -4997,7 +5031,7 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void
+static void
 e1000_clear_hw_cntrs(struct e1000_hw *hw)
 {
     volatile uint32_t temp;
@@ -5283,6 +5317,8 @@
         break;
     }
 }
+
+#if 0
 /******************************************************************************
  * Reads a value from one of the devices registers using port I/O (as opposed
  * memory mapped I/O). Only 82544 and newer devices support port I/O.
@@ -5300,6 +5336,7 @@
     e1000_io_write(hw, io_addr, offset);
     return e1000_io_read(hw, io_data);
 }
+#endif  /*  0  */
 
 /******************************************************************************
  * Writes a value to one of the devices registers using port I/O (as opposed to
@@ -5309,7 +5346,7 @@
  * offset - offset to write to
  * value - value to write
  *****************************************************************************/
-void
+static void
 e1000_write_reg_io(struct e1000_hw *hw,
                    uint32_t offset,
                    uint32_t value)
@@ -5337,7 +5374,7 @@
  * register to the minimum and maximum range.
  * For IGP phy's, the function calculates the range by the AGC registers.
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_get_cable_length(struct e1000_hw *hw,
                        uint16_t *min_length,
                        uint16_t *max_length)
@@ -5489,7 +5526,7 @@
  * return 0.  If the link speed is 1000 Mbps the polarity status is in the
  * IGP01E1000_PHY_PCS_INIT_REG.
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_check_polarity(struct e1000_hw *hw,
                      uint16_t *polarity)
 {
@@ -5551,7 +5588,7 @@
  * Link Health register.  In IGP this bit is latched high, so the driver must
  * read it immediately after link is established.
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_check_downshift(struct e1000_hw *hw)
 {
     int32_t ret_val;
@@ -5592,7 +5629,7 @@
  *
  ****************************************************************************/
 
-int32_t
+static int32_t
 e1000_config_dsp_after_link_change(struct e1000_hw *hw,
                                    boolean_t link_up)
 {
@@ -5823,7 +5860,7 @@
  *
  ****************************************************************************/
 
-int32_t
+static int32_t
 e1000_set_d3_lplu_state(struct e1000_hw *hw,
                         boolean_t active)
 {
@@ -5936,7 +5973,7 @@
  *
  ****************************************************************************/
 
-int32_t
+static int32_t
 e1000_set_d0_lplu_state(struct e1000_hw *hw,
                         boolean_t active)
 {
@@ -6103,7 +6140,7 @@
  *            timeout
  *          - E1000_SUCCESS for success.
  ****************************************************************************/
-int32_t
+static int32_t
 e1000_mng_enable_host_if(struct e1000_hw * hw)
 {
     uint32_t hicr;
@@ -6137,7 +6174,7 @@
  *
  * returns  - E1000_SUCCESS for success.
  ****************************************************************************/
-int32_t
+static int32_t
 e1000_mng_host_if_write(struct e1000_hw * hw, uint8_t *buffer,
                         uint16_t length, uint16_t offset, uint8_t *sum)
 {
@@ -6205,7 +6242,7 @@
  *
  * returns  - E1000_SUCCESS for success.
  ****************************************************************************/
-int32_t
+static int32_t
 e1000_mng_write_cmd_header(struct e1000_hw * hw,
                            struct e1000_host_mng_command_header * hdr)
 {
@@ -6243,7 +6280,7 @@
  *
  * returns  - E1000_SUCCESS for success.
  ****************************************************************************/
-int32_t
+static int32_t
 e1000_mng_write_commit(
     struct e1000_hw * hw)
 {
@@ -6496,7 +6533,7 @@
  * returns: - none.
  *
  ***************************************************************************/
-void
+static void
 e1000_set_pci_express_master_disable(struct e1000_hw *hw)
 {
     uint32_t ctrl;
@@ -6511,6 +6548,7 @@
     E1000_WRITE_REG(hw, CTRL, ctrl);
 }
 
+#if 0
 /***************************************************************************
  *
  * Enables PCI-Express master access.
@@ -6534,6 +6572,7 @@
     ctrl &= ~E1000_CTRL_GIO_MASTER_DISABLE;
     E1000_WRITE_REG(hw, CTRL, ctrl);
 }
+#endif  /*  0  */
 
 /*******************************************************************************
  *
@@ -6584,7 +6623,7 @@
  *            E1000_SUCCESS at any other case.
  *
  ******************************************************************************/
-int32_t
+static int32_t
 e1000_get_auto_rd_done(struct e1000_hw *hw)
 {
     int32_t timeout = AUTO_READ_DONE_TIMEOUT;
@@ -6623,7 +6662,7 @@
  *            E1000_SUCCESS at any other case.
  *
  ***************************************************************************/
-int32_t
+static int32_t
 e1000_get_phy_cfg_done(struct e1000_hw *hw)
 {
     int32_t timeout = PHY_CFG_TIMEOUT;
@@ -6666,7 +6705,7 @@
  *            E1000_SUCCESS at any other case.
  *
  ***************************************************************************/
-int32_t
+static int32_t
 e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
 {
     int32_t timeout;
@@ -6711,7 +6750,7 @@
  * returns: - None.
  *
  ***************************************************************************/
-void
+static void
 e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw)
 {
     uint32_t swsm;
@@ -6747,7 +6786,7 @@
 	    E1000_BLK_PHY_RESET : E1000_SUCCESS;
 }
 
-uint8_t
+static uint8_t
 e1000_arc_subsystem_valid(struct e1000_hw *hw)
 {
     uint32_t fwsm;
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index 4f2c196..76ce128 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -284,7 +284,6 @@
 /* Initialization */
 int32_t e1000_reset_hw(struct e1000_hw *hw);
 int32_t e1000_init_hw(struct e1000_hw *hw);
-int32_t e1000_id_led_init(struct e1000_hw * hw);
 int32_t e1000_set_mac_type(struct e1000_hw *hw);
 void e1000_set_media_type(struct e1000_hw *hw);
 
@@ -292,10 +291,8 @@
 int32_t e1000_setup_link(struct e1000_hw *hw);
 int32_t e1000_phy_setup_autoneg(struct e1000_hw *hw);
 void e1000_config_collision_dist(struct e1000_hw *hw);
-int32_t e1000_config_fc_after_link_up(struct e1000_hw *hw);
 int32_t e1000_check_for_link(struct e1000_hw *hw);
 int32_t e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed, uint16_t * duplex);
-int32_t e1000_wait_autoneg(struct e1000_hw *hw);
 int32_t e1000_force_mac_fc(struct e1000_hw *hw);
 
 /* PHY */
@@ -303,21 +300,11 @@
 int32_t e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data);
 int32_t e1000_phy_hw_reset(struct e1000_hw *hw);
 int32_t e1000_phy_reset(struct e1000_hw *hw);
-int32_t e1000_detect_gig_phy(struct e1000_hw *hw);
 int32_t e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
-int32_t e1000_phy_m88_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
-int32_t e1000_phy_igp_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
-int32_t e1000_get_cable_length(struct e1000_hw *hw, uint16_t *min_length, uint16_t *max_length);
-int32_t e1000_check_polarity(struct e1000_hw *hw, uint16_t *polarity);
-int32_t e1000_check_downshift(struct e1000_hw *hw);
 int32_t e1000_validate_mdi_setting(struct e1000_hw *hw);
 
 /* EEPROM Functions */
 int32_t e1000_init_eeprom_params(struct e1000_hw *hw);
-boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw);
-int32_t e1000_read_eeprom_eerd(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
-int32_t e1000_write_eeprom_eewr(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
-int32_t e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
 
 /* MNG HOST IF functions */
 uint32_t e1000_enable_mng_pass_thru(struct e1000_hw *hw);
@@ -377,13 +364,6 @@
 							uint16_t length);
 boolean_t e1000_check_mng_mode(struct e1000_hw *hw);
 boolean_t e1000_enable_tx_pkt_filtering(struct e1000_hw *hw);
-int32_t e1000_mng_enable_host_if(struct e1000_hw *hw);
-int32_t e1000_mng_host_if_write(struct e1000_hw *hw, uint8_t *buffer,
-                            uint16_t length, uint16_t offset, uint8_t *sum);
-int32_t e1000_mng_write_cmd_header(struct e1000_hw* hw, 
-                                   struct e1000_host_mng_command_header* hdr);
-
-int32_t e1000_mng_write_commit(struct e1000_hw *hw);
 
 int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uint16_t *data);
 int32_t e1000_validate_eeprom_checksum(struct e1000_hw *hw);
@@ -395,13 +375,10 @@
 void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask);
 
 /* Filters (multicast, vlan, receive) */
-void e1000_init_rx_addrs(struct e1000_hw *hw);
-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);
 void e1000_write_vfta(struct e1000_hw *hw, uint32_t offset, uint32_t value);
-void e1000_clear_vfta(struct e1000_hw *hw);
 
 /* LED functions */
 int32_t e1000_setup_led(struct e1000_hw *hw);
@@ -412,7 +389,6 @@
 /* Adaptive IFS Functions */
 
 /* Everything else */
-void e1000_clear_hw_cntrs(struct e1000_hw *hw);
 void e1000_reset_adaptive(struct e1000_hw *hw);
 void e1000_update_adaptive(struct e1000_hw *hw);
 void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats, uint32_t frame_len, uint8_t * mac_addr);
@@ -423,29 +399,11 @@
 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_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
-int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw, boolean_t link_up);
-int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
-int32_t e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active);
-void e1000_set_pci_express_master_disable(struct e1000_hw *hw);
-void e1000_enable_pciex_master(struct e1000_hw *hw);
 int32_t e1000_disable_pciex_master(struct e1000_hw *hw);
-int32_t e1000_get_auto_rd_done(struct e1000_hw *hw);
-int32_t e1000_get_phy_cfg_done(struct e1000_hw *hw);
 int32_t e1000_get_software_semaphore(struct e1000_hw *hw);
 void e1000_release_software_semaphore(struct e1000_hw *hw);
 int32_t e1000_check_phy_reset_block(struct e1000_hw *hw);
-int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
-void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
-int32_t e1000_commit_shadow_ram(struct e1000_hw *hw);
-uint8_t e1000_arc_subsystem_valid(struct e1000_hw *hw);
-
-#define E1000_READ_REG_IO(a, reg) \
-    e1000_read_reg_io((a), E1000_##reg)
-#define E1000_WRITE_REG_IO(a, reg, val) \
-    e1000_write_reg_io((a), E1000_##reg, val)
 
 /* PCI Device IDs */
 #define E1000_DEV_ID_82542               0x1000
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index efbbda7..8b207f0 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -37,7 +37,7 @@
  */
 
 char e1000_driver_name[] = "e1000";
-char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
+static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
 #ifndef CONFIG_E1000_NAPI
 #define DRIVERNAPI
 #else
@@ -45,7 +45,7 @@
 #endif
 #define DRV_VERSION "6.1.16-k2"DRIVERNAPI
 char e1000_driver_version[] = DRV_VERSION;
-char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation.";
+static char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation.";
 
 /* e1000_pci_tbl - PCI Device ID Table
  *
@@ -112,14 +112,14 @@
 int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
 void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
 void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
-int e1000_setup_tx_resources(struct e1000_adapter *adapter,
-                             struct e1000_tx_ring *txdr);
-int e1000_setup_rx_resources(struct e1000_adapter *adapter,
-                             struct e1000_rx_ring *rxdr);
-void e1000_free_tx_resources(struct e1000_adapter *adapter,
-                             struct e1000_tx_ring *tx_ring);
-void e1000_free_rx_resources(struct e1000_adapter *adapter,
-                             struct e1000_rx_ring *rx_ring);
+static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
+				    struct e1000_tx_ring *txdr);
+static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
+				    struct e1000_rx_ring *rxdr);
+static void e1000_free_tx_resources(struct e1000_adapter *adapter,
+				    struct e1000_tx_ring *tx_ring);
+static void e1000_free_rx_resources(struct e1000_adapter *adapter,
+				    struct e1000_rx_ring *rx_ring);
 void e1000_update_stats(struct e1000_adapter *adapter);
 
 /* Local Function Prototypes */
@@ -296,7 +296,8 @@
 		E1000_WRITE_FLUSH(&adapter->hw);
 	}
 }
-void
+
+static void
 e1000_update_mng_vlan(struct e1000_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
@@ -1141,7 +1142,7 @@
  * Return 0 on success, negative on failure
  **/
 
-int
+static int
 e1000_setup_tx_resources(struct e1000_adapter *adapter,
                          struct e1000_tx_ring *txdr)
 {
@@ -1359,7 +1360,7 @@
  * Returns 0 on success, negative on failure
  **/
 
-int
+static int
 e1000_setup_rx_resources(struct e1000_adapter *adapter,
                          struct e1000_rx_ring *rxdr)
 {
@@ -1747,7 +1748,7 @@
  * Free all transmit software resources
  **/
 
-void
+static void
 e1000_free_tx_resources(struct e1000_adapter *adapter,
                         struct e1000_tx_ring *tx_ring)
 {
@@ -1858,7 +1859,7 @@
  * Free all receive software resources
  **/
 
-void
+static void
 e1000_free_rx_resources(struct e1000_adapter *adapter,
                         struct e1000_rx_ring *rx_ring)
 {
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 85504fb9..bd6983d 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -18,8 +18,8 @@
  * Much better multiple PHY support by Magnus Damm.
  * Copyright (c) 2000 Ericsson Radio Systems AB.
  *
- * Support for FEC controller of ColdFire/5270/5271/5272/5274/5275/5280/5282.
- * Copyright (c) 2001-2004 Greg Ungerer (gerg@snapgear.com)
+ * Support for FEC controller of ColdFire processors.
+ * Copyright (c) 2001-2005 Greg Ungerer (gerg@snapgear.com)
  *
  * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be)
  * Copyright (c) 2004-2005 Macq Electronique SA.
@@ -50,7 +50,8 @@
 #include <asm/pgtable.h>
 
 #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \
-    defined(CONFIG_M5272) || defined(CONFIG_M528x)
+    defined(CONFIG_M5272) || defined(CONFIG_M528x) || \
+    defined(CONFIG_M520x)
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
 #include "fec.h"
@@ -77,6 +78,8 @@
 	(MCF_MBAR + 0x1800),
 #elif defined(CONFIG_M523x) || defined(CONFIG_M528x)
 	(MCF_MBAR + 0x1000),
+#elif defined(CONFIG_M520x)
+	(MCF_MBAR+0x30000),
 #else
 	&(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec),
 #endif
@@ -139,6 +142,10 @@
 #define TX_RING_SIZE		16	/* Must be power of two */
 #define TX_RING_MOD_MASK	15	/*   for this to work */
 
+#if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE)
+#error "FEC: descriptor ring size contants too large"
+#endif
+
 /* Interrupt events/masks.
 */
 #define FEC_ENET_HBERR	((uint)0x80000000)	/* Heartbeat error */
@@ -164,7 +171,8 @@
  * size bits. Other FEC hardware does not, so we need to take that into
  * account when setting it.
  */
-#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
+    defined(CONFIG_M520x)
 #define	OPT_FRAME_SIZE	(PKT_MAXBUF_SIZE << 16)
 #else
 #define	OPT_FRAME_SIZE	0
@@ -1137,6 +1145,65 @@
 };
 
 /* ------------------------------------------------------------------------- */
+/* register definitions for the DP83848 */
+
+#define MII_DP8384X_PHYSTST    16  /* PHY Status Register */
+
+static void mii_parse_dp8384x_sr2(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	*s &= ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC);
+
+	/* Link up */
+	if (mii_reg & 0x0001) {
+		fep->link = 1;
+		*s |= PHY_STAT_LINK;
+	} else
+		fep->link = 0;
+	/* Status of link */
+	if (mii_reg & 0x0010)   /* Autonegotioation complete */
+		*s |= PHY_STAT_ANC;
+	if (mii_reg & 0x0002) {   /* 10MBps? */
+		if (mii_reg & 0x0004)   /* Full Duplex? */
+			*s |= PHY_STAT_10FDX;
+		else
+			*s |= PHY_STAT_10HDX;
+	} else {                  /* 100 Mbps? */
+		if (mii_reg & 0x0004)   /* Full Duplex? */
+			*s |= PHY_STAT_100FDX;
+		else
+			*s |= PHY_STAT_100HDX;
+	}
+	if (mii_reg & 0x0008)
+		*s |= PHY_STAT_FAULT;
+}
+
+static phy_info_t phy_info_dp83848= {
+	0x020005c9,
+	"DP83848",
+
+	(const phy_cmd_t []) {  /* config */
+		{ mk_mii_read(MII_REG_CR), mii_parse_cr },
+		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
+		{ mk_mii_read(MII_DP8384X_PHYSTST), mii_parse_dp8384x_sr2 },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* startup - enable interrupts */
+		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* ack_int - never happens, no interrupt */
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* shutdown */
+		{ mk_mii_end, }
+	},
+};
+
+/* ------------------------------------------------------------------------- */
 
 static phy_info_t const * const phy_info[] = {
 	&phy_info_lxt970,
@@ -1144,6 +1211,7 @@
 	&phy_info_qs6612,
 	&phy_info_am79c874,
 	&phy_info_ks8721bl,
+	&phy_info_dp83848,
 	NULL
 };
 
@@ -1422,6 +1490,134 @@
 
 /* ------------------------------------------------------------------------- */
 
+#elif defined(CONFIG_M520x)
+
+/*
+ *	Code specific to Coldfire 520x
+ */
+static void __inline__ fec_request_intrs(struct net_device *dev)
+{
+	struct fec_enet_private *fep;
+	int b;
+	static const struct idesc {
+		char *name;
+		unsigned short irq;
+	} *idp, id[] = {
+		{ "fec(TXF)", 23 },
+		{ "fec(TXB)", 24 },
+		{ "fec(TXFIFO)", 25 },
+		{ "fec(TXCR)", 26 },
+		{ "fec(RXF)", 27 },
+		{ "fec(RXB)", 28 },
+		{ "fec(MII)", 29 },
+		{ "fec(LC)", 30 },
+		{ "fec(HBERR)", 31 },
+		{ "fec(GRA)", 32 },
+		{ "fec(EBERR)", 33 },
+		{ "fec(BABT)", 34 },
+		{ "fec(BABR)", 35 },
+		{ NULL },
+	};
+
+	fep = netdev_priv(dev);
+	b = 64 + 13;
+
+	/* Setup interrupt handlers. */
+	for (idp = id; idp->name; idp++) {
+		if (request_irq(b+idp->irq,fec_enet_interrupt,0,idp->name,dev)!=0)
+			printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq);
+	}
+
+	/* Unmask interrupts at ColdFire interrupt controller */
+	{
+		volatile unsigned char  *icrp;
+		volatile unsigned long  *imrp;
+
+		icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 +
+			MCFINTC_ICR0);
+		for (b = 36; (b < 49); b++)
+			icrp[b] = 0x04;
+		imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 +
+			MCFINTC_IMRH);
+		*imrp &= ~0x0001FFF0;
+	}
+	*(volatile unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FEC) |= 0xf0;
+	*(volatile unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C) |= 0x0f;
+}
+
+static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
+{
+	volatile fec_t *fecp;
+
+	fecp = fep->hwp;
+	fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
+	fecp->fec_x_cntrl = 0x00;
+
+	/*
+	 * Set MII speed to 2.5 MHz
+	 * See 5282 manual section 17.5.4.7: MSCR
+	 */
+	fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
+	fecp->fec_mii_speed = fep->phy_speed;
+
+	fec_restart(dev, 0);
+}
+
+static void __inline__ fec_get_mac(struct net_device *dev)
+{
+	struct fec_enet_private *fep = netdev_priv(dev);
+	volatile fec_t *fecp;
+	unsigned char *iap, tmpaddr[ETH_ALEN];
+
+	fecp = fep->hwp;
+
+	if (FEC_FLASHMAC) {
+		/*
+		 * Get MAC address from FLASH.
+		 * If it is all 1's or 0's, use the default.
+		 */
+		iap = FEC_FLASHMAC;
+		if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
+		   (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
+			iap = fec_mac_default;
+		if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) &&
+		   (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
+			iap = fec_mac_default;
+	} else {
+		*((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low;
+		*((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16);
+		iap = &tmpaddr[0];
+	}
+
+	memcpy(dev->dev_addr, iap, ETH_ALEN);
+
+	/* Adjust MAC if using default MAC address */
+	if (iap == fec_mac_default)
+		dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
+}
+
+static void __inline__ fec_enable_phy_intr(void)
+{
+}
+
+static void __inline__ fec_disable_phy_intr(void)
+{
+}
+
+static void __inline__ fec_phy_ack_intr(void)
+{
+}
+
+static void __inline__ fec_localhw_setup(void)
+{
+}
+
+static void __inline__ fec_uncache(unsigned long addr)
+{
+}
+
+/* ------------------------------------------------------------------------- */
+
 #else
 
 /*
@@ -1952,6 +2148,14 @@
 	if (index >= FEC_MAX_PORTS)
 		return -ENXIO;
 
+	/* Allocate memory for buffer descriptors.
+	*/
+	mem_addr = __get_free_page(GFP_KERNEL);
+	if (mem_addr == 0) {
+		printk("FEC: allocate descriptor memory failed?\n");
+		return -ENOMEM;
+	}
+
 	/* Create an Ethernet device instance.
 	*/
 	fecp = (volatile fec_t *) fec_hw[index];
@@ -1964,16 +2168,6 @@
 	fecp->fec_ecntrl = 1;
 	udelay(10);
 
-	/* Clear and enable interrupts */
-	fecp->fec_ievent = 0xffc00000;
-	fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
-		FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
-	fecp->fec_hash_table_high = 0;
-	fecp->fec_hash_table_low = 0;
-	fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
-        fecp->fec_ecntrl = 2;
-        fecp->fec_r_des_active = 0x01000000;
-
 	/* Set the Ethernet address.  If using multiple Enets on the 8xx,
 	 * this needs some work to get unique addresses.
 	 *
@@ -1982,14 +2176,6 @@
 	 */
 	fec_get_mac(dev);
 
-	/* Allocate memory for buffer descriptors.
-	*/
-	if (((RX_RING_SIZE + TX_RING_SIZE) * sizeof(cbd_t)) > PAGE_SIZE) {
-		printk("FEC init error.  Need more space.\n");
-		printk("FEC initialization failed.\n");
-		return 1;
-	}
-	mem_addr = __get_free_page(GFP_KERNEL);
 	cbd_base = (cbd_t *)mem_addr;
 	/* XXX: missing check for allocation failure */
 
@@ -2067,6 +2253,16 @@
 	*/
 	fec_request_intrs(dev);
 
+	/* Clear and enable interrupts */
+	fecp->fec_ievent = 0xffc00000;
+	fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
+		FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
+	fecp->fec_hash_table_high = 0;
+	fecp->fec_hash_table_low = 0;
+	fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
+	fecp->fec_ecntrl = 2;
+	fecp->fec_r_des_active = 0x01000000;
+
 	dev->base_addr = (unsigned long)fecp;
 
 	/* The FEC Ethernet specific entries in the device structure. */
diff --git a/drivers/net/fec.h b/drivers/net/fec.h
index 045761b..965c5c4 100644
--- a/drivers/net/fec.h
+++ b/drivers/net/fec.h
@@ -1,11 +1,10 @@
 /****************************************************************************/
 
 /*
- *	fec.h  --  Fast Ethernet Controller for Motorola ColdFire 5230,
- *		   5231, 5232, 5234, 5235, 5270, 5271, 5272, 5274, 5275,
- *		   5280 and 5282.
+ *	fec.h  --  Fast Ethernet Controller for Motorola ColdFire SoC
+ *		   processors.
  *
- *	(C) Copyright 2000-2003, Greg Ungerer (gerg@snapgear.com)
+ *	(C) Copyright 2000-2005, Greg Ungerer (gerg@snapgear.com)
  *	(C) Copyright 2000-2001, Lineo (www.lineo.com)
  */
 
@@ -14,7 +13,8 @@
 #define	FEC_H
 /****************************************************************************/
 
-#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
+    defined(CONFIG_M520x)
 /*
  *	Just figures, Motorola would have to change the offsets for
  *	registers in the same peripheral device on different models
diff --git a/drivers/net/fec_8xx/Kconfig b/drivers/net/fec_8xx/Kconfig
index 4560026..94e7a9a 100644
--- a/drivers/net/fec_8xx/Kconfig
+++ b/drivers/net/fec_8xx/Kconfig
@@ -1,6 +1,6 @@
 config FEC_8XX
 	tristate "Motorola 8xx FEC driver"
-	depends on NET_ETHERNET
+	depends on NET_ETHERNET && FEC
 	select MII
 
 config FEC_8XX_GENERIC_PHY
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
index 3be3f91..c8dc402 100644
--- a/drivers/net/hamradio/dmascc.c
+++ b/drivers/net/hamradio/dmascc.c
@@ -311,16 +311,6 @@
 	}
 }
 
-#ifndef MODULE
-void __init dmascc_setup(char *str, int *ints)
-{
-	int i;
-
-	for (i = 0; i < MAX_NUM_DEVS && i < ints[0]; i++)
-		io[i] = ints[i + 1];
-}
-#endif
-
 static int __init dmascc_init(void)
 {
 	int h, i, j, n;
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index 04e4718..d38ade5 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -694,7 +694,7 @@
 	}
 }
 
-struct ethtool_ops ixgb_ethtool_ops = {
+static struct ethtool_ops ixgb_ethtool_ops = {
 	.get_settings = ixgb_get_settings,
 	.set_settings = ixgb_set_settings,
 	.get_drvinfo = ixgb_get_drvinfo,
diff --git a/drivers/net/ixgb/ixgb_hw.c b/drivers/net/ixgb/ixgb_hw.c
index 69329c7..620cad4 100644
--- a/drivers/net/ixgb/ixgb_hw.c
+++ b/drivers/net/ixgb/ixgb_hw.c
@@ -47,9 +47,22 @@
 
 static ixgb_phy_type ixgb_identify_phy(struct ixgb_hw *hw);
 
-uint32_t ixgb_mac_reset(struct ixgb_hw *hw);
+static void ixgb_clear_hw_cntrs(struct ixgb_hw *hw);
 
-uint32_t ixgb_mac_reset(struct ixgb_hw *hw)
+static void ixgb_clear_vfta(struct ixgb_hw *hw);
+
+static void ixgb_init_rx_addrs(struct ixgb_hw *hw);
+
+static uint16_t ixgb_read_phy_reg(struct ixgb_hw *hw,
+				  uint32_t reg_address,
+				  uint32_t phy_address,
+				  uint32_t device_type);
+
+static boolean_t ixgb_setup_fc(struct ixgb_hw *hw);
+
+static boolean_t mac_addr_valid(uint8_t *mac_addr);
+
+static uint32_t ixgb_mac_reset(struct ixgb_hw *hw)
 {
 	uint32_t ctrl_reg;
 
@@ -335,7 +348,7 @@
  * of the receive addresss registers. Clears the multicast table. Assumes
  * the receiver is in reset when the routine is called.
  *****************************************************************************/
-void
+static void
 ixgb_init_rx_addrs(struct ixgb_hw *hw)
 {
 	uint32_t i;
@@ -604,7 +617,7 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void
+static void
 ixgb_clear_vfta(struct ixgb_hw *hw)
 {
 	uint32_t offset;
@@ -620,7 +633,7 @@
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
 
-boolean_t
+static boolean_t
 ixgb_setup_fc(struct ixgb_hw *hw)
 {
 	uint32_t ctrl_reg;
@@ -722,7 +735,7 @@
  * This requires that first an address cycle command is sent, followed by a
  * read command.
  *****************************************************************************/
-uint16_t
+static uint16_t
 ixgb_read_phy_reg(struct ixgb_hw *hw,
 		uint32_t reg_address,
 		uint32_t phy_address,
@@ -815,7 +828,7 @@
  * This requires that first an address cycle command is sent, followed by a
  * write command.
  *****************************************************************************/
-void
+static void
 ixgb_write_phy_reg(struct ixgb_hw *hw,
 			uint32_t reg_address,
 			uint32_t phy_address,
@@ -959,7 +972,7 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void
+static void
 ixgb_clear_hw_cntrs(struct ixgb_hw *hw)
 {
 	volatile uint32_t temp_reg;
@@ -1114,7 +1127,7 @@
  * mac_addr - pointer to MAC address.
  *
  *****************************************************************************/
-boolean_t
+static boolean_t
 mac_addr_valid(uint8_t *mac_addr)
 {
 	boolean_t is_valid = TRUE;
diff --git a/drivers/net/ixgb/ixgb_hw.h b/drivers/net/ixgb/ixgb_hw.h
index 8bcf31e..382c630 100644
--- a/drivers/net/ixgb/ixgb_hw.h
+++ b/drivers/net/ixgb/ixgb_hw.h
@@ -784,23 +784,8 @@
 extern boolean_t ixgb_adapter_stop(struct ixgb_hw *hw);
 extern boolean_t ixgb_init_hw(struct ixgb_hw *hw);
 extern boolean_t ixgb_adapter_start(struct ixgb_hw *hw);
-extern void ixgb_init_rx_addrs(struct ixgb_hw *hw);
 extern void ixgb_check_for_link(struct ixgb_hw *hw);
 extern boolean_t ixgb_check_for_bad_link(struct ixgb_hw *hw);
-extern boolean_t ixgb_setup_fc(struct ixgb_hw *hw);
-extern void ixgb_clear_hw_cntrs(struct ixgb_hw *hw);
-extern boolean_t mac_addr_valid(uint8_t *mac_addr);
-
-extern uint16_t ixgb_read_phy_reg(struct ixgb_hw *hw,
-				uint32_t reg_addr,
-				uint32_t phy_addr,
-				uint32_t device_type);
-
-extern void ixgb_write_phy_reg(struct ixgb_hw *hw,
-				uint32_t reg_addr,
-				uint32_t phy_addr,
-				uint32_t device_type,
-				uint16_t data);
 
 extern void ixgb_rar_set(struct ixgb_hw *hw,
 				uint8_t *addr,
@@ -818,8 +803,6 @@
 				 uint32_t offset,
 				 uint32_t value);
 
-extern void ixgb_clear_vfta(struct ixgb_hw *hw);
-
 /* Access functions to eeprom data */
 void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t *mac_addr);
 uint32_t ixgb_get_ee_pba_number(struct ixgb_hw *hw);
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 176680c..f9f77e4 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -45,7 +45,7 @@
  */
 
 char ixgb_driver_name[] = "ixgb";
-char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver";
+static char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver";
 
 #ifndef CONFIG_IXGB_NAPI
 #define DRIVERNAPI
diff --git a/drivers/net/phy/cicada.c b/drivers/net/phy/cicada.c
index c47fb2e..7d8d534 100644
--- a/drivers/net/phy/cicada.c
+++ b/drivers/net/phy/cicada.c
@@ -29,7 +29,6 @@
 #include <linux/spinlock.h>
 #include <linux/mm.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/mii.h>
 #include <linux/ethtool.h>
 #include <linux/phy.h>
diff --git a/drivers/net/phy/davicom.c b/drivers/net/phy/davicom.c
index 6caf499..5e9002e 100644
--- a/drivers/net/phy/davicom.c
+++ b/drivers/net/phy/davicom.c
@@ -29,7 +29,6 @@
 #include <linux/spinlock.h>
 #include <linux/mm.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/mii.h>
 #include <linux/ethtool.h>
 #include <linux/phy.h>
diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c
index 4c84044..bef79e4 100644
--- a/drivers/net/phy/lxt.c
+++ b/drivers/net/phy/lxt.c
@@ -29,7 +29,6 @@
 #include <linux/spinlock.h>
 #include <linux/mm.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/mii.h>
 #include <linux/ethtool.h>
 #include <linux/phy.h>
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 4a72b02..a2d6386 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -29,7 +29,6 @@
 #include <linux/spinlock.h>
 #include <linux/mm.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/mii.h>
 #include <linux/ethtool.h>
 #include <linux/phy.h>
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 5eab9c4..02940c0 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -29,7 +29,6 @@
 #include <linux/spinlock.h>
 #include <linux/mm.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/mii.h>
 #include <linux/ethtool.h>
 #include <linux/phy.h>
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 9209da9..b8686e4 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -30,7 +30,6 @@
 #include <linux/spinlock.h>
 #include <linux/mm.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/mii.h>
 #include <linux/ethtool.h>
 #include <linux/phy.h>
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 6da1aa0..16bebe7 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -30,7 +30,6 @@
 #include <linux/spinlock.h>
 #include <linux/mm.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/mii.h>
 #include <linux/ethtool.h>
 #include <linux/phy.h>
diff --git a/drivers/net/phy/qsemi.c b/drivers/net/phy/qsemi.c
index d461ba4..65d995b 100644
--- a/drivers/net/phy/qsemi.c
+++ b/drivers/net/phy/qsemi.c
@@ -29,7 +29,6 @@
 #include <linux/spinlock.h>
 #include <linux/mm.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/mii.h>
 #include <linux/ethtool.h>
 #include <linux/phy.h>
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 9c49354..0745dd9 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -2110,7 +2110,7 @@
 {
 	struct net_device *dev = nic->dev;
 	struct sk_buff *frag_list;
-	u64 tmp;
+	void *tmp;
 
 	/* Buffer-1 receives L3/L4 headers */
 	((RxD3_t*)rxdp)->Buffer1_ptr = pci_map_single
@@ -2125,11 +2125,9 @@
 	}
 	frag_list = skb_shinfo(skb)->frag_list;
 	frag_list->next = NULL;
-	tmp = (u64) frag_list->data;
-	tmp += ALIGN_SIZE;
-	tmp &= ~ALIGN_SIZE;
-	frag_list->data = (void *) tmp;
-	frag_list->tail = (void *) tmp;
+	tmp = (void *)ALIGN((long)frag_list->data, ALIGN_SIZE + 1);
+	frag_list->data = tmp;
+	frag_list->tail = tmp;
 
 	/* Buffer-2 receives L4 data payload */
 	((RxD3_t*)rxdp)->Buffer2_ptr = pci_map_single(nic->pdev,
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 849ac88..6afc6e5 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -47,6 +47,8 @@
 #include <linux/pci.h>
 #include <asm/uaccess.h>
 
+#include "airo.h"
+
 #ifdef CONFIG_PCI
 static struct pci_device_id card_ids[] = {
 	{ 0x14b9, 1, PCI_ANY_ID, PCI_ANY_ID, },
diff --git a/drivers/net/wireless/airo.h b/drivers/net/wireless/airo.h
new file mode 100644
index 0000000..e480adf
--- /dev/null
+++ b/drivers/net/wireless/airo.h
@@ -0,0 +1,9 @@
+#ifndef _AIRO_H_
+#define _AIRO_H_
+
+struct net_device *init_airo_card(unsigned short irq, int port, int is_pcmcia,
+				  struct device *dmdev);
+int reset_airo_card(struct net_device *dev);
+void stop_airo_card(struct net_device *dev, int freeres);
+
+#endif  /*  _AIRO_H_  */
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index 784de91..96ed8da 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -42,6 +42,8 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
+#include "airo.h"
+
 /*
    All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
    you do not define PCMCIA_DEBUG at all, all the debug code will be
@@ -78,10 +80,6 @@
    event handler. 
 */
 
-struct net_device *init_airo_card( int, int, int, struct device * );
-void stop_airo_card( struct net_device *, int );
-int reset_airo_card( struct net_device * );
-
 static void airo_config(dev_link_t *link);
 static void airo_release(dev_link_t *link);
 static int airo_event(event_t event, int priority,
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index 3b49efa..fc1eb35 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -244,7 +244,6 @@
 	priv->statistics.tx_dropped++;
 	spin_unlock_irqrestore(&priv->slock, flags);
 	dev_kfree_skb(skb);
-	skb = NULL;
 	return err;
 }
 
diff --git a/drivers/parport/probe.c b/drivers/parport/probe.c
index 6e6f42d..4b48b31 100644
--- a/drivers/parport/probe.c
+++ b/drivers/parport/probe.c
@@ -78,17 +78,15 @@
 				u++;
 			}
 			if (!strcmp(p, "MFG") || !strcmp(p, "MANUFACTURER")) {
-				if (info->mfr)
-					kfree (info->mfr);
+				kfree(info->mfr);
 				info->mfr = kstrdup(sep, GFP_KERNEL);
 			} else if (!strcmp(p, "MDL") || !strcmp(p, "MODEL")) {
-				if (info->model)
-					kfree (info->model);
+				kfree(info->model);
 				info->model = kstrdup(sep, GFP_KERNEL);
 			} else if (!strcmp(p, "CLS") || !strcmp(p, "CLASS")) {
 				int i;
-				if (info->class_name)
-					kfree (info->class_name);
+
+				kfree(info->class_name);
 				info->class_name = kstrdup(sep, GFP_KERNEL);
 				for (u = sep; *u; u++)
 					*u = toupper(*u);
@@ -102,21 +100,22 @@
 				info->class = PARPORT_CLASS_OTHER;
 			} else if (!strcmp(p, "CMD") ||
 				   !strcmp(p, "COMMAND SET")) {
-				if (info->cmdset)
-					kfree (info->cmdset);
+				kfree(info->cmdset);
 				info->cmdset = kstrdup(sep, GFP_KERNEL);
 				/* if it speaks printer language, it's
 				   probably a printer */
 				if (strstr(sep, "PJL") || strstr(sep, "PCL"))
 					guessed_class = PARPORT_CLASS_PRINTER;
 			} else if (!strcmp(p, "DES") || !strcmp(p, "DESCRIPTION")) {
-				if (info->description)
-					kfree (info->description);
+				kfree(info->description);
 				info->description = kstrdup(sep, GFP_KERNEL);
 			}
 		}
 	rock_on:
-		if (q) p = q+1; else p=NULL;
+		if (q)
+			p = q + 1;
+		else
+			p = NULL;
 	}
 
 	/* If the device didn't tell us its class, maybe we have managed to
diff --git a/drivers/parport/share.c b/drivers/parport/share.c
index ae7becf..9cb3ab1 100644
--- a/drivers/parport/share.c
+++ b/drivers/parport/share.c
@@ -202,16 +202,11 @@
 	list_del(&port->full_list);
 	spin_unlock(&full_list_lock);
 	for (d = 0; d < 5; d++) {
-		if (port->probe_info[d].class_name)
-			kfree (port->probe_info[d].class_name);
-		if (port->probe_info[d].mfr)
-			kfree (port->probe_info[d].mfr);
-		if (port->probe_info[d].model)
-			kfree (port->probe_info[d].model);
-		if (port->probe_info[d].cmdset)
-			kfree (port->probe_info[d].cmdset);
-		if (port->probe_info[d].description)
-			kfree (port->probe_info[d].description);
+		kfree(port->probe_info[d].class_name);
+		kfree(port->probe_info[d].mfr);
+		kfree(port->probe_info[d].model);
+		kfree(port->probe_info[d].cmdset);
+		kfree(port->probe_info[d].description);
 	}
 
 	kfree(port->name);
@@ -618,9 +613,9 @@
 	return tmp;
 
  out_free_all:
-	kfree (tmp->state);
+	kfree(tmp->state);
  out_free_pardevice:
-	kfree (tmp);
+	kfree(tmp);
  out:
 	parport_put_port (port);
 	module_put(port->ops->owner);
diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c
index 93e39c4..00b81a7 100644
--- a/drivers/pci/hotplug/cpqphp_pci.c
+++ b/drivers/pci/hotplug/cpqphp_pci.c
@@ -259,8 +259,7 @@
 	       sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
 	// Make sure I got at least one entry
 	if (len == 0) {
-		if (PCIIRQRoutingInfoLength != NULL)
-			kfree(PCIIRQRoutingInfoLength );
+		kfree(PCIIRQRoutingInfoLength );
 		return -1;
 	}
 
@@ -275,8 +274,7 @@
 			ctrl->pci_bus->number = tbus;
 			pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work);
 			if (!nobridge || (work == 0xffffffff)) {
-				if (PCIIRQRoutingInfoLength != NULL)
-					kfree(PCIIRQRoutingInfoLength );
+				kfree(PCIIRQRoutingInfoLength );
 				return 0;
 			}
 
@@ -289,20 +287,17 @@
 				dbg("Scan bus for Non Bridge: bus %d\n", tbus);
 				if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) {
 					*bus_num = tbus;
-					if (PCIIRQRoutingInfoLength != NULL)
-						kfree(PCIIRQRoutingInfoLength );
+					kfree(PCIIRQRoutingInfoLength );
 					return 0;
 				}
 			} else {
-				if (PCIIRQRoutingInfoLength != NULL)
-					kfree(PCIIRQRoutingInfoLength );
+				kfree(PCIIRQRoutingInfoLength );
 				return 0;
 			}
 
 		}
 	}
-	if (PCIIRQRoutingInfoLength != NULL)
-		kfree(PCIIRQRoutingInfoLength );
+	kfree(PCIIRQRoutingInfoLength );
 	return -1;
 }
 
diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.c b/drivers/pci/hotplug/pciehprm_nonacpi.c
index 33b2c69..76c727c 100644
--- a/drivers/pci/hotplug/pciehprm_nonacpi.c
+++ b/drivers/pci/hotplug/pciehprm_nonacpi.c
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/sched.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/slab.h>
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index ae986e5..94e68c5 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -10,6 +10,7 @@
 #include <linux/mempolicy.h>
 #include <linux/string.h>
 #include <linux/slab.h>
+#include <linux/sched.h>
 #include "pci.h"
 
 /*
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index 3afb682..2dc3e61 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -334,10 +334,8 @@
 	/*
 	 * If there was a fake CIS, destroy that as well.
 	 */
-	if (s->fake_cis) {
-		kfree(s->fake_cis);
-		s->fake_cis = NULL;
-	}
+	kfree(s->fake_cis);
+	s->fake_cis = NULL;
 }
 EXPORT_SYMBOL(destroy_cis_cache);
 
@@ -386,10 +384,8 @@
 
 int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis)
 {
-    if (s->fake_cis != NULL) {
-	kfree(s->fake_cis);
-	s->fake_cis = NULL;
-    }
+    kfree(s->fake_cis);
+    s->fake_cis = NULL;
     if (cis->Length > CISTPL_MAX_CIS_SIZE)
 	return CS_BAD_SIZE;
     s->fake_cis = kmalloc(cis->Length, GFP_KERNEL);
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index d5e7642..234cdca 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -331,10 +331,8 @@
 	cb_free(s);
 #endif
 	s->functions = 0;
-	if (s->config) {
-		kfree(s->config);
-		s->config = NULL;
-	}
+	kfree(s->config);
+	s->config = NULL;
 
 	{
 		int status;
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c
index e95ed67..bd7c966 100644
--- a/drivers/pnp/card.c
+++ b/drivers/pnp/card.c
@@ -12,7 +12,7 @@
 #include "base.h"
 
 LIST_HEAD(pnp_cards);
-LIST_HEAD(pnp_card_drivers);
+static LIST_HEAD(pnp_card_drivers);
 
 
 static const struct pnp_card_device_id * match_card(struct pnp_card_driver * drv, struct pnp_card * card)
@@ -374,11 +374,13 @@
 	pnp_unregister_driver(&drv->link);
 }
 
+#if 0
 EXPORT_SYMBOL(pnp_add_card);
 EXPORT_SYMBOL(pnp_remove_card);
 EXPORT_SYMBOL(pnp_add_card_device);
 EXPORT_SYMBOL(pnp_remove_card_device);
 EXPORT_SYMBOL(pnp_add_card_id);
+#endif  /*  0  */
 EXPORT_SYMBOL(pnp_request_card_device);
 EXPORT_SYMBOL(pnp_release_card_device);
 EXPORT_SYMBOL(pnp_register_card_driver);
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index deed92459..aec83ec 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -158,13 +158,14 @@
  *
  * this function will free all mem used by dev
  */
-
+#if 0
 void pnp_remove_device(struct pnp_dev *dev)
 {
 	if (!dev || dev->card)
 		return;
 	__pnp_remove_device(dev);
 }
+#endif  /*  0  */
 
 static int __init pnp_init(void)
 {
@@ -174,7 +175,9 @@
 
 subsys_initcall(pnp_init);
 
+#if 0
 EXPORT_SYMBOL(pnp_register_protocol);
 EXPORT_SYMBOL(pnp_unregister_protocol);
 EXPORT_SYMBOL(pnp_add_device);
 EXPORT_SYMBOL(pnp_remove_device);
+#endif  /*  0  */
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c
index 33da25f..d3ccce7 100644
--- a/drivers/pnp/driver.c
+++ b/drivers/pnp/driver.c
@@ -214,6 +214,8 @@
 
 EXPORT_SYMBOL(pnp_register_driver);
 EXPORT_SYMBOL(pnp_unregister_driver);
+#if 0
 EXPORT_SYMBOL(pnp_add_id);
+#endif
 EXPORT_SYMBOL(pnp_device_attach);
 EXPORT_SYMBOL(pnp_device_detach);
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index beedd86..57fd603 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -941,7 +941,9 @@
 EXPORT_SYMBOL(isapnp_present);
 EXPORT_SYMBOL(isapnp_cfg_begin);
 EXPORT_SYMBOL(isapnp_cfg_end);
+#if 0
 EXPORT_SYMBOL(isapnp_read_byte);
+#endif
 EXPORT_SYMBOL(isapnp_write_byte);
 
 static int isapnp_read_resources(struct pnp_dev *dev, struct pnp_resource_table *res)
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index cbb2749..2616686 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -555,7 +555,9 @@
 
 
 EXPORT_SYMBOL(pnp_manual_config_dev);
+#if 0
 EXPORT_SYMBOL(pnp_auto_config_dev);
+#endif
 EXPORT_SYMBOL(pnp_activate_dev);
 EXPORT_SYMBOL(pnp_disable_dev);
 EXPORT_SYMBOL(pnp_resource_change);
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 1a8915e..816479a 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -117,7 +117,7 @@
 	return ACPI_FAILURE(status) ? -ENODEV : 0;
 }
 
-struct pnp_protocol pnpacpi_protocol = {
+static struct pnp_protocol pnpacpi_protocol = {
 	.name	= "Plug and Play ACPI",
 	.get	= pnpacpi_get_resources,
 	.set	= pnpacpi_set_resources,
@@ -234,7 +234,7 @@
 }
 
 int pnpacpi_disabled __initdata;
-int __init pnpacpi_init(void)
+static int __init pnpacpi_init(void)
 {
 	if (acpi_disabled || pnpacpi_disabled) {
 		pnp_info("PnP ACPI: disabled");
@@ -258,4 +258,6 @@
 }
 __setup("pnpacpi=", pnpacpi_setup);
 
+#if 0
 EXPORT_SYMBOL(pnpacpi_protocol);
+#endif
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index 887ad89..6ded527 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -477,12 +477,14 @@
 }
 
 
+#if 0
 EXPORT_SYMBOL(pnp_register_dependent_option);
 EXPORT_SYMBOL(pnp_register_independent_option);
 EXPORT_SYMBOL(pnp_register_irq_resource);
 EXPORT_SYMBOL(pnp_register_dma_resource);
 EXPORT_SYMBOL(pnp_register_port_resource);
 EXPORT_SYMBOL(pnp_register_mem_resource);
+#endif  /*  0  */
 
 
 /* format is: pnp_reserve_irq=irq1[,irq2] .... */
diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
new file mode 100644
index 0000000..0b2d2c3
--- /dev/null
+++ b/drivers/rapidio/Kconfig
@@ -0,0 +1,18 @@
+#
+# RapidIO configuration
+#
+config RAPIDIO_8_BIT_TRANSPORT
+	bool "8-bit transport addressing"
+	depends on RAPIDIO
+	---help---
+	  By default, the kernel assumes a 16-bit addressed RapidIO
+	  network. By selecting this option, the kernel will support
+	  an 8-bit addressed network.
+
+config RAPIDIO_DISC_TIMEOUT
+	int "Discovery timeout duration (seconds)"
+	depends on RAPIDIO
+	default "30"
+	---help---
+	  Amount of time a discovery node waits for a host to complete
+	  enumeration beforing giving up.
diff --git a/drivers/rapidio/Makefile b/drivers/rapidio/Makefile
new file mode 100644
index 0000000..7c0e181
--- /dev/null
+++ b/drivers/rapidio/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for RapidIO interconnect services
+#
+obj-y += rio.o rio-access.o rio-driver.o rio-scan.o rio-sysfs.o
+
+obj-$(CONFIG_RAPIDIO)		+= switches/
diff --git a/drivers/rapidio/rio-access.c b/drivers/rapidio/rio-access.c
new file mode 100644
index 0000000..b9fab2a
--- /dev/null
+++ b/drivers/rapidio/rio-access.c
@@ -0,0 +1,175 @@
+/*
+ * RapidIO configuration space access support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/rio.h>
+#include <linux/module.h>
+
+/*
+ * These interrupt-safe spinlocks protect all accesses to RIO
+ * configuration space and doorbell access.
+ */
+static spinlock_t rio_config_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t rio_doorbell_lock = SPIN_LOCK_UNLOCKED;
+
+/*
+ *  Wrappers for all RIO configuration access functions.  They just check
+ *  alignment, do locking and call the low-level functions pointed to
+ *  by rio_mport->ops.
+ */
+
+#define RIO_8_BAD 0
+#define RIO_16_BAD (offset & 1)
+#define RIO_32_BAD (offset & 3)
+
+/**
+ * RIO_LOP_READ - Generate rio_local_read_config_* functions
+ * @size: Size of configuration space read (8, 16, 32 bits)
+ * @type: C type of value argument
+ * @len: Length of configuration space read (1, 2, 4 bytes)
+ *
+ * Generates rio_local_read_config_* functions used to access
+ * configuration space registers on the local device.
+ */
+#define RIO_LOP_READ(size,type,len) \
+int __rio_local_read_config_##size \
+	(struct rio_mport *mport, u32 offset, type *value)		\
+{									\
+	int res;							\
+	unsigned long flags;						\
+	u32 data = 0;							\
+	if (RIO_##size##_BAD) return RIO_BAD_SIZE;			\
+	spin_lock_irqsave(&rio_config_lock, flags);			\
+	res = mport->ops->lcread(mport->id, offset, len, &data);	\
+	*value = (type)data;						\
+	spin_unlock_irqrestore(&rio_config_lock, flags);		\
+	return res;							\
+}
+
+/**
+ * RIO_LOP_WRITE - Generate rio_local_write_config_* functions
+ * @size: Size of configuration space write (8, 16, 32 bits)
+ * @type: C type of value argument
+ * @len: Length of configuration space write (1, 2, 4 bytes)
+ *
+ * Generates rio_local_write_config_* functions used to access
+ * configuration space registers on the local device.
+ */
+#define RIO_LOP_WRITE(size,type,len) \
+int __rio_local_write_config_##size \
+	(struct rio_mport *mport, u32 offset, type value)		\
+{									\
+	int res;							\
+	unsigned long flags;						\
+	if (RIO_##size##_BAD) return RIO_BAD_SIZE;			\
+	spin_lock_irqsave(&rio_config_lock, flags);			\
+	res = mport->ops->lcwrite(mport->id, offset, len, value);	\
+	spin_unlock_irqrestore(&rio_config_lock, flags);		\
+	return res;							\
+}
+
+RIO_LOP_READ(8, u8, 1)
+RIO_LOP_READ(16, u16, 2)
+RIO_LOP_READ(32, u32, 4)
+RIO_LOP_WRITE(8, u8, 1)
+RIO_LOP_WRITE(16, u16, 2)
+RIO_LOP_WRITE(32, u32, 4)
+
+EXPORT_SYMBOL_GPL(__rio_local_read_config_8);
+EXPORT_SYMBOL_GPL(__rio_local_read_config_16);
+EXPORT_SYMBOL_GPL(__rio_local_read_config_32);
+EXPORT_SYMBOL_GPL(__rio_local_write_config_8);
+EXPORT_SYMBOL_GPL(__rio_local_write_config_16);
+EXPORT_SYMBOL_GPL(__rio_local_write_config_32);
+
+/**
+ * RIO_OP_READ - Generate rio_mport_read_config_* functions
+ * @size: Size of configuration space read (8, 16, 32 bits)
+ * @type: C type of value argument
+ * @len: Length of configuration space read (1, 2, 4 bytes)
+ *
+ * Generates rio_mport_read_config_* functions used to access
+ * configuration space registers on the local device.
+ */
+#define RIO_OP_READ(size,type,len) \
+int rio_mport_read_config_##size \
+	(struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type *value)	\
+{									\
+	int res;							\
+	unsigned long flags;						\
+	u32 data = 0;							\
+	if (RIO_##size##_BAD) return RIO_BAD_SIZE;			\
+	spin_lock_irqsave(&rio_config_lock, flags);			\
+	res = mport->ops->cread(mport->id, destid, hopcount, offset, len, &data); \
+	*value = (type)data;						\
+	spin_unlock_irqrestore(&rio_config_lock, flags);		\
+	return res;							\
+}
+
+/**
+ * RIO_OP_WRITE - Generate rio_mport_write_config_* functions
+ * @size: Size of configuration space write (8, 16, 32 bits)
+ * @type: C type of value argument
+ * @len: Length of configuration space write (1, 2, 4 bytes)
+ *
+ * Generates rio_mport_write_config_* functions used to access
+ * configuration space registers on the local device.
+ */
+#define RIO_OP_WRITE(size,type,len) \
+int rio_mport_write_config_##size \
+	(struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type value)	\
+{									\
+	int res;							\
+	unsigned long flags;						\
+	if (RIO_##size##_BAD) return RIO_BAD_SIZE;			\
+	spin_lock_irqsave(&rio_config_lock, flags);			\
+	res = mport->ops->cwrite(mport->id, destid, hopcount, offset, len, value); \
+	spin_unlock_irqrestore(&rio_config_lock, flags);		\
+	return res;							\
+}
+
+RIO_OP_READ(8, u8, 1)
+RIO_OP_READ(16, u16, 2)
+RIO_OP_READ(32, u32, 4)
+RIO_OP_WRITE(8, u8, 1)
+RIO_OP_WRITE(16, u16, 2)
+RIO_OP_WRITE(32, u32, 4)
+
+EXPORT_SYMBOL_GPL(rio_mport_read_config_8);
+EXPORT_SYMBOL_GPL(rio_mport_read_config_16);
+EXPORT_SYMBOL_GPL(rio_mport_read_config_32);
+EXPORT_SYMBOL_GPL(rio_mport_write_config_8);
+EXPORT_SYMBOL_GPL(rio_mport_write_config_16);
+EXPORT_SYMBOL_GPL(rio_mport_write_config_32);
+
+/**
+ * rio_mport_send_doorbell - Send a doorbell message
+ *
+ * @mport: RIO master port
+ * @destid: RIO device destination ID
+ * @data: Doorbell message data
+ *
+ * Send a doorbell message to a RIO device. The doorbell message
+ * has a 16-bit info field provided by the data argument.
+ */
+int rio_mport_send_doorbell(struct rio_mport *mport, u16 destid, u16 data)
+{
+	int res;
+	unsigned long flags;
+
+	spin_lock_irqsave(&rio_doorbell_lock, flags);
+	res = mport->ops->dsend(mport->id, destid, data);
+	spin_unlock_irqrestore(&rio_doorbell_lock, flags);
+
+	return res;
+}
+
+EXPORT_SYMBOL_GPL(rio_mport_send_doorbell);
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
new file mode 100644
index 0000000..dc74960
--- /dev/null
+++ b/drivers/rapidio/rio-driver.c
@@ -0,0 +1,229 @@
+/*
+ * RapidIO driver support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/rio.h>
+#include <linux/rio_ids.h>
+
+#include "rio.h"
+
+/**
+ *  rio_match_device - Tell if a RIO device has a matching RIO device id structure
+ *  @id: the RIO device id structure to match against
+ *  @rdev: the RIO device structure to match against
+ *
+ *  Used from driver probe and bus matching to check whether a RIO device
+ *  matches a device id structure provided by a RIO driver. Returns the
+ *  matching &struct rio_device_id or %NULL if there is no match.
+ */
+static const struct rio_device_id *rio_match_device(const struct rio_device_id
+						    *id,
+						    const struct rio_dev *rdev)
+{
+	while (id->vid || id->asm_vid) {
+		if (((id->vid == RIO_ANY_ID) || (id->vid == rdev->vid)) &&
+		    ((id->did == RIO_ANY_ID) || (id->did == rdev->did)) &&
+		    ((id->asm_vid == RIO_ANY_ID)
+		     || (id->asm_vid == rdev->asm_vid))
+		    && ((id->asm_did == RIO_ANY_ID)
+			|| (id->asm_did == rdev->asm_did)))
+			return id;
+		id++;
+	}
+	return NULL;
+}
+
+/**
+ * rio_dev_get - Increments the reference count of the RIO device structure
+ *
+ * @rdev: RIO device being referenced
+ *
+ * Each live reference to a device should be refcounted.
+ *
+ * Drivers for RIO devices should normally record such references in
+ * their probe() methods, when they bind to a device, and release
+ * them by calling rio_dev_put(), in their disconnect() methods.
+ */
+struct rio_dev *rio_dev_get(struct rio_dev *rdev)
+{
+	if (rdev)
+		get_device(&rdev->dev);
+
+	return rdev;
+}
+
+/**
+ * rio_dev_put - Release a use of the RIO device structure
+ *
+ * @rdev: RIO device being disconnected
+ *
+ * Must be called when a user of a device is finished with it.
+ * When the last user of the device calls this function, the
+ * memory of the device is freed.
+ */
+void rio_dev_put(struct rio_dev *rdev)
+{
+	if (rdev)
+		put_device(&rdev->dev);
+}
+
+/**
+ *  rio_device_probe - Tell if a RIO device structure has a matching RIO
+ *                     device id structure
+ *  @id: the RIO device id structure to match against
+ *  @dev: the RIO device structure to match against
+ *
+ * return 0 and set rio_dev->driver when drv claims rio_dev, else error
+ */
+static int rio_device_probe(struct device *dev)
+{
+	struct rio_driver *rdrv = to_rio_driver(dev->driver);
+	struct rio_dev *rdev = to_rio_dev(dev);
+	int error = -ENODEV;
+	const struct rio_device_id *id;
+
+	if (!rdev->driver && rdrv->probe) {
+		if (!rdrv->id_table)
+			return error;
+		id = rio_match_device(rdrv->id_table, rdev);
+		rio_dev_get(rdev);
+		if (id)
+			error = rdrv->probe(rdev, id);
+		if (error >= 0) {
+			rdev->driver = rdrv;
+			error = 0;
+			rio_dev_put(rdev);
+		}
+	}
+	return error;
+}
+
+/**
+ *  rio_device_remove - Remove a RIO device from the system
+ *
+ *  @dev: the RIO device structure to match against
+ *
+ * Remove a RIO device from the system. If it has an associated
+ * driver, then run the driver remove() method.  Then update
+ * the reference count.
+ */
+static int rio_device_remove(struct device *dev)
+{
+	struct rio_dev *rdev = to_rio_dev(dev);
+	struct rio_driver *rdrv = rdev->driver;
+
+	if (rdrv) {
+		if (rdrv->remove)
+			rdrv->remove(rdev);
+		rdev->driver = NULL;
+	}
+
+	rio_dev_put(rdev);
+
+	return 0;
+}
+
+/**
+ *  rio_register_driver - register a new RIO driver
+ *  @rdrv: the RIO driver structure to register
+ *
+ *  Adds a &struct rio_driver to the list of registered drivers
+ *  Returns a negative value on error, otherwise 0. If no error
+ *  occurred, the driver remains registered even if no device
+ *  was claimed during registration.
+ */
+int rio_register_driver(struct rio_driver *rdrv)
+{
+	/* initialize common driver fields */
+	rdrv->driver.name = rdrv->name;
+	rdrv->driver.bus = &rio_bus_type;
+	rdrv->driver.probe = rio_device_probe;
+	rdrv->driver.remove = rio_device_remove;
+
+	/* register with core */
+	return driver_register(&rdrv->driver);
+}
+
+/**
+ *  rio_unregister_driver - unregister a RIO driver
+ *  @rdrv: the RIO driver structure to unregister
+ *
+ *  Deletes the &struct rio_driver from the list of registered RIO
+ *  drivers, gives it a chance to clean up by calling its remove()
+ *  function for each device it was responsible for, and marks those
+ *  devices as driverless.
+ */
+void rio_unregister_driver(struct rio_driver *rdrv)
+{
+	driver_unregister(&rdrv->driver);
+}
+
+/**
+ *  rio_match_bus - Tell if a RIO device structure has a matching RIO
+ *                  driver device id structure
+ *  @dev: the standard device structure to match against
+ *  @drv: the standard driver structure containing the ids to match against
+ *
+ *  Used by a driver to check whether a RIO device present in the
+ *  system is in its list of supported devices. Returns 1 if
+ *  there is a matching &struct rio_device_id or 0 if there is
+ *  no match.
+ */
+static int rio_match_bus(struct device *dev, struct device_driver *drv)
+{
+	struct rio_dev *rdev = to_rio_dev(dev);
+	struct rio_driver *rdrv = to_rio_driver(drv);
+	const struct rio_device_id *id = rdrv->id_table;
+	const struct rio_device_id *found_id;
+
+	if (!id)
+		goto out;
+
+	found_id = rio_match_device(id, rdev);
+
+	if (found_id)
+		return 1;
+
+      out:return 0;
+}
+
+static struct device rio_bus = {
+	.bus_id = "rapidio",
+};
+
+struct bus_type rio_bus_type = {
+	.name = "rapidio",
+	.match = rio_match_bus,
+	.dev_attrs = rio_dev_attrs
+};
+
+/**
+ *  rio_bus_init - Register the RapidIO bus with the device model
+ *
+ *  Registers the RIO bus device and RIO bus type with the Linux
+ *  device model.
+ */
+static int __init rio_bus_init(void)
+{
+	if (device_register(&rio_bus) < 0)
+		printk("RIO: failed to register RIO bus device\n");
+	return bus_register(&rio_bus_type);
+}
+
+postcore_initcall(rio_bus_init);
+
+EXPORT_SYMBOL_GPL(rio_register_driver);
+EXPORT_SYMBOL_GPL(rio_unregister_driver);
+EXPORT_SYMBOL_GPL(rio_bus_type);
+EXPORT_SYMBOL_GPL(rio_dev_get);
+EXPORT_SYMBOL_GPL(rio_dev_put);
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
new file mode 100644
index 0000000..4f7ed4b
--- /dev/null
+++ b/drivers/rapidio/rio-scan.c
@@ -0,0 +1,945 @@
+/*
+ * RapidIO enumeration and discovery support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/rio.h>
+#include <linux/rio_drv.h>
+#include <linux/rio_ids.h>
+#include <linux/rio_regs.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/timer.h>
+
+#include "rio.h"
+
+LIST_HEAD(rio_devices);
+static LIST_HEAD(rio_switches);
+
+#define RIO_ENUM_CMPL_MAGIC	0xdeadbeef
+
+static void rio_enum_timeout(unsigned long);
+
+DEFINE_SPINLOCK(rio_global_list_lock);
+
+static int next_destid = 0;
+static int next_switchid = 0;
+static int next_net = 0;
+
+static struct timer_list rio_enum_timer =
+TIMER_INITIALIZER(rio_enum_timeout, 0, 0);
+
+static int rio_mport_phys_table[] = {
+	RIO_EFB_PAR_EP_ID,
+	RIO_EFB_PAR_EP_REC_ID,
+	RIO_EFB_SER_EP_ID,
+	RIO_EFB_SER_EP_REC_ID,
+	-1,
+};
+
+static int rio_sport_phys_table[] = {
+	RIO_EFB_PAR_EP_FREE_ID,
+	RIO_EFB_SER_EP_FREE_ID,
+	-1,
+};
+
+/**
+ * rio_get_device_id - Get the base/extended device id for a device
+ * @port: RIO master port
+ * @destid: Destination ID of device
+ * @hopcount: Hopcount to device
+ *
+ * Reads the base/extended device id from a device. Returns the
+ * 8/16-bit device ID.
+ */
+static u16 rio_get_device_id(struct rio_mport *port, u16 destid, u8 hopcount)
+{
+	u32 result;
+
+	rio_mport_read_config_32(port, destid, hopcount, RIO_DID_CSR, &result);
+
+	return RIO_GET_DID(result);
+}
+
+/**
+ * rio_set_device_id - Set the base/extended device id for a device
+ * @port: RIO master port
+ * @destid: Destination ID of device
+ * @hopcount: Hopcount to device
+ * @did: Device ID value to be written
+ *
+ * Writes the base/extended device id from a device.
+ */
+static void rio_set_device_id(struct rio_mport *port, u16 destid, u8 hopcount, u16 did)
+{
+	rio_mport_write_config_32(port, destid, hopcount, RIO_DID_CSR,
+				  RIO_SET_DID(did));
+}
+
+/**
+ * rio_local_set_device_id - Set the base/extended device id for a port
+ * @port: RIO master port
+ * @did: Device ID value to be written
+ *
+ * Writes the base/extended device id from a device.
+ */
+static void rio_local_set_device_id(struct rio_mport *port, u16 did)
+{
+	rio_local_write_config_32(port, RIO_DID_CSR, RIO_SET_DID(did));
+}
+
+/**
+ * rio_clear_locks- Release all host locks and signal enumeration complete
+ * @port: Master port to issue transaction
+ *
+ * Marks the component tag CSR on each device with the enumeration
+ * complete flag. When complete, it then release the host locks on
+ * each device. Returns 0 on success or %-EINVAL on failure.
+ */
+static int rio_clear_locks(struct rio_mport *port)
+{
+	struct rio_dev *rdev;
+	u32 result;
+	int ret = 0;
+
+	/* Write component tag CSR magic complete value */
+	rio_local_write_config_32(port, RIO_COMPONENT_TAG_CSR,
+				  RIO_ENUM_CMPL_MAGIC);
+	list_for_each_entry(rdev, &rio_devices, global_list)
+	    rio_write_config_32(rdev, RIO_COMPONENT_TAG_CSR,
+				RIO_ENUM_CMPL_MAGIC);
+
+	/* Release host device id locks */
+	rio_local_write_config_32(port, RIO_HOST_DID_LOCK_CSR,
+				  port->host_deviceid);
+	rio_local_read_config_32(port, RIO_HOST_DID_LOCK_CSR, &result);
+	if ((result & 0xffff) != 0xffff) {
+		printk(KERN_INFO
+		       "RIO: badness when releasing host lock on master port, result %8.8x\n",
+		       result);
+		ret = -EINVAL;
+	}
+	list_for_each_entry(rdev, &rio_devices, global_list) {
+		rio_write_config_32(rdev, RIO_HOST_DID_LOCK_CSR,
+				    port->host_deviceid);
+		rio_read_config_32(rdev, RIO_HOST_DID_LOCK_CSR, &result);
+		if ((result & 0xffff) != 0xffff) {
+			printk(KERN_INFO
+			       "RIO: badness when releasing host lock on vid %4.4x did %4.4x\n",
+			       rdev->vid, rdev->did);
+			ret = -EINVAL;
+		}
+	}
+
+	return ret;
+}
+
+/**
+ * rio_enum_host- Set host lock and initialize host destination ID
+ * @port: Master port to issue transaction
+ *
+ * Sets the local host master port lock and destination ID register
+ * with the host device ID value. The host device ID value is provided
+ * by the platform. Returns %0 on success or %-1 on failure.
+ */
+static int rio_enum_host(struct rio_mport *port)
+{
+	u32 result;
+
+	/* Set master port host device id lock */
+	rio_local_write_config_32(port, RIO_HOST_DID_LOCK_CSR,
+				  port->host_deviceid);
+
+	rio_local_read_config_32(port, RIO_HOST_DID_LOCK_CSR, &result);
+	if ((result & 0xffff) != port->host_deviceid)
+		return -1;
+
+	/* Set master port destid and init destid ctr */
+	rio_local_set_device_id(port, port->host_deviceid);
+
+	if (next_destid == port->host_deviceid)
+		next_destid++;
+
+	return 0;
+}
+
+/**
+ * rio_device_has_destid- Test if a device contains a destination ID register
+ * @port: Master port to issue transaction
+ * @src_ops: RIO device source operations
+ * @dst_ops: RIO device destination operations
+ *
+ * Checks the provided @src_ops and @dst_ops for the necessary transaction
+ * capabilities that indicate whether or not a device will implement a
+ * destination ID register. Returns 1 if true or 0 if false.
+ */
+static int rio_device_has_destid(struct rio_mport *port, int src_ops,
+				 int dst_ops)
+{
+	u32 mask = RIO_OPS_READ | RIO_OPS_WRITE | RIO_OPS_ATOMIC_TST_SWP | RIO_OPS_ATOMIC_INC | RIO_OPS_ATOMIC_DEC | RIO_OPS_ATOMIC_SET | RIO_OPS_ATOMIC_CLR;
+
+	return !!((src_ops | dst_ops) & mask);
+}
+
+/**
+ * rio_release_dev- Frees a RIO device struct
+ * @dev: LDM device associated with a RIO device struct
+ *
+ * Gets the RIO device struct associated a RIO device struct.
+ * The RIO device struct is freed.
+ */
+static void rio_release_dev(struct device *dev)
+{
+	struct rio_dev *rdev;
+
+	rdev = to_rio_dev(dev);
+	kfree(rdev);
+}
+
+/**
+ * rio_is_switch- Tests if a RIO device has switch capabilities
+ * @rdev: RIO device
+ *
+ * Gets the RIO device Processing Element Features register
+ * contents and tests for switch capabilities. Returns 1 if
+ * the device is a switch or 0 if it is not a switch.
+ * The RIO device struct is freed.
+ */
+static int rio_is_switch(struct rio_dev *rdev)
+{
+	if (rdev->pef & RIO_PEF_SWITCH)
+		return 1;
+	return 0;
+}
+
+/**
+ * rio_route_set_ops- Sets routing operations for a particular vendor switch
+ * @rdev: RIO device
+ *
+ * Searches the RIO route ops table for known switch types. If the vid
+ * and did match a switch table entry, then set the add_entry() and
+ * get_entry() ops to the table entry values.
+ */
+static void rio_route_set_ops(struct rio_dev *rdev)
+{
+	struct rio_route_ops *cur = __start_rio_route_ops;
+	struct rio_route_ops *end = __end_rio_route_ops;
+
+	while (cur < end) {
+		if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) {
+			pr_debug("RIO: adding routing ops for %s\n", rio_name(rdev));
+			rdev->rswitch->add_entry = cur->add_hook;
+			rdev->rswitch->get_entry = cur->get_hook;
+		}
+		cur++;
+	}
+
+	if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry)
+		printk(KERN_ERR "RIO: missing routing ops for %s\n",
+		       rio_name(rdev));
+}
+
+/**
+ * rio_add_device- Adds a RIO device to the device model
+ * @rdev: RIO device
+ *
+ * Adds the RIO device to the global device list and adds the RIO
+ * device to the RIO device list.  Creates the generic sysfs nodes
+ * for an RIO device.
+ */
+static void __devinit rio_add_device(struct rio_dev *rdev)
+{
+	device_add(&rdev->dev);
+
+	spin_lock(&rio_global_list_lock);
+	list_add_tail(&rdev->global_list, &rio_devices);
+	spin_unlock(&rio_global_list_lock);
+
+	rio_create_sysfs_dev_files(rdev);
+}
+
+/**
+ * rio_setup_device- Allocates and sets up a RIO device
+ * @net: RIO network
+ * @port: Master port to send transactions
+ * @destid: Current destination ID
+ * @hopcount: Current hopcount
+ * @do_enum: Enumeration/Discovery mode flag
+ *
+ * Allocates a RIO device and configures fields based on configuration
+ * space contents. If device has a destination ID register, a destination
+ * ID is either assigned in enumeration mode or read from configuration
+ * space in discovery mode.  If the device has switch capabilities, then
+ * a switch is allocated and configured appropriately. Returns a pointer
+ * to a RIO device on success or NULL on failure.
+ *
+ */
+static struct rio_dev *rio_setup_device(struct rio_net *net,
+					struct rio_mport *port, u16 destid,
+					u8 hopcount, int do_enum)
+{
+	struct rio_dev *rdev;
+	struct rio_switch *rswitch;
+	int result, rdid;
+
+	rdev = kmalloc(sizeof(struct rio_dev), GFP_KERNEL);
+	if (!rdev)
+		goto out;
+
+	memset(rdev, 0, sizeof(struct rio_dev));
+	rdev->net = net;
+	rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_ID_CAR,
+				 &result);
+	rdev->did = result >> 16;
+	rdev->vid = result & 0xffff;
+	rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_INFO_CAR,
+				 &rdev->device_rev);
+	rio_mport_read_config_32(port, destid, hopcount, RIO_ASM_ID_CAR,
+				 &result);
+	rdev->asm_did = result >> 16;
+	rdev->asm_vid = result & 0xffff;
+	rio_mport_read_config_32(port, destid, hopcount, RIO_ASM_INFO_CAR,
+				 &result);
+	rdev->asm_rev = result >> 16;
+	rio_mport_read_config_32(port, destid, hopcount, RIO_PEF_CAR,
+				 &rdev->pef);
+	if (rdev->pef & RIO_PEF_EXT_FEATURES)
+		rdev->efptr = result & 0xffff;
+
+	rio_mport_read_config_32(port, destid, hopcount, RIO_SRC_OPS_CAR,
+				 &rdev->src_ops);
+	rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR,
+				 &rdev->dst_ops);
+
+	if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)
+	    && do_enum) {
+		rio_set_device_id(port, destid, hopcount, next_destid);
+		rdev->destid = next_destid++;
+		if (next_destid == port->host_deviceid)
+			next_destid++;
+	} else
+		rdev->destid = rio_get_device_id(port, destid, hopcount);
+
+	/* If a PE has both switch and other functions, show it as a switch */
+	if (rio_is_switch(rdev)) {
+		rio_mport_read_config_32(port, destid, hopcount,
+					 RIO_SWP_INFO_CAR, &rdev->swpinfo);
+		rswitch = kmalloc(sizeof(struct rio_switch), GFP_KERNEL);
+		if (!rswitch) {
+			kfree(rdev);
+			rdev = NULL;
+			goto out;
+		}
+		rswitch->switchid = next_switchid;
+		rswitch->hopcount = hopcount;
+		rswitch->destid = 0xffff;
+		/* Initialize switch route table */
+		for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES; rdid++)
+			rswitch->route_table[rdid] = RIO_INVALID_ROUTE;
+		rdev->rswitch = rswitch;
+		sprintf(rio_name(rdev), "%02x:s:%04x", rdev->net->id,
+			rdev->rswitch->switchid);
+		rio_route_set_ops(rdev);
+
+		list_add_tail(&rswitch->node, &rio_switches);
+
+	} else
+		sprintf(rio_name(rdev), "%02x:e:%04x", rdev->net->id,
+			rdev->destid);
+
+	rdev->dev.bus = &rio_bus_type;
+
+	device_initialize(&rdev->dev);
+	rdev->dev.release = rio_release_dev;
+	rio_dev_get(rdev);
+
+	rdev->dma_mask = DMA_32BIT_MASK;
+	rdev->dev.dma_mask = &rdev->dma_mask;
+	rdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
+
+	if ((rdev->pef & RIO_PEF_INB_DOORBELL) &&
+	    (rdev->dst_ops & RIO_DST_OPS_DOORBELL))
+		rio_init_dbell_res(&rdev->riores[RIO_DOORBELL_RESOURCE],
+				   0, 0xffff);
+
+	rio_add_device(rdev);
+
+      out:
+	return rdev;
+}
+
+/**
+ * rio_sport_is_active- Tests if a switch port has an active connection.
+ * @port: Master port to send transaction
+ * @destid: Associated destination ID for switch
+ * @hopcount: Hopcount to reach switch
+ * @sport: Switch port number
+ *
+ * Reads the port error status CSR for a particular switch port to
+ * determine if the port has an active link.  Returns
+ * %PORT_N_ERR_STS_PORT_OK if the port is active or %0 if it is
+ * inactive.
+ */
+static int
+rio_sport_is_active(struct rio_mport *port, u16 destid, u8 hopcount, int sport)
+{
+	u32 result;
+	u32 ext_ftr_ptr;
+
+	int *entry = rio_sport_phys_table;
+
+	do {
+		if ((ext_ftr_ptr =
+		     rio_mport_get_feature(port, 0, destid, hopcount, *entry)))
+
+			break;
+	} while (*++entry >= 0);
+
+	if (ext_ftr_ptr)
+		rio_mport_read_config_32(port, destid, hopcount,
+					 ext_ftr_ptr +
+					 RIO_PORT_N_ERR_STS_CSR(sport),
+					 &result);
+
+	return (result & PORT_N_ERR_STS_PORT_OK);
+}
+
+/**
+ * rio_route_add_entry- Add a route entry to a switch routing table
+ * @mport: Master port to send transaction
+ * @rdev: Switch device
+ * @table: Routing table ID
+ * @route_destid: Destination ID to be routed
+ * @route_port: Port number to be routed
+ *
+ * Calls the switch specific add_entry() method to add a route entry
+ * on a switch. The route table can be specified using the @table
+ * argument if a switch has per port routing tables or the normal
+ * use is to specific all tables (or the global table) by passing
+ * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL
+ * on failure.
+ */
+static int rio_route_add_entry(struct rio_mport *mport, struct rio_dev *rdev,
+			       u16 table, u16 route_destid, u8 route_port)
+{
+	return rdev->rswitch->add_entry(mport, rdev->rswitch->destid,
+					rdev->rswitch->hopcount, table,
+					route_destid, route_port);
+}
+
+/**
+ * rio_route_get_entry- Read a route entry in a switch routing table
+ * @mport: Master port to send transaction
+ * @rdev: Switch device
+ * @table: Routing table ID
+ * @route_destid: Destination ID to be routed
+ * @route_port: Pointer to read port number into
+ *
+ * Calls the switch specific get_entry() method to read a route entry
+ * in a switch. The route table can be specified using the @table
+ * argument if a switch has per port routing tables or the normal
+ * use is to specific all tables (or the global table) by passing
+ * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL
+ * on failure.
+ */
+static int
+rio_route_get_entry(struct rio_mport *mport, struct rio_dev *rdev, u16 table,
+		    u16 route_destid, u8 * route_port)
+{
+	return rdev->rswitch->get_entry(mport, rdev->rswitch->destid,
+					rdev->rswitch->hopcount, table,
+					route_destid, route_port);
+}
+
+/**
+ * rio_get_host_deviceid_lock- Reads the Host Device ID Lock CSR on a device
+ * @port: Master port to send transaction
+ * @hopcount: Number of hops to the device
+ *
+ * Used during enumeration to read the Host Device ID Lock CSR on a
+ * RIO device. Returns the value of the lock register.
+ */
+static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount)
+{
+	u32 result;
+
+	rio_mport_read_config_32(port, RIO_ANY_DESTID, hopcount,
+				 RIO_HOST_DID_LOCK_CSR, &result);
+
+	return (u16) (result & 0xffff);
+}
+
+/**
+ * rio_get_swpinfo_inport- Gets the ingress port number
+ * @mport: Master port to send transaction
+ * @destid: Destination ID associated with the switch
+ * @hopcount: Number of hops to the device
+ *
+ * Returns port number being used to access the switch device.
+ */
+static u8
+rio_get_swpinfo_inport(struct rio_mport *mport, u16 destid, u8 hopcount)
+{
+	u32 result;
+
+	rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR,
+				 &result);
+
+	return (u8) (result & 0xff);
+}
+
+/**
+ * rio_get_swpinfo_tports- Gets total number of ports on the switch
+ * @mport: Master port to send transaction
+ * @destid: Destination ID associated with the switch
+ * @hopcount: Number of hops to the device
+ *
+ * Returns total numbers of ports implemented by the switch device.
+ */
+static u8 rio_get_swpinfo_tports(struct rio_mport *mport, u16 destid,
+				 u8 hopcount)
+{
+	u32 result;
+
+	rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR,
+				 &result);
+
+	return RIO_GET_TOTAL_PORTS(result);
+}
+
+/**
+ * rio_net_add_mport- Add a master port to a RIO network
+ * @net: RIO network
+ * @port: Master port to add
+ *
+ * Adds a master port to the network list of associated master
+ * ports..
+ */
+static void rio_net_add_mport(struct rio_net *net, struct rio_mport *port)
+{
+	spin_lock(&rio_global_list_lock);
+	list_add_tail(&port->nnode, &net->mports);
+	spin_unlock(&rio_global_list_lock);
+}
+
+/**
+ * rio_enum_peer- Recursively enumerate a RIO network through a master port
+ * @net: RIO network being enumerated
+ * @port: Master port to send transactions
+ * @hopcount: Number of hops into the network
+ *
+ * Recursively enumerates a RIO network.  Transactions are sent via the
+ * master port passed in @port.
+ */
+static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
+			 u8 hopcount)
+{
+	int port_num;
+	int num_ports;
+	int cur_destid;
+	struct rio_dev *rdev;
+	u16 destid;
+	int tmp;
+
+	if (rio_get_host_deviceid_lock(port, hopcount) == port->host_deviceid) {
+		pr_debug("RIO: PE already discovered by this host\n");
+		/*
+		 * Already discovered by this host. Add it as another
+		 * master port for the current network.
+		 */
+		rio_net_add_mport(net, port);
+		return 0;
+	}
+
+	/* Attempt to acquire device lock */
+	rio_mport_write_config_32(port, RIO_ANY_DESTID, hopcount,
+				  RIO_HOST_DID_LOCK_CSR, port->host_deviceid);
+	while ((tmp = rio_get_host_deviceid_lock(port, hopcount))
+	       < port->host_deviceid) {
+		/* Delay a bit */
+		mdelay(1);
+		/* Attempt to acquire device lock again */
+		rio_mport_write_config_32(port, RIO_ANY_DESTID, hopcount,
+					  RIO_HOST_DID_LOCK_CSR,
+					  port->host_deviceid);
+	}
+
+	if (rio_get_host_deviceid_lock(port, hopcount) > port->host_deviceid) {
+		pr_debug(
+		    "RIO: PE locked by a higher priority host...retreating\n");
+		return -1;
+	}
+
+	/* Setup new RIO device */
+	if ((rdev = rio_setup_device(net, port, RIO_ANY_DESTID, hopcount, 1))) {
+		/* Add device to the global and bus/net specific list. */
+		list_add_tail(&rdev->net_list, &net->devices);
+	} else
+		return -1;
+
+	if (rio_is_switch(rdev)) {
+		next_switchid++;
+
+		for (destid = 0; destid < next_destid; destid++) {
+			rio_route_add_entry(port, rdev, RIO_GLOBAL_TABLE,
+					    destid, rio_get_swpinfo_inport(port,
+									   RIO_ANY_DESTID,
+									   hopcount));
+			rdev->rswitch->route_table[destid] =
+			    rio_get_swpinfo_inport(port, RIO_ANY_DESTID,
+						   hopcount);
+		}
+
+		num_ports =
+		    rio_get_swpinfo_tports(port, RIO_ANY_DESTID, hopcount);
+		pr_debug(
+		    "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
+		    rio_name(rdev), rdev->vid, rdev->did, num_ports);
+		for (port_num = 0; port_num < num_ports; port_num++) {
+			if (rio_get_swpinfo_inport
+			    (port, RIO_ANY_DESTID, hopcount) == port_num)
+				continue;
+
+			cur_destid = next_destid;
+
+			if (rio_sport_is_active
+			    (port, RIO_ANY_DESTID, hopcount, port_num)) {
+				pr_debug(
+				    "RIO: scanning device on port %d\n",
+				    port_num);
+				rio_route_add_entry(port, rdev,
+						    RIO_GLOBAL_TABLE,
+						    RIO_ANY_DESTID, port_num);
+
+				if (rio_enum_peer(net, port, hopcount + 1) < 0)
+					return -1;
+
+				/* Update routing tables */
+				if (next_destid > cur_destid) {
+					for (destid = cur_destid;
+					     destid < next_destid; destid++) {
+						rio_route_add_entry(port, rdev,
+								    RIO_GLOBAL_TABLE,
+								    destid,
+								    port_num);
+						rdev->rswitch->
+						    route_table[destid] =
+						    port_num;
+					}
+					rdev->rswitch->destid = cur_destid;
+				}
+			}
+		}
+	} else
+		pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n",
+		    rio_name(rdev), rdev->vid, rdev->did);
+
+	return 0;
+}
+
+/**
+ * rio_enum_complete- Tests if enumeration of a network is complete
+ * @port: Master port to send transaction
+ *
+ * Tests the Component Tag CSR for presence of the magic enumeration
+ * complete flag. Return %1 if enumeration is complete or %0 if
+ * enumeration is incomplete.
+ */
+static int rio_enum_complete(struct rio_mport *port)
+{
+	u32 tag_csr;
+	int ret = 0;
+
+	rio_local_read_config_32(port, RIO_COMPONENT_TAG_CSR, &tag_csr);
+
+	if (tag_csr == RIO_ENUM_CMPL_MAGIC)
+		ret = 1;
+
+	return ret;
+}
+
+/**
+ * rio_disc_peer- Recursively discovers a RIO network through a master port
+ * @net: RIO network being discovered
+ * @port: Master port to send transactions
+ * @destid: Current destination ID in network
+ * @hopcount: Number of hops into the network
+ *
+ * Recursively discovers a RIO network.  Transactions are sent via the
+ * master port passed in @port.
+ */
+static int
+rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
+	      u8 hopcount)
+{
+	u8 port_num, route_port;
+	int num_ports;
+	struct rio_dev *rdev;
+	u16 ndestid;
+
+	/* Setup new RIO device */
+	if ((rdev = rio_setup_device(net, port, destid, hopcount, 0))) {
+		/* Add device to the global and bus/net specific list. */
+		list_add_tail(&rdev->net_list, &net->devices);
+	} else
+		return -1;
+
+	if (rio_is_switch(rdev)) {
+		next_switchid++;
+
+		/* Associated destid is how we accessed this switch */
+		rdev->rswitch->destid = destid;
+
+		num_ports = rio_get_swpinfo_tports(port, destid, hopcount);
+		pr_debug(
+		    "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
+		    rio_name(rdev), rdev->vid, rdev->did, num_ports);
+		for (port_num = 0; port_num < num_ports; port_num++) {
+			if (rio_get_swpinfo_inport(port, destid, hopcount) ==
+			    port_num)
+				continue;
+
+			if (rio_sport_is_active
+			    (port, destid, hopcount, port_num)) {
+				pr_debug(
+				    "RIO: scanning device on port %d\n",
+				    port_num);
+				for (ndestid = 0; ndestid < RIO_ANY_DESTID;
+				     ndestid++) {
+					rio_route_get_entry(port, rdev,
+							    RIO_GLOBAL_TABLE,
+							    ndestid,
+							    &route_port);
+					if (route_port == port_num)
+						break;
+				}
+
+				if (rio_disc_peer
+				    (net, port, ndestid, hopcount + 1) < 0)
+					return -1;
+			}
+		}
+	} else
+		pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n",
+		    rio_name(rdev), rdev->vid, rdev->did);
+
+	return 0;
+}
+
+/**
+ * rio_mport_is_active- Tests if master port link is active
+ * @port: Master port to test
+ *
+ * Reads the port error status CSR for the master port to
+ * determine if the port has an active link.  Returns
+ * %PORT_N_ERR_STS_PORT_OK if the  master port is active
+ * or %0 if it is inactive.
+ */
+static int rio_mport_is_active(struct rio_mport *port)
+{
+	u32 result = 0;
+	u32 ext_ftr_ptr;
+	int *entry = rio_mport_phys_table;
+
+	do {
+		if ((ext_ftr_ptr =
+		     rio_mport_get_feature(port, 1, 0, 0, *entry)))
+			break;
+	} while (*++entry >= 0);
+
+	if (ext_ftr_ptr)
+		rio_local_read_config_32(port,
+					 ext_ftr_ptr +
+					 RIO_PORT_N_ERR_STS_CSR(port->index),
+					 &result);
+
+	return (result & PORT_N_ERR_STS_PORT_OK);
+}
+
+/**
+ * rio_alloc_net- Allocate and configure a new RIO network
+ * @port: Master port associated with the RIO network
+ *
+ * Allocates a RIO network structure, initializes per-network
+ * list heads, and adds the associated master port to the
+ * network list of associated master ports. Returns a
+ * RIO network pointer on success or %NULL on failure.
+ */
+static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port)
+{
+	struct rio_net *net;
+
+	net = kmalloc(sizeof(struct rio_net), GFP_KERNEL);
+	if (net) {
+		memset(net, 0, sizeof(struct rio_net));
+		INIT_LIST_HEAD(&net->node);
+		INIT_LIST_HEAD(&net->devices);
+		INIT_LIST_HEAD(&net->mports);
+		list_add_tail(&port->nnode, &net->mports);
+		net->hport = port;
+		net->id = next_net++;
+	}
+	return net;
+}
+
+/**
+ * rio_enum_mport- Start enumeration through a master port
+ * @mport: Master port to send transactions
+ *
+ * Starts the enumeration process. If somebody has enumerated our
+ * master port device, then give up. If not and we have an active
+ * link, then start recursive peer enumeration. Returns %0 if
+ * enumeration succeeds or %-EBUSY if enumeration fails.
+ */
+int rio_enum_mport(struct rio_mport *mport)
+{
+	struct rio_net *net = NULL;
+	int rc = 0;
+
+	printk(KERN_INFO "RIO: enumerate master port %d, %s\n", mport->id,
+	       mport->name);
+	/* If somebody else enumerated our master port device, bail. */
+	if (rio_enum_host(mport) < 0) {
+		printk(KERN_INFO
+		       "RIO: master port %d device has been enumerated by a remote host\n",
+		       mport->id);
+		rc = -EBUSY;
+		goto out;
+	}
+
+	/* If master port has an active link, allocate net and enum peers */
+	if (rio_mport_is_active(mport)) {
+		if (!(net = rio_alloc_net(mport))) {
+			printk(KERN_ERR "RIO: failed to allocate new net\n");
+			rc = -ENOMEM;
+			goto out;
+		}
+		if (rio_enum_peer(net, mport, 0) < 0) {
+			/* A higher priority host won enumeration, bail. */
+			printk(KERN_INFO
+			       "RIO: master port %d device has lost enumeration to a remote host\n",
+			       mport->id);
+			rio_clear_locks(mport);
+			rc = -EBUSY;
+			goto out;
+		}
+		rio_clear_locks(mport);
+	} else {
+		printk(KERN_INFO "RIO: master port %d link inactive\n",
+		       mport->id);
+		rc = -EINVAL;
+	}
+
+      out:
+	return rc;
+}
+
+/**
+ * rio_build_route_tables- Generate route tables from switch route entries
+ *
+ * For each switch device, generate a route table by copying existing
+ * route entries from the switch.
+ */
+static void rio_build_route_tables(void)
+{
+	struct rio_dev *rdev;
+	int i;
+	u8 sport;
+
+	list_for_each_entry(rdev, &rio_devices, global_list)
+	    if (rio_is_switch(rdev))
+		for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) {
+			if (rio_route_get_entry
+			    (rdev->net->hport, rdev, RIO_GLOBAL_TABLE, i,
+			     &sport) < 0)
+				continue;
+			rdev->rswitch->route_table[i] = sport;
+		}
+}
+
+/**
+ * rio_enum_timeout- Signal that enumeration timed out
+ * @data: Address of timeout flag.
+ *
+ * When the enumeration complete timer expires, set a flag that
+ * signals to the discovery process that enumeration did not
+ * complete in a sane amount of time.
+ */
+static void rio_enum_timeout(unsigned long data)
+{
+	/* Enumeration timed out, set flag */
+	*(int *)data = 1;
+}
+
+/**
+ * rio_disc_mport- Start discovery through a master port
+ * @mport: Master port to send transactions
+ *
+ * Starts the discovery process. If we have an active link,
+ * then wait for the signal that enumeration is complete.
+ * When enumeration completion is signaled, start recursive
+ * peer discovery. Returns %0 if discovery succeeds or %-EBUSY
+ * on failure.
+ */
+int rio_disc_mport(struct rio_mport *mport)
+{
+	struct rio_net *net = NULL;
+	int enum_timeout_flag = 0;
+
+	printk(KERN_INFO "RIO: discover master port %d, %s\n", mport->id,
+	       mport->name);
+
+	/* If master port has an active link, allocate net and discover peers */
+	if (rio_mport_is_active(mport)) {
+		if (!(net = rio_alloc_net(mport))) {
+			printk(KERN_ERR "RIO: Failed to allocate new net\n");
+			goto bail;
+		}
+
+		pr_debug("RIO: wait for enumeration complete...");
+
+		rio_enum_timer.expires =
+		    jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ;
+		rio_enum_timer.data = (unsigned long)&enum_timeout_flag;
+		add_timer(&rio_enum_timer);
+		while (!rio_enum_complete(mport)) {
+			mdelay(1);
+			if (enum_timeout_flag) {
+				del_timer_sync(&rio_enum_timer);
+				goto timeout;
+			}
+		}
+		del_timer_sync(&rio_enum_timer);
+
+		pr_debug("done\n");
+		if (rio_disc_peer(net, mport, RIO_ANY_DESTID, 0) < 0) {
+			printk(KERN_INFO
+			       "RIO: master port %d device has failed discovery\n",
+			       mport->id);
+			goto bail;
+		}
+
+		rio_build_route_tables();
+	}
+
+	return 0;
+
+      timeout:
+	pr_debug("timeout\n");
+      bail:
+	return -EBUSY;
+}
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
new file mode 100644
index 0000000..30a1143
--- /dev/null
+++ b/drivers/rapidio/rio-sysfs.c
@@ -0,0 +1,230 @@
+/*
+ * RapidIO sysfs attributes and support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/rio.h>
+#include <linux/rio_drv.h>
+#include <linux/stat.h>
+
+#include "rio.h"
+
+/* Sysfs support */
+#define rio_config_attr(field, format_string)					\
+static ssize_t								\
+field##_show(struct device *dev, struct device_attribute *attr, char *buf)			\
+{									\
+	struct rio_dev *rdev = to_rio_dev(dev);				\
+									\
+	return sprintf(buf, format_string, rdev->field);		\
+}									\
+
+rio_config_attr(did, "0x%04x\n");
+rio_config_attr(vid, "0x%04x\n");
+rio_config_attr(device_rev, "0x%08x\n");
+rio_config_attr(asm_did, "0x%04x\n");
+rio_config_attr(asm_vid, "0x%04x\n");
+rio_config_attr(asm_rev, "0x%04x\n");
+
+static ssize_t routes_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct rio_dev *rdev = to_rio_dev(dev);
+	char *str = buf;
+	int i;
+
+	if (!rdev->rswitch)
+		goto out;
+
+	for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) {
+		if (rdev->rswitch->route_table[i] == RIO_INVALID_ROUTE)
+			continue;
+		str +=
+		    sprintf(str, "%04x %02x\n", i,
+			    rdev->rswitch->route_table[i]);
+	}
+
+      out:
+	return (str - buf);
+}
+
+struct device_attribute rio_dev_attrs[] = {
+	__ATTR_RO(did),
+	__ATTR_RO(vid),
+	__ATTR_RO(device_rev),
+	__ATTR_RO(asm_did),
+	__ATTR_RO(asm_vid),
+	__ATTR_RO(asm_rev),
+	__ATTR_RO(routes),
+	__ATTR_NULL,
+};
+
+static ssize_t
+rio_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+	struct rio_dev *dev =
+	    to_rio_dev(container_of(kobj, struct device, kobj));
+	unsigned int size = 0x100;
+	loff_t init_off = off;
+	u8 *data = (u8 *) buf;
+
+	/* Several chips lock up trying to read undefined config space */
+	if (capable(CAP_SYS_ADMIN))
+		size = 0x200000;
+
+	if (off > size)
+		return 0;
+	if (off + count > size) {
+		size -= off;
+		count = size;
+	} else {
+		size = count;
+	}
+
+	if ((off & 1) && size) {
+		u8 val;
+		rio_read_config_8(dev, off, &val);
+		data[off - init_off] = val;
+		off++;
+		size--;
+	}
+
+	if ((off & 3) && size > 2) {
+		u16 val;
+		rio_read_config_16(dev, off, &val);
+		data[off - init_off] = (val >> 8) & 0xff;
+		data[off - init_off + 1] = val & 0xff;
+		off += 2;
+		size -= 2;
+	}
+
+	while (size > 3) {
+		u32 val;
+		rio_read_config_32(dev, off, &val);
+		data[off - init_off] = (val >> 24) & 0xff;
+		data[off - init_off + 1] = (val >> 16) & 0xff;
+		data[off - init_off + 2] = (val >> 8) & 0xff;
+		data[off - init_off + 3] = val & 0xff;
+		off += 4;
+		size -= 4;
+	}
+
+	if (size >= 2) {
+		u16 val;
+		rio_read_config_16(dev, off, &val);
+		data[off - init_off] = (val >> 8) & 0xff;
+		data[off - init_off + 1] = val & 0xff;
+		off += 2;
+		size -= 2;
+	}
+
+	if (size > 0) {
+		u8 val;
+		rio_read_config_8(dev, off, &val);
+		data[off - init_off] = val;
+		off++;
+		--size;
+	}
+
+	return count;
+}
+
+static ssize_t
+rio_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+	struct rio_dev *dev =
+	    to_rio_dev(container_of(kobj, struct device, kobj));
+	unsigned int size = count;
+	loff_t init_off = off;
+	u8 *data = (u8 *) buf;
+
+	if (off > 0x200000)
+		return 0;
+	if (off + count > 0x200000) {
+		size = 0x200000 - off;
+		count = size;
+	}
+
+	if ((off & 1) && size) {
+		rio_write_config_8(dev, off, data[off - init_off]);
+		off++;
+		size--;
+	}
+
+	if ((off & 3) && (size > 2)) {
+		u16 val = data[off - init_off + 1];
+		val |= (u16) data[off - init_off] << 8;
+		rio_write_config_16(dev, off, val);
+		off += 2;
+		size -= 2;
+	}
+
+	while (size > 3) {
+		u32 val = data[off - init_off + 3];
+		val |= (u32) data[off - init_off + 2] << 8;
+		val |= (u32) data[off - init_off + 1] << 16;
+		val |= (u32) data[off - init_off] << 24;
+		rio_write_config_32(dev, off, val);
+		off += 4;
+		size -= 4;
+	}
+
+	if (size >= 2) {
+		u16 val = data[off - init_off + 1];
+		val |= (u16) data[off - init_off] << 8;
+		rio_write_config_16(dev, off, val);
+		off += 2;
+		size -= 2;
+	}
+
+	if (size) {
+		rio_write_config_8(dev, off, data[off - init_off]);
+		off++;
+		--size;
+	}
+
+	return count;
+}
+
+static struct bin_attribute rio_config_attr = {
+	.attr = {
+		 .name = "config",
+		 .mode = S_IRUGO | S_IWUSR,
+		 .owner = THIS_MODULE,
+		 },
+	.size = 0x200000,
+	.read = rio_read_config,
+	.write = rio_write_config,
+};
+
+/**
+ * rio_create_sysfs_dev_files - create RIO specific sysfs files
+ * @rdev: device whose entries should be created
+ *
+ * Create files when @rdev is added to sysfs.
+ */
+int rio_create_sysfs_dev_files(struct rio_dev *rdev)
+{
+	sysfs_create_bin_file(&rdev->dev.kobj, &rio_config_attr);
+
+	return 0;
+}
+
+/**
+ * rio_remove_sysfs_dev_files - cleanup RIO specific sysfs files
+ * @rdev: device whose entries we should free
+ *
+ * Cleanup when @rdev is removed from sysfs.
+ */
+void rio_remove_sysfs_dev_files(struct rio_dev *rdev)
+{
+	sysfs_remove_bin_file(&rdev->dev.kobj, &rio_config_attr);
+}
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
new file mode 100644
index 0000000..3ca1011
--- /dev/null
+++ b/drivers/rapidio/rio.c
@@ -0,0 +1,510 @@
+/*
+ * RapidIO interconnect services
+ * (RapidIO Interconnect Specification, http://www.rapidio.org)
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/rio.h>
+#include <linux/rio_drv.h>
+#include <linux/rio_ids.h>
+#include <linux/rio_regs.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+
+#include "rio.h"
+
+static LIST_HEAD(rio_mports);
+
+/**
+ * rio_local_get_device_id - Get the base/extended device id for a port
+ * @port: RIO master port from which to get the deviceid
+ *
+ * Reads the base/extended device id from the local device
+ * implementing the master port. Returns the 8/16-bit device
+ * id.
+ */
+u16 rio_local_get_device_id(struct rio_mport *port)
+{
+	u32 result;
+
+	rio_local_read_config_32(port, RIO_DID_CSR, &result);
+
+	return (RIO_GET_DID(result));
+}
+
+/**
+ * rio_request_inb_mbox - request inbound mailbox service
+ * @mport: RIO master port from which to allocate the mailbox resource
+ * @dev_id: Device specific pointer to pass on event
+ * @mbox: Mailbox number to claim
+ * @entries: Number of entries in inbound mailbox queue
+ * @minb: Callback to execute when inbound message is received
+ *
+ * Requests ownership of an inbound mailbox resource and binds
+ * a callback function to the resource. Returns %0 on success.
+ */
+int rio_request_inb_mbox(struct rio_mport *mport,
+			 void *dev_id,
+			 int mbox,
+			 int entries,
+			 void (*minb) (struct rio_mport * mport, void *dev_id, int mbox,
+				       int slot))
+{
+	int rc = 0;
+
+	struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL);
+
+	if (res) {
+		rio_init_mbox_res(res, mbox, mbox);
+
+		/* Make sure this mailbox isn't in use */
+		if ((rc =
+		     request_resource(&mport->riores[RIO_INB_MBOX_RESOURCE],
+				      res)) < 0) {
+			kfree(res);
+			goto out;
+		}
+
+		mport->inb_msg[mbox].res = res;
+
+		/* Hook the inbound message callback */
+		mport->inb_msg[mbox].mcback = minb;
+
+		rc = rio_open_inb_mbox(mport, dev_id, mbox, entries);
+	} else
+		rc = -ENOMEM;
+
+      out:
+	return rc;
+}
+
+/**
+ * rio_release_inb_mbox - release inbound mailbox message service
+ * @mport: RIO master port from which to release the mailbox resource
+ * @mbox: Mailbox number to release
+ *
+ * Releases ownership of an inbound mailbox resource. Returns 0
+ * if the request has been satisfied.
+ */
+int rio_release_inb_mbox(struct rio_mport *mport, int mbox)
+{
+	rio_close_inb_mbox(mport, mbox);
+
+	/* Release the mailbox resource */
+	return release_resource(mport->inb_msg[mbox].res);
+}
+
+/**
+ * rio_request_outb_mbox - request outbound mailbox service
+ * @mport: RIO master port from which to allocate the mailbox resource
+ * @dev_id: Device specific pointer to pass on event
+ * @mbox: Mailbox number to claim
+ * @entries: Number of entries in outbound mailbox queue
+ * @moutb: Callback to execute when outbound message is sent
+ *
+ * Requests ownership of an outbound mailbox resource and binds
+ * a callback function to the resource. Returns 0 on success.
+ */
+int rio_request_outb_mbox(struct rio_mport *mport,
+			  void *dev_id,
+			  int mbox,
+			  int entries,
+			  void (*moutb) (struct rio_mport * mport, void *dev_id, int mbox, int slot))
+{
+	int rc = 0;
+
+	struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL);
+
+	if (res) {
+		rio_init_mbox_res(res, mbox, mbox);
+
+		/* Make sure this outbound mailbox isn't in use */
+		if ((rc =
+		     request_resource(&mport->riores[RIO_OUTB_MBOX_RESOURCE],
+				      res)) < 0) {
+			kfree(res);
+			goto out;
+		}
+
+		mport->outb_msg[mbox].res = res;
+
+		/* Hook the inbound message callback */
+		mport->outb_msg[mbox].mcback = moutb;
+
+		rc = rio_open_outb_mbox(mport, dev_id, mbox, entries);
+	} else
+		rc = -ENOMEM;
+
+      out:
+	return rc;
+}
+
+/**
+ * rio_release_outb_mbox - release outbound mailbox message service
+ * @mport: RIO master port from which to release the mailbox resource
+ * @mbox: Mailbox number to release
+ *
+ * Releases ownership of an inbound mailbox resource. Returns 0
+ * if the request has been satisfied.
+ */
+int rio_release_outb_mbox(struct rio_mport *mport, int mbox)
+{
+	rio_close_outb_mbox(mport, mbox);
+
+	/* Release the mailbox resource */
+	return release_resource(mport->outb_msg[mbox].res);
+}
+
+/**
+ * rio_setup_inb_dbell - bind inbound doorbell callback
+ * @mport: RIO master port to bind the doorbell callback
+ * @dev_id: Device specific pointer to pass on event
+ * @res: Doorbell message resource
+ * @dinb: Callback to execute when doorbell is received
+ *
+ * Adds a doorbell resource/callback pair into a port's
+ * doorbell event list. Returns 0 if the request has been
+ * satisfied.
+ */
+static int
+rio_setup_inb_dbell(struct rio_mport *mport, void *dev_id, struct resource *res,
+		    void (*dinb) (struct rio_mport * mport, void *dev_id, u16 src, u16 dst,
+				  u16 info))
+{
+	int rc = 0;
+	struct rio_dbell *dbell;
+
+	if (!(dbell = kmalloc(sizeof(struct rio_dbell), GFP_KERNEL))) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	dbell->res = res;
+	dbell->dinb = dinb;
+	dbell->dev_id = dev_id;
+
+	list_add_tail(&dbell->node, &mport->dbells);
+
+      out:
+	return rc;
+}
+
+/**
+ * rio_request_inb_dbell - request inbound doorbell message service
+ * @mport: RIO master port from which to allocate the doorbell resource
+ * @dev_id: Device specific pointer to pass on event
+ * @start: Doorbell info range start
+ * @end: Doorbell info range end
+ * @dinb: Callback to execute when doorbell is received
+ *
+ * Requests ownership of an inbound doorbell resource and binds
+ * a callback function to the resource. Returns 0 if the request
+ * has been satisfied.
+ */
+int rio_request_inb_dbell(struct rio_mport *mport,
+			  void *dev_id,
+			  u16 start,
+			  u16 end,
+			  void (*dinb) (struct rio_mport * mport, void *dev_id, u16 src,
+					u16 dst, u16 info))
+{
+	int rc = 0;
+
+	struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL);
+
+	if (res) {
+		rio_init_dbell_res(res, start, end);
+
+		/* Make sure these doorbells aren't in use */
+		if ((rc =
+		     request_resource(&mport->riores[RIO_DOORBELL_RESOURCE],
+				      res)) < 0) {
+			kfree(res);
+			goto out;
+		}
+
+		/* Hook the doorbell callback */
+		rc = rio_setup_inb_dbell(mport, dev_id, res, dinb);
+	} else
+		rc = -ENOMEM;
+
+      out:
+	return rc;
+}
+
+/**
+ * rio_release_inb_dbell - release inbound doorbell message service
+ * @mport: RIO master port from which to release the doorbell resource
+ * @start: Doorbell info range start
+ * @end: Doorbell info range end
+ *
+ * Releases ownership of an inbound doorbell resource and removes
+ * callback from the doorbell event list. Returns 0 if the request
+ * has been satisfied.
+ */
+int rio_release_inb_dbell(struct rio_mport *mport, u16 start, u16 end)
+{
+	int rc = 0, found = 0;
+	struct rio_dbell *dbell;
+
+	list_for_each_entry(dbell, &mport->dbells, node) {
+		if ((dbell->res->start == start) && (dbell->res->end == end)) {
+			found = 1;
+			break;
+		}
+	}
+
+	/* If we can't find an exact match, fail */
+	if (!found) {
+		rc = -EINVAL;
+		goto out;
+	}
+
+	/* Delete from list */
+	list_del(&dbell->node);
+
+	/* Release the doorbell resource */
+	rc = release_resource(dbell->res);
+
+	/* Free the doorbell event */
+	kfree(dbell);
+
+      out:
+	return rc;
+}
+
+/**
+ * rio_request_outb_dbell - request outbound doorbell message range
+ * @rdev: RIO device from which to allocate the doorbell resource
+ * @start: Doorbell message range start
+ * @end: Doorbell message range end
+ *
+ * Requests ownership of a doorbell message range. Returns a resource
+ * if the request has been satisfied or %NULL on failure.
+ */
+struct resource *rio_request_outb_dbell(struct rio_dev *rdev, u16 start,
+					u16 end)
+{
+	struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL);
+
+	if (res) {
+		rio_init_dbell_res(res, start, end);
+
+		/* Make sure these doorbells aren't in use */
+		if (request_resource(&rdev->riores[RIO_DOORBELL_RESOURCE], res)
+		    < 0) {
+			kfree(res);
+			res = NULL;
+		}
+	}
+
+	return res;
+}
+
+/**
+ * rio_release_outb_dbell - release outbound doorbell message range
+ * @rdev: RIO device from which to release the doorbell resource
+ * @res: Doorbell resource to be freed
+ *
+ * Releases ownership of a doorbell message range. Returns 0 if the
+ * request has been satisfied.
+ */
+int rio_release_outb_dbell(struct rio_dev *rdev, struct resource *res)
+{
+	int rc = release_resource(res);
+
+	kfree(res);
+
+	return rc;
+}
+
+/**
+ * rio_mport_get_feature - query for devices' extended features
+ * @port: Master port to issue transaction
+ * @local: Indicate a local master port or remote device access
+ * @destid: Destination ID of the device
+ * @hopcount: Number of switch hops to the device
+ * @ftr: Extended feature code
+ *
+ * Tell if a device supports a given RapidIO capability.
+ * Returns the offset of the requested extended feature
+ * block within the device's RIO configuration space or
+ * 0 in case the device does not support it.  Possible
+ * values for @ftr:
+ *
+ * %RIO_EFB_PAR_EP_ID		LP/LVDS EP Devices
+ *
+ * %RIO_EFB_PAR_EP_REC_ID	LP/LVDS EP Recovery Devices
+ *
+ * %RIO_EFB_PAR_EP_FREE_ID	LP/LVDS EP Free Devices
+ *
+ * %RIO_EFB_SER_EP_ID		LP/Serial EP Devices
+ *
+ * %RIO_EFB_SER_EP_REC_ID	LP/Serial EP Recovery Devices
+ *
+ * %RIO_EFB_SER_EP_FREE_ID	LP/Serial EP Free Devices
+ */
+u32
+rio_mport_get_feature(struct rio_mport * port, int local, u16 destid,
+		      u8 hopcount, int ftr)
+{
+	u32 asm_info, ext_ftr_ptr, ftr_header;
+
+	if (local)
+		rio_local_read_config_32(port, RIO_ASM_INFO_CAR, &asm_info);
+	else
+		rio_mport_read_config_32(port, destid, hopcount,
+					 RIO_ASM_INFO_CAR, &asm_info);
+
+	ext_ftr_ptr = asm_info & RIO_EXT_FTR_PTR_MASK;
+
+	while (ext_ftr_ptr) {
+		if (local)
+			rio_local_read_config_32(port, ext_ftr_ptr,
+						 &ftr_header);
+		else
+			rio_mport_read_config_32(port, destid, hopcount,
+						 ext_ftr_ptr, &ftr_header);
+		if (RIO_GET_BLOCK_ID(ftr_header) == ftr)
+			return ext_ftr_ptr;
+		if (!(ext_ftr_ptr = RIO_GET_BLOCK_PTR(ftr_header)))
+			break;
+	}
+
+	return 0;
+}
+
+/**
+ * rio_get_asm - Begin or continue searching for a RIO device by vid/did/asm_vid/asm_did
+ * @vid: RIO vid to match or %RIO_ANY_ID to match all vids
+ * @did: RIO did to match or %RIO_ANY_ID to match all dids
+ * @asm_vid: RIO asm_vid to match or %RIO_ANY_ID to match all asm_vids
+ * @asm_did: RIO asm_did to match or %RIO_ANY_ID to match all asm_dids
+ * @from: Previous RIO device found in search, or %NULL for new search
+ *
+ * Iterates through the list of known RIO devices. If a RIO device is
+ * found with a matching @vid, @did, @asm_vid, @asm_did, the reference
+ * count to the device is incrememted and a pointer to its device
+ * structure is returned. Otherwise, %NULL is returned. A new search
+ * is initiated by passing %NULL to the @from argument. Otherwise, if
+ * @from is not %NULL, searches continue from next device on the global
+ * list. The reference count for @from is always decremented if it is
+ * not %NULL.
+ */
+struct rio_dev *rio_get_asm(u16 vid, u16 did,
+			    u16 asm_vid, u16 asm_did, struct rio_dev *from)
+{
+	struct list_head *n;
+	struct rio_dev *rdev;
+
+	WARN_ON(in_interrupt());
+	spin_lock(&rio_global_list_lock);
+	n = from ? from->global_list.next : rio_devices.next;
+
+	while (n && (n != &rio_devices)) {
+		rdev = rio_dev_g(n);
+		if ((vid == RIO_ANY_ID || rdev->vid == vid) &&
+		    (did == RIO_ANY_ID || rdev->did == did) &&
+		    (asm_vid == RIO_ANY_ID || rdev->asm_vid == asm_vid) &&
+		    (asm_did == RIO_ANY_ID || rdev->asm_did == asm_did))
+			goto exit;
+		n = n->next;
+	}
+	rdev = NULL;
+      exit:
+	rio_dev_put(from);
+	rdev = rio_dev_get(rdev);
+	spin_unlock(&rio_global_list_lock);
+	return rdev;
+}
+
+/**
+ * rio_get_device - Begin or continue searching for a RIO device by vid/did
+ * @vid: RIO vid to match or %RIO_ANY_ID to match all vids
+ * @did: RIO did to match or %RIO_ANY_ID to match all dids
+ * @from: Previous RIO device found in search, or %NULL for new search
+ *
+ * Iterates through the list of known RIO devices. If a RIO device is
+ * found with a matching @vid and @did, the reference count to the
+ * device is incrememted and a pointer to its device structure is returned.
+ * Otherwise, %NULL is returned. A new search is initiated by passing %NULL
+ * to the @from argument. Otherwise, if @from is not %NULL, searches
+ * continue from next device on the global list. The reference count for
+ * @from is always decremented if it is not %NULL.
+ */
+struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from)
+{
+	return rio_get_asm(vid, did, RIO_ANY_ID, RIO_ANY_ID, from);
+}
+
+static void rio_fixup_device(struct rio_dev *dev)
+{
+}
+
+static int __devinit rio_init(void)
+{
+	struct rio_dev *dev = NULL;
+
+	while ((dev = rio_get_device(RIO_ANY_ID, RIO_ANY_ID, dev)) != NULL) {
+		rio_fixup_device(dev);
+	}
+	return 0;
+}
+
+device_initcall(rio_init);
+
+int rio_init_mports(void)
+{
+	int rc = 0;
+	struct rio_mport *port;
+
+	list_for_each_entry(port, &rio_mports, node) {
+		if (!request_mem_region(port->iores.start,
+					port->iores.end - port->iores.start,
+					port->name)) {
+			printk(KERN_ERR
+			       "RIO: Error requesting master port region %8.8lx-%8.8lx\n",
+			       port->iores.start, port->iores.end - 1);
+			rc = -ENOMEM;
+			goto out;
+		}
+
+		if (port->host_deviceid >= 0)
+			rio_enum_mport(port);
+		else
+			rio_disc_mport(port);
+	}
+
+      out:
+	return rc;
+}
+
+void rio_register_mport(struct rio_mport *port)
+{
+	list_add_tail(&port->node, &rio_mports);
+}
+
+EXPORT_SYMBOL_GPL(rio_local_get_device_id);
+EXPORT_SYMBOL_GPL(rio_get_device);
+EXPORT_SYMBOL_GPL(rio_get_asm);
+EXPORT_SYMBOL_GPL(rio_request_inb_dbell);
+EXPORT_SYMBOL_GPL(rio_release_inb_dbell);
+EXPORT_SYMBOL_GPL(rio_request_outb_dbell);
+EXPORT_SYMBOL_GPL(rio_release_outb_dbell);
+EXPORT_SYMBOL_GPL(rio_request_inb_mbox);
+EXPORT_SYMBOL_GPL(rio_release_inb_mbox);
+EXPORT_SYMBOL_GPL(rio_request_outb_mbox);
+EXPORT_SYMBOL_GPL(rio_release_outb_mbox);
diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h
new file mode 100644
index 0000000..b242cee
--- /dev/null
+++ b/drivers/rapidio/rio.h
@@ -0,0 +1,60 @@
+/*
+ * RapidIO interconnect services
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/rio.h>
+
+/* Functions internal to the RIO core code */
+
+extern u32 rio_mport_get_feature(struct rio_mport *mport, int local, u16 destid,
+				 u8 hopcount, int ftr);
+extern int rio_create_sysfs_dev_files(struct rio_dev *rdev);
+extern int rio_enum_mport(struct rio_mport *mport);
+extern int rio_disc_mport(struct rio_mport *mport);
+
+/* Structures internal to the RIO core code */
+extern struct device_attribute rio_dev_attrs[];
+extern spinlock_t rio_global_list_lock;
+
+extern struct rio_route_ops __start_rio_route_ops[];
+extern struct rio_route_ops __end_rio_route_ops[];
+
+/* Helpers internal to the RIO core code */
+#define DECLARE_RIO_ROUTE_SECTION(section, vid, did, add_hook, get_hook)  \
+        static struct rio_route_ops __rio_route_ops __attribute_used__   \
+	        __attribute__((__section__(#section))) = { vid, did, add_hook, get_hook };
+
+/**
+ * DECLARE_RIO_ROUTE_OPS - Registers switch routing operations
+ * @vid: RIO vendor ID
+ * @did: RIO device ID
+ * @add_hook: Callback that adds a route entry
+ * @get_hook: Callback that gets a route entry
+ *
+ * Manipulating switch route tables in RIO is switch specific. This
+ * registers a switch by vendor and device ID with two callbacks for
+ * modifying and retrieving route entries in a switch. A &struct
+ * rio_route_ops is initialized with the ops and placed into a
+ * RIO-specific kernel section.
+ */
+#define DECLARE_RIO_ROUTE_OPS(vid, did, add_hook, get_hook)		\
+	DECLARE_RIO_ROUTE_SECTION(.rio_route_ops,			\
+			vid, did, add_hook, get_hook)
+
+#ifdef CONFIG_RAPIDIO_8_BIT_TRANSPORT
+#define RIO_GET_DID(x)	((x & 0x00ff0000) >> 16)
+#define RIO_SET_DID(x)	((x & 0x000000ff) << 16)
+#else
+#define RIO_GET_DID(x)	(x & 0xffff)
+#define RIO_SET_DID(x)	(x & 0xffff)
+#endif
diff --git a/drivers/rapidio/switches/Makefile b/drivers/rapidio/switches/Makefile
new file mode 100644
index 0000000..b924f83
--- /dev/null
+++ b/drivers/rapidio/switches/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for RIO switches
+#
+
+obj-$(CONFIG_RAPIDIO)	+= tsi500.o
diff --git a/drivers/rapidio/switches/tsi500.c b/drivers/rapidio/switches/tsi500.c
new file mode 100644
index 0000000..c77c23b
--- /dev/null
+++ b/drivers/rapidio/switches/tsi500.c
@@ -0,0 +1,60 @@
+/*
+ * RapidIO Tsi500 switch support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/rio.h>
+#include <linux/rio_drv.h>
+#include <linux/rio_ids.h>
+#include "../rio.h"
+
+static int
+tsi500_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 route_port)
+{
+	int i;
+	u32 offset = 0x10000 + 0xa00 + ((route_destid / 2)&~0x3);
+	u32 result;
+
+	if (table == 0xff) {
+		rio_mport_read_config_32(mport, destid, hopcount, offset, &result);
+		result &= ~(0xf << (4*(route_destid & 0x7)));
+		for (i=0;i<4;i++)
+			rio_mport_write_config_32(mport, destid, hopcount, offset + (0x20000*i), result | (route_port << (4*(route_destid & 0x7))));
+	}
+	else {
+		rio_mport_read_config_32(mport, destid, hopcount, offset + (0x20000*table), &result);
+		result &= ~(0xf << (4*(route_destid & 0x7)));
+		rio_mport_write_config_32(mport, destid, hopcount, offset + (0x20000*table), result | (route_port << (4*(route_destid & 0x7))));
+	}
+
+	return 0;
+}
+
+static int
+tsi500_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 *route_port)
+{
+	int ret = 0;
+	u32 offset = 0x10000 + 0xa00 + ((route_destid / 2)&~0x3);
+	u32 result;
+
+	if (table == 0xff)
+		rio_mport_read_config_32(mport, destid, hopcount, offset, &result);
+	else
+		rio_mport_read_config_32(mport, destid, hopcount, offset + (0x20000*table), &result);
+
+	result &= 0xf << (4*(route_destid & 0x7));
+	*route_port = result >> (4*(route_destid & 0x7));
+	if (*route_port > 3)
+		ret = -1;
+
+	return ret;
+}
+
+DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI500, tsi500_route_add_entry, tsi500_route_get_entry);
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 8fc891a..7008d32 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -115,8 +115,7 @@
 void
 dasd_free_device(struct dasd_device *device)
 {
-	if (device->private)
-		kfree(device->private);
+	kfree(device->private);
 	free_page((unsigned long) device->erp_mem);
 	free_pages((unsigned long) device->ccw_mem, 1);
 	kfree(device);
@@ -539,8 +538,7 @@
 	if (datasize > 0) {
 		cqr->data = kmalloc(datasize, GFP_ATOMIC | GFP_DMA);
 		if (cqr->data == NULL) {
-			if (cqr->cpaddr != NULL)
-				kfree(cqr->cpaddr);
+			kfree(cqr->cpaddr);
 			kfree(cqr);
 			return ERR_PTR(-ENOMEM);
 		}
@@ -615,10 +613,8 @@
 		clear_normalized_cda(ccw);
 	} while (ccw++->flags & (CCW_FLAG_CC | CCW_FLAG_DC));
 #endif
-	if (cqr->cpaddr != NULL)
-		kfree(cqr->cpaddr);
-	if (cqr->data != NULL)
-		kfree(cqr->data);
+	kfree(cqr->cpaddr);
+	kfree(cqr->data);
 	kfree(cqr);
 	dasd_put_device(device);
 }
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index bda896d..caee16a 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -387,8 +387,7 @@
 		new = 0;
 	}
 	spin_unlock(&dasd_devmap_lock);
-	if (new)
-		kfree(new);
+	kfree(new);
 	return devmap;
 }
 
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index 7478423..ab8754e 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -6,7 +6,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.49 $
+ * $Revision: 1.51 $
  */
 
 #include <linux/config.h>
@@ -67,9 +67,9 @@
 static __inline__ int
 dia250(void *iob, int cmd)
 {
-	typedef struct {
-		char _[max(sizeof (struct dasd_diag_init_io),
-			   sizeof (struct dasd_diag_rw_io))];
+	typedef union {
+		struct dasd_diag_init_io init_io;
+		struct dasd_diag_rw_io rw_io;
 	} addr_type;
 	int rc;
 
@@ -190,7 +190,7 @@
 	private->iob.flags = DASD_DIAG_RWFLAG_ASYNC;
 	private->iob.block_count = dreq->block_count;
 	private->iob.interrupt_params = (addr_t) cqr;
-	private->iob.bio_list = __pa(dreq->bio);
+	private->iob.bio_list = dreq->bio;
 	private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT;
 
 	cqr->startclk = get_clock();
@@ -394,47 +394,57 @@
 		memset(&bio, 0, sizeof (struct dasd_diag_bio));
 		bio.type = MDSK_READ_REQ;
 		bio.block_number = private->pt_block + 1;
-		bio.buffer = __pa(label);
+		bio.buffer = label;
 		memset(&private->iob, 0, sizeof (struct dasd_diag_rw_io));
 		private->iob.dev_nr = rdc_data->dev_nr;
 		private->iob.key = 0;
 		private->iob.flags = 0;	/* do synchronous io */
 		private->iob.block_count = 1;
 		private->iob.interrupt_params = 0;
-		private->iob.bio_list = __pa(&bio);
+		private->iob.bio_list = &bio;
 		private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT;
 		rc = dia250(&private->iob, RW_BIO);
-		if (rc == 0 || rc == 3)
-			break;
+		if (rc == 3) {
+			DEV_MESSAGE(KERN_WARNING, device, "%s",
+				"DIAG call failed");
+			rc = -EOPNOTSUPP;
+			goto out;
+		}
 		mdsk_term_io(device);
+		if (rc == 0)
+			break;
 	}
-	if (rc == 3) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s", "DIAG call failed");
-		rc = -EOPNOTSUPP;
-	} else if (rc != 0) {
+	if (bsize > PAGE_SIZE) {
 		DEV_MESSAGE(KERN_WARNING, device, "device access failed "
 			    "(rc=%d)", rc);
 		rc = -EIO;
+		goto out;
+	}
+	/* check for label block */
+	if (memcmp(label->label_id, DASD_DIAG_CMS1,
+		  sizeof(DASD_DIAG_CMS1)) == 0) {
+		/* get formatted blocksize from label block */
+		bsize = (unsigned int) label->block_size;
+		device->blocks = (unsigned long) label->block_count;
+	} else
+		device->blocks = end_block;
+	device->bp_block = bsize;
+	device->s2b_shift = 0;	/* bits to shift 512 to get a block */
+	for (sb = 512; sb < bsize; sb = sb << 1)
+		device->s2b_shift++;
+	rc = mdsk_init_io(device, device->bp_block, 0, NULL);
+	if (rc) {
+		DEV_MESSAGE(KERN_WARNING, device, "DIAG initialization "
+			"failed (rc=%d)", rc);
+		rc = -EIO;
 	} else {
-		if (memcmp(label->label_id, DASD_DIAG_CMS1,
-			  sizeof(DASD_DIAG_CMS1)) == 0) {
-			/* get formatted blocksize from label block */
-			bsize = (unsigned int) label->block_size;
-			device->blocks = (unsigned long) label->block_count;
-		} else
-			device->blocks = end_block;
-		device->bp_block = bsize;
-		device->s2b_shift = 0;	/* bits to shift 512 to get a block */
-		for (sb = 512; sb < bsize; sb = sb << 1)
-			device->s2b_shift++;
-		
 		DEV_MESSAGE(KERN_INFO, device,
 			    "(%ld B/blk): %ldkB",
 			    (unsigned long) device->bp_block,
 			    (unsigned long) (device->blocks <<
 				device->s2b_shift) >> 1);
-		rc = 0;
 	}
+out:
 	free_page((long) label);
 	return rc;
 }
@@ -529,7 +539,7 @@
 				memset(dbio, 0, sizeof (struct dasd_diag_bio));
 				dbio->type = rw_cmd;
 				dbio->block_number = recid + 1;
-				dbio->buffer = __pa(dst);
+				dbio->buffer = dst;
 				dbio++;
 				dst += blksize;
 				recid++;
diff --git a/drivers/s390/block/dasd_diag.h b/drivers/s390/block/dasd_diag.h
index b26eb28..df31484 100644
--- a/drivers/s390/block/dasd_diag.h
+++ b/drivers/s390/block/dasd_diag.h
@@ -6,7 +6,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.7 $
+ * $Revision: 1.8 $
  */
 
 #define MDSK_WRITE_REQ 0x01
@@ -78,7 +78,7 @@
 	u8 spare1[2];
 	u32 alet;
 	blocknum_t block_number;
-	u64 buffer;
+	void *buffer;
 } __attribute__ ((packed, aligned(8)));
 
 struct dasd_diag_init_io {
@@ -104,7 +104,7 @@
 	u32 alet;
 	u8  spare3[4];
 	u64 interrupt_params;
-	u64 bio_list;
+	struct dasd_diag_bio *bio_list;
 	u8  spare4[8];
 } __attribute__ ((packed, aligned(8)));
 #else /* CONFIG_ARCH_S390X */
@@ -119,7 +119,7 @@
 	u16 spare1;
 	blocknum_t block_number;
 	u32 alet;
-	u32 buffer;
+	void *buffer;
 } __attribute__ ((packed, aligned(8)));
 
 struct dasd_diag_init_io {
@@ -142,7 +142,7 @@
 	u8 spare2[2];
 	u32 block_count;
 	u32 alet;
-	u32 bio_list;
+	struct dasd_diag_bio *bio_list;
 	u32 interrupt_params;
 	u8 spare3[20];
 } __attribute__ ((packed, aligned(8)));
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index f11a67f..75419cf 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -727,8 +727,7 @@
 	raw = cdev->dev.driver_data;
 	if (raw) {
 		cdev->dev.driver_data = NULL;
-		if (raw->buffer)
-			kfree(raw->buffer);
+		kfree(raw->buffer);
 		kfree(raw);
 	}
 }
diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c
index fd43d99..5bda234 100644
--- a/drivers/s390/char/keyboard.c
+++ b/drivers/s390/char/keyboard.c
@@ -99,13 +99,11 @@
 	kfree(kbd->fn_handler);
 out_func:
 	for (i = 0; i < ARRAY_SIZE(func_table); i++)
-		if (kbd->func_table[i])
-			kfree(kbd->func_table[i]);
+		kfree(kbd->func_table[i]);
 	kfree(kbd->func_table);
 out_maps:
 	for (i = 0; i < ARRAY_SIZE(key_maps); i++)
-		if (kbd->key_maps[i])
-			kfree(kbd->key_maps[i]);
+		kfree(kbd->key_maps[i]);
 	kfree(kbd->key_maps);
 out_kbd:
 	kfree(kbd);
@@ -121,12 +119,10 @@
 	kfree(kbd->accent_table);
 	kfree(kbd->fn_handler);
 	for (i = 0; i < ARRAY_SIZE(func_table); i++)
-		if (kbd->func_table[i])
-			kfree(kbd->func_table[i]);
+		kfree(kbd->func_table[i]);
 	kfree(kbd->func_table);
 	for (i = 0; i < ARRAY_SIZE(key_maps); i++)
-		if (kbd->key_maps[i])
-			kfree(kbd->key_maps[i]);
+		kfree(kbd->key_maps[i]);
 	kfree(kbd->key_maps);
 	kfree(kbd);
 }
@@ -452,8 +448,7 @@
 			return -EFAULT;
 		}
 		p[len] = 0;
-		if (kbd->func_table[kb_func])
-			kfree(kbd->func_table[kb_func]);
+		kfree(kbd->func_table[kb_func]);
 		kbd->func_table[kb_func] = p;
 		break;
 	}
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index d669464..f5b7d36 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -183,8 +183,7 @@
 void
 raw3270_request_free (struct raw3270_request *rq)
 {
-	if (rq->buffer)
-		kfree(rq->buffer);
+	kfree(rq->buffer);
 	kfree(rq);
 }
 
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index 6c52e83..8f486e1 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -682,8 +682,7 @@
 		request->cpdata = kmalloc(datasize, GFP_KERNEL | GFP_DMA);
 		if (request->cpdata == NULL) {
 			DBF_EXCEPTION(1, "cqra nomem\n");
-			if (request->cpaddr != NULL)
-				kfree(request->cpaddr);
+			kfree(request->cpaddr);
 			kfree(request);
 			return ERR_PTR(-ENOMEM);
 		}
@@ -706,10 +705,8 @@
 	if (request->device != NULL) {
 		request->device = tape_put_device(request->device);
 	}
-	if (request->cpdata != NULL)
-		kfree(request->cpdata);
-	if (request->cpaddr != NULL)
-		kfree(request->cpaddr);
+	kfree(request->cpdata);
+	kfree(request->cpaddr);
 	kfree(request);
 }
 
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c
index 8990d80..19762f3 100644
--- a/drivers/s390/char/vmcp.c
+++ b/drivers/s390/char/vmcp.c
@@ -103,8 +103,10 @@
 	}
 	cmd[count] = '\0';
 	session = (struct vmcp_session *)file->private_data;
-	if (down_interruptible(&session->mutex))
+	if (down_interruptible(&session->mutex)) {
+		kfree(cmd);
 		return -ERESTARTSYS;
+	}
 	if (!session->response)
 		session->response = (char *)__get_free_pages(GFP_KERNEL
 						| __GFP_REPEAT 	| GFP_DMA,
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index dbb3eb0..e7bd7f3 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/ccwgroup.c
  *  bus driver for ccwgroup
- *   $Revision: 1.29 $
+ *   $Revision: 1.32 $
  *
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
  *                       IBM Corporation
@@ -274,7 +274,7 @@
 		goto out;
 	}
 	gdrv = to_ccwgroupdrv (gdev->dev.driver);
-	if ((ret = gdrv->set_online(gdev)))
+	if ((ret = gdrv->set_online ? gdrv->set_online(gdev) : 0))
 		goto out;
 
 	gdev->state = CCWGROUP_ONLINE;
@@ -300,7 +300,7 @@
 		goto out;
 	}
 	gdrv = to_ccwgroupdrv (gdev->dev.driver);
-	if ((ret = gdrv->set_offline(gdev)))
+	if ((ret = gdrv->set_offline ? gdrv->set_offline(gdev) : 0))
 		goto out;
 
 	gdev->state = CCWGROUP_OFFLINE;
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index c05b069..b978f7f 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -642,8 +642,7 @@
 free_cmbe (struct ccw_device *cdev)
 {
 	spin_lock_irq(cdev->ccwlock);
-	if (cdev->private->cmb)
-		kfree(cdev->private->cmb);
+	kfree(cdev->private->cmb);
 	cdev->private->cmb = NULL;
 	spin_unlock_irq(cdev->ccwlock);
 
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index ad3fe5a..85a3026 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -550,10 +550,8 @@
 	/* Clear irb. */
 	memset(&cdev->private->irb, 0, sizeof(struct irb));
 out_unlock:
-	if (buf)
-		kfree(buf);
-	if (buf2)
-		kfree(buf2);
+	kfree(buf);
+	kfree(buf2);
 	spin_unlock_irqrestore(&sch->lock, flags);
 	return ret;
 }
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index 381f339..eb39218 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -56,7 +56,7 @@
 #include "ioasm.h"
 #include "chsc.h"
 
-#define VERSION_QDIO_C "$Revision: 1.101 $"
+#define VERSION_QDIO_C "$Revision: 1.108 $"
 
 /****************** MODULE PARAMETER VARIABLES ********************/
 MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
@@ -1338,16 +1338,14 @@
 		if (!irq_ptr->input_qs[i])
 			goto next;
 
-		if (irq_ptr->input_qs[i]->slib)
-			kfree(irq_ptr->input_qs[i]->slib);
+		kfree(irq_ptr->input_qs[i]->slib);
 		kfree(irq_ptr->input_qs[i]);
 
 next:
 		if (!irq_ptr->output_qs[i])
 			continue;
 
-		if (irq_ptr->output_qs[i]->slib)
-			kfree(irq_ptr->output_qs[i]->slib);
+		kfree(irq_ptr->output_qs[i]->slib);
 		kfree(irq_ptr->output_qs[i]);
 
 	}
@@ -2873,10 +2871,10 @@
 		return result;
 	}
 	
-	wait_event_interruptible_timeout(cdev->private->wait_q,
+	/* Timeout is cared for already by using ccw_device_start_timeout(). */
+	wait_event_interruptible(cdev->private->wait_q,
 		 irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED ||
-		 irq_ptr->state == QDIO_IRQ_STATE_ERR,
-		 QDIO_ESTABLISH_TIMEOUT);
+		 irq_ptr->state == QDIO_IRQ_STATE_ERR);
 
 	if (irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED)
 		result = 0;
@@ -3315,8 +3313,7 @@
 static void
 qdio_release_qdio_memory(void)
 {
-	if (indicators)
-		kfree(indicators);
+	kfree(indicators);
 }
 
 static void
diff --git a/drivers/s390/crypto/z90main.c b/drivers/s390/crypto/z90main.c
index 0cb47ec..04c2ef7 100644
--- a/drivers/s390/crypto/z90main.c
+++ b/drivers/s390/crypto/z90main.c
@@ -3051,8 +3051,7 @@
 	if (dev_ptr) {
 		disabledFlag = dev_ptr->disabled;
 		t = dev_ptr->dev_type;
-		if (dev_ptr->dev_resp_p)
-			kfree(dev_ptr->dev_resp_p);
+		kfree(dev_ptr->dev_resp_p);
 		kfree(dev_ptr);
 	} else {
 		disabledFlag = 0;
@@ -3080,11 +3079,11 @@
 destroy_z90crypt(void)
 {
 	int i;
+
 	for (i = 0; i < z90crypt.max_count; i++)
 		if (z90crypt.device_p[i])
 			destroy_crypto_device(i);
-	if (z90crypt.hdware_info)
-		kfree((void *)z90crypt.hdware_info);
+	kfree(z90crypt.hdware_info);
 	memset((void *)&z90crypt, 0, sizeof(z90crypt));
 }
 
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index 3092473..1a1c3de 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -2743,14 +2743,10 @@
 #endif
         privptr=(struct claw_privbk *)cgdev->dev.driver_data;
 	if (privptr!=NULL) {
-		if (privptr->p_env != NULL) {
-			kfree(privptr->p_env);
-			privptr->p_env=NULL;
-		}
-        	if (privptr->p_mtc_envelope!=NULL) {
-                	kfree(privptr->p_mtc_envelope);
-                	privptr->p_mtc_envelope=NULL;
-        	}
+		kfree(privptr->p_env);
+		privptr->p_env=NULL;
+                kfree(privptr->p_mtc_envelope);
+               	privptr->p_mtc_envelope=NULL;
                 kfree(privptr);
                 privptr=NULL;
         }
@@ -4121,22 +4117,14 @@
 	if (cgdev->state == CCWGROUP_ONLINE)
 		claw_shutdown_device(cgdev);
 	claw_remove_files(&cgdev->dev);
-	if (priv->p_mtc_envelope!=NULL) {
-                kfree(priv->p_mtc_envelope);
-                priv->p_mtc_envelope=NULL;
-        }
-	if (priv->p_env != NULL) {
-		kfree(priv->p_env);
-		priv->p_env=NULL;
-	}
-	if (priv->channel[0].irb != NULL) {
-		kfree(priv->channel[0].irb);
-		priv->channel[0].irb=NULL;
-	}
-	if (priv->channel[1].irb != NULL) {
-		kfree(priv->channel[1].irb);
-		priv->channel[1].irb=NULL;
-	}
+	kfree(priv->p_mtc_envelope);
+	priv->p_mtc_envelope=NULL;
+	kfree(priv->p_env);
+	priv->p_env=NULL;
+	kfree(priv->channel[0].irb);
+	priv->channel[0].irb=NULL;
+	kfree(priv->channel[1].irb);
+	priv->channel[1].irb=NULL;
 	kfree(priv);
 	cgdev->dev.driver_data=NULL;
 	cgdev->cdev[READ]->dev.driver_data = NULL;
diff --git a/drivers/s390/net/fsm.c b/drivers/s390/net/fsm.c
index 38f50b7..24029bd 100644
--- a/drivers/s390/net/fsm.c
+++ b/drivers/s390/net/fsm.c
@@ -78,8 +78,7 @@
 {
 	if (this) {
 		if (this->f) {
-			if (this->f->jumpmatrix)
-				kfree(this->f->jumpmatrix);
+			kfree(this->f->jumpmatrix);
 			kfree(this->f);
 		}
 		kfree(this);
diff --git a/drivers/s390/net/iucv.c b/drivers/s390/net/iucv.c
index e08e74e..df7647c 100644
--- a/drivers/s390/net/iucv.c
+++ b/drivers/s390/net/iucv.c
@@ -447,14 +447,10 @@
 iucv_exit(void)
 {
 	iucv_retrieve_buffer();
-      	if (iucv_external_int_buffer) {
-		kfree(iucv_external_int_buffer);
-		iucv_external_int_buffer = NULL;
-	}
-	if (iucv_param_pool) {
-		kfree(iucv_param_pool);
-		iucv_param_pool = NULL;
-	}
+	kfree(iucv_external_int_buffer);
+	iucv_external_int_buffer = NULL;
+	kfree(iucv_param_pool);
+	iucv_param_pool = NULL;
 	s390_root_dev_unregister(iucv_root);
 	bus_unregister(&iucv_bus);
 	printk(KERN_INFO "IUCV lowlevel driver unloaded\n");
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 46f34ba..1c8ad2f 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -145,8 +145,7 @@
 
 	LCS_DBF_TEXT(2, setup, "ichfree");
 	for (cnt = 0; cnt < LCS_NUM_BUFFS; cnt++) {
-		if (channel->iob[cnt].data != NULL)
-			kfree(channel->iob[cnt].data);
+		kfree(channel->iob[cnt].data);
 		channel->iob[cnt].data = NULL;
 	}
 }
diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c
index f94f1f25..011915d 100644
--- a/drivers/s390/net/qeth_eddp.c
+++ b/drivers/s390/net/qeth_eddp.c
@@ -62,8 +62,7 @@
 	for (i = 0; i < ctx->num_pages; ++i)
 		free_page((unsigned long)ctx->pages[i]);
 	kfree(ctx->pages);
-	if (ctx->elements != NULL)
-		kfree(ctx->elements);
+	kfree(ctx->elements);
 	kfree(ctx);
 }
 
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index cab0985..c218b5c 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -450,8 +450,7 @@
 		kfree(sg_list);
 	}
 
-	if (sense_data != NULL)
-		kfree(sense_data);
+	kfree(sense_data);
 
 	return retval;
 }
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
index b0cc3c2..ba56762 100644
--- a/drivers/sbus/char/envctrl.c
+++ b/drivers/sbus/char/envctrl.c
@@ -1125,10 +1125,9 @@
 	misc_deregister(&envctrl_dev);
 out_iounmap:
 	iounmap(i2c);
-	for (i = 0; i < ENVCTRL_MAX_CPU * 2; i++) {
-		if (i2c_childlist[i].tables)
-			kfree(i2c_childlist[i].tables);
-	}
+	for (i = 0; i < ENVCTRL_MAX_CPU * 2; i++)
+		kfree(i2c_childlist[i].tables);
+
 	return err;
 }
 
@@ -1141,10 +1140,8 @@
 	iounmap(i2c);
 	misc_deregister(&envctrl_dev);
 
-	for (i = 0; i < ENVCTRL_MAX_CPU * 2; i++) {
-		if (i2c_childlist[i].tables)
-			kfree(i2c_childlist[i].tables);
-	}
+	for (i = 0; i < ENVCTRL_MAX_CPU * 2; i++)
+		kfree(i2c_childlist[i].tables);
 }
 
 module_init(envctrl_init);
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index d06ee65..3ff74f4 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -1017,8 +1017,7 @@
 				    tw_dev->generic_buffer_virt[0],
 				    tw_dev->generic_buffer_phys[0]);
 
-	if (tw_dev->event_queue[0])
-		kfree(tw_dev->event_queue[0]);
+	kfree(tw_dev->event_queue[0]);
 } /* End twa_free_device_extension() */
 
 /* This function will free a request id */
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index cc9ecb3..cba9655 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -606,10 +606,7 @@
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL);
 
 	while (probe_irq == SCSI_IRQ_NONE && time_before(jiffies, timeout))
-	{
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
-	}
+		schedule_timeout_uninterruptible(1);
 	
 	NCR5380_write(SELECT_ENABLE_REG, 0);
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index ee90672..723c0ce 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -1164,7 +1164,7 @@
 						kfree(hw_fib_pool);
 						hw_fib_pool = NULL;
 					}
-				} else if (hw_fib_pool) {
+				} else {
 					kfree(hw_fib_pool);
 					hw_fib_pool = NULL;
 				}
@@ -1247,17 +1247,13 @@
 				hw_fib_p = hw_fib_pool;
 				fib_p = fib_pool;
 				while (hw_fib_p < &hw_fib_pool[num]) {
-					if (*hw_fib_p)
-						kfree(*hw_fib_p);
-					if (*fib_p)
-						kfree(*fib_p);
+					kfree(*hw_fib_p);
+					kfree(*fib_p);
 					++fib_p;
 					++hw_fib_p;
 				}
-				if (hw_fib_pool)
-					kfree(hw_fib_pool);
-				if (fib_pool)
-					kfree(fib_pool);
+				kfree(hw_fib_pool);
+				kfree(fib_pool);
 			}
 			kfree(fib);
 			spin_lock_irqsave(dev->queues->queue[HostNormCmdQueue].lock, flags);
diff --git a/drivers/scsi/aacraid/rkt.c b/drivers/scsi/aacraid/rkt.c
index fc4c73c..e9b775d 100644
--- a/drivers/scsi/aacraid/rkt.c
+++ b/drivers/scsi/aacraid/rkt.c
@@ -183,8 +183,7 @@
 		/*
 		 *	Yield the processor in case we are slow 
 		 */
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	}
 	if (ok != 1) {
 		/*
@@ -452,8 +451,7 @@
 					dev->name, instance, status);
 			goto error_iounmap;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	}
 	if (request_irq(dev->scsi_host_ptr->irq, aac_rkt_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev)<0) 
 	{
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
index da99046..6998bc8 100644
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -183,8 +183,7 @@
 		/*
 		 *	Yield the processor in case we are slow 
 		 */
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	}
 	if (ok != 1) {
 		/*
@@ -452,8 +451,7 @@
 					dev->name, instance, status);
 			goto error_iounmap;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	}
 	if (request_irq(dev->scsi_host_ptr->irq, aac_rx_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev)<0) 
 	{
diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c
index 8b95962..466f05c 100644
--- a/drivers/scsi/aacraid/sa.c
+++ b/drivers/scsi/aacraid/sa.c
@@ -189,8 +189,7 @@
 			ok = 1;
 			break;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	}
 
 	if (ok != 1)
@@ -325,8 +324,7 @@
 					name, instance, status);
 			goto error_iounmap;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	}
 
 	if (request_irq(dev->scsi_host_ptr->irq, aac_sa_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev ) < 0) {
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index 37ec541..f4cfb8f 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -5402,10 +5402,8 @@
                 release_region(shp->io_port, boardp->asc_n_io_port);
                 if (ASC_WIDE_BOARD(boardp)) {
                     iounmap(boardp->ioremap_addr);
-                    if (boardp->orig_carrp) {
-                        kfree(boardp->orig_carrp);
-                        boardp->orig_carrp = NULL;
-                    }
+                    kfree(boardp->orig_carrp);
+                    boardp->orig_carrp = NULL;
                     if (boardp->orig_reqp) {
                         kfree(boardp->orig_reqp);
                         boardp->orig_reqp = boardp->adv_reqp = NULL;
@@ -5457,10 +5455,8 @@
         adv_sgblk_t    *sgp = NULL;
 
         iounmap(boardp->ioremap_addr);
-        if (boardp->orig_carrp) {
-            kfree(boardp->orig_carrp);
-            boardp->orig_carrp = NULL;
-        }
+        kfree(boardp->orig_carrp);
+        boardp->orig_carrp = NULL;
         if (boardp->orig_reqp) {
             kfree(boardp->orig_reqp);
             boardp->orig_reqp = boardp->adv_reqp = NULL;
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index adda750..1b1adfb 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -543,10 +543,8 @@
 			return;
 		}
 		my_done = SCtmp->scsi_done;
-		if (SCtmp->host_scribble) {
-			kfree(SCtmp->host_scribble);
-			SCtmp->host_scribble = NULL;
-		}
+		kfree(SCtmp->host_scribble);
+		SCtmp->host_scribble = NULL;
 		/* Fetch the sense data, and tuck it away, in the required slot.  The
 		   Adaptec automatically fetches it, and there is no guarantee that
 		   we will still have it in the cdb when we come back */
@@ -1432,10 +1430,8 @@
 		    HOSTDATA(SCpnt->host)->SCint[i]->target == SCpnt->target) {
 			Scsi_Cmnd *SCtmp;
 			SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
-			if (SCtmp->host_scribble) {
-				kfree(SCtmp->host_scribble);
-				SCtmp->host_scribble = NULL;
-			}
+			kfree(SCtmp->host_scribble);
+			SCtmp->host_scribble = NULL;
 			HOSTDATA(SCpnt->host)->SCint[i] = NULL;
 			HOSTDATA(SCpnt->host)->mb[i].status = 0;
 		}
@@ -1495,10 +1491,8 @@
 				 */
 				continue;
 			}
-			if (SCtmp->host_scribble) {
-				kfree(SCtmp->host_scribble);
-				SCtmp->host_scribble = NULL;
-			}
+			kfree(SCtmp->host_scribble);
+			SCtmp->host_scribble = NULL;
 			HOSTDATA(SCpnt->device->host)->SCint[i] = NULL;
 			HOSTDATA(SCpnt->device->host)->mb[i].status = 0;
 		}
@@ -1565,10 +1559,8 @@
 				 */
 				continue;
 			}
-			if (SCtmp->host_scribble) {
-				kfree(SCtmp->host_scribble);
-				SCtmp->host_scribble = NULL;
-			}
+			kfree(SCtmp->host_scribble);
+			SCtmp->host_scribble = NULL;
 			HOSTDATA(SCpnt->device->host)->SCint[i] = NULL;
 			HOSTDATA(SCpnt->device->host)->mb[i].status = 0;
 		}
@@ -1711,10 +1703,8 @@
 				Scsi_Cmnd *SCtmp;
 				SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
 				SCtmp->result = DID_RESET << 16;
-				if (SCtmp->host_scribble) {
-					kfree(SCtmp->host_scribble);
-					SCtmp->host_scribble = NULL;
-				}
+				kfree(SCtmp->host_scribble);
+				SCtmp->host_scribble = NULL;
 				printk(KERN_WARNING "Sending DID_RESET for target %d\n", SCpnt->target);
 				SCtmp->scsi_done(SCpnt);
 
@@ -1757,10 +1747,8 @@
 						Scsi_Cmnd *SCtmp;
 						SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
 						SCtmp->result = DID_RESET << 16;
-						if (SCtmp->host_scribble) {
-							kfree(SCtmp->host_scribble);
-							SCtmp->host_scribble = NULL;
-						}
+						kfree(SCtmp->host_scribble);
+						SCtmp->host_scribble = NULL;
 						printk(KERN_WARNING "Sending DID_RESET for target %d\n", SCpnt->target);
 						SCtmp->scsi_done(SCpnt);
 
diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
index 52b72d7..880e2d9 100644
--- a/drivers/scsi/aic7xxx_old.c
+++ b/drivers/scsi/aic7xxx_old.c
@@ -8492,8 +8492,7 @@
                                      - scb_dma->dma_offset),
 			    scb_dma->dma_address);
       }
-      if (p->scb_data->scb_array[i]->kmalloc_ptr != NULL)
-        kfree(p->scb_data->scb_array[i]->kmalloc_ptr);
+      kfree(p->scb_data->scb_array[i]->kmalloc_ptr);
       p->scb_data->scb_array[i] = NULL;
     }
   
diff --git a/drivers/scsi/arm/queue.c b/drivers/scsi/arm/queue.c
index e6d1592..b10750b 100644
--- a/drivers/scsi/arm/queue.c
+++ b/drivers/scsi/arm/queue.c
@@ -91,8 +91,7 @@
 {
 	if (!list_empty(&queue->head))
 		printk(KERN_WARNING "freeing non-empty queue %p\n", queue);
-	if (queue->alloc)
-		kfree(queue->alloc);
+	kfree(queue->alloc);
 }
      
 
diff --git a/drivers/scsi/atari_dma_emul.c b/drivers/scsi/atari_dma_emul.c
index 7026045..8d5d2a5 100644
--- a/drivers/scsi/atari_dma_emul.c
+++ b/drivers/scsi/atari_dma_emul.c
@@ -19,6 +19,8 @@
  * this code.
  */
 
+#include <linux/compiler.h>
+#include <asm/thread_info.h>
 #include <asm/uaccess.h>
 
 #define hades_dma_ctrl		(*(unsigned char *) 0xffff8717)
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index c44af57..c8a32cf 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -4270,8 +4270,7 @@
 	const unsigned srbs_per_page = PAGE_SIZE/SEGMENTX_LEN;
 
 	for (i = 0; i < DC395x_MAX_SRB_CNT; i += srbs_per_page)
-		if (acb->srb_array[i].segment_x)
-			kfree(acb->srb_array[i].segment_x);
+		kfree(acb->srb_array[i].segment_x);
 }
 
 
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 7235f94..c28e3ae 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -1037,18 +1037,10 @@
 	if(pHba->msg_addr_virt != pHba->base_addr_virt){
 		iounmap(pHba->msg_addr_virt);
 	}
-	if(pHba->hrt) {
-		kfree(pHba->hrt);
-	}
-	if(pHba->lct){
-		kfree(pHba->lct);
-	}
-	if(pHba->status_block) {
-		kfree(pHba->status_block);
-	}
-	if(pHba->reply_pool){
-		kfree(pHba->reply_pool);
-	}
+	kfree(pHba->hrt);
+	kfree(pHba->lct);
+	kfree(pHba->status_block);
+	kfree(pHba->reply_pool);
 
 	for(d = pHba->devices; d ; d = next){
 		next = d->next;
@@ -1218,8 +1210,7 @@
 			printk(KERN_WARNING"dpti%d: Timeout waiting for message frame!\n", pHba->unit);
 			return -ETIMEDOUT;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	} while(m == EMPTY_QUEUE);
 		
 	msg = pHba->msg_addr_virt + m;
@@ -1294,8 +1285,7 @@
 			printk(KERN_WARNING"Timeout waiting for message!\n");
 			return -ETIMEDOUT;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	} while (m == EMPTY_QUEUE);
 
 	status = (u8*)kmalloc(4, GFP_KERNEL|ADDR32);
@@ -1327,8 +1317,7 @@
 			return -ETIMEDOUT;
 		}
 		rmb();
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	}
 
 	if(*status == 0x01 /*I2O_EXEC_IOP_RESET_IN_PROGRESS*/) {
@@ -1345,8 +1334,7 @@
 				printk(KERN_ERR "%s:Timeout waiting for IOP Reset.\n",pHba->name);
 				return -ETIMEDOUT;
 			}
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
+			schedule_timeout_uninterruptible(1);
 		} while (m == EMPTY_QUEUE);
 		// Flush the offset
 		adpt_send_nop(pHba, m);
@@ -1917,11 +1905,8 @@
 		return -ENXIO;
 	}
 
-	while((volatile u32) pHba->state & DPTI_STATE_RESET ) {
-		set_task_state(current,TASK_UNINTERRUPTIBLE);
-		schedule_timeout(2);
-
-	}
+	while((volatile u32) pHba->state & DPTI_STATE_RESET )
+		schedule_timeout_uninterruptible(2);
 
 	switch (cmd) {
 	// TODO: handle 3 cases
@@ -2635,8 +2620,7 @@
 			printk(KERN_ERR "%s: Timeout waiting for message frame!\n",pHba->name);
 			return 2;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	}
 	msg = (u32 __iomem *)(pHba->msg_addr_virt + m);
 	writel( THREE_WORD_MSG_SIZE | SGL_OFFSET_0,&msg[0]);
@@ -2670,8 +2654,7 @@
 			printk(KERN_WARNING"%s: Timeout waiting for message frame\n",pHba->name);
 			return -ETIMEDOUT;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	} while(m == EMPTY_QUEUE);
 
 	msg=(u32 __iomem *)(pHba->msg_addr_virt+m);
@@ -2709,21 +2692,18 @@
 			printk(KERN_WARNING"%s: Timeout Initializing\n",pHba->name);
 			return -ETIMEDOUT;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	} while (1);
 
 	// If the command was successful, fill the fifo with our reply
 	// message packets
 	if(*status != 0x04 /*I2O_EXEC_OUTBOUND_INIT_COMPLETE*/) {
-		kfree((void*)status);
+		kfree(status);
 		return -2;
 	}
-	kfree((void*)status);
+	kfree(status);
 
-	if(pHba->reply_pool != NULL){
-		kfree(pHba->reply_pool);
-	}
+	kfree(pHba->reply_pool);
 
 	pHba->reply_pool = (u32*)kmalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32);
 	if(!pHba->reply_pool){
@@ -2788,8 +2768,7 @@
 					pHba->name);
 			return -ETIMEDOUT;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	} while(m==EMPTY_QUEUE);
 
 	
@@ -2816,8 +2795,7 @@
 			return -ETIMEDOUT;
 		}
 		rmb();
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	}
 
 	// Set up our number of outbound and inbound messages
@@ -2941,8 +2919,7 @@
 	sys_tbl_len = sizeof(struct i2o_sys_tbl) +	// Header + IOPs
 				(hba_count) * sizeof(struct i2o_sys_tbl_entry);
 
-	if(sys_tbl)
-		kfree(sys_tbl);
+	kfree(sys_tbl);
 
 	sys_tbl = kmalloc(sys_tbl_len, GFP_KERNEL|ADDR32);
 	if(!sys_tbl) {
diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
index b45a4c7..b3f9de8 100644
--- a/drivers/scsi/eata.c
+++ b/drivers/scsi/eata.c
@@ -2580,8 +2580,7 @@
 	unsigned int i;
 
 	for (i = 0; i < shost->can_queue; i++)
-		if ((&ha->cp[i])->sglist)
-			kfree((&ha->cp[i])->sglist);
+		kfree((&ha->cp[i])->sglist);
 
 	for (i = 0; i < shost->can_queue; i++)
 		pci_unmap_single(ha->pdev, ha->cp[i].cp_dma_addr,
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index f04f328..c888af4 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -331,9 +331,9 @@
 	rq = kmalloc (sizeof (struct request), GFP_ATOMIC);
 	buf = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_ATOMIC);
 	if (pc == NULL || rq == NULL || buf == NULL) {
-		if (pc) kfree(pc);
-		if (rq) kfree(rq);
-		if (buf) kfree(buf);
+		kfree(buf);
+		kfree(rq);
+		kfree(pc);
 		return -ENOMEM;
 	}
 	memset (pc, 0, sizeof (idescsi_pc_t));
@@ -949,8 +949,8 @@
 	spin_lock_irq(host->host_lock);
 	return 0;
 abort:
-	if (pc) kfree (pc);
-	if (rq) kfree (rq);
+	kfree (pc);
+	kfree (rq);
 	cmd->result = DID_ERROR << 16;
 	done(cmd);
 	return 0;
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index 68e5b2a..cd9b95d 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -4517,10 +4517,8 @@
 			ha->enq = NULL;
 		}
 
-		if (ha->conf) {
-			kfree(ha->conf);
-			ha->conf = NULL;
-		}
+		kfree(ha->conf);
+		ha->conf = NULL;
 
 		if (ha->adapt) {
 			pci_free_consistent(ha->pcidev,
@@ -4538,15 +4536,11 @@
 			ha->logical_drive_info = NULL;
 		}
 
-		if (ha->nvram) {
-			kfree(ha->nvram);
-			ha->nvram = NULL;
-		}
+		kfree(ha->nvram);
+		ha->nvram = NULL;
 
-		if (ha->subsys) {
-			kfree(ha->subsys);
-			ha->subsys = NULL;
-		}
+		kfree(ha->subsys);
+		ha->subsys = NULL;
 
 		if (ha->ioctl_data) {
 			pci_free_consistent(ha->pcidev, ha->ioctl_len,
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 08a0c00..bcc29ec 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -127,8 +127,7 @@
 	if (((pcmd = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == 0) ||
 	    ((pcmd->virt = lpfc_mbuf_alloc(phba,
 					   MEM_PRI, &(pcmd->phys))) == 0)) {
-		if (pcmd)
-			kfree(pcmd);
+		kfree(pcmd);
 
 		spin_lock_irq(phba->host->host_lock);
 		lpfc_sli_release_iocbq(phba, elsiocb);
@@ -145,8 +144,7 @@
 			prsp->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
 						     &prsp->phys);
 		if (prsp == 0 || prsp->virt == 0) {
-			if (prsp)
-				kfree(prsp);
+			kfree(prsp);
 			lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
 			kfree(pcmd);
 			spin_lock_irq(phba->host->host_lock);
@@ -172,8 +170,7 @@
 		lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
 		kfree(pcmd);
 		kfree(prsp);
-		if (pbuflist)
-			kfree(pbuflist);
+		kfree(pbuflist);
 		return NULL;
 	}
 
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 4e04470..c907238 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -894,8 +894,7 @@
 		    mp1->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
 						&mp1->phys);
 		if (mp1 == 0 || mp1->virt == 0) {
-			if (mp1)
-				kfree(mp1);
+			kfree(mp1);
 			spin_lock_irq(phba->host->host_lock);
 			lpfc_sli_release_iocbq(phba, iocb);
 			spin_unlock_irq(phba->host->host_lock);
@@ -911,8 +910,7 @@
 				mp2->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
 							    &mp2->phys);
 			if (mp2 == 0 || mp2->virt == 0) {
-				if (mp2)
-					kfree(mp2);
+				kfree(mp2);
 				lpfc_mbuf_free(phba, mp1->virt, mp1->phys);
 				kfree(mp1);
 				spin_lock_irq(phba->host->host_lock);
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index 31c20cc..e3bc8d3 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -248,8 +248,7 @@
 
 	if (((mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == 0) ||
 	    ((mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys))) == 0)) {
-		if (mp)
-			kfree(mp);
+		kfree(mp);
 		mb->mbxCommand = MBX_READ_SPARM64;
 		/* READ_SPARAM: no buffers */
 		lpfc_printf_log(phba,
@@ -363,9 +362,7 @@
 	/* Get a buffer to hold NPorts Service Parameters */
 	if (((mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == NULL) ||
 	    ((mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys))) == 0)) {
-		if (mp)
-			kfree(mp);
-
+		kfree(mp);
 		mb->mbxCommand = MBX_REG_LOGIN64;
 		/* REG_LOGIN: no buffers */
 		lpfc_printf_log(phba,
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index c34d3cf..c63275e 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -825,8 +825,7 @@
 	while (lpfc_cmd->pCmd == cmnd)
 	{
 		spin_unlock_irq(phba->host->host_lock);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(LPFC_ABORT_WAIT*HZ);
+			schedule_timeout_uninterruptible(LPFC_ABORT_WAIT*HZ);
 		spin_lock_irq(phba->host->host_lock);
 		if (++loop_count
 		    > (2 * phba->cfg_nodev_tmo)/LPFC_ABORT_WAIT)
@@ -885,8 +884,7 @@
 
 		if (pnode->nlp_state != NLP_STE_MAPPED_NODE) {
 			spin_unlock_irq(phba->host->host_lock);
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout( HZ/2);
+			schedule_timeout_uninterruptible(msecs_to_jiffies(500));
 			spin_lock_irq(phba->host->host_lock);
 		}
 		if ((pnode) && (pnode->nlp_state == NLP_STE_MAPPED_NODE))
@@ -939,8 +937,7 @@
 				       cmnd->device->id, cmnd->device->lun,
 				       LPFC_CTX_LUN))) {
 		spin_unlock_irq(phba->host->host_lock);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(LPFC_RESET_WAIT*HZ);
+		schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ);
 		spin_lock_irq(phba->host->host_lock);
 
 		if (++loopcnt
@@ -1038,8 +1035,7 @@
 				&phba->sli.ring[phba->sli.fcp_ring],
 				0, 0, LPFC_CTX_HOST))) {
 		spin_unlock_irq(phba->host->host_lock);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(LPFC_RESET_WAIT*HZ);
+		schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ);
 		spin_lock_irq(phba->host->host_lock);
 
 		if (++loopcnt
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 5087100..e2c08c5 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -2269,11 +2269,8 @@
 
 		INIT_LIST_HEAD(&(pring->txq));
 
-		if (pring->fast_lookup) {
-			kfree(pring->fast_lookup);
-			pring->fast_lookup = NULL;
-		}
-
+		kfree(pring->fast_lookup);
+		pring->fast_lookup = NULL;
 	}
 
 	spin_unlock_irqrestore(phba->host->host_lock, flags);
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index c9e743b..1a3d195 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -3937,9 +3937,8 @@
 {
 	mraid_device_t	*raid_dev = ADAP2RAIDDEV(adapter);
 
-	if (raid_dev->sysfs_uioc) kfree(raid_dev->sysfs_uioc);
-
-	if (raid_dev->sysfs_mbox64) kfree(raid_dev->sysfs_mbox64);
+	kfree(raid_dev->sysfs_uioc);
+	kfree(raid_dev->sysfs_mbox64);
 
 	if (raid_dev->sysfs_buffer) {
 		pci_free_consistent(adapter->pdev, PAGE_SIZE,
diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c
index 37d110e..8f3ce04 100644
--- a/drivers/scsi/megaraid/megaraid_mm.c
+++ b/drivers/scsi/megaraid/megaraid_mm.c
@@ -995,17 +995,13 @@
 
 memalloc_error:
 
-	if (adapter->kioc_list)
-		kfree(adapter->kioc_list);
-
-	if (adapter->mbox_list)
-		kfree(adapter->mbox_list);
+	kfree(adapter->kioc_list);
+	kfree(adapter->mbox_list);
 
 	if (adapter->pthru_dma_pool)
 		pci_pool_destroy(adapter->pthru_dma_pool);
 
-	if (adapter)
-		kfree(adapter);
+	kfree(adapter);
 
 	return rval;
 }
@@ -1157,7 +1153,6 @@
 	}
 
 	kfree(adp->kioc_list);
-
 	kfree(adp->mbox_list);
 
 	pci_pool_destroy(adp->pthru_dma_pool);
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 1cf11c3..d9946bd 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -862,8 +862,7 @@
 				retval = osst_write_error_recovery(STp, aSRpnt, 0);
 				break;
 			}
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout (HZ / OSST_POLL_PER_SEC);
+			schedule_timeout_interruptible(HZ / OSST_POLL_PER_SEC);
 
 			STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
 			memset(cmd, 0, MAX_COMMAND_SIZE);
@@ -1558,8 +1557,7 @@
 			osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
 			flag = 0;
 			attempts--;
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(HZ / 10);
+			schedule_timeout_interruptible(msecs_to_jiffies(100));
 		}
 		if (osst_get_frame_position(STp, aSRpnt) < 0) {		/* additional write error */
 #if DEBUG
@@ -1620,8 +1618,7 @@
 			debugging = 0;
 		}
 #endif
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(HZ / 10);
+		schedule_timeout_interruptible(msecs_to_jiffies(100));
 	}
 	printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name);
 #if DEBUG
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 290a6b9..72d9090 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1977,8 +1977,7 @@
 	}
 
 cleanup_allocation:
-	if (new_fcport)
-		kfree(new_fcport);
+	kfree(new_fcport);
 
 	if (rval != QLA_SUCCESS) {
 		DEBUG2(printk("scsi(%ld): Configure local loop error exit: "
@@ -2348,8 +2347,7 @@
 	/* Allocate temporary fcport for any new fcports discovered. */
 	new_fcport = qla2x00_alloc_fcport(ha, GFP_KERNEL);
 	if (new_fcport == NULL) {
-		if (swl)
-			kfree(swl);
+		kfree(swl);
 		return (QLA_MEMORY_ALLOC_FAILED);
 	}
 	new_fcport->flags |= (FCF_FABRIC_DEVICE | FCF_LOGIN_NEEDED);
@@ -2485,19 +2483,15 @@
 		nxt_d_id.b24 = new_fcport->d_id.b24;
 		new_fcport = qla2x00_alloc_fcport(ha, GFP_KERNEL);
 		if (new_fcport == NULL) {
-			if (swl)
-				kfree(swl);
+			kfree(swl);
 			return (QLA_MEMORY_ALLOC_FAILED);
 		}
 		new_fcport->flags |= (FCF_FABRIC_DEVICE | FCF_LOGIN_NEEDED);
 		new_fcport->d_id.b24 = nxt_d_id.b24;
 	}
 
-	if (swl)
-		kfree(swl);
-
-	if (new_fcport)
-		kfree(new_fcport);
+	kfree(swl);
+	kfree(new_fcport);
 
 	if (!list_empty(new_fcports))
 		ha->device_flags |= DFLG_FABRIC_DEVICES;
diff --git a/drivers/scsi/raid_class.c b/drivers/scsi/raid_class.c
index f1ea502..caa0c36 100644
--- a/drivers/scsi/raid_class.c
+++ b/drivers/scsi/raid_class.c
@@ -4,6 +4,8 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/string.h>
 #include <linux/raid_class.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index 0cc766a..edabbd0 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -26,6 +26,8 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/string.h>
 
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 4f30a37..62e3f34 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -476,8 +476,7 @@
 	sg_finish_rem_req(srp);
 	retval = count;
 free_old_hdr:
-	if (old_hdr)
-		kfree(old_hdr);
+	kfree(old_hdr);
 	return retval;
 }
 
@@ -1703,10 +1702,8 @@
 	sg_sysfs_valid = 0;
 	unregister_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0),
 				 SG_MAX_DEVS);
-	if (sg_dev_arr != NULL) {
-		kfree((char *) sg_dev_arr);
-		sg_dev_arr = NULL;
-	}
+	kfree((char *)sg_dev_arr);
+	sg_dev_arr = NULL;
 	sg_dev_max = 0;
 }
 
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 6b85f84..770c432 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -4107,8 +4107,7 @@
 	write_unlock(&st_dev_arr_lock);
 out_put_disk:
 	put_disk(disk);
-	if (tpnt)
-		kfree(tpnt);
+	kfree(tpnt);
 out_buffer_free:
 	kfree(buffer);
 out:
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
index a1a58e1..a7420ca 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c
@@ -39,6 +39,7 @@
  */
 
 #include <linux/slab.h>
+#include <asm/param.h>		/* for timeouts in units of HZ */
 
 #include "sym_glue.h"
 #include "sym_nvram.h"
diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c
index cfab8f1..1ce29ba 100644
--- a/drivers/scsi/u14-34f.c
+++ b/drivers/scsi/u14-34f.c
@@ -1953,11 +1953,11 @@
 
    for (j = 0; sh[j] != NULL && sh[j] != shpnt; j++);
 
-   if (sh[j] == NULL) panic("%s: release, invalid Scsi_Host pointer.\n",
-                            driver_name);
+   if (sh[j] == NULL)
+      panic("%s: release, invalid Scsi_Host pointer.\n", driver_name);
 
    for (i = 0; i < sh[j]->can_queue; i++)
-      if ((&HD(j)->cp[i])->sglist) kfree((&HD(j)->cp[i])->sglist);
+      kfree((&HD(j)->cp[i])->sglist);
 
    for (i = 0; i < sh[j]->can_queue; i++)
       pci_unmap_single(HD(j)->pdev, HD(j)->cp[i].cp_dma_addr,
@@ -1965,7 +1965,8 @@
 
    free_irq(sh[j]->irq, &sha[j]);
 
-   if (sh[j]->dma_channel != NO_DMA) free_dma(sh[j]->dma_channel);
+   if (sh[j]->dma_channel != NO_DMA)
+      free_dma(sh[j]->dma_channel);
 
    release_region(sh[j]->io_port, sh[j]->n_io_port);
    scsi_unregister(sh[j]);
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 186e96c..9882060 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -40,6 +40,7 @@
 #include <linux/serial_core.h>
 #include <linux/serial.h>
 #include <linux/serial_8250.h>
+#include <linux/nmi.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -2208,6 +2209,8 @@
 	unsigned int ier;
 	int i;
 
+	touch_nmi_watchdog();
+
 	/*
 	 *	First save the UER then disable the interrupts
 	 */
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index 40d3e71..08c42c0 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -4416,10 +4416,8 @@
 	info->event = 0;
 	info->tty = 0;
 	if (info->blocked_open) {
-		if (info->close_delay) {
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(info->close_delay);
-		}
+		if (info->close_delay)
+			schedule_timeout_interruptible(info->close_delay);
 		wake_up_interruptible(&info->open_wait);
 	}
 	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
@@ -4469,8 +4467,7 @@
 	while (info->xmit.head != info->xmit.tail || /* More in send queue */
 	       (*info->ostatusadr & 0x007f) ||  /* more in FIFO */
 	       (elapsed_usec < 2*info->char_time_usec)) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_interruptible(1);
 		if (signal_pending(current))
 			break;
 		if (timeout && time_after(jiffies, orig_jiffies + timeout))
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c
index e2ebdca..47f7404 100644
--- a/drivers/serial/mcfserial.c
+++ b/drivers/serial/mcfserial.c
@@ -57,7 +57,8 @@
  *	keep going.  Perhaps one day the cflag settings for the
  *	console can be used instead.
  */
-#if defined(CONFIG_ARNEWSH) || defined(CONFIG_MOTOROLA) || defined(CONFIG_senTec) || defined(CONFIG_SNEHA)
+#if defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \
+    defined(CONFIG_senTec) || defined(CONFIG_SNEHA)
 #define	CONSOLE_BAUD_RATE	19200
 #define	DEFAULT_CBAUD		B19200
 #endif
@@ -67,7 +68,7 @@
 #define	DEFAULT_CBAUD		B38400
 #endif
 
-#if defined(CONFIG_MOD5272)
+#if defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB)
 #define CONSOLE_BAUD_RATE 	115200
 #define DEFAULT_CBAUD		B115200
 #endif
@@ -95,7 +96,8 @@
 #undef SERIAL_DEBUG_OPEN
 #undef SERIAL_DEBUG_FLOW
 
-#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
+    defined(CONFIG_M520x)
 #define	IRQBASE	(MCFINT_VECBASE+MCFINT_UART0)
 #else
 #define	IRQBASE	73
@@ -1528,6 +1530,35 @@
 	imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 +
 		MCFINTC_IMRL);
 	*imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1);
+#elif defined(CONFIG_M520x)
+	volatile unsigned char *icrp, *uartp;
+	volatile unsigned long *imrp;
+
+	uartp = info->addr;
+
+	icrp = (volatile unsigned char *) (MCF_MBAR + MCFICM_INTC0 +
+		MCFINTC_ICR0 + MCFINT_UART0 + info->line);
+	*icrp = 0x03;
+
+	imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 +
+		MCFINTC_IMRL);
+	*imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1);
+	if (info->line < 2) {
+		unsigned short *uart_par;
+		uart_par = (unsigned short *)(MCF_IPSBAR + MCF_GPIO_PAR_UART);
+		if (info->line == 0)
+			*uart_par |=  MCF_GPIO_PAR_UART_PAR_UTXD0
+				  | MCF_GPIO_PAR_UART_PAR_URXD0;
+		else if (info->line == 1)
+			*uart_par |=  MCF_GPIO_PAR_UART_PAR_UTXD1
+				  | MCF_GPIO_PAR_UART_PAR_URXD1;
+		} else if (info->line == 2) {
+			unsigned char *feci2c_par;
+			feci2c_par = (unsigned char *)(MCF_IPSBAR +  MCF_GPIO_PAR_FECI2C);
+			*feci2c_par &= ~0x0F;
+			*feci2c_par |=  MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2
+				    | MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2;
+		}
 #else
 	volatile unsigned char	*icrp, *uartp;
 
diff --git a/drivers/sh/superhyway/superhyway-sysfs.c b/drivers/sh/superhyway/superhyway-sysfs.c
index dc119ce..5543433 100644
--- a/drivers/sh/superhyway/superhyway-sysfs.c
+++ b/drivers/sh/superhyway/superhyway-sysfs.c
@@ -30,7 +30,7 @@
 superhyway_ro_attr(top_mb, "0x%02x\n", vcr.top_mb);
 
 /* Misc */
-superhyway_ro_attr(resource, "0x%08lx\n", resource.start);
+superhyway_ro_attr(resource, "0x%08lx\n", resource[0].start);
 
 struct device_attribute superhyway_dev_attrs[] = {
 	__ATTR_RO(perr_flags),
diff --git a/drivers/sh/superhyway/superhyway.c b/drivers/sh/superhyway/superhyway.c
index 28757cb..7bdab2a 100644
--- a/drivers/sh/superhyway/superhyway.c
+++ b/drivers/sh/superhyway/superhyway.c
@@ -27,19 +27,20 @@
 
 static void superhyway_device_release(struct device *dev)
 {
-	kfree(to_superhyway_device(dev));
+	struct superhyway_device *sdev = to_superhyway_device(dev);
+
+	kfree(sdev->resource);
+	kfree(sdev);
 }
 
 /**
  * superhyway_add_device - Add a SuperHyway module
- * @mod_id: Module ID (taken from MODULE.VCR.MOD_ID).
  * @base: Physical address where module is mapped.
- * @vcr: VCR value.
+ * @sdev: SuperHyway device to add, or NULL to allocate a new one.
+ * @bus: Bus where SuperHyway module resides.
  *
  * This is responsible for adding a new SuperHyway module. This sets up a new
- * struct superhyway_device for the module being added. Each one of @mod_id,
- * @base, and @vcr are registered with the new device for further use
- * elsewhere.
+ * struct superhyway_device for the module being added if @sdev == NULL.
  *
  * Devices are initially added in the order that they are scanned (from the
  * top-down of the memory map), and are assigned an ID based on the order that
@@ -49,28 +50,40 @@
  * Further work can and should be done in superhyway_scan_bus(), to be sure
  * that any new modules are properly discovered and subsequently registered.
  */
-int superhyway_add_device(unsigned int mod_id, unsigned long base,
-			  unsigned long long vcr)
+int superhyway_add_device(unsigned long base, struct superhyway_device *sdev,
+			  struct superhyway_bus *bus)
 {
-	struct superhyway_device *dev;
+	struct superhyway_device *dev = sdev;
 
-	dev = kmalloc(sizeof(struct superhyway_device), GFP_KERNEL);
-	if (!dev)
-		return -ENOMEM;
+	if (!dev) {
+		dev = kmalloc(sizeof(struct superhyway_device), GFP_KERNEL);
+		if (!dev)
+			return -ENOMEM;
 
-	memset(dev, 0, sizeof(struct superhyway_device));
+		memset(dev, 0, sizeof(struct superhyway_device));
+	}
 
-	dev->id.id = mod_id;
-	sprintf(dev->name, "SuperHyway device %04x", dev->id.id);
+	dev->bus = bus;
+	superhyway_read_vcr(dev, base, &dev->vcr);
 
-	dev->vcr		= *((struct vcr_info *)(&vcr));
-	dev->resource.name	= dev->name;
-	dev->resource.start	= base;
-	dev->resource.end	= dev->resource.start + 0x01000000;
+	if (!dev->resource) {
+		dev->resource = kmalloc(sizeof(struct resource), GFP_KERNEL);
+		if (!dev->resource) {
+			kfree(dev);
+			return -ENOMEM;
+		}
+
+		dev->resource->name	= dev->name;
+		dev->resource->start	= base;
+		dev->resource->end	= dev->resource->start + 0x01000000;
+	}
+
 	dev->dev.parent		= &superhyway_bus_device;
 	dev->dev.bus		= &superhyway_bus_type;
 	dev->dev.release	= superhyway_device_release;
+	dev->id.id		= dev->vcr.mod_id;
 
+	sprintf(dev->name, "SuperHyway device %04x", dev->id.id);
 	sprintf(dev->dev.bus_id, "%02x", superhyway_devices);
 
 	superhyway_devices++;
@@ -78,10 +91,31 @@
 	return device_register(&dev->dev);
 }
 
+int superhyway_add_devices(struct superhyway_bus *bus,
+			   struct superhyway_device **devices,
+			   int nr_devices)
+{
+	int i, ret = 0;
+
+	for (i = 0; i < nr_devices; i++) {
+		struct superhyway_device *dev = devices[i];
+		ret |= superhyway_add_device(dev->resource[0].start, dev, bus);
+	}
+
+	return ret;
+}
+
 static int __init superhyway_init(void)
 {
+	struct superhyway_bus *bus;
+	int ret = 0;
+
 	device_register(&superhyway_bus_device);
-	return superhyway_scan_bus();
+
+	for (bus = superhyway_channels; bus->ops; bus++)
+		ret |= superhyway_scan_bus(bus);
+
+	return ret;
 }
 
 postcore_initcall(superhyway_init);
@@ -197,6 +231,7 @@
 
 EXPORT_SYMBOL(superhyway_bus_type);
 EXPORT_SYMBOL(superhyway_add_device);
+EXPORT_SYMBOL(superhyway_add_devices);
 EXPORT_SYMBOL(superhyway_register_driver);
 EXPORT_SYMBOL(superhyway_unregister_driver);
 
diff --git a/drivers/video/68328fb.c b/drivers/video/68328fb.c
index 6a3cfbd..3b0ddc5 100644
--- a/drivers/video/68328fb.c
+++ b/drivers/video/68328fb.c
@@ -113,7 +113,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 	.fb_mmap	= mc68x328fb_mmap,
 };
 
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 7192b77..44b6ca2 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -65,15 +65,6 @@
 	  blitting. This is used by drivers that don't provide their own
 	  (accelerated) version.
 
-config FB_SOFT_CURSOR
-	tristate
-	depends on FB
-	default n
-	---help---
-	  Include the soft_cursor function for generic software cursor support.
-	  This is used by drivers that don't provide their own (accelerated)
-	  version.
-
 config FB_MACMODES
        tristate
        depends on FB
@@ -114,7 +105,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	---help---
 	  This enables support for Cirrus Logic GD542x/543x based boards on
 	  Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum.
@@ -133,7 +123,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This is the frame buffer device driver for the Permedia2 AGP frame
 	  buffer card from ASK, aka `Graphic Blaster Exxtreme'.  There is a
@@ -152,7 +141,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This framebuffer device driver is for the ARM PrimeCell PL110
 	  Colour LCD controller.  ARM PrimeCells provide the building
@@ -169,7 +157,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This is the frame buffer device driver for the Acorn VIDC graphics
 	  hardware found in Acorn RISC PCs and other ARM-based machines.  If
@@ -181,7 +168,9 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
+	help
+	  Say Y to enable the Framebuffer driver for the CLPS7111 and
+	  EP7212 processors.
 
 config FB_SA1100
 	bool "SA-1100 LCD support"
@@ -189,7 +178,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This is a framebuffer device for the SA-1100 LCD Controller.
 	  See <http://www.linux-fbdev.org/> for information on framebuffer
@@ -204,7 +192,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 
 config FB_CYBER2000
 	tristate "CyberPro 2000/2010/5000 support"
@@ -212,7 +199,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This enables support for the Integraphics CyberPro 20x0 and 5000
 	  VGA chips used in the Rebel.com Netwinder and other machines.
@@ -225,7 +211,6 @@
 	default y
 	select FB_CFB_FILLRECT
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 
 config FB_Q40
 	bool
@@ -234,12 +219,10 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 
 config FB_AMIGA
 	tristate "Amiga native chipset support"
 	depends on FB && AMIGA
-	select FB_SOFT_CURSOR
 	help
 	  This is the frame buffer device driver for the builtin graphics
 	  chipset found in Amigas.
@@ -279,7 +262,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This enables support for the Cybervision 64 graphics card from
 	  Phase5. Please note that its use is not all that intuitive (i.e. if
@@ -294,7 +276,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This enables support for the Cybervision 64/3D graphics card from
 	  Phase5. Please note that its use is not all that intuitive (i.e. if
@@ -317,7 +298,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This is the frame buffer device driver for the Amiga FrameMaster
 	  card from BSC (exhibited 1992 but not shipped as a CBM product).
@@ -328,7 +308,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This enables support for the Arc Monochrome LCD board. The board
 	  is based on the KS-108 lcd controller and is typically a matrix
@@ -351,7 +330,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	select FB_MACMODES
 	help
 	  Say Y if you want support with Open Firmware for your graphics
@@ -363,7 +341,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	select FB_MACMODES
 	help
 	  This driver supports a frame buffer for the graphics adapter in the
@@ -375,7 +352,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	select FB_MACMODES
 	help
 	  This driver supports a frame buffer for the "platinum" graphics
@@ -387,7 +363,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	select FB_MACMODES
 	help
 	  This driver supports a frame buffer for the "valkyrie" graphics
@@ -399,42 +374,32 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This is the frame buffer device driver for the Chips & Technologies
 	  65550 graphics chip in PowerBooks.
 
 config FB_ASILIANT
-	bool "Chips 69000 display support"
+	bool "Asiliant (Chips) 69000 display support"
 	depends on (FB = y) && PCI
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 
 config FB_IMSTT
 	bool "IMS Twin Turbo display support"
 	depends on (FB = y) && PCI
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	select FB_MACMODES if PPC
 	help
 	  The IMS Twin Turbo is a PCI-based frame buffer card bundled with
 	  many Macintosh and compatible computers.
 
-config FB_S3TRIO
-	bool "S3 Trio display support"
-	depends on (FB = y) && PPC && BROKEN
-	help
-	  If you have a S3 Trio say Y. Say N for S3 Virge.
-
 config FB_VGA16
 	tristate "VGA 16-color graphics support"
 	depends on FB && (X86 || PPC)
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This is the frame buffer device driver for VGA 16 color graphic
 	  cards. Say Y if you have such a card.
@@ -448,7 +413,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	default y
 	---help---
 	  STI refers to the HP "Standard Text Interface" which is a set of
@@ -469,7 +433,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	select FB_MACMODES
 
 #      bool '  Apple DAFB display support' CONFIG_FB_DAFB
@@ -478,7 +441,6 @@
 	depends on (FB = y) && HP300
 	select FB_CFB_FILLRECT
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	default y
 
 config FB_TGA
@@ -487,7 +449,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This is the frame buffer device driver for generic TGA graphic
 	  cards. Say Y if you have one of those.
@@ -498,7 +459,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This is the frame buffer device driver for generic VESA 2.0
 	  compliant graphic cards. The older VESA 1.2 cards are not supported.
@@ -516,7 +476,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  Say Y here if you have a Hercules mono graphics card.
 
@@ -545,7 +504,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  SGI Visual Workstation support for framebuffer graphics.
 
@@ -555,7 +513,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
  	help
 	  This is the frame buffer device driver for SGI Graphics Backend.
 	  This chip is used in SGI O2 and Visual Workstation 320/540.
@@ -583,7 +540,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This is the frame buffer device driver for the BWtwo frame buffer.
 
@@ -592,7 +548,6 @@
 	depends on (FB = y) && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This is the frame buffer device driver for the CGthree frame buffer.
 
@@ -601,7 +556,6 @@
 	depends on (FB = y) && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This is the frame buffer device driver for the CGsix (GX, TurboGX)
 	  frame buffer.
@@ -612,7 +566,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	---help---
 	  Say Y here if you have a PowerVR 2 card in your box.  If you plan to
 	  run linux on your Dreamcast, you will have to say Y here.
@@ -634,13 +587,55 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  Build in support for the SED1355 Epson Research Embedded RAMDAC
 	  LCD/CRT Controller (since redesignated as the S1D13505) as a
 	  framebuffer.  Product specs at
 	  <http://www.erd.epson.com/vdc/html/products.htm>.
 
+config FB_E1356
+	tristate "Epson SED1356 framebuffer support"
+	depends on FB && EXPERIMENTAL && PCI && MIPS
+
+config PB1000_CRT
+	bool "Use CRT on Pb1000 (J65)"
+	depends on MIPS_PB1000=y && FB_E1356
+
+config PB1000_NTSC
+	bool "Use Compsite NTSC on Pb1000 (J63)"
+	depends on MIPS_PB1000=y && FB_E1356
+
+config PB1000_TFT
+	bool "Use TFT Panel on Pb1000 (J64)"
+	depends on MIPS_PB1000=y && FB_E1356
+
+config PB1500_CRT
+	bool "Use CRT on Pb1500 " if MIPS_PB1500=y
+	depends on FB_E1356
+
+config PB1500_CRT
+	prompt "Use CRT on Pb1100 "
+	depends on FB_E1356 && MIPS_PB1100=y
+
+config PB1500_TFT
+	bool "Use TFT Panel on Pb1500 " if MIPS_PB1500=y
+	depends on FB_E1356
+
+config PB1500_TFT
+	prompt "Use TFT Panel on Pb1100 "
+	depends on FB_E1356 && MIPS_PB1100=y
+
+config FB_S1D13XXX
+	tristate "Epson S1D13XXX framebuffer support"
+	depends on FB
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  Support for S1D13XXX framebuffer device family (currently only
+	  working with S1D13806). Product specs at
+	  <http://www.erd.epson.com/vdc/html/legacy_13xxx.htm>
+
 config FB_NVIDIA
 	tristate "nVidia Framebuffer Support"
 	depends on FB && PCI
@@ -650,7 +645,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This driver supports graphics boards with the nVidia chips, TNT
 	  and newer. For very old chipsets, such as the RIVA128, then use
@@ -662,7 +656,7 @@
 
 config FB_NVIDIA_I2C
        bool "Enable DDC Support"
-       depends on FB_NVIDIA && !PPC_OF
+       depends on FB_NVIDIA
        help
 	  This enables I2C support for nVidia Chipsets.  This is used
 	  only for getting EDID information from the attached display
@@ -768,7 +762,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This driver supports the on-board graphics built in to the Intel
           830M/845G/852GM/855GM/865G chipsets.
@@ -791,7 +784,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	select FB_TILEBLITTING
 	select FB_MACMODES if PPC_PMAC
 	---help---
@@ -932,7 +924,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	select FB_MACMODES if PPC
 	help
 	  Choose this option if you want to use an ATI Radeon graphics card as
@@ -950,7 +941,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	select FB_MACMODES if PPC_OF
 	help
 	  Choose this option if you want to use an ATI Radeon graphics card as
@@ -988,7 +978,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	select FB_MACMODES if PPC_PMAC
 	help
 	  This driver supports graphics boards with the ATI Rage128 chips.
@@ -1004,7 +993,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	select FB_MACMODES if PPC
 	help
 	  This driver supports graphics boards with the ATI Mach64 chips.
@@ -1047,6 +1035,12 @@
 	  is at
 	  <http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
 
+config FB_S3TRIO
+	bool "S3 Trio display support"
+	depends on (FB = y) && PPC && BROKEN
+	help
+	  If you have a S3 Trio say Y. Say N for S3 Virge.
+
 config FB_SAVAGE
 	tristate "S3 Savage support"
 	depends on FB && PCI && EXPERIMENTAL
@@ -1056,7 +1050,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This driver supports notebooks and computers with S3 Savage PCI/AGP
 	  chips.
@@ -1093,7 +1086,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This is the frame buffer device driver for the SiS 300, 315, 330
 	  and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets.
@@ -1123,7 +1115,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This driver supports notebooks with NeoMagic PCI chips.
 	  Say Y if you have such a graphics card. 
@@ -1137,7 +1128,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  Say Y here if you have a STG4000 / Kyro / PowerVR 3 based
 	  graphics board.
@@ -1151,7 +1141,6 @@
 	select FB_CFB_IMAGEBLIT
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
-	select FB_SOFT_CURSOR
 	help
 	  This driver supports graphics boards with the 3Dfx Banshee/Voodoo3
 	  chips. Say Y if you have such a graphics board.
@@ -1173,7 +1162,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	---help---
 	  Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or 
 	  Voodoo2 (cvg) based graphics card.
@@ -1190,7 +1178,6 @@
 	tristate "Cyberblade/i1 support"
 	depends on FB && PCI
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	select VIDEO_SELECT
 	---help---
 	  This driver is supposed to support the Trident Cyberblade/i1
@@ -1218,7 +1205,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	---help---
 	  This driver is supposed to support graphics boards with the
 	  Trident CyberXXXX/Image/CyberBlade chips mostly found in laptops
@@ -1250,38 +1236,6 @@
 	  similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000
 	  and maybe other boards.
 
-config FB_E1356
-	tristate "Epson SED1356 framebuffer support"
-	depends on FB && EXPERIMENTAL && PCI && MIPS
-
-config PB1000_CRT
-	bool "Use CRT on Pb1000 (J65)"
-	depends on MIPS_PB1000=y && FB_E1356
-
-config PB1000_NTSC
-	bool "Use Compsite NTSC on Pb1000 (J63)"
-	depends on MIPS_PB1000=y && FB_E1356
-
-config PB1000_TFT
-	bool "Use TFT Panel on Pb1000 (J64)"
-	depends on MIPS_PB1000=y && FB_E1356
-
-config PB1500_CRT
-	bool "Use CRT on Pb1500 " if MIPS_PB1500=y
-	depends on FB_E1356
-
-config PB1500_CRT
-	prompt "Use CRT on Pb1100 "
-	depends on FB_E1356 && MIPS_PB1100=y
-
-config PB1500_TFT
-	bool "Use TFT Panel on Pb1500 " if MIPS_PB1500=y
-	depends on FB_E1356
-
-config PB1500_TFT
-	prompt "Use TFT Panel on Pb1100 "
-	depends on FB_E1356 && MIPS_PB1100=y
-
 config FB_AU1100
 	bool "Au1100 LCD Driver"
 	depends on (FB = y) && EXPERIMENTAL && PCI && MIPS && MIPS_PB1100=y
@@ -1299,7 +1253,6 @@
 	depends on FB_SBUS && SPARC64
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This is the frame buffer device driver for the Creator, Creator3D,
 	  and Elite3D graphics boards.
@@ -1310,7 +1263,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This is the frame buffer device driver for the TCX 24/8bit frame
 	  buffer.
@@ -1321,7 +1273,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This is the frame buffer device driver for the CGfourteen frame
 	  buffer on Desktop SPARCsystems with the SX graphics option.
@@ -1332,7 +1283,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This is the frame buffer device driver for the P9100 card
 	  supported on Sparcbook 3 machines.
@@ -1343,7 +1293,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This is the frame buffer device driver for the SBUS-based Sun ZX
 	  (leo) frame buffer cards.
@@ -1358,7 +1307,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This is the framebuffer device for the INTERGRAPHICS 1680 and
 	  successor frame buffer cards.
@@ -1369,7 +1317,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  This is the frame buffer device driver for the Hitachi HD64461 LCD
 	  frame buffer card.
@@ -1380,7 +1327,6 @@
  	select FB_CFB_FILLRECT
  	select FB_CFB_COPYAREA
  	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1)
 	  used mainly in the MIPS-based DECstation series.
@@ -1391,7 +1337,6 @@
  	select FB_CFB_FILLRECT
  	select FB_CFB_COPYAREA
  	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8)
 	  used mainly in the MIPS-based DECstation series.
@@ -1402,7 +1347,6 @@
  	select FB_CFB_FILLRECT
  	select FB_CFB_COPYAREA
  	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  Support for the PMAGB-B TURBOchannel framebuffer card used mainly
 	  in the MIPS-based DECstation series. The card is currently only
@@ -1414,7 +1358,6 @@
  	select FB_CFB_FILLRECT
  	select FB_CFB_COPYAREA
  	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  Support for the onboard framebuffer (1024x768x8) in the Personal
 	  DECstation series (Personal DECstation 5000/20, /25, /33, /50,
@@ -1426,7 +1369,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  The TX3912 is a Toshiba RISC processor based on the MIPS 3900 core
 	  see <http://www.toshiba.com/taec/components/Generic/risc/tx3912.htm>.
@@ -1439,7 +1381,6 @@
  	select FB_CFB_FILLRECT
  	select FB_CFB_COPYAREA
  	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  The G364 driver is the framebuffer used in MIPS Magnum 4000 and
 	  Olivetti M700-10 systems.
@@ -1450,7 +1391,6 @@
  	select FB_CFB_FILLRECT
  	select FB_CFB_COPYAREA
  	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	help
 	  Say Y here if you want to support the built-in frame buffer of
 	  the Motorola 68328 CPU family.
@@ -1461,7 +1401,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	---help---
 	  Frame buffer driver for the built-in LCD controller in the Intel
 	  PXA2x0 processor.
@@ -1473,23 +1412,6 @@
 
 	  If unsure, say N.
 
-config FB_W100
-	tristate "W100 frame buffer support"
-	depends on FB && PXA_SHARPSL
- 	select FB_CFB_FILLRECT
- 	select FB_CFB_COPYAREA
- 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
-	---help---
-	  Frame buffer driver for the w100 as found on the Sharp SL-Cxx series.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted and removed from the running kernel whenever you want). The
-	  module will be called vfb. If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  If unsure, say N.
-
 config FB_PXA_PARAMETERS
 	bool "PXA LCD command line parameters"
 	default n
@@ -1507,17 +1429,21 @@
 
 	  <file:Documentation/fb/pxafb.txt> describes the available parameters.
 
-config FB_S1D13XXX
-	tristate "Epson S1D13XXX framebuffer support"
-	depends on FB
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
-	help
-	  Support for S1D13XXX framebuffer device family (currently only
-	  working with S1D13806). Product specs at
-	  <http://www.erd.epson.com/vdc/html/legacy_13xxx.htm>
+config FB_W100
+	tristate "W100 frame buffer support"
+	depends on FB && PXA_SHARPSL
+ 	select FB_CFB_FILLRECT
+ 	select FB_CFB_COPYAREA
+ 	select FB_CFB_IMAGEBLIT
+	---help---
+	  Frame buffer driver for the w100 as found on the Sharp SL-Cxx series.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted and removed from the running kernel whenever you want). The
+	  module will be called vfb. If you want to compile it as a module,
+	  say M here and read <file:Documentation/modules.txt>.
+
+	  If unsure, say N.
 
 config FB_S3C2410
 	tristate "S3C2410 LCD framebuffer support"
@@ -1525,7 +1451,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	---help---
 	  Frame buffer driver for the built-in LCD controller in the Samsung
 	  S3C2410 processor.
@@ -1549,7 +1474,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	---help---
 	  This is a `virtual' frame buffer device. It operates on a chunk of
 	  unswappable kernel memory instead of on the memory of a graphics
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 97c5d03..aa434e7 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -16,7 +16,6 @@
 obj-$(CONFIG_FB_CFB_FILLRECT)  += cfbfillrect.o
 obj-$(CONFIG_FB_CFB_COPYAREA)  += cfbcopyarea.o
 obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
-obj-$(CONFIG_FB_SOFT_CURSOR)   += softcursor.o
 obj-$(CONFIG_FB_MACMODES)      += macmodes.o
 
 # Hardware specific drivers go first
diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c
index 9b6a393..193b482 100644
--- a/drivers/video/acornfb.c
+++ b/drivers/video/acornfb.c
@@ -926,7 +926,6 @@
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
 	.fb_mmap	= acornfb_mmap,
-	.fb_cursor	= soft_cursor,
 };
 
 /*
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
index 4fc93dc..467a1d7 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/amba-clcd.c
@@ -333,7 +333,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 	.fb_mmap	= clcdfb_mmap,
 };
 
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index cf8bb67..d549e21 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -1185,7 +1185,6 @@
 	.fb_fillrect	= amifb_fillrect,
 	.fb_copyarea	= amifb_copyarea,
 	.fb_imageblit	= amifb_imageblit,
-	.fb_cursor	= soft_cursor,
 	.fb_ioctl	= amifb_ioctl,
 };
 
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index 6aa9f82..a1fc8bb 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -511,7 +511,6 @@
 	.fb_fillrect	= arcfb_fillrect,
 	.fb_copyarea	= arcfb_copyarea,
 	.fb_imageblit	= arcfb_imageblit,
-	.fb_cursor	= soft_cursor,
 	.fb_ioctl 	= arcfb_ioctl,
 };
 
diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c
index f4729f4..c64de59 100644
--- a/drivers/video/asiliantfb.c
+++ b/drivers/video/asiliantfb.c
@@ -106,7 +106,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 /* Calculate the ratios for the dot clocks without using a single long long
diff --git a/drivers/video/aty/ati_ids.h b/drivers/video/aty/ati_ids.h
index 13321c6..39ab483 100644
--- a/drivers/video/aty/ati_ids.h
+++ b/drivers/video/aty/ati_ids.h
@@ -150,6 +150,7 @@
 #define PCI_CHIP_RV200_QX		0x5158
 #define PCI_CHIP_RV100_QY		0x5159
 #define PCI_CHIP_RV100_QZ		0x515A
+#define PCI_CHIP_RN50			0x515E
 #define PCI_CHIP_RAGE128RE		0x5245
 #define PCI_CHIP_RAGE128RF		0x5246
 #define PCI_CHIP_RAGE128RG		0x5247
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index e380ee8..e686185 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -478,7 +478,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 #ifdef CONFIG_PMAC_BACKLIGHT
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 037fe9d..08edbfc 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -292,7 +292,6 @@
 	.fb_fillrect	= atyfb_fillrect,
 	.fb_copyarea	= atyfb_copyarea,
 	.fb_imageblit	= atyfb_imageblit,
-	.fb_cursor	= soft_cursor,
 #ifdef __sparc__
 	.fb_mmap	= atyfb_mmap,
 #endif
@@ -2157,11 +2156,38 @@
 
 static struct fb_info *fb_list = NULL;
 
+#if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
+static int __devinit atyfb_get_timings_from_lcd(struct atyfb_par *par,
+						struct fb_var_screeninfo *var)
+{
+	int ret = -EINVAL;
+
+	if (par->lcd_table != 0 && (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
+		*var = default_var;
+		var->xres = var->xres_virtual = par->lcd_hdisp;
+		var->right_margin = par->lcd_right_margin;
+		var->left_margin = par->lcd_hblank_len -
+			(par->lcd_right_margin + par->lcd_hsync_dly +
+			 par->lcd_hsync_len);
+		var->hsync_len = par->lcd_hsync_len + par->lcd_hsync_dly;
+		var->yres = var->yres_virtual = par->lcd_vdisp;
+		var->lower_margin = par->lcd_lower_margin;
+		var->upper_margin = par->lcd_vblank_len -
+			(par->lcd_lower_margin + par->lcd_vsync_len);
+		var->vsync_len = par->lcd_vsync_len;
+		var->pixclock = par->lcd_pixclock;
+		ret = 0;
+	}
+
+	return ret;
+}
+#endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */
+
 static int __init aty_init(struct fb_info *info, const char *name)
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
 	const char *ramname = NULL, *xtal;
-	int gtb_memsize;
+	int gtb_memsize, has_var = 0;
 	struct fb_var_screeninfo var;
 	u8 pll_ref_div;
 	u32 i;
@@ -2469,8 +2495,8 @@
 		 *         applies to all Mac video cards
 		 */
 		if (mode) {
-			if (!mac_find_mode(&var, info, mode, 8))
-				var = default_var;
+			if (mac_find_mode(&var, info, mode, 8))
+				has_var = 1;
 		} else {
 			if (default_vmode == VMODE_CHOOSE) {
 				if (M64_HAS(G3_PB_1024x768))
@@ -2492,20 +2518,23 @@
 				default_vmode = VMODE_640_480_60;
 			if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
 				default_cmode = CMODE_8;
-			if (mac_vmode_to_var(default_vmode, default_cmode, &var))
-				var = default_var;
+			if (!mac_vmode_to_var(default_vmode, default_cmode,
+					       &var))
+				has_var = 1;
 		}
-	} else
+	}
+
 #endif /* !CONFIG_PPC */
-	if (
-#if defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)
-	   /* On Sparc, unless the user gave a specific mode
-	    * specification, use the PROM probed values in
-	    * default_var.
-	    */
-	    !mode ||
+
+#if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
+	if (!atyfb_get_timings_from_lcd(par, &var))
+		has_var = 1;
 #endif
-	    !fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8))
+
+	if (mode && fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8))
+		has_var = 1;
+
+	if (!has_var)
 		var = default_var;
 
 	if (noaccel)
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 8a24a66..4f01ccc 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -69,7 +69,6 @@
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
 #include <linux/device.h>
-#include <linux/i2c.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -113,6 +112,7 @@
 	/* Radeon VE/7000 */
 	CHIP_DEF(PCI_CHIP_RV100_QY, 	RV100,	CHIP_HAS_CRTC2),
 	CHIP_DEF(PCI_CHIP_RV100_QZ, 	RV100,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RN50,		RV100,	CHIP_HAS_CRTC2),
 	/* Radeon IGP320M (U1) */
 	CHIP_DEF(PCI_CHIP_RS100_4336,	RS100,	CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
 	/* Radeon IGP320 (A3) */
@@ -1874,7 +1874,6 @@
 	.fb_fillrect		= radeonfb_fillrect,
 	.fb_copyarea		= radeonfb_copyarea,
 	.fb_imageblit		= radeonfb_imageblit,
-	.fb_cursor		= soft_cursor,
 };
 
 
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
index 01b8b2f..217e00a 100644
--- a/drivers/video/aty/radeonfb.h
+++ b/drivers/video/aty/radeonfb.h
@@ -10,9 +10,10 @@
 #include <linux/fb.h>
 
 
+#ifdef CONFIG_FB_RADEON_I2C
 #include <linux/i2c.h>
-#include <linux/i2c-id.h>
 #include <linux/i2c-algo-bit.h>
+#endif
 
 #include <asm/io.h>
 
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c
index 3d20b2d..f53bf3ba 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/bw2.c
@@ -51,7 +51,6 @@
 	.fb_imageblit		= cfb_imageblit,
 	.fb_mmap		= bw2_mmap,
 	.fb_ioctl		= bw2_ioctl,
-	.fb_cursor		= soft_cursor,
 };
 
 /* OBio addresses for the bwtwo registers */
diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c
index 67711f7..cdc7157 100644
--- a/drivers/video/cfbcopyarea.c
+++ b/drivers/video/cfbcopyarea.c
@@ -349,46 +349,10 @@
 	unsigned long __iomem *dst = NULL, *src = NULL;
 	int bits = BITS_PER_LONG, bytes = bits >> 3;
 	int dst_idx = 0, src_idx = 0, rev_copy = 0;
-	int x2, y2, vxres, vyres;
 
 	if (p->state != FBINFO_STATE_RUNNING)
 		return;
 
-	/* We want rotation but lack hardware to do it for us. */
-	if (!p->fbops->fb_rotate && p->var.rotate) {
-	}
-
-	vxres = p->var.xres_virtual;
-	vyres = p->var.yres_virtual;
-
-	if (area->dx > vxres || area->sx > vxres ||
-	    area->dy > vyres || area->sy > vyres)
-		return;
-
-	/* clip the destination
-	 * We could use hardware clipping but on many cards you get around
-	 * hardware clipping by writing to framebuffer directly.
-	 */
-	x2 = area->dx + area->width;
-	y2 = area->dy + area->height;
-	dx = area->dx > 0 ? area->dx : 0;
-	dy = area->dy > 0 ? area->dy : 0;
-	x2 = x2 < vxres ? x2 : vxres;
-	y2 = y2 < vyres ? y2 : vyres;
-	width = x2 - dx;
-	height = y2 - dy;
-
-	if ((width==0) ||(height==0))
-		return;
-
-	/* update sx1,sy1 */
-	sx += (dx - area->dx);
-	sy += (dy - area->dy);
-
-	/* the source must be completely inside the virtual screen */
-	if (sx < 0 || sy < 0 || (sx + width) > vxres || (sy + height) > vyres)
-		return;
-
 	/* if the beginning of the target area might overlap with the end of
 	the source area, be have to copy the area reverse. */
 	if ((dy == sy && dx > sx) || (dy > sy)) {
diff --git a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c
index e4fc42b..167d931 100644
--- a/drivers/video/cfbfillrect.c
+++ b/drivers/video/cfbfillrect.c
@@ -344,7 +344,8 @@
 
 void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
 {
-	unsigned long x2, y2, vxres, vyres, height, width, pat, fg;
+	unsigned long pat, fg;
+	unsigned long width = rect->width, height = rect->height;
 	int bits = BITS_PER_LONG, bytes = bits >> 3;
 	u32 bpp = p->var.bits_per_pixel;
 	unsigned long __iomem *dst;
@@ -353,27 +354,6 @@
 	if (p->state != FBINFO_STATE_RUNNING)
 		return;
 
-	/* We want rotation but lack hardware to do it for us. */
-	if (!p->fbops->fb_rotate && p->var.rotate) {
-	}
-
-	vxres = p->var.xres_virtual;
-	vyres = p->var.yres_virtual;
-
-	if (!rect->width || !rect->height ||
-	    rect->dx > vxres || rect->dy > vyres)
-		return;
-
-	/* We could use hardware clipping but on many cards you get around
-	 * hardware clipping by writing to framebuffer directly. */
-
-	x2 = rect->dx + rect->width;
-	y2 = rect->dy + rect->height;
-	x2 = x2 < vxres ? x2 : vxres;
-	y2 = y2 < vyres ? y2 : vyres;
-	width = x2 - rect->dx;
-	height = y2 - rect->dy;
-
 	if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
 	    p->fix.visual == FB_VISUAL_DIRECTCOLOR )
 		fg = ((u32 *) (p->pseudo_palette))[rect->color];
diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
index 4c123ab..da664ce 100644
--- a/drivers/video/cfbimgblt.c
+++ b/drivers/video/cfbimgblt.c
@@ -272,33 +272,13 @@
 {
 	u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
 	u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel;
-	u32 width = image->width, height = image->height; 
+	u32 width = image->width;
 	u32 dx = image->dx, dy = image->dy;
-	int x2, y2, vxres, vyres;
 	u8 __iomem *dst1;
 
 	if (p->state != FBINFO_STATE_RUNNING)
 		return;
 
-	vxres = p->var.xres_virtual;
-	vyres = p->var.yres_virtual;
-	/* 
-	 * We could use hardware clipping but on many cards you get around
-	 * hardware clipping by writing to framebuffer directly like we are
-	 * doing here. 
-	 */
-	if (image->dx > vxres || image->dy > vyres)
-		return;
-
-	x2 = image->dx + image->width;
-	y2 = image->dy + image->height;
-	dx = image->dx > 0 ? image->dx : 0;
-	dy = image->dy > 0 ? image->dy : 0;
-	x2 = x2 < vxres ? x2 : vxres;
-	y2 = y2 < vyres ? y2 : vyres;
-	width  = x2 - dx;
-	height = y2 - dy;
-
 	bitstart = (dy * p->fix.line_length * 8) + (dx * bpp);
 	start_index = bitstart & (32 - 1);
 	pitch_index = (p->fix.line_length & (bpl - 1)) * 8;
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index 18e60b9..030d4b1 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -49,7 +49,6 @@
 	.fb_imageblit		= cfb_imageblit,
 	.fb_mmap		= cg14_mmap,
 	.fb_ioctl		= cg14_ioctl,
-	.fb_cursor		= soft_cursor,
 };
 
 #define CG14_MCR_INTENABLE_SHIFT	7
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c
index 6e7d8d4..b94eee8 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -50,7 +50,6 @@
 	.fb_imageblit		= cfb_imageblit,
 	.fb_mmap		= cg3_mmap,
 	.fb_ioctl		= cg3_ioctl,
-	.fb_cursor		= soft_cursor,
 };
 
 
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 49a2545..3280bb9 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -54,7 +54,6 @@
 	.fb_sync		= cg6_sync,
 	.fb_mmap		= cg6_mmap,
 	.fb_ioctl		= cg6_ioctl,
-	.fb_cursor		= soft_cursor,
 };
 
 /* Offset of interesting structures in the OBIO space */
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
index 4131243..bc061d4 100644
--- a/drivers/video/chipsfb.c
+++ b/drivers/video/chipsfb.c
@@ -91,7 +91,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 static int chipsfb_check_var(struct fb_var_screeninfo *var,
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 3a26f9c..2858c5c 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -548,7 +548,6 @@
 	.fb_fillrect	= cirrusfb_fillrect,
 	.fb_copyarea	= cirrusfb_copyarea,
 	.fb_imageblit	= cirrusfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 /*--- Hardware Specific Routines -------------------------------------------*/
diff --git a/drivers/video/clps711xfb.c b/drivers/video/clps711xfb.c
index 8692e00..50b78af 100644
--- a/drivers/video/clps711xfb.c
+++ b/drivers/video/clps711xfb.c
@@ -219,7 +219,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 static int 
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 6a9ae2b..fadf7c5 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -98,6 +98,8 @@
 	tristate "Framebuffer Console support"
 	depends on FB
 	select CRC32
+	help
+	  Low-level framebuffer-based console driver.
 
 config STI_CONSOLE
         tristate "STI text console" 
@@ -203,5 +205,12 @@
 	  big letters. It fits between the sun 12x22 and the normal 8x16 font.
 	  If other fonts are too big or too small for you, say Y, otherwise say N.
 
+config FONT_RL
+	bool "console Roman Large 8x16 font" if FONTS
+	depends on FRAMEBUFFER_CONSOLE
+	help
+	  This is the visually-appealing "RL" console font that is
+	  included with the kbd package.
+
 endmenu
 
diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
index 42c7b8d..5222628 100644
--- a/drivers/video/console/Makefile
+++ b/drivers/video/console/Makefile
@@ -15,6 +15,7 @@
 font-objs-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o
 font-objs-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o
 font-objs-$(CONFIG_FONT_MINI_4x6)  += font_mini_4x6.o
+font-objs-$(CONFIG_FONT_RL)  += font_rl.o
 
 font-objs += $(font-objs-y)
 
@@ -26,7 +27,7 @@
 obj-$(CONFIG_STI_CONSOLE)         += sticon.o sticore.o font.o
 obj-$(CONFIG_VGA_CONSOLE)         += vgacon.o
 obj-$(CONFIG_MDA_CONSOLE)         += mdacon.o
-obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o bitblit.o font.o
+obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o bitblit.o font.o softcursor.o
 ifeq ($(CONFIG_FB_TILEBLITTING),y)
 obj-$(CONFIG_FRAMEBUFFER_CONSOLE)     += tileblit.o
 endif
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
index 9f70e51..67857b3 100644
--- a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
@@ -272,6 +272,7 @@
 	int w = (vc->vc_font.width + 7) >> 3, c;
 	int y = real_y(p, vc->vc_y);
 	int attribute, use_sw = (vc->vc_cursor_type & 0x10);
+	int err = 1;
 	char *src;
 
 	cursor.set = 0;
@@ -408,7 +409,11 @@
 	cursor.image.depth = 1;
 	cursor.rop = ROP_XOR;
 
-	info->fbops->fb_cursor(info, &cursor);
+	if (info->fbops->fb_cursor)
+		err = info->fbops->fb_cursor(info, &cursor);
+
+	if (err)
+		soft_cursor(info, &cursor);
 
 	ops->cursor_reset = 0;
 }
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 0fc8bb4..3cf1b61 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -281,6 +281,18 @@
 	return color;
 }
 
+static void fbcon_update_softback(struct vc_data *vc)
+{
+	int l = fbcon_softback_size / vc->vc_size_row;
+
+	if (l > 5)
+		softback_end = softback_buf + l * vc->vc_size_row;
+	else
+		/* Smaller scrollback makes no sense, and 0 would screw
+		   the operation totally */
+		softback_top = 0;
+}
+
 static void fb_flashcursor(void *private)
 {
 	struct fb_info *info = private;
@@ -618,6 +630,15 @@
 		kfree(oldinfo->fbcon_par);
 		oldinfo->fbcon_par = NULL;
 		module_put(oldinfo->fbops->owner);
+		/*
+		  If oldinfo and newinfo are driving the same hardware,
+		  the fb_release() method of oldinfo may attempt to
+		  restore the hardware state.  This will leave the
+		  newinfo in an undefined state. Thus, a call to
+		  fb_set_par() may be needed for the newinfo.
+		*/
+		if (newinfo->fbops->fb_set_par)
+			newinfo->fbops->fb_set_par(newinfo);
 	}
 
 	return err;
@@ -1007,16 +1028,8 @@
 	if (logo)
 		fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows);
 
-	if (vc == svc && softback_buf) {
-		int l = fbcon_softback_size / vc->vc_size_row;
-		if (l > 5)
-			softback_end = softback_buf + l * vc->vc_size_row;
-		else {
-			/* Smaller scrollback makes no sense, and 0 would screw
-			   the operation totally */
-			softback_top = 0;
-		}
-	}
+	if (vc == svc && softback_buf)
+		fbcon_update_softback(vc);
 }
 
 static void fbcon_deinit(struct vc_data *vc)
@@ -1223,18 +1236,8 @@
 	vc_resize(vc, cols, rows);
 	if (CON_IS_VISIBLE(vc)) {
 		update_screen(vc);
-		if (softback_buf) {
-			int l = fbcon_softback_size / vc->vc_size_row;
-
-			if (l > 5)
-				softback_end = softback_buf + l *
-					vc->vc_size_row;
-			else {
-				/* Smaller scrollback makes no sense, and 0
-				   would screw the operation totally */
-				softback_top = 0;
-			}
-		}
+		if (softback_buf)
+			fbcon_update_softback(vc);
 	}
 }
 
@@ -1892,24 +1895,11 @@
 		mode = fb_find_best_mode(&var, &info->modelist);
 		if (mode == NULL)
 			return -EINVAL;
+		display_to_var(&var, p);
 		fb_videomode_to_var(&var, mode);
+
 		if (width > var.xres/fw || height > var.yres/fh)
 			return -EINVAL;
-		/*
-		 * The following can probably have any value... Do we need to
-		 * set all of them?
-		 */
-		var.bits_per_pixel = p->bits_per_pixel;
-		var.xres_virtual = p->xres_virtual;
-		var.yres_virtual = p->yres_virtual;
-		var.accel_flags = p->accel_flags;
-		var.width = p->width;
-		var.height = p->height;
-		var.red = p->red;
-		var.green = p->green;
-		var.blue = p->blue;
-		var.transp = p->transp;
-		var.nonstd = p->nonstd;
 
 		DPRINTK("resize now %ix%i\n", var.xres, var.yres);
 		if (CON_IS_VISIBLE(vc)) {
@@ -1933,19 +1923,11 @@
 	info = registered_fb[con2fb_map[vc->vc_num]];
 
 	if (softback_top) {
-		int l = fbcon_softback_size / vc->vc_size_row;
 		if (softback_lines)
 			fbcon_set_origin(vc);
 		softback_top = softback_curr = softback_in = softback_buf;
 		softback_lines = 0;
-
-		if (l > 5)
-			softback_end = softback_buf + l * vc->vc_size_row;
-		else {
-			/* Smaller scrollback makes no sense, and 0 would screw
-			   the operation totally */
-			softback_top = 0;
-		}
+		fbcon_update_softback(vc);
 	}
 
 	if (logo_shown >= 0) {
@@ -2235,17 +2217,8 @@
 		/* reset wrap/pan */
 		info->var.xoffset = info->var.yoffset = p->yscroll = 0;
 		vc_resize(vc, info->var.xres / w, info->var.yres / h);
-		if (CON_IS_VISIBLE(vc) && softback_buf) {
-			int l = fbcon_softback_size / vc->vc_size_row;
-			if (l > 5)
-				softback_end =
-				    softback_buf + l * vc->vc_size_row;
-			else {
-				/* Smaller scrollback makes no sense, and 0 would screw
-				   the operation totally */
-				softback_top = 0;
-			}
-		}
+		if (CON_IS_VISIBLE(vc) && softback_buf)
+			fbcon_update_softback(vc);
 	} else if (CON_IS_VISIBLE(vc)
 		   && vc->vc_mode == KD_TEXT) {
 		fbcon_clear_margins(vc, 0);
@@ -2615,16 +2588,8 @@
 		update_var(vc->vc_num, info);
 		fbcon_set_palette(vc, color_table);
 		update_screen(vc);
-		if (softback_buf) {
-			int l = fbcon_softback_size / vc->vc_size_row;
-			if (l > 5)
-				softback_end = softback_buf + l * vc->vc_size_row;
-			else {
-				/* Smaller scrollback makes no sense, and 0
-				   would screw the operation totally */
-				softback_top = 0;
-			}
-		}
+		if (softback_buf)
+			fbcon_update_softback(vc);
 	}
 }
 
@@ -2659,16 +2624,8 @@
 			update_var(vc->vc_num, info);
 			fbcon_set_palette(vc, color_table);
 			update_screen(vc);
-			if (softback_buf) {
-				int l = fbcon_softback_size / vc->vc_size_row;
-				if (l > 5)
-					softback_end = softback_buf + l * vc->vc_size_row;
-				else {
-					/* Smaller scrollback makes no sense, and 0
-					   would screw the operation totally */
-					softback_top = 0;
-				}
-			}
+			if (softback_buf)
+				fbcon_update_softback(vc);
 		}
 	}
 }
@@ -2758,7 +2715,8 @@
 			continue;
 		vc = vc_cons[i].d;
 		display_to_var(&var, &fb_display[i]);
-		mode = fb_find_nearest_mode(&var, &info->modelist);
+		mode = fb_find_nearest_mode(fb_display[i].mode,
+					    &info->modelist);
 		fb_videomode_to_var(&var, mode);
 
 		if (vc)
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index 0738cd6..b68e0e2 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -167,5 +167,5 @@
 			      struct display *p, struct fbcon_ops *ops);
 #endif
 extern void fbcon_set_bitops(struct fbcon_ops *ops);
-
+extern int  soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
 #endif /* _VIDEO_FBCON_H */
diff --git a/drivers/video/console/font_rl.c b/drivers/video/console/font_rl.c
new file mode 100644
index 0000000..dfecc27
--- /dev/null
+++ b/drivers/video/console/font_rl.c
@@ -0,0 +1,4374 @@
+
+/* This font is simply the "rl.fnt" console font from the kbd utility.
+ * Converted by Zack T Smith, fbui@comcast.net.
+ * The original binary file is covered under the GNU Public License.
+ */
+
+#include <linux/font.h>
+
+#define FONTDATAMAX 4096
+
+static unsigned char patterns[4096] = {
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x3c,
+0x42,
+0x81,
+0xe7,
+0xa5,
+0x99,
+0x81,
+0x81,
+0x99,
+0x42,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x3c,
+0x7e,
+0xff,
+0x99,
+0xdb,
+0xe7,
+0xff,
+0xff,
+0xe7,
+0x7e,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x6c,
+0xfe,
+0xfe,
+0xfe,
+0xfe,
+0xfe,
+0x7c,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x7c,
+0xfe,
+0x7c,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x38,
+0x38,
+0x10,
+0xd6,
+0xfe,
+0xd6,
+0x10,
+0x10,
+0x38,
+0x7c,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x10,
+0x38,
+0x7c,
+0xfe,
+0xfe,
+0x54,
+0x10,
+0x10,
+0x38,
+0x7c,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x18,
+0x3c,
+0x3c,
+0x18,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xe7,
+0xc3,
+0xc3,
+0xe7,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x3c,
+0x66,
+0x42,
+0x42,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xc3,
+0x99,
+0xbd,
+0xbd,
+0x99,
+0xc3,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+
+0x00,
+0x00,
+0x0f,
+0x07,
+0x0d,
+0x18,
+0x78,
+0xcc,
+0xcc,
+0xcc,
+0xcc,
+0x78,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x3c,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x18,
+0x7e,
+0x18,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x08,
+0x0c,
+0x0a,
+0x0a,
+0x0a,
+0x08,
+0x08,
+0x08,
+0x38,
+0x78,
+0x30,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x10,
+0x18,
+0x1c,
+0x1e,
+0x1e,
+0x16,
+0x12,
+0x72,
+0xf2,
+0x62,
+0x0e,
+0x1e,
+0x0c,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x10,
+0x92,
+0x54,
+0x38,
+0xfe,
+0x38,
+0x54,
+0x92,
+0x10,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x80,
+0xc0,
+0xe0,
+0xb8,
+0x8e,
+0xb8,
+0xe0,
+0xc0,
+0x80,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x02,
+0x06,
+0x0e,
+0x3a,
+0xe2,
+0x3a,
+0x0e,
+0x06,
+0x02,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x10,
+0x38,
+0x7c,
+0xd6,
+0x10,
+0x10,
+0x10,
+0x10,
+0xd6,
+0x7c,
+0x38,
+0x10,
+0x00,
+0x00,
+
+0x00,
+0x42,
+0xe7,
+0xe7,
+0xe7,
+0xe7,
+0x42,
+0x42,
+0x42,
+0x00,
+0x66,
+0x66,
+0x66,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x7f,
+0xca,
+0xca,
+0xca,
+0xca,
+0x7a,
+0x0a,
+0x0a,
+0x0a,
+0x0a,
+0x0a,
+0x1b,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x1e,
+0x31,
+0x78,
+0xcc,
+0xc6,
+0xc3,
+0x63,
+0x33,
+0x1e,
+0x8c,
+0x78,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xfe,
+0xfe,
+0xfe,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x10,
+0x38,
+0x7c,
+0xd6,
+0x10,
+0x10,
+0x10,
+0x10,
+0xd6,
+0x7c,
+0x38,
+0x10,
+0xfe,
+0x00,
+
+0x00,
+0x00,
+0x10,
+0x38,
+0x7c,
+0xd6,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0xd6,
+0x7c,
+0x38,
+0x10,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x08,
+0x0c,
+0x06,
+0xff,
+0x06,
+0x0c,
+0x08,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x10,
+0x30,
+0x60,
+0xff,
+0x60,
+0x30,
+0x10,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x22,
+0x44,
+0x88,
+0xcc,
+0xee,
+0x44,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x24,
+0x42,
+0xff,
+0x42,
+0x24,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x38,
+0x6c,
+0x6c,
+0xc6,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0xfe,
+0xc6,
+0x6c,
+0x6c,
+0x38,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x18,
+0x3c,
+0x3c,
+0x3c,
+0x3c,
+0x18,
+0x18,
+0x18,
+0x10,
+0x00,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+
+0x22,
+0x77,
+0x33,
+0x11,
+0x22,
+0x44,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x12,
+0x12,
+0x12,
+0x7f,
+0x24,
+0x24,
+0x24,
+0xfe,
+0x48,
+0x48,
+0x48,
+0x00,
+0x00,
+0x00,
+
+0x10,
+0x10,
+0x7c,
+0xd2,
+0xd0,
+0xd0,
+0xd0,
+0x7c,
+0x16,
+0x16,
+0x16,
+0x96,
+0x7c,
+0x10,
+0x10,
+0x00,
+
+0x00,
+0x42,
+0xbe,
+0x44,
+0x0c,
+0x08,
+0x18,
+0x10,
+0x30,
+0x20,
+0x64,
+0x4a,
+0xc4,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x38,
+0x6c,
+0x6c,
+0x6c,
+0x38,
+0x37,
+0x72,
+0xdc,
+0xcc,
+0xcc,
+0xcc,
+0x77,
+0x00,
+0x00,
+0x00,
+
+0x10,
+0x38,
+0x18,
+0x08,
+0x10,
+0x20,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x04,
+0x08,
+0x10,
+0x10,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x10,
+0x10,
+0x08,
+0x04,
+0x00,
+0x00,
+
+0x00,
+0x20,
+0x10,
+0x08,
+0x08,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x08,
+0x08,
+0x10,
+0x20,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x44,
+0x28,
+0x38,
+0xfe,
+0x38,
+0x28,
+0x44,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x18,
+0x18,
+0x7e,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x18,
+0x08,
+0x10,
+0x20,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7e,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x06,
+0x06,
+0x0c,
+0x0c,
+0x18,
+0x18,
+0x30,
+0x30,
+0x60,
+0x60,
+0xc0,
+0xc0,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x3c,
+0x46,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc4,
+0x78,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x08,
+0x18,
+0x78,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x7e,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x7c,
+0x86,
+0x06,
+0x0c,
+0x18,
+0x20,
+0x40,
+0xc1,
+0xfe,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x3c,
+0x46,
+0x04,
+0x08,
+0x1c,
+0x06,
+0x06,
+0x06,
+0x06,
+0x0c,
+0x70,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x04,
+0x08,
+0x10,
+0x2c,
+0x4c,
+0x8c,
+0x8c,
+0xfe,
+0x0c,
+0x0c,
+0x0c,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x02,
+0x3c,
+0x20,
+0x20,
+0x70,
+0x0c,
+0x06,
+0x06,
+0x06,
+0x06,
+0x0c,
+0x70,
+0x00,
+
+0x00,
+0x00,
+0x18,
+0x20,
+0x40,
+0xc0,
+0xdc,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0x44,
+0x38,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x40,
+0x7e,
+0x82,
+0x06,
+0x04,
+0x0c,
+0x18,
+0x18,
+0x30,
+0x30,
+0x30,
+0x30,
+0x00,
+
+0x00,
+0x00,
+0x7c,
+0xc6,
+0xc6,
+0x64,
+0x38,
+0x4c,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0x7c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x38,
+0x44,
+0xc6,
+0xc6,
+0x76,
+0x06,
+0x06,
+0x06,
+0x04,
+0x08,
+0x30,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x18,
+0x08,
+0x10,
+0x20,
+
+0x00,
+0x06,
+0x0c,
+0x18,
+0x30,
+0x60,
+0xa0,
+0xa0,
+0x60,
+0x30,
+0x18,
+0x0c,
+0x06,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7e,
+0x00,
+0x00,
+0x7e,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x60,
+0x30,
+0x18,
+0x0c,
+0x06,
+0x05,
+0x05,
+0x06,
+0x0c,
+0x18,
+0x30,
+0x60,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x7c,
+0x86,
+0xc6,
+0x06,
+0x04,
+0x08,
+0x10,
+0x10,
+0x18,
+0x00,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x3c,
+0x46,
+0xc6,
+0xce,
+0xd6,
+0xd6,
+0xd6,
+0xdc,
+0xc0,
+0xc4,
+0x78,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x2c,
+0x2c,
+0x2c,
+0x7e,
+0x46,
+0x46,
+0x46,
+0xef,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xfc,
+0x66,
+0x66,
+0x66,
+0x66,
+0x7c,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xfc,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3a,
+0x66,
+0xc2,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xfc,
+0x66,
+0x63,
+0x63,
+0x63,
+0x63,
+0x63,
+0x63,
+0x63,
+0x63,
+0x66,
+0xfc,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xff,
+0x61,
+0x60,
+0x60,
+0x64,
+0x7c,
+0x64,
+0x60,
+0x60,
+0x60,
+0x61,
+0xfe,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xff,
+0x61,
+0x61,
+0x60,
+0x64,
+0x7c,
+0x64,
+0x60,
+0x60,
+0x60,
+0x60,
+0xf0,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3a,
+0x66,
+0xc2,
+0xc0,
+0xc0,
+0xc0,
+0xcf,
+0xc6,
+0xc6,
+0xc6,
+0x66,
+0x38,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xf7,
+0x62,
+0x62,
+0x62,
+0x62,
+0x7e,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0xf7,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3c,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x1e,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x08,
+0xf0,
+
+0x00,
+0xf7,
+0x64,
+0x6c,
+0x68,
+0x68,
+0x78,
+0x6c,
+0x6c,
+0x6c,
+0x66,
+0x66,
+0xf7,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xf8,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x61,
+0xfe,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xc3,
+0x66,
+0x76,
+0x7e,
+0x56,
+0x56,
+0x46,
+0x46,
+0x46,
+0x46,
+0x46,
+0xef,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xe7,
+0x62,
+0x62,
+0x72,
+0x52,
+0x5a,
+0x4a,
+0x4e,
+0x46,
+0x46,
+0x42,
+0xe2,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3c,
+0x66,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xfc,
+0x66,
+0x66,
+0x66,
+0x66,
+0x6c,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0xf0,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3c,
+0x66,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0x66,
+0x3c,
+0x10,
+0x39,
+0x0e,
+
+0x00,
+0xfc,
+0x66,
+0x66,
+0x66,
+0x66,
+0x7c,
+0x6c,
+0x66,
+0x66,
+0x66,
+0x66,
+0xf3,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x7a,
+0xc6,
+0xc2,
+0xc0,
+0x70,
+0x3c,
+0x0e,
+0x06,
+0x06,
+0x86,
+0xc6,
+0xbc,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xff,
+0x99,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xf7,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xf7,
+0x62,
+0x62,
+0x62,
+0x76,
+0x34,
+0x34,
+0x34,
+0x3c,
+0x18,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xf7,
+0x62,
+0x62,
+0x62,
+0x62,
+0x6a,
+0x6a,
+0x6a,
+0x6a,
+0x7e,
+0x7e,
+0x34,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xf7,
+0x62,
+0x62,
+0x34,
+0x34,
+0x18,
+0x18,
+0x2c,
+0x2c,
+0x46,
+0x46,
+0xef,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xf7,
+0x62,
+0x62,
+0x62,
+0x34,
+0x34,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x7f,
+0x46,
+0x86,
+0x0c,
+0x0c,
+0x18,
+0x18,
+0x30,
+0x30,
+0x61,
+0x62,
+0xfe,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3c,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xc0,
+0xc0,
+0x60,
+0x60,
+0x30,
+0x30,
+0x18,
+0x18,
+0x0c,
+0x0c,
+0x06,
+0x06,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x10,
+0x38,
+0x4c,
+0x86,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+
+0x00,
+0x18,
+0x20,
+0x30,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x78,
+0x8c,
+0x0c,
+0x3c,
+0xcc,
+0xcc,
+0xcd,
+0x76,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x20,
+0xe0,
+0x60,
+0x60,
+0x6c,
+0x76,
+0x66,
+0x66,
+0x66,
+0x66,
+0x76,
+0x6c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x3c,
+0x66,
+0x60,
+0x60,
+0x60,
+0x60,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x04,
+0x1c,
+0x0c,
+0x0c,
+0x6c,
+0xdc,
+0xcc,
+0xcc,
+0xcc,
+0xcc,
+0xdc,
+0x66,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x3c,
+0x66,
+0x7e,
+0x60,
+0x60,
+0x60,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x1e,
+0x31,
+0x33,
+0x30,
+0x30,
+0x78,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x78,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7b,
+0xce,
+0xcc,
+0xcc,
+0xcc,
+0x78,
+0x60,
+0x7c,
+0x86,
+0xc6,
+0x7c,
+
+0x00,
+0x20,
+0xe0,
+0x60,
+0x60,
+0x6c,
+0x76,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xf7,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x10,
+0x38,
+0x10,
+0x00,
+0x18,
+0x38,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x08,
+0x1c,
+0x08,
+0x00,
+0x0c,
+0x1c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x6c,
+0x4c,
+0x38,
+0x00,
+
+0x00,
+0x20,
+0xe0,
+0x60,
+0x60,
+0x67,
+0x66,
+0x6c,
+0x78,
+0x6c,
+0x6c,
+0x66,
+0xe7,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x08,
+0x38,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x6a,
+0xfe,
+0x6a,
+0x6a,
+0x6a,
+0x62,
+0x62,
+0xf7,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x5c,
+0xf6,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xf7,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x3c,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x5c,
+0xe6,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x7c,
+0x60,
+0x60,
+0xf0,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x76,
+0xcc,
+0xcc,
+0xcc,
+0xcc,
+0xcc,
+0xcc,
+0x7c,
+0x0c,
+0x0c,
+0x1e,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x5e,
+0xf6,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0xf0,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7a,
+0xc6,
+0x72,
+0x1c,
+0x06,
+0x86,
+0xc6,
+0xbc,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x10,
+0x30,
+0x7c,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x34,
+0x18,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xee,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x67,
+0x3a,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xf7,
+0x62,
+0x76,
+0x34,
+0x34,
+0x3c,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xf7,
+0x62,
+0x6a,
+0x6a,
+0x6a,
+0x6a,
+0x7e,
+0x24,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xf7,
+0x62,
+0x34,
+0x18,
+0x2c,
+0x46,
+0x46,
+0xef,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xf7,
+0x62,
+0x62,
+0x34,
+0x34,
+0x18,
+0x18,
+0x18,
+0x10,
+0xb0,
+0xe0,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xfe,
+0x8c,
+0x18,
+0x30,
+0x30,
+0x60,
+0xc2,
+0xfe,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x0e,
+0x18,
+0x10,
+0x10,
+0x08,
+0x70,
+0x70,
+0x08,
+0x10,
+0x10,
+0x18,
+0x0e,
+0x00,
+0x00,
+0x00,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x00,
+0x00,
+
+0x00,
+0x70,
+0x18,
+0x08,
+0x08,
+0x10,
+0x0e,
+0x0e,
+0x10,
+0x08,
+0x08,
+0x18,
+0x70,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x76,
+0xdc,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x6c,
+0xc6,
+0xc6,
+0xc6,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x3a,
+0x66,
+0xc2,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0x62,
+0x3c,
+0x18,
+0x0c,
+0x24,
+0x18,
+
+0x00,
+0x00,
+0x66,
+0x00,
+0x00,
+0xee,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3b,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x0c,
+0x18,
+0x20,
+0x00,
+0x3c,
+0x66,
+0x7e,
+0x60,
+0x60,
+0x60,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x30,
+0x58,
+0x8c,
+0x00,
+0x78,
+0x8c,
+0x0c,
+0x3c,
+0xcc,
+0xcc,
+0xcd,
+0x76,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x66,
+0x00,
+0x00,
+0x78,
+0x8c,
+0x0c,
+0x3c,
+0xcc,
+0xcc,
+0xcd,
+0x76,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x30,
+0x18,
+0x04,
+0x00,
+0x78,
+0x8c,
+0x0c,
+0x3c,
+0xcc,
+0xcc,
+0xcd,
+0x76,
+0x00,
+0x00,
+0x00,
+
+0x38,
+0x44,
+0x44,
+0x38,
+0x00,
+0x78,
+0x8c,
+0x0c,
+0x3c,
+0xcc,
+0xcc,
+0xcd,
+0x76,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x3c,
+0x66,
+0x60,
+0x60,
+0x60,
+0x60,
+0x62,
+0x3c,
+0x08,
+0x24,
+0x18,
+
+0x00,
+0x18,
+0x2c,
+0x46,
+0x00,
+0x3c,
+0x66,
+0x7e,
+0x60,
+0x60,
+0x60,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x66,
+0x00,
+0x00,
+0x3c,
+0x66,
+0x7e,
+0x60,
+0x60,
+0x60,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x30,
+0x18,
+0x04,
+0x00,
+0x3c,
+0x66,
+0x7e,
+0x60,
+0x60,
+0x60,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x66,
+0x00,
+0x00,
+0x38,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x18,
+0x2c,
+0x46,
+0x00,
+0x38,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x60,
+0x30,
+0x08,
+0x00,
+0x38,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x66,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x2c,
+0x2c,
+0x2c,
+0x7e,
+0x46,
+0x46,
+0x46,
+0xef,
+0x00,
+0x00,
+0x00,
+
+0x18,
+0x24,
+0x18,
+0x18,
+0x3c,
+0x2c,
+0x2c,
+0x2c,
+0x7e,
+0x46,
+0x46,
+0x46,
+0xef,
+0x00,
+0x00,
+0x00,
+
+0x0c,
+0x18,
+0xff,
+0x61,
+0x60,
+0x60,
+0x64,
+0x7c,
+0x64,
+0x60,
+0x60,
+0x61,
+0xfe,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x76,
+0x9b,
+0x1b,
+0x3f,
+0xd8,
+0xd8,
+0xd9,
+0x6e,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x1f,
+0x1d,
+0x1d,
+0x3c,
+0x2c,
+0x2e,
+0x2c,
+0x7c,
+0x4c,
+0x4c,
+0x4d,
+0xef,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x18,
+0x2c,
+0x46,
+0x00,
+0x3c,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x66,
+0x00,
+0x00,
+0x3c,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x30,
+0x18,
+0x04,
+0x00,
+0x3c,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x18,
+0x2c,
+0x46,
+0x00,
+0xee,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x67,
+0x3a,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x30,
+0x18,
+0x04,
+0x00,
+0xee,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x67,
+0x3a,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x66,
+0x00,
+0x00,
+0xf7,
+0x62,
+0x62,
+0x34,
+0x34,
+0x18,
+0x18,
+0x18,
+0x10,
+0xb0,
+0xe0,
+
+0x66,
+0x00,
+0x3c,
+0x66,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x66,
+0x00,
+0xf7,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x10,
+0x10,
+0x10,
+0x7c,
+0xc6,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0xc2,
+0x7c,
+0x10,
+0x10,
+0x00,
+
+0x00,
+0x38,
+0x64,
+0x6c,
+0x60,
+0x60,
+0xf0,
+0x60,
+0x60,
+0x60,
+0x60,
+0x66,
+0xfc,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x81,
+0xc3,
+0x66,
+0x3c,
+0x18,
+0xff,
+0x18,
+0x18,
+0xff,
+0x18,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xfe,
+0x63,
+0x63,
+0x63,
+0x63,
+0x6e,
+0x60,
+0x64,
+0x6e,
+0x64,
+0x64,
+0xf5,
+0x06,
+0x00,
+0x00,
+
+0x00,
+0x0e,
+0x19,
+0x1b,
+0x18,
+0x18,
+0x3c,
+0x18,
+0x18,
+0x18,
+0x18,
+0xd8,
+0x98,
+0x70,
+0x00,
+0x00,
+
+0x00,
+0x0c,
+0x18,
+0x20,
+0x00,
+0x78,
+0x8c,
+0x0c,
+0x3c,
+0xcc,
+0xcc,
+0xcd,
+0x76,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x06,
+0x0c,
+0x10,
+0x00,
+0x38,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x0c,
+0x18,
+0x20,
+0x00,
+0x3c,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x0c,
+0x18,
+0x20,
+0x00,
+0xee,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x67,
+0x3a,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x32,
+0x4c,
+0x00,
+0x5c,
+0xf6,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xf7,
+0x00,
+0x00,
+0x00,
+
+0x32,
+0x4c,
+0x00,
+0xe7,
+0x72,
+0x52,
+0x5a,
+0x4a,
+0x4e,
+0x46,
+0x46,
+0x42,
+0xe2,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x78,
+0x8c,
+0x0c,
+0x3c,
+0xcc,
+0xcc,
+0xcd,
+0x76,
+0x00,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3c,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x00,
+0x7e,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x30,
+0x30,
+0x00,
+0x30,
+0x10,
+0x10,
+0x20,
+0x40,
+0xc0,
+0xc6,
+0xc2,
+0x7c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xfe,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xfe,
+0x06,
+0x06,
+0x06,
+0x06,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x20,
+0xe0,
+0x63,
+0x66,
+0xfc,
+0x18,
+0x30,
+0x60,
+0xce,
+0x93,
+0x06,
+0x0c,
+0x1f,
+0x00,
+0x00,
+
+0x00,
+0x20,
+0xe0,
+0x63,
+0x66,
+0xfc,
+0x18,
+0x30,
+0x64,
+0xc8,
+0x96,
+0x3f,
+0x06,
+0x06,
+0x00,
+0x00,
+
+0x00,
+0x18,
+0x18,
+0x00,
+0x08,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x3c,
+0x3c,
+0x3c,
+0x18,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x36,
+0x6c,
+0xd8,
+0xd8,
+0x6c,
+0x36,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xd8,
+0x6c,
+0x36,
+0x36,
+0x6c,
+0xd8,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x82,
+0x10,
+0x82,
+0x10,
+0x82,
+0x10,
+0x82,
+0x10,
+0x82,
+0x10,
+0x82,
+0x10,
+0x82,
+0x10,
+0x82,
+0x10,
+
+0x00,
+0x95,
+0x00,
+0xa9,
+0x00,
+0x95,
+0x00,
+0xa9,
+0x00,
+0x95,
+0x00,
+0xa9,
+0x00,
+0x95,
+0x00,
+0xa9,
+
+0x92,
+0x49,
+0x92,
+0x49,
+0x92,
+0x49,
+0x92,
+0x49,
+0x92,
+0x49,
+0x92,
+0x49,
+0x92,
+0x49,
+0x92,
+0x49,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xf8,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xf8,
+0x18,
+0x18,
+0xf8,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xe6,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xfe,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xf8,
+0x18,
+0x18,
+0xf8,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xe6,
+0x06,
+0x06,
+0xe6,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xfe,
+0x06,
+0x06,
+0xe6,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xe6,
+0x06,
+0x06,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xf8,
+0x18,
+0x18,
+0xf8,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xf8,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x1f,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xff,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x1f,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xff,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x1f,
+0x18,
+0x18,
+0x1f,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x67,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x67,
+0x60,
+0x60,
+0x7f,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7f,
+0x60,
+0x60,
+0x67,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xe7,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+0xe7,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x67,
+0x60,
+0x60,
+0x67,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xe7,
+0x00,
+0x00,
+0xe7,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xff,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xff,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+0xff,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x7f,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x1f,
+0x18,
+0x18,
+0x1f,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x1f,
+0x18,
+0x18,
+0x1f,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7f,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xff,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xff,
+0x00,
+0x00,
+0xff,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xf8,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x1f,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x77,
+0xcc,
+0xcc,
+0xcc,
+0xcc,
+0xde,
+0x73,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x7c,
+0xc6,
+0xc6,
+0xc6,
+0xc4,
+0xc8,
+0xc4,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xdc,
+0xc0,
+0xc0,
+0x00,
+
+0x00,
+0xff,
+0x61,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0xf0,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x01,
+0x7e,
+0xa4,
+0x24,
+0x2c,
+0x6c,
+0x6c,
+0x6c,
+0x48,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xff,
+0xc1,
+0x60,
+0x30,
+0x18,
+0x0c,
+0x18,
+0x30,
+0x60,
+0xc0,
+0xc1,
+0xfe,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7f,
+0xc8,
+0xc8,
+0xc8,
+0xc8,
+0xc8,
+0xc8,
+0x70,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x22,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x7c,
+0x60,
+0x60,
+0x60,
+0xc0,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x76,
+0xdc,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x10,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x38,
+0x10,
+0x7c,
+0xd6,
+0xd6,
+0xd6,
+0xd6,
+0xd6,
+0xd6,
+0x7c,
+0x10,
+0x38,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x38,
+0x6c,
+0xc6,
+0xc6,
+0xc6,
+0xfe,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0x6c,
+0x38,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3c,
+0x66,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0x66,
+0x24,
+0x24,
+0xa5,
+0xe7,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x1e,
+0x31,
+0x30,
+0x18,
+0x0c,
+0x3e,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x6e,
+0xff,
+0x99,
+0x99,
+0x99,
+0x99,
+0xff,
+0x76,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x02,
+0x04,
+0x7c,
+0xca,
+0x92,
+0xa6,
+0x7c,
+0x40,
+0x80,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x1c,
+0x30,
+0x60,
+0x60,
+0x60,
+0x7c,
+0x60,
+0x60,
+0x60,
+0x60,
+0x30,
+0x1c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x7c,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x7c,
+0x00,
+0x00,
+0x00,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x18,
+0x18,
+0x7e,
+0x18,
+0x18,
+0x00,
+0x00,
+0x7e,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x30,
+0x18,
+0x0c,
+0x06,
+0x0c,
+0x18,
+0x30,
+0x00,
+0x7e,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x0c,
+0x18,
+0x30,
+0x60,
+0x30,
+0x18,
+0x0c,
+0x00,
+0x7e,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x0e,
+0x19,
+0x1b,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xd8,
+0x98,
+0x70,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x18,
+0x18,
+0x00,
+0x7e,
+0x00,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x76,
+0xdc,
+0x00,
+0x00,
+0x76,
+0xdc,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x38,
+0x44,
+0x44,
+0x44,
+0x38,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x18,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x07,
+0x06,
+0x06,
+0x0c,
+0x0c,
+0x08,
+0x98,
+0xd0,
+0xf0,
+0x60,
+0x20,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xcc,
+0x76,
+0x66,
+0x66,
+0x66,
+0x66,
+0xf7,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x70,
+0x98,
+0x18,
+0x30,
+0x60,
+0x88,
+0xf8,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7c,
+0x64,
+0x64,
+0x64,
+0x64,
+0x64,
+0x7c,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+};
+
+
+const struct font_desc font_rl = {
+	RL_IDX,
+	"RomanLarge",
+	8,
+	16,
+	patterns,
+	-1
+};
diff --git a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c
index 4fd07d9..9be83be 100644
--- a/drivers/video/console/fonts.c
+++ b/drivers/video/console/fonts.c
@@ -64,6 +64,10 @@
 #undef NO_FONTS
     &font_mini_4x6,
 #endif
+#ifdef CONFIG_FONT_RL
+#undef NO_FONTS
+    &font_rl,
+#endif
 };
 
 #define num_fonts (sizeof(fonts)/sizeof(*fonts))
diff --git a/drivers/video/softcursor.c b/drivers/video/console/softcursor.c
similarity index 96%
rename from drivers/video/softcursor.c
rename to drivers/video/console/softcursor.c
index 229c4bc..8529bf0 100644
--- a/drivers/video/softcursor.c
+++ b/drivers/video/console/softcursor.c
@@ -1,7 +1,7 @@
 /*
  * linux/drivers/video/softcursor.c -- Generic software cursor for frame buffer devices
  *
- *  Created 14 Nov 2002 by James Simmons 
+ *  Created 14 Nov 2002 by James Simmons
  *
  * 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
@@ -55,9 +55,9 @@
 				src[i] = image->data[i] & cursor->mask[i];
 			break;
 		}
-	} else 
+	} else
 		memcpy(src, image->data, dsize);
-	
+
 	fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height);
 	image->data = dst;
 	info->fbops->fb_imageblit(info, image);
@@ -66,7 +66,7 @@
 }
 
 EXPORT_SYMBOL(soft_cursor);
- 
+
 MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
 MODULE_DESCRIPTION("Generic software cursor");
 MODULE_LICENSE("GPL");
diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c
index 989e700..403d173 100644
--- a/drivers/video/controlfb.c
+++ b/drivers/video/controlfb.c
@@ -176,7 +176,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index 3894b2a..c589d23 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -1064,7 +1064,6 @@
 	.fb_fillrect	= cyber2000fb_fillrect,
 	.fb_copyarea	= cyber2000fb_copyarea,
 	.fb_imageblit	= cyber2000fb_imageblit,
-	.fb_cursor	= soft_cursor,
 	.fb_sync	= cyber2000fb_sync,
 };
 
diff --git a/drivers/video/cyblafb.c b/drivers/video/cyblafb.c
index 6992100..03fbe83 100644
--- a/drivers/video/cyblafb.c
+++ b/drivers/video/cyblafb.c
@@ -968,7 +968,6 @@
 	.fb_fillrect = cyblafb_fillrect,
 	.fb_copyarea= cyblafb_copyarea,
 	.fb_imageblit = cyblafb_imageblit,
-	.fb_cursor = soft_cursor,
 };
 
 //==========================================================================
diff --git a/drivers/video/dnfb.c b/drivers/video/dnfb.c
index 1785686..957a3ad 100644
--- a/drivers/video/dnfb.c
+++ b/drivers/video/dnfb.c
@@ -116,7 +116,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= dnfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 struct fb_var_screeninfo dnfb_var __devinitdata = {
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
index 7363d0b..6a81a1d 100644
--- a/drivers/video/epson1355fb.c
+++ b/drivers/video/epson1355fb.c
@@ -484,7 +484,6 @@
 	.fb_imageblit 	= cfb_imageblit,
 	.fb_read 	= epson1355fb_read,
 	.fb_write 	= epson1355fb_write,
-	.fb_cursor 	= soft_cursor,
 };
 
 /* ------------------------------------------------------------------------- */
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 713226c..fc7965b 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -538,25 +538,12 @@
 
 	*dbsize = 0;
 
-	DPRINTK("   Supported VESA Modes\n");
-	block = edid + ESTABLISHED_TIMING_1;
-	num += get_est_timing(block, &mode[num]);
-
-	DPRINTK("   Standard Timings\n");
-	block = edid + STD_TIMING_DESCRIPTIONS_START;
-	for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE) 
-		num += get_std_timing(block, &mode[num]);
-
 	DPRINTK("   Detailed Timings\n");
 	block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
 	for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
 	        int first = 1;
 
-		if (block[0] == 0x00 && block[1] == 0x00) {
-			if (block[3] == 0xfa) {
-				num += get_dst_timing(block + 5, &mode[num]);
-			}
-		} else  {
+		if (!(block[0] == 0x00 && block[1] == 0x00)) {
 			get_detailed_timing(block, &mode[num]);
 			if (first) {
 			        mode[num].flag |= FB_MODE_IS_FIRST;
@@ -565,6 +552,21 @@
 			num++;
 		}
 	}
+
+	DPRINTK("   Supported VESA Modes\n");
+	block = edid + ESTABLISHED_TIMING_1;
+	num += get_est_timing(block, &mode[num]);
+
+	DPRINTK("   Standard Timings\n");
+	block = edid + STD_TIMING_DESCRIPTIONS_START;
+	for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE)
+		num += get_std_timing(block, &mode[num]);
+
+	block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
+	for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
+		if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa)
+			num += get_dst_timing(block + 5, &mode[num]);
+	}
 	
 	/* Yikes, EDID data is totally useless */
 	if (!num) {
@@ -827,7 +829,7 @@
 void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
 {
 	unsigned char *block;
-	int i;
+	int i, found = 0;
 
 	if (edid == NULL)
 		return;
@@ -869,6 +871,22 @@
 	get_monspecs(edid, specs);
 
 	specs->modedb = fb_create_modedb(edid, &specs->modedb_len);
+
+	/*
+	 * Workaround for buggy EDIDs that sets that the first
+	 * detailed timing is preferred but has not detailed
+	 * timing specified
+	 */
+	for (i = 0; i < specs->modedb_len; i++) {
+		if (specs->modedb[i].flag & FB_MODE_IS_DETAILED) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (!found)
+		specs->misc &= ~FB_MISC_1ST_DETAIL;
+
 	DPRINTK("========================================\n");
 }
 
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 10cd050..04417dc 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -57,9 +57,6 @@
 	.fb_sync		= ffb_sync,
 	.fb_mmap		= ffb_mmap,
 	.fb_ioctl		= ffb_ioctl,
-
-	/* XXX Use FFB hw cursor once fb cursor API is better understood... */
-	.fb_cursor		= soft_cursor,
 };
 
 /* Register layout and definitions */
diff --git a/drivers/video/fm2fb.c b/drivers/video/fm2fb.c
index a076328..998374c 100644
--- a/drivers/video/fm2fb.c
+++ b/drivers/video/fm2fb.c
@@ -172,7 +172,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
     /*
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
index ed853be..9d5e4f3 100644
--- a/drivers/video/gbefb.c
+++ b/drivers/video/gbefb.c
@@ -1038,7 +1038,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 /*
diff --git a/drivers/video/geode/Kconfig b/drivers/video/geode/Kconfig
index 5a9b89c..42fb9a8 100644
--- a/drivers/video/geode/Kconfig
+++ b/drivers/video/geode/Kconfig
@@ -14,7 +14,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_SOFT_CURSOR
 	---help---
 	  Framebuffer driver for the display controller integrated into the
 	  AMD Geode GX1 processor.
diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/geode/gx1fb_core.c
index 74a5fca..8e8da74 100644
--- a/drivers/video/geode/gx1fb_core.c
+++ b/drivers/video/geode/gx1fb_core.c
@@ -275,7 +275,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 static struct fb_info * __init gx1fb_init_fbinfo(struct device *dev)
diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c
index 0d376ba..f04ca72 100644
--- a/drivers/video/hitfb.c
+++ b/drivers/video/hitfb.c
@@ -262,7 +262,6 @@
 	.fb_fillrect	= hitfb_fillrect,
 	.fb_copyarea	= hitfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 int __init hitfb_init(void)
diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c
index e97fe84..bebdac5 100644
--- a/drivers/video/hpfb.c
+++ b/drivers/video/hpfb.c
@@ -193,7 +193,6 @@
 	.fb_fillrect	= hpfb_fillrect,
 	.fb_copyarea	= hpfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 	.fb_sync	= hpfb_sync,
 };
 
diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c
index 689d258..c61bad0 100644
--- a/drivers/video/i810/i810-i2c.c
+++ b/drivers/video/i810/i810-i2c.c
@@ -46,92 +46,45 @@
         struct i810fb_par         *par = chan->par;
 	u8                        __iomem *mmio = par->mmio_start_virtual;
 
-	i810_writel(mmio, GPIOB, (state ? SCL_VAL_OUT : 0) | SCL_DIR |
+	i810_writel(mmio, chan->ddc_base, (state ? SCL_VAL_OUT : 0) | SCL_DIR |
 		    SCL_DIR_MASK | SCL_VAL_MASK);
-	i810_readl(mmio, GPIOB);	/* flush posted write */
+	i810_readl(mmio, chan->ddc_base);	/* flush posted write */
 }
 
 static void i810i2c_setsda(void *data, int state)
 {
-        struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
+        struct i810fb_i2c_chan    *chan = data;
         struct i810fb_par         *par = chan->par;
 	u8                        __iomem *mmio = par->mmio_start_virtual;
 
- 	i810_writel(mmio, GPIOB, (state ? SDA_VAL_OUT : 0) | SDA_DIR |
+ 	i810_writel(mmio, chan->ddc_base, (state ? SDA_VAL_OUT : 0) | SDA_DIR |
 		    SDA_DIR_MASK | SDA_VAL_MASK);
-	i810_readl(mmio, GPIOB);	/* flush posted write */
+	i810_readl(mmio, chan->ddc_base);	/* flush posted write */
 }
 
 static int i810i2c_getscl(void *data)
 {
-        struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
+        struct i810fb_i2c_chan    *chan = data;
         struct i810fb_par         *par = chan->par;
 	u8                        __iomem *mmio = par->mmio_start_virtual;
 
-	i810_writel(mmio, GPIOB, SCL_DIR_MASK);
-	i810_writel(mmio, GPIOB, 0);
-	return (0 != (i810_readl(mmio, GPIOB) & SCL_VAL_IN));
+	i810_writel(mmio, chan->ddc_base, SCL_DIR_MASK);
+	i810_writel(mmio, chan->ddc_base, 0);
+	return ((i810_readl(mmio, chan->ddc_base) & SCL_VAL_IN) != 0);
 }
 
 static int i810i2c_getsda(void *data)
 {
-        struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
+        struct i810fb_i2c_chan    *chan = data;
         struct i810fb_par         *par = chan->par;
 	u8                        __iomem *mmio = par->mmio_start_virtual;
 
-	i810_writel(mmio, GPIOB, SDA_DIR_MASK);
-	i810_writel(mmio, GPIOB, 0);
-	return (0 != (i810_readl(mmio, GPIOB) & SDA_VAL_IN));
+	i810_writel(mmio, chan->ddc_base, SDA_DIR_MASK);
+	i810_writel(mmio, chan->ddc_base, 0);
+	return ((i810_readl(mmio, chan->ddc_base) & SDA_VAL_IN) != 0);
 }
 
-static void i810ddc_setscl(void *data, int state)
-{
-        struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
-        struct i810fb_par       *par = chan->par;
-	u8                      __iomem *mmio = par->mmio_start_virtual;
-
-	i810_writel(mmio, GPIOA, (state ? SCL_VAL_OUT : 0) | SCL_DIR |
-		    SCL_DIR_MASK | SCL_VAL_MASK);
-	i810_readl(mmio, GPIOA);	/* flush posted write */
-}
-
-static void i810ddc_setsda(void *data, int state)
-{
-        struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
-        struct i810fb_par         *par = chan->par;
-	u8                      __iomem *mmio = par->mmio_start_virtual;
-
- 	i810_writel(mmio, GPIOA, (state ? SDA_VAL_OUT : 0) | SDA_DIR |
-		    SDA_DIR_MASK | SDA_VAL_MASK);
-	i810_readl(mmio, GPIOA);	/* flush posted write */
-}
-
-static int i810ddc_getscl(void *data)
-{
-        struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
-        struct i810fb_par         *par = chan->par;
-	u8                      __iomem *mmio = par->mmio_start_virtual;
-
-	i810_writel(mmio, GPIOA, SCL_DIR_MASK);
-	i810_writel(mmio, GPIOA, 0);
-	return (0 != (i810_readl(mmio, GPIOA) & SCL_VAL_IN));
-}
-
-static int i810ddc_getsda(void *data)
-{
-        struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
-        struct i810fb_par         *par = chan->par;
-	u8                      __iomem *mmio = par->mmio_start_virtual;
-
-	i810_writel(mmio, GPIOA, SDA_DIR_MASK);
-	i810_writel(mmio, GPIOA, 0);
-	return (0 != (i810_readl(mmio, GPIOA) & SDA_VAL_IN));
-}
-
-#define I2C_ALGO_DDC_I810   0x0e0000
-#define I2C_ALGO_I2C_I810   0x0f0000
-static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name,
-			      int conn)
+static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name)
 {
         int rc;
 
@@ -139,22 +92,11 @@
         chan->adapter.owner             = THIS_MODULE;
         chan->adapter.algo_data         = &chan->algo;
         chan->adapter.dev.parent        = &chan->par->dev->dev;
-	switch (conn) {
-	case 1:
-		chan->adapter.id                = I2C_ALGO_DDC_I810;
-		chan->algo.setsda               = i810ddc_setsda;
-		chan->algo.setscl               = i810ddc_setscl;
-		chan->algo.getsda               = i810ddc_getsda;
-		chan->algo.getscl               = i810ddc_getscl;
-		break;
-	case 2:
-		chan->adapter.id                = I2C_ALGO_I2C_I810;
-		chan->algo.setsda               = i810i2c_setsda;
-		chan->algo.setscl               = i810i2c_setscl;
-		chan->algo.getsda               = i810i2c_getsda;
-		chan->algo.getscl               = i810i2c_getscl;
-		break;
-	}
+	chan->adapter.id                = I2C_HW_B_I810;
+	chan->algo.setsda               = i810i2c_setsda;
+	chan->algo.setscl               = i810i2c_setscl;
+	chan->algo.getsda               = i810i2c_getsda;
+	chan->algo.getscl               = i810i2c_getscl;
 	chan->algo.udelay               = 10;
 	chan->algo.mdelay               = 10;
         chan->algo.timeout              = (HZ/2);
@@ -168,11 +110,15 @@
         udelay(20);
 
         rc = i2c_bit_add_bus(&chan->adapter);
+
         if (rc == 0)
                 dev_dbg(&chan->par->dev->dev, "I2C bus %s registered.\n",name);
-        else
+        else {
                 dev_warn(&chan->par->dev->dev, "Failed to register I2C bus "
 			 "%s.\n", name);
+		chan->par = NULL;
+	}
+
         return rc;
 }
 
@@ -180,8 +126,14 @@
 {
         par->chan[0].par        = par;
 	par->chan[1].par        = par;
-	i810_setup_i2c_bus(&par->chan[0], "I810-DDC", 1);
-	i810_setup_i2c_bus(&par->chan[1], "I810-I2C", 2);
+	par->chan[2].par        = par;
+
+	par->chan[0].ddc_base = GPIOA;
+	i810_setup_i2c_bus(&par->chan[0], "I810-DDC");
+	par->chan[1].ddc_base = GPIOB;
+	i810_setup_i2c_bus(&par->chan[1], "I810-I2C");
+	par->chan[2].ddc_base = GPIOC;
+	i810_setup_i2c_bus(&par->chan[2], "I810-GPIOC");
 }
 
 void i810_delete_i2c_busses(struct i810fb_par *par)
@@ -189,9 +141,14 @@
         if (par->chan[0].par)
                 i2c_bit_del_bus(&par->chan[0].adapter);
         par->chan[0].par = NULL;
+
 	if (par->chan[1].par)
 		i2c_bit_del_bus(&par->chan[1].adapter);
 	par->chan[1].par = NULL;
+
+	if (par->chan[2].par)
+		i2c_bit_del_bus(&par->chan[2].adapter);
+	par->chan[2].par = NULL;
 }
 
 static u8 *i810_do_probe_i2c_edid(struct i810fb_i2c_chan *chan)
@@ -221,6 +178,7 @@
 		DPRINTK("i810-i2c: I2C Transfer successful\n");
                 return buf;
 	}
+
         DPRINTK("i810-i2c: Unable to read EDID block.\n");
         kfree(buf);
         return NULL;
@@ -233,7 +191,7 @@
         int i;
 
 	DPRINTK("i810-i2c: Probe DDC%i Bus\n", conn);
-	if (conn < 3) {
+	if (conn < 4) {
 		for (i = 0; i < 3; i++) {
 			/* Do the real work */
 			edid = i810_do_probe_i2c_edid(&par->chan[conn-1]);
@@ -241,11 +199,14 @@
 				break;
 		}
 	} else {
-		DPRINTK("i810-i2c: Getting EDID from BIOS\n");
-		edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
-		if (edid)
-			memcpy(edid, fb_firmware_edid(info->device),
-			       EDID_LENGTH);
+		const u8 *e = fb_firmware_edid(info->device);
+
+		if (e != NULL) {
+			DPRINTK("i810-i2c: Getting EDID from BIOS\n");
+			edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
+			if (edid)
+				memcpy(edid, e, EDID_LENGTH);
+		}
 	}
 
         if (out_edid)
@@ -253,5 +214,3 @@
 
         return (edid) ? 0 : 1;
 }
-
-
diff --git a/drivers/video/i810/i810.h b/drivers/video/i810/i810.h
index d48949c..6c187d5 100644
--- a/drivers/video/i810/i810.h
+++ b/drivers/video/i810/i810.h
@@ -249,6 +249,7 @@
 	struct i810fb_par *par;
 	struct i2c_adapter adapter;
 	struct i2c_algo_bit_data algo;
+	unsigned long ddc_base;
 };
 
 struct i810fb_par {
@@ -262,7 +263,7 @@
 	struct heap_data         iring;
 	struct heap_data         cursor_heap;
 	struct vgastate          state;
-	struct i810fb_i2c_chan   chan[2];
+	struct i810fb_i2c_chan   chan[3];
 	atomic_t                 use_count;
 	u32 pseudo_palette[17];
 	unsigned long mmio_start_phys;
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index 0dbc9dd..c0c974b 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -1854,7 +1854,7 @@
 #ifdef CONFIG_FB_I810_I2C
 	i810_create_i2c_busses(par);
 
-	for (i = 0; i < 3; i++) {
+	for (i = 0; i < 4; i++) {
 		err = i810_probe_i2c_connector(info, &par->edid, i+1);
 		if (!err)
 			break;
@@ -1871,27 +1871,18 @@
 	fb_videomode_to_modelist(specs->modedb, specs->modedb_len,
 				 &info->modelist);
 	if (specs->modedb != NULL) {
-		if (xres && yres) {
-			struct fb_videomode *m;
+		struct fb_videomode *m;
 
+		if (xres && yres) {
 			if ((m = fb_find_best_mode(&var, &info->modelist))) {
 				mode = *m;
 				found  = 1;
 			}
 		}
 
-		if (!found && specs->misc & FB_MISC_1ST_DETAIL) {
-			for (i = 0; i < specs->modedb_len; i++) {
-				if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
-					mode = specs->modedb[i];
-					found = 1;
-					break;
-				}
-			}
-		}
-
 		if (!found) {
-			mode = specs->modedb[0];
+			m = fb_find_best_display(&info->monspecs, &info->modelist);
+			mode = *m;
 			found = 1;
 		}
 
@@ -2066,8 +2057,7 @@
 		iounmap(par->mmio_start_virtual);
 	if (par->aperture.virtual)
 		iounmap(par->aperture.virtual);
-	if (par->edid)
-		kfree(par->edid);
+	kfree(par->edid);
 	if (par->res_flags & FRAMEBUFFER_REQ)
 		release_mem_region(par->aperture.physical,
 				   par->aperture.size);
diff --git a/drivers/video/i810/i810_regs.h b/drivers/video/i810/i810_regs.h
index 6e4b9af..91c6bd9 100644
--- a/drivers/video/i810/i810_regs.h
+++ b/drivers/video/i810/i810_regs.h
@@ -70,6 +70,7 @@
 #define HVSYNC                0x05000 
 #define GPIOA                 0x05010
 #define GPIOB                 0x05014 
+#define GPIOC                 0x0501C
 
 /* Clock Control and Power Management Registers (06000h 06FFFh) */
 #define DCLK_0D               0x06000
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
index 7b9bf45..7fbe242 100644
--- a/drivers/video/imsttfb.c
+++ b/drivers/video/imsttfb.c
@@ -1344,7 +1344,6 @@
 	.fb_fillrect	= imsttfb_fillrect,
 	.fb_copyarea	= imsttfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 	.fb_ioctl 	= imsttfb_ioctl,
 };
 
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 64d9bcc..e20b9f3 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -298,7 +298,6 @@
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
 	.fb_blank	= imxfb_blank,
-	.fb_cursor	= soft_cursor, /* FIXME: i.MX can do hardware cursor */
 };
 
 /*
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h
index 011e116..f077ca3 100644
--- a/drivers/video/intelfb/intelfb.h
+++ b/drivers/video/intelfb/intelfb.h
@@ -10,7 +10,7 @@
 /*** Version/name ***/
 #define INTELFB_VERSION			"0.9.2"
 #define INTELFB_MODULE_NAME		"intelfb"
-#define SUPPORTED_CHIPSETS		"830M/845G/852GM/855GM/865G/915G"
+#define SUPPORTED_CHIPSETS		"830M/845G/852GM/855GM/865G/915G/915GM"
 
 
 /*** Debug/feature defines ***/
@@ -47,6 +47,7 @@
 #define PCI_DEVICE_ID_INTEL_85XGM	0x3582
 #define PCI_DEVICE_ID_INTEL_865G	0x2572
 #define PCI_DEVICE_ID_INTEL_915G	0x2582
+#define PCI_DEVICE_ID_INTEL_915GM	0x2592
 
 /* Size of MMIO region */
 #define INTEL_REG_SIZE			0x80000
@@ -119,7 +120,8 @@
 	INTEL_855GM,
 	INTEL_855GME,
 	INTEL_865G,
-	INTEL_915G
+	INTEL_915G,
+	INTEL_915GM
 };
 
 struct intelfb_hwstate {
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 80a0934..0799b99 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -1,7 +1,7 @@
 /*
  * intelfb
  *
- * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G
+ * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM
  * integrated graphics chips.
  *
  * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org>
@@ -186,6 +186,7 @@
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_85XGM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_85XGM },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_865G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_865G },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915G },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM },
 	{ 0, }
 };
 
@@ -549,10 +550,11 @@
 	}
 
 	/* Set base addresses. */
-	if (ent->device == PCI_DEVICE_ID_INTEL_915G) {
+	if ((ent->device == PCI_DEVICE_ID_INTEL_915G) ||
+			(ent->device == PCI_DEVICE_ID_INTEL_915GM)) {
 		aperture_bar = 2;
 		mmio_bar = 0;
-		/* Disable HW cursor on 915G (not implemented yet) */
+		/* Disable HW cursor on 915G/M (not implemented yet) */
 		hwcursor = 0;
 	}
 	dinfo->aperture.physical = pci_resource_start(pdev, aperture_bar);
@@ -1483,7 +1485,7 @@
 #endif
 
 	if (!dinfo->hwcursor)
-		return soft_cursor(info, cursor);
+		return -ENODEV;
 
 	intelfbhw_cursor_hide(dinfo);
 
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index 5bafc3c..ac94c2e 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -99,6 +99,11 @@
 		*chipset = INTEL_915G;
 		*mobile = 0;
 		return 0;
+	case PCI_DEVICE_ID_INTEL_915GM:
+		*name = "Intel(R) 915GM";
+		*chipset = INTEL_915GM;
+		*mobile = 1;
+		return 0;
 	default:
 		return 1;
 	}
diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/kyro/fbdev.c
index d8bac9e..5eb4d5c 100644
--- a/drivers/video/kyro/fbdev.c
+++ b/drivers/video/kyro/fbdev.c
@@ -669,7 +669,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 static int __devinit kyrofb_probe(struct pci_dev *pdev,
diff --git a/drivers/video/leo.c b/drivers/video/leo.c
index 7e1e7fb..84a7fe4 100644
--- a/drivers/video/leo.c
+++ b/drivers/video/leo.c
@@ -51,7 +51,6 @@
 	.fb_imageblit		= cfb_imageblit,
 	.fb_mmap		= leo_mmap,
 	.fb_ioctl		= leo_ioctl,
-	.fb_cursor		= soft_cursor,
 };
 
 #define LEO_OFF_LC_SS0_KRN	0x00200000UL
diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig
index 3e9ccf3..8cb7fb4 100644
--- a/drivers/video/logo/Kconfig
+++ b/drivers/video/logo/Kconfig
@@ -7,6 +7,8 @@
 config LOGO
 	bool "Bootup logo"
 	depends on FB || SGI_NEWPORT_CONSOLE
+	help
+	  Enable and select frame buffer bootup logos.
 
 config LOGO_LINUX_MONO
 	bool "Standard black and white Linux logo"
diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c
index 4945a4c..cfc748e 100644
--- a/drivers/video/macfb.c
+++ b/drivers/video/macfb.c
@@ -589,7 +589,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 void __init macfb_setup(char *options)
diff --git a/drivers/video/matrox/matroxfb_DAC1064.c b/drivers/video/matrox/matroxfb_DAC1064.c
index 149680f..0fbd9b5 100644
--- a/drivers/video/matrox/matroxfb_DAC1064.c
+++ b/drivers/video/matrox/matroxfb_DAC1064.c
@@ -657,7 +657,6 @@
 	/* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
 	ACCESS_FBINFO(capable.text) = 1;
 	ACCESS_FBINFO(capable.vxres) = vxres_mystique;
-	ACCESS_FBINFO(features.accel.has_cacheflush) = 1;
 
 	ACCESS_FBINFO(outputs[0]).output = &m1064;
 	ACCESS_FBINFO(outputs[0]).src = ACCESS_FBINFO(outputs[0]).default_src;
@@ -842,7 +841,6 @@
 	/* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
 	ACCESS_FBINFO(capable.text) = 1;
 	ACCESS_FBINFO(capable.vxres) = vxres_g100;
-	ACCESS_FBINFO(features.accel.has_cacheflush) = 1;
 	ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100
 			? ACCESS_FBINFO(devflags.sgram) : 1;
 
@@ -980,7 +978,7 @@
 				hw->MXoptionReg |= 0x40;	/* FIXME... */
 				pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
 			}
-			mga_setr(M_EXTVGA_INDEX, 0x06, 0x50);
+			mga_setr(M_EXTVGA_INDEX, 0x06, 0x00);
 		}
 	}
 	if (ACCESS_FBINFO(devflags.g450dac)) {
diff --git a/drivers/video/matrox/matroxfb_accel.c b/drivers/video/matrox/matroxfb_accel.c
index c7f3e13..a5c825d 100644
--- a/drivers/video/matrox/matroxfb_accel.c
+++ b/drivers/video/matrox/matroxfb_accel.c
@@ -122,7 +122,7 @@
 	ACCESS_FBINFO(fbops).fb_copyarea = cfb_copyarea;
 	ACCESS_FBINFO(fbops).fb_fillrect = cfb_fillrect;
 	ACCESS_FBINFO(fbops).fb_imageblit = cfb_imageblit;
-	ACCESS_FBINFO(fbops).fb_cursor = soft_cursor;
+	ACCESS_FBINFO(fbops).fb_cursor = NULL;
 
 	accel = (ACCESS_FBINFO(fbcon).var.accel_flags & FB_ACCELF_TEXT) == FB_ACCELF_TEXT;
 
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index e02da41..1e74f4c 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -264,7 +264,6 @@
 }
 
 int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc) {
-	wait_queue_t __wait;
 	struct matrox_vsync *vs;
 	unsigned int cnt;
 	int ret;
@@ -286,7 +285,6 @@
 	if (ret) {
 		return ret;
 	}
-        init_waitqueue_entry(&__wait, current);
 
 	cnt = vs->cnt;
 	ret = wait_event_interruptible_timeout(vs->wait, cnt != vs->cnt, HZ/10);
@@ -500,10 +498,6 @@
 	} else {
 		xres_new = matroxfb_test_and_set_rounding(PMINFO xres, bpp);
 	}
-	if (!xres_new) return 0;
-	if (xres != xres_new) {
-		printk(KERN_INFO "matroxfb: cannot set xres to %d, rounded up to %d\n", xres, xres_new);
-	}
 	return xres_new;
 }
 
@@ -1285,7 +1279,7 @@
 	vaddr_t vm;
 	unsigned int offs;
 	unsigned int offs2;
-	unsigned char store, orig;
+	unsigned char orig;
 	unsigned char bytes[32];
 	unsigned char* tmp;
 
@@ -1301,16 +1295,12 @@
 	orig = mga_inb(M_EXTVGA_DATA);
 	mga_outb(M_EXTVGA_DATA, orig | 0x80);
 
-	store = mga_readb(vm, 0x1234);
 	tmp = bytes;
 	for (offs = 0x100000; offs < maxSize; offs += 0x200000)
 		*tmp++ = mga_readb(vm, offs);
 	for (offs = 0x100000; offs < maxSize; offs += 0x200000)
 		mga_writeb(vm, offs, 0x02);
-	if (ACCESS_FBINFO(features.accel.has_cacheflush))
-		mga_outb(M_CACHEFLUSH, 0x00);
-	else
-		mga_writeb(vm, 0x1234, 0x99);
+	mga_outb(M_CACHEFLUSH, 0x00);
 	for (offs = 0x100000; offs < maxSize; offs += 0x200000) {
 		if (mga_readb(vm, offs) != 0x02)
 			break;
@@ -1321,7 +1311,6 @@
 	tmp = bytes;
 	for (offs2 = 0x100000; offs2 < maxSize; offs2 += 0x200000)
 		mga_writeb(vm, offs2, *tmp++);
-	mga_writeb(vm, 0x1234, store);
 
 	mga_outb(M_EXTVGA_INDEX, 0x03);
 	mga_outb(M_EXTVGA_DATA, orig);
@@ -1430,6 +1419,20 @@
 		MGA_1164,
 		&vbMystique,
 		"Mystique 220 (PCI)"},
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MYS_AGP,	0x02,
+		0,			0,
+		DEVF_VIDEO64BIT | DEVF_CROSS4MB,
+		180000,
+		MGA_1064,
+		&vbMystique,
+		"Mystique (AGP)"},
+	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MYS_AGP,	0xFF,
+		0,			0,
+		DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+		220000,
+		MGA_1164,
+		&vbMystique,
+		"Mystique 220 (AGP)"},
 #endif
 #ifdef CONFIG_FB_MATROX_G
 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_MM,	0xFF,
diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h
index 85a0b25..a8c47ad 100644
--- a/drivers/video/matrox/matroxfb_base.h
+++ b/drivers/video/matrox/matroxfb_base.h
@@ -272,10 +272,6 @@
 	u_int8_t	xmiscctrl;
 };
 
-struct matrox_accel_features {
-	int		has_cacheflush;
-};
-
 /* current hardware status */
 struct mavenregs {
 	u_int8_t regs[256];
@@ -440,7 +436,6 @@
 	struct {
 		struct matrox_pll_features pll;
 		struct matrox_DAC1064_features DAC1064;
-		struct matrox_accel_features accel;
 			      } features;
 	struct {
 		spinlock_t	DAC;
diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c
index 429047a..d52d7d8 100644
--- a/drivers/video/matrox/matroxfb_crtc2.c
+++ b/drivers/video/matrox/matroxfb_crtc2.c
@@ -576,7 +576,6 @@
 	.fb_fillrect =	cfb_fillrect,
 	.fb_copyarea =	cfb_copyarea,
 	.fb_imageblit =	cfb_imageblit,
-	.fb_cursor =	soft_cursor,
 };
 
 static struct fb_var_screeninfo matroxfb_dh_defined = {
diff --git a/drivers/video/maxinefb.c b/drivers/video/maxinefb.c
index f192d99..743e7ad 100644
--- a/drivers/video/maxinefb.c
+++ b/drivers/video/maxinefb.c
@@ -113,7 +113,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 int __init maxinefb_init(void)
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 47516c4..1789a52 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -676,6 +676,8 @@
 	mode->sync = var->sync;
 	mode->vmode = var->vmode & FB_VMODE_MASK;
 	mode->flag = FB_MODE_IS_FROM_VAR;
+	mode->refresh = 0;
+
 	if (!var->pixclock)
 		return;
 
@@ -785,39 +787,39 @@
 }
 
 /**
- * fb_find_nearest_mode - find mode closest video mode
+ * fb_find_nearest_mode - find closest videomode
  *
- * @var: pointer to struct fb_var_screeninfo
+ * @mode: pointer to struct fb_videomode
  * @head: pointer to modelist
  *
  * Finds best matching videomode, smaller or greater in dimension.
  * If more than 1 videomode is found, will return the videomode with
- * the closest refresh rate
+ * the closest refresh rate.
  */
-struct fb_videomode *fb_find_nearest_mode(struct fb_var_screeninfo *var,
+struct fb_videomode *fb_find_nearest_mode(struct fb_videomode *mode,
 					  struct list_head *head)
 {
 	struct list_head *pos;
 	struct fb_modelist *modelist;
-	struct fb_videomode *mode, *best = NULL;
+	struct fb_videomode *cmode, *best = NULL;
 	u32 diff = -1, diff_refresh = -1;
 
 	list_for_each(pos, head) {
 		u32 d;
 
 		modelist = list_entry(pos, struct fb_modelist, list);
-		mode = &modelist->mode;
+		cmode = &modelist->mode;
 
-		d = abs(mode->xres - var->xres) +
-			abs(mode->yres - var->yres);
+		d = abs(cmode->xres - mode->xres) +
+			abs(cmode->yres - mode->yres);
 		if (diff > d) {
 			diff = d;
-			best = mode;
+			best = cmode;
 		} else if (diff == d) {
-			d = abs(mode->refresh - best->refresh);
+			d = abs(cmode->refresh - mode->refresh);
 			if (diff_refresh > d) {
 				diff_refresh = d;
-				best = mode;
+				best = cmode;
 			}
 		}
 	}
@@ -942,6 +944,66 @@
 	}
 }
 
+struct fb_videomode *fb_find_best_display(struct fb_monspecs *specs,
+					  struct list_head *head)
+{
+	struct list_head *pos;
+	struct fb_modelist *modelist;
+	struct fb_videomode *m, *m1 = NULL, *md = NULL, *best = NULL;
+	int first = 0;
+
+	if (!head->prev || !head->next || list_empty(head))
+		goto finished;
+
+	/* get the first detailed mode and the very first mode */
+	list_for_each(pos, head) {
+		modelist = list_entry(pos, struct fb_modelist, list);
+		m = &modelist->mode;
+
+		if (!first) {
+			m1 = m;
+			first = 1;
+		}
+
+		if (m->flag & FB_MODE_IS_FIRST) {
+ 			md = m;
+			break;
+		}
+	}
+
+	/* first detailed timing is preferred */
+	if (specs->misc & FB_MISC_1ST_DETAIL) {
+		best = md;
+		goto finished;
+	}
+
+	/* find best mode based on display width and height */
+	if (specs->max_x && specs->max_y) {
+		struct fb_var_screeninfo var;
+
+		memset(&var, 0, sizeof(struct fb_var_screeninfo));
+		var.xres = (specs->max_x * 7200)/254;
+		var.yres = (specs->max_y * 7200)/254;
+		m = fb_find_best_mode(&var, head);
+		if (m) {
+			best = m;
+			goto finished;
+		}
+	}
+
+	/* use first detailed mode */
+	if (md) {
+		best = md;
+		goto finished;
+	}
+
+	/* last resort, use the very first mode */
+	best = m1;
+finished:
+	return best;
+}
+EXPORT_SYMBOL(fb_find_best_display);
+
 EXPORT_SYMBOL(fb_videomode_to_var);
 EXPORT_SYMBOL(fb_var_to_videomode);
 EXPORT_SYMBOL(fb_mode_is_equal);
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index 5d424a3..8486e77 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -1665,7 +1665,6 @@
 	.fb_fillrect	= neofb_fillrect,
 	.fb_copyarea	= neofb_copyarea,
 	.fb_imageblit	= neofb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 /* --------------------------------------------------------------------- */
diff --git a/drivers/video/nvidia/nv_local.h b/drivers/video/nvidia/nv_local.h
index afee284..4243d7f 100644
--- a/drivers/video/nvidia/nv_local.h
+++ b/drivers/video/nvidia/nv_local.h
@@ -105,7 +105,7 @@
 	*a = byte_rev[*a];      \
 } while(0)
 #else
-#define reverse_order(l)
+#define reverse_order(l) do { } while(0)
 #endif                          /* __LITTLE_ENDIAN */
 
 #endif				/* __NV_LOCAL_H__ */
diff --git a/drivers/video/nvidia/nv_of.c b/drivers/video/nvidia/nv_of.c
index 4fa2cf9..7a03d04 100644
--- a/drivers/video/nvidia/nv_of.c
+++ b/drivers/video/nvidia/nv_of.c
@@ -27,34 +27,60 @@
 #include "nv_local.h"
 #include "nv_proto.h"
 
-void nvidia_create_i2c_busses(struct nvidia_par *par) {}
-void nvidia_delete_i2c_busses(struct nvidia_par *par) {}
+#include "../edid.h"
 
-int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid)
+int nvidia_probe_of_connector(struct fb_info *info, int conn, u8 **out_edid)
 {
 	struct nvidia_par *par = info->par;
-	struct device_node *dp;
+	struct device_node *parent, *dp;
 	unsigned char *pedid = NULL;
-	unsigned char *disptype = NULL;
 	static char *propnames[] = {
-		"DFP,EDID", "LCD,EDID", "EDID", "EDID1", "EDID,B", "EDID,A", NULL };
+		"DFP,EDID", "LCD,EDID", "EDID", "EDID1",
+		"EDID,B", "EDID,A", NULL };
 	int i;
 
-	dp = pci_device_to_OF_node(par->pci_dev);
-	for (; dp != NULL; dp = dp->child) {
-		disptype = (unsigned char *)get_property(dp, "display-type", NULL);
-		if (disptype == NULL)
-			continue;
-		if (strncmp(disptype, "LCD", 3) != 0)
-			continue;
-		for (i = 0; propnames[i] != NULL; ++i) {
-			pedid = (unsigned char *)
-				get_property(dp, propnames[i], NULL);
-			if (pedid != NULL) {
-				*out_edid = pedid;
-				return 0;
+	parent = pci_device_to_OF_node(par->pci_dev);
+	if (parent == NULL)
+		return -1;
+	if (par->twoHeads) {
+		char *pname;
+		int len;
+
+		for (dp = NULL;
+		     (dp = of_get_next_child(parent, dp)) != NULL;) {
+			pname = (char *)get_property(dp, "name", NULL);
+			if (!pname)
+				continue;
+			len = strlen(pname);
+			if ((pname[len-1] == 'A' && conn == 1) ||
+			    (pname[len-1] == 'B' && conn == 2)) {
+				for (i = 0; propnames[i] != NULL; ++i) {
+					pedid = (unsigned char *)
+						get_property(dp, propnames[i],
+							     NULL);
+					if (pedid != NULL)
+						break;
+				}
+				of_node_put(dp);
+				break;
 			}
 		}
 	}
-	return 1;
+	if (pedid == NULL) {
+		for (i = 0; propnames[i] != NULL; ++i) {
+			pedid = (unsigned char *)
+				get_property(parent, propnames[i], NULL);
+			if (pedid != NULL)
+				break;
+		}
+	}
+	if (pedid) {
+		*out_edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
+		if (*out_edid == NULL)
+			return -1;
+		memcpy(*out_edid, pedid, EDID_LENGTH);
+		printk(KERN_DEBUG "nvidiafb: Found OF EDID for head %d\n", conn);
+		return 0;
+	}
+	return -1;
 }
diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/nvidia/nv_proto.h
index cac44fc..f60b1f4 100644
--- a/drivers/video/nvidia/nv_proto.h
+++ b/drivers/video/nvidia/nv_proto.h
@@ -31,7 +31,7 @@
 void NVLockUnlock(struct nvidia_par *par, int);
 
 /* in nvidia-i2c.c */
-#if defined(CONFIG_FB_NVIDIA_I2C) || defined (CONFIG_PPC_OF)
+#ifdef CONFIG_FB_NVIDIA_I2C
 void nvidia_create_i2c_busses(struct nvidia_par *par);
 void nvidia_delete_i2c_busses(struct nvidia_par *par);
 int nvidia_probe_i2c_connector(struct fb_info *info, int conn,
@@ -39,10 +39,18 @@
 #else
 #define nvidia_create_i2c_busses(...)
 #define nvidia_delete_i2c_busses(...)
-#define nvidia_probe_i2c_connector(p, c, edid) \
-do {                                           \
-	*(edid) = NULL;                        \
-} while(0)
+#define nvidia_probe_i2c_connector(p, c, edid) (-1)
+#endif
+
+#ifdef CONFIG_FB_OF
+int nvidia_probe_of_connector(struct fb_info *info, int conn,
+			      u8 ** out_edid);
+#else
+static inline int nvidia_probe_of_connector(struct fb_info *info, int conn,
+				      u8 ** out_edid)
+{
+	return -1;
+}
 #endif
 
 /* in nv_accel.c */
diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c
index 11c8417..1f06a9f 100644
--- a/drivers/video/nvidia/nv_setup.c
+++ b/drivers/video/nvidia/nv_setup.c
@@ -190,9 +190,9 @@
 	present = (NV_RD32(PRAMDAC, 0x0608) & (1 << 28)) ? 1 : 0;
 
 	if (present)
-		printk("nvidiafb: CRTC%i found\n", output);
+		printk("nvidiafb: CRTC%i analog found\n", output);
 	else
-		printk("nvidiafb: CRTC%i not found\n", output);
+		printk("nvidiafb: CRTC%i analog not found\n", output);
 
 	NV_WR32(par->PRAMDAC0, 0x0608, NV_RD32(par->PRAMDAC0, 0x0608) &
 		0x0000EFFF);
@@ -305,6 +305,9 @@
 	int FlatPanel = -1;	/* really means the CRTC is slaved */
 	int Television = 0;
 
+	memset(&monitorA, 0, sizeof(struct fb_monspecs));
+	memset(&monitorB, 0, sizeof(struct fb_monspecs));
+
 	par->PRAMIN = par->REGS + (0x00710000 / 4);
 	par->PCRTC0 = par->REGS + (0x00600000 / 4);
 	par->PRAMDAC0 = par->REGS + (0x00680000 / 4);
@@ -401,7 +404,8 @@
 	nvidia_create_i2c_busses(par);
 	if (!par->twoHeads) {
 		par->CRTCnumber = 0;
-		nvidia_probe_i2c_connector(info, 1, &edidA);
+		if (nvidia_probe_i2c_connector(info, 1, &edidA))
+			nvidia_probe_of_connector(info, 1, &edidA);
 		if (edidA && !fb_parse_edid(edidA, &var)) {
 			printk("nvidiafb: EDID found from BUS1\n");
 			monA = &monitorA;
@@ -488,14 +492,16 @@
 		oldhead = NV_RD32(par->PCRTC0, 0x00000860);
 		NV_WR32(par->PCRTC0, 0x00000860, oldhead | 0x00000010);
 
-		nvidia_probe_i2c_connector(info, 1, &edidA);
+		if (nvidia_probe_i2c_connector(info, 1, &edidA))
+			nvidia_probe_of_connector(info, 1, &edidA);
 		if (edidA && !fb_parse_edid(edidA, &var)) {
 			printk("nvidiafb: EDID found from BUS1\n");
 			monA = &monitorA;
 			fb_edid_to_monspecs(edidA, monA);
 		}
 
-		nvidia_probe_i2c_connector(info, 2, &edidB);
+		if (nvidia_probe_i2c_connector(info, 2, &edidB))
+			nvidia_probe_of_connector(info, 2, &edidB);
 		if (edidB && !fb_parse_edid(edidB, &var)) {
 			printk("nvidiafb: EDID found from BUS2\n");
 			monB = &monitorB;
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 308defc..0b40a2a 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -411,6 +411,7 @@
 
 /* command line data, set in nvidiafb_setup() */
 static int flatpanel __devinitdata = -1;	/* Autodetect later */
+static int fpdither __devinitdata = -1;
 static int forceCRTC __devinitdata = -1;
 static int hwcur __devinitdata = 0;
 static int noaccel __devinitdata = 0;
@@ -627,41 +628,85 @@
 	NVTRACE_LEAVE();
 }
 
+#undef DUMP_REG
+
 static void nvidia_write_regs(struct nvidia_par *par)
 {
 	struct _riva_hw_state *state = &par->ModeReg;
 	int i;
 
 	NVTRACE_ENTER();
-	NVWriteCrtc(par, 0x11, 0x00);
-
-	NVLockUnlock(par, 0);
 
 	NVLoadStateExt(par, state);
 
 	NVWriteMiscOut(par, state->misc_output);
 
+	for (i = 1; i < NUM_SEQ_REGS; i++) {
+#ifdef DUMP_REG
+		printk(" SEQ[%02x] = %08x\n", i, state->seq[i]);
+#endif
+		NVWriteSeq(par, i, state->seq[i]);
+	}
+
+	/* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
+	NVWriteCrtc(par, 0x11, state->crtc[0x11] & ~0x80);
+
 	for (i = 0; i < NUM_CRT_REGS; i++) {
 		switch (i) {
 		case 0x19:
 		case 0x20 ... 0x40:
 			break;
 		default:
+#ifdef DUMP_REG
+			printk("CRTC[%02x] = %08x\n", i, state->crtc[i]);
+#endif
 			NVWriteCrtc(par, i, state->crtc[i]);
 		}
 	}
 
-	for (i = 0; i < NUM_ATC_REGS; i++)
-		NVWriteAttr(par, i, state->attr[i]);
-
-	for (i = 0; i < NUM_GRC_REGS; i++)
+	for (i = 0; i < NUM_GRC_REGS; i++) {
+#ifdef DUMP_REG
+		printk(" GRA[%02x] = %08x\n", i, state->gra[i]);
+#endif
 		NVWriteGr(par, i, state->gra[i]);
+	}
 
-	for (i = 0; i < NUM_SEQ_REGS; i++)
-		NVWriteSeq(par, i, state->seq[i]);
+	for (i = 0; i < NUM_ATC_REGS; i++) {
+#ifdef DUMP_REG
+		printk("ATTR[%02x] = %08x\n", i, state->attr[i]);
+#endif
+		NVWriteAttr(par, i, state->attr[i]);
+	}
+
 	NVTRACE_LEAVE();
 }
 
+static void nvidia_vga_protect(struct nvidia_par *par, int on)
+{
+	unsigned char tmp;
+
+	if (on) {
+		/*
+		 * Turn off screen and disable sequencer.
+		 */
+		tmp = NVReadSeq(par, 0x01);
+
+		NVWriteSeq(par, 0x00, 0x01);		/* Synchronous Reset */
+		NVWriteSeq(par, 0x01, tmp | 0x20);	/* disable the display */
+	} else {
+		/*
+		 * Reenable sequencer, then turn on screen.
+		 */
+
+		tmp = NVReadSeq(par, 0x01);
+
+		NVWriteSeq(par, 0x01, tmp & ~0x20);	/* reenable display */
+		NVWriteSeq(par, 0x00, 0x03);		/* End Reset */
+	}
+}
+
+
+
 static int nvidia_calc_regs(struct fb_info *info)
 {
 	struct nvidia_par *par = info->par;
@@ -868,7 +913,7 @@
 	for (i = 0; i < 0x10; i++)
 		state->attr[i] = i;
 	state->attr[0x10] = 0x41;
-	state->attr[0x11] = 0x01;
+	state->attr[0x11] = 0xff;
 	state->attr[0x12] = 0x0f;
 	state->attr[0x13] = 0x00;
 	state->attr[0x14] = 0x00;
@@ -982,16 +1027,24 @@
 	NVTRACE_ENTER();
 
 	NVLockUnlock(par, 1);
-	if (!par->FlatPanel || (info->var.bits_per_pixel != 24) ||
-	    !par->twoHeads)
+	if (!par->FlatPanel || !par->twoHeads)
 		par->FPDither = 0;
 
+	if (par->FPDither < 0) {
+		if ((par->Chipset & 0x0ff0) == 0x0110)
+			par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x0528)
+					   & 0x00010000);
+		else
+			par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x083C) & 1);
+		printk(KERN_INFO PFX "Flat panel dithering %s\n",
+		       par->FPDither ? "enabled" : "disabled");
+	}
+
 	info->fix.visual = (info->var.bits_per_pixel == 8) ?
 	    FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
 
 	nvidia_init_vga(info);
 	nvidia_calc_regs(info);
-	nvidia_write_regs(par);
 
 	NVLockUnlock(par, 0);
 	if (par->twoHeads) {
@@ -1000,7 +1053,22 @@
 		NVLockUnlock(par, 0);
 	}
 
-	NVWriteCrtc(par, 0x11, 0x00);
+	nvidia_vga_protect(par, 1);
+
+	nvidia_write_regs(par);
+
+#if defined (__BIG_ENDIAN)
+	/* turn on LFB swapping */
+	{
+		unsigned char tmp;
+
+		VGA_WR08(par->PCIO, 0x3d4, 0x46);
+		tmp = VGA_RD08(par->PCIO, 0x3d5);
+		tmp |= (1 << 7);
+		VGA_WR08(par->PCIO, 0x3d5, tmp);
+    }
+#endif
+
 	info->fix.line_length = (info->var.xres_virtual *
 				 info->var.bits_per_pixel) >> 3;
 	if (info->var.accel_flags) {
@@ -1022,7 +1090,7 @@
 
 	par->cursor_reset = 1;
 
-	NVWriteCrtc(par, 0x11, 0xff);
+	nvidia_vga_protect(par, 0);
 
 	NVTRACE_LEAVE();
 	return 0;
@@ -1315,22 +1383,10 @@
 	fb_var_to_videomode(&modedb, &nvidiafb_default_var);
 
 	if (specs->modedb != NULL) {
-		/* get preferred timing */
-		if (specs->misc & FB_MISC_1ST_DETAIL) {
-			int i;
+		struct fb_videomode *modedb;
 
-			for (i = 0; i < specs->modedb_len; i++) {
-				if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
-					modedb = specs->modedb[i];
-					break;
-				}
-			}
-		} else {
-			/* otherwise, get first mode in database */
-			modedb = specs->modedb[0];
-		}
-
-		fb_videomode_to_var(&nvidiafb_default_var, &modedb);
+		modedb = fb_find_best_display(specs, &info->modelist);
+		fb_videomode_to_var(&nvidiafb_default_var, modedb);
 		nvidiafb_default_var.bits_per_pixel = 8;
 	} else if (par->fpWidth && par->fpHeight) {
 		char buf[16];
@@ -1365,7 +1421,7 @@
 	info->pixmap.flags = FB_PIXMAP_SYSTEM;
 
 	if (!hwcur)
-	    info->fbops->fb_cursor = soft_cursor;
+	    info->fbops->fb_cursor = NULL;
 
 	info->var.accel_flags = (!noaccel);
 
@@ -1490,9 +1546,9 @@
 	sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4);
 
 	par->FlatPanel = flatpanel;
-
 	if (flatpanel == 1)
 		printk(KERN_INFO PFX "flatpanel support enabled\n");
+	par->FPDither = fpdither;
 
 	par->CRTCnumber = forceCRTC;
 	par->FpScale = (!noscale);
@@ -1671,6 +1727,8 @@
 		} else if (!strncmp(this_opt, "nomtrr", 6)) {
 			nomtrr = 1;
 #endif
+		} else if (!strncmp(this_opt, "fpdither:", 9)) {
+			fpdither = simple_strtol(this_opt+9, NULL, 0);
 		} else
 			mode_option = this_opt;
 	}
@@ -1717,7 +1775,11 @@
 module_param(flatpanel, int, 0);
 MODULE_PARM_DESC(flatpanel,
 		 "Enables experimental flat panel support for some chipsets. "
-		 "(0 or 1=enabled) (default=0)");
+		 "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
+module_param(fpdither, int, 0);
+MODULE_PARM_DESC(fpdither,
+		 "Enables dithering of flat panel for 6 bits panels. "
+		 "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
 module_param(hwcur, int, 0);
 MODULE_PARM_DESC(hwcur,
 		 "Enables hardware cursor implementation. (0 or 1=enabled) "
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index 611922c..2c85683 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -85,7 +85,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
     /*
diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c
index b76a5a9..9aaf65f 100644
--- a/drivers/video/p9100.c
+++ b/drivers/video/p9100.c
@@ -48,7 +48,6 @@
 	.fb_imageblit		= cfb_imageblit,
 	.fb_mmap		= p9100_mmap,
 	.fb_ioctl		= p9100_ioctl,
-	.fb_cursor		= soft_cursor,
 };
 
 /* P9100 control registers */
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
index b00887e..ca4082a 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -109,7 +109,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 /*
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index 42c17ef..0277ce0 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -1034,7 +1034,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 /*
@@ -1121,6 +1120,22 @@
 		default_par->mem_control, default_par->boot_address,
 		default_par->mem_config);
 
+	if(default_par->mem_control == 0 &&
+		default_par->boot_address == 0x31 &&
+		default_par->mem_config == 0x259fffff &&
+		pdev->subsystem_vendor == 0x1048 &&
+		pdev->subsystem_device == 0x0a31) {
+		DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n",
+			pdev->subsystem_vendor, pdev->subsystem_device);
+		DPRINTK("We have not been initialized by VGA BIOS "
+			"and are running on an Elsa Winner 2000 Office\n");
+		DPRINTK("Initializing card timings manually...\n");
+		default_par->mem_control=0;
+		default_par->boot_address=0x20;
+		default_par->mem_config=0xe6002021;
+		default_par->memclock=100000;
+	}
+
 	/* Now work out how big lfb is going to be. */
 	switch(default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) {
 	case PM2F_MEM_BANKS_1:
diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c
index c98f1c8..f3927b6 100644
--- a/drivers/video/pmag-ba-fb.c
+++ b/drivers/video/pmag-ba-fb.c
@@ -128,7 +128,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 
diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c
index a483b13..25148de 100644
--- a/drivers/video/pmagb-b-fb.c
+++ b/drivers/video/pmagb-b-fb.c
@@ -132,7 +132,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index 31c547f..ec4bacf 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -230,7 +230,6 @@
 	.fb_fillrect 	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 static struct fb_videomode pvr2_modedb[] __initdata = {
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index efd9333..f305a5b 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -418,7 +418,6 @@
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
 	.fb_blank	= pxafb_blank,
-	.fb_cursor	= soft_cursor,
 	.fb_mmap	= pxafb_mmap,
 };
 
diff --git a/drivers/video/q40fb.c b/drivers/video/q40fb.c
index 8416b2e..bfc41f2 100644
--- a/drivers/video/q40fb.c
+++ b/drivers/video/q40fb.c
@@ -84,7 +84,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 static int __init q40fb_probe(struct device *device)
diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c
index a78b9bd..600318f 100644
--- a/drivers/video/radeonfb.c
+++ b/drivers/video/radeonfb.c
@@ -2218,7 +2218,6 @@
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
 #endif
-	.fb_cursor	= soft_cursor,
 };
 
 
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c
index f443743..3edbd14 100644
--- a/drivers/video/s1d13xxxfb.c
+++ b/drivers/video/s1d13xxxfb.c
@@ -388,7 +388,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor
 };
 
 static int s1d13xxxfb_width_tab[2][4] __devinitdata = {
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 3cef904..855a677 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -495,7 +495,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 
@@ -885,6 +884,7 @@
 
 static struct device_driver s3c2410fb_driver = {
 	.name		= "s3c2410-lcd",
+	.owner		= THIS_MODULE,
 	.bus		= &platform_bus_type,
 	.probe		= s3c2410fb_probe,
 	.suspend	= s3c2410fb_suspend,
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index 3d35b28..a518457 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -853,7 +853,6 @@
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
 	.fb_blank	= sa1100fb_blank,
-	.fb_cursor	= soft_cursor,
 	.fb_mmap	= sa1100fb_mmap,
 };
 
diff --git a/drivers/video/savage/savagefb.h b/drivers/video/savage/savagefb.h
index ea17f7e..58cfdfb 100644
--- a/drivers/video/savage/savagefb.h
+++ b/drivers/video/savage/savagefb.h
@@ -169,6 +169,7 @@
 	struct savagefb_i2c_chan chan;
 	unsigned char   *edid;
 	u32 pseudo_palette[16];
+	int paletteEnabled;
 	int pm_state;
 	int display_type;
 	int dvi;
@@ -244,105 +245,150 @@
 
 
 /* IO functions */
-
-#define  vga_in8(addr)         (inb (addr))
-#define vga_in16(addr)         (inw (addr))
-#define vga_in32(addr)         (inl (addr))
-
-#define  vga_out8(addr,val)    (outb ((val), (addr)))
-#define vga_out16(addr,val)    (outw ((val), (addr)))
-#define vga_out32(addr,val)    (outl ((val), (addr)))
-
-#define savage_in16(addr)      readw(par->mmio.vbase + (addr))
-#define savage_in32(addr)      readl(par->mmio.vbase + (addr))
-
-#define savage_out16(addr,val) writew((val), par->mmio.vbase + (addr))
-#define savage_out32(addr,val) writel((val), par->mmio.vbase + (addr))
-
-static inline u8 VGArCR (u8 index)
+static inline u8 savage_in8(u32 addr, struct savagefb_par *par)
 {
-  outb (index, 0x3d4);
-  return inb (0x3d5);
+	return readb(par->mmio.vbase + addr);
 }
 
-static inline u8 VGArGR (u8 index)
+static inline u16 savage_in16(u32 addr, struct savagefb_par *par)
 {
-  outb (index, 0x3ce);
-  return inb (0x3cf);
+	return readw(par->mmio.vbase + addr);
 }
 
-static inline u8 VGArSEQ (u8 index)
+static inline u32 savage_in32(u32 addr, struct savagefb_par *par)
 {
-  outb (index, 0x3c4);
-  return inb (0x3c5);
+	return readl(par->mmio.vbase + addr);
 }
 
-#define VGAwCR(index, val) \
-do {                       \
-  vga_out8 (0x3d4, index); \
-  vga_out8 (0x3d5, val);   \
-} while (0)
+static inline void savage_out8(u32 addr, u8 val, struct savagefb_par *par)
+{
+	writeb(val, par->mmio.vbase + addr);
+}
 
-#define VGAwGR(index, val) \
-do {                       \
-  vga_out8 (0x3ce, index); \
-  vga_out8 (0x3cf, val);   \
-} while (0)
+static inline void savage_out16(u32 addr, u16 val, struct savagefb_par *par)
+{
+	writew(val, par->mmio.vbase + addr);
+}
 
-#define VGAwSEQ(index, val) \
-do {                        \
-  vga_out8 (0x3c4, index);  \
-  vga_out8 (0x3c5, val);    \
-} while (0)
+static inline void savage_out32(u32 addr, u32 val, struct savagefb_par *par)
+{
+	writel(val, par->mmio.vbase + addr);
+}
 
-#define VGAenablePalette() \
-do {                       \
-  u8 tmp;                  \
-                           \
-  tmp = vga_in8 (0x3da);   \
-  vga_out8 (0x3c0, 0x00);  \
-  paletteEnabled = 1;      \
-} while (0)
+static inline u8 vga_in8(int addr, struct savagefb_par *par)
+{
+	return savage_in8(0x8000 + addr, par);
+}
 
-#define VGAdisablePalette() \
-do {                        \
-  u8 tmp;                   \
-                            \
-  tmp = vga_in8 (0x3da);    \
-  vga_out8 (0x3c0, 0x20);   \
-  paletteEnabled = 0;       \
-} while (0)
+static inline u16 vga_in16(int addr, struct savagefb_par *par)
+{
+	return savage_in16(0x8000 + addr, par);
+}
 
-#define VGAwATTR(index, value) \
-do {                           \
-  u8 tmp;                      \
-                               \
-  if (paletteEnabled)          \
-    index &= ~0x20;            \
-  else                         \
-    index |= 0x20;             \
-                               \
-  tmp = vga_in8 (0x3da);       \
-  vga_out8 (0x3c0, index);     \
-  vga_out8 (0x3c0, value);     \
-} while (0)
+static inline u8 vga_in32(int addr, struct savagefb_par *par)
+{
+	return savage_in32(0x8000 + addr, par);
+}
 
-#define VGAwMISC(value)    \
-do {                       \
-  vga_out8 (0x3c2, value); \
-} while (0)
+static inline void vga_out8(int addr, u8 val, struct savagefb_par *par)
+{
+	savage_out8(0x8000 + addr, val, par);
+}
+
+static inline void vga_out16(int addr, u16 val, struct savagefb_par *par)
+{
+	savage_out16(0x8000 + addr, val, par);
+}
+
+static inline void vga_out32(int addr, u32 val, struct savagefb_par *par)
+{
+	savage_out32(0x8000 + addr, val, par);
+}
+
+static inline u8 VGArCR (u8 index, struct savagefb_par *par)
+{
+	vga_out8(0x3d4, index,  par);
+	return vga_in8(0x3d5, par);
+}
+
+static inline u8 VGArGR (u8 index, struct savagefb_par *par)
+{
+	vga_out8(0x3ce, index, par);
+	return vga_in8(0x3cf, par);
+}
+
+static inline u8 VGArSEQ (u8 index, struct savagefb_par *par)
+{
+	vga_out8(0x3c4, index, par);
+	return vga_in8(0x3c5, par);
+}
+
+static inline void VGAwCR(u8 index, u8 val, struct savagefb_par *par)
+{
+	vga_out8(0x3d4, index, par);
+	vga_out8(0x3d5, val, par);
+}
+
+static inline void VGAwGR(u8 index, u8 val, struct savagefb_par *par)
+{
+	vga_out8(0x3ce, index, par);
+	vga_out8(0x3cf, val, par);
+}
+
+static inline void VGAwSEQ(u8 index, u8 val, struct savagefb_par *par)
+{
+	vga_out8(0x3c4, index, par);
+	vga_out8 (0x3c5, val, par);
+}
+
+static inline void VGAenablePalette(struct savagefb_par *par)
+{
+	u8 tmp;
+
+	tmp = vga_in8(0x3da, par);
+	vga_out8(0x3c0, 0x00, par);
+	par->paletteEnabled = 1;
+}
+
+static inline void VGAdisablePalette(struct savagefb_par *par)
+{
+	u8 tmp;
+
+	tmp = vga_in8(0x3da, par);
+	vga_out8(0x3c0, 0x20, par);
+	par->paletteEnabled = 0;
+}
+
+static inline void VGAwATTR(u8 index, u8 value, struct savagefb_par *par)
+{
+	u8 tmp;
+
+	if (par->paletteEnabled)
+		index &= ~0x20;
+	else
+		index |= 0x20;
+
+	tmp = vga_in8(0x3da, par);
+	vga_out8(0x3c0, index, par);
+	vga_out8 (0x3c0, value, par);
+}
+
+static inline void VGAwMISC(u8 value, struct savagefb_par *par)
+{
+	vga_out8(0x3c2, value, par);
+}
 
 #ifndef CONFIG_FB_SAVAGE_ACCEL
 #define savagefb_set_clip(x)
 #endif
 
-#define VerticalRetraceWait() \
-{ \
-	vga_out8 (0x3d4, 0x17); \
-	if (vga_in8 (0x3d5) & 0x80) { \
-		while ((vga_in8(0x3da) & 0x08) == 0x08) ; \
-		while ((vga_in8(0x3da) & 0x08) == 0x00) ; \
-	} \
+static inline void VerticalRetraceWait(struct savagefb_par *par)
+{
+	vga_out8(0x3d4, 0x17, par);
+	if (vga_in8(0x3d5, par) & 0x80) {
+		while ((vga_in8(0x3da, par) & 0x08) == 0x08);
+		while ((vga_in8(0x3da, par) & 0x08) == 0x00);
+	}
 }
 
 extern int savagefb_probe_i2c_connector(struct fb_info *info,
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index 7c28545..f0dfb35 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -74,7 +74,6 @@
 
 
 static char *mode_option __initdata = NULL;
-static int   paletteEnabled = 0;
 
 #ifdef MODULE
 
@@ -90,9 +89,9 @@
 static void vgaHWSeqReset (struct savagefb_par *par, int start)
 {
 	if (start)
-		VGAwSEQ (0x00, 0x01);		/* Synchronous Reset */
+		VGAwSEQ (0x00, 0x01, par);	/* Synchronous Reset */
 	else
-		VGAwSEQ (0x00, 0x03);		/* End Reset */
+		VGAwSEQ (0x00, 0x03, par);	/* End Reset */
 }
 
 static void vgaHWProtect (struct savagefb_par *par, int on)
@@ -103,23 +102,23 @@
 		/*
 		 * Turn off screen and disable sequencer.
 		 */
-		tmp = VGArSEQ (0x01);
+		tmp = VGArSEQ (0x01, par);
 
 		vgaHWSeqReset (par, 1);	        /* start synchronous reset */
-		VGAwSEQ (0x01, tmp | 0x20);	/* disable the display */
+		VGAwSEQ (0x01, tmp | 0x20, par);/* disable the display */
 
-		VGAenablePalette();
+		VGAenablePalette(par);
 	} else {
 		/*
 		 * Reenable sequencer, then turn on screen.
 		 */
 
-		tmp = VGArSEQ (0x01);
+		tmp = VGArSEQ (0x01, par);
 
-		VGAwSEQ (0x01, tmp & ~0x20);	/* reenable display */
+		VGAwSEQ (0x01, tmp & ~0x20, par);/* reenable display */
 		vgaHWSeqReset (par, 0);	        /* clear synchronous reset */
 
-		VGAdisablePalette();
+		VGAdisablePalette(par);
 	}
 }
 
@@ -127,27 +126,27 @@
 {
 	int i;
 
-	VGAwMISC (par->MiscOutReg);
+	VGAwMISC (par->MiscOutReg, par);
 
 	for (i = 1; i < 5; i++)
-		VGAwSEQ (i, par->Sequencer[i]);
+		VGAwSEQ (i, par->Sequencer[i], par);
 
 	/* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or
 	   CRTC[17] */
-	VGAwCR (17, par->CRTC[17] & ~0x80);
+	VGAwCR (17, par->CRTC[17] & ~0x80, par);
 
 	for (i = 0; i < 25; i++)
-		VGAwCR (i, par->CRTC[i]);
+		VGAwCR (i, par->CRTC[i], par);
 
 	for (i = 0; i < 9; i++)
-		VGAwGR (i, par->Graphics[i]);
+		VGAwGR (i, par->Graphics[i], par);
 
-	VGAenablePalette();
+	VGAenablePalette(par);
 
 	for (i = 0; i < 21; i++)
-		VGAwATTR (i, par->Attribute[i]);
+		VGAwATTR (i, par->Attribute[i], par);
 
-	VGAdisablePalette();
+	VGAdisablePalette(par);
 }
 
 static void vgaHWInit (struct fb_var_screeninfo *var,
@@ -267,7 +266,7 @@
 {
 	int slots = MAXFIFO - space;
 
-	while ((savage_in32(0x48C00) & 0x0000ffff) > slots);
+	while ((savage_in32(0x48C00, par) & 0x0000ffff) > slots);
 }
 
 static void
@@ -275,7 +274,7 @@
 {
 	int slots = MAXFIFO - space;
 
-	while ((savage_in32(0x48C60) & 0x001fffff) > slots);
+	while ((savage_in32(0x48C60, par) & 0x001fffff) > slots);
 }
 
 static void
@@ -283,26 +282,26 @@
 {
 	int slots = MAXFIFO - space;
 
-	while ((savage_in32(0x48C60) & 0x0000ffff) > slots);
+	while ((savage_in32(0x48C60, par) & 0x0000ffff) > slots);
 }
 
 /* Wait for idle accelerator */
 static void
 savage3D_waitidle(struct savagefb_par *par)
 {
-	while ((savage_in32(0x48C00) & 0x0008ffff) != 0x80000);
+	while ((savage_in32(0x48C00, par) & 0x0008ffff) != 0x80000);
 }
 
 static void
 savage4_waitidle(struct savagefb_par *par)
 {
-	while ((savage_in32(0x48C60) & 0x00a00000) != 0x00a00000);
+	while ((savage_in32(0x48C60, par) & 0x00a00000) != 0x00a00000);
 }
 
 static void
 savage2000_waitidle(struct savagefb_par *par)
 {
-	while ((savage_in32(0x48C60) & 0x009fffff));
+	while ((savage_in32(0x48C60, par) & 0x009fffff));
 }
 
 
@@ -319,59 +318,64 @@
 	case S3_SAVAGE3D:
 	case S3_SAVAGE_MX:
 		/* Disable BCI */
-		savage_out32(0x48C18, savage_in32(0x48C18) & 0x3FF0);
+		savage_out32(0x48C18, savage_in32(0x48C18, par) & 0x3FF0, par);
 		/* Setup BCI command overflow buffer */
-		savage_out32(0x48C14, (par->cob_offset >> 11) | (par->cob_index << 29));
+		savage_out32(0x48C14,
+			     (par->cob_offset >> 11) | (par->cob_index << 29),
+			     par);
 		/* Program shadow status update. */
-		savage_out32(0x48C10, 0x78207220);
-		savage_out32(0x48C0C, 0);
+		savage_out32(0x48C10, 0x78207220, par);
+		savage_out32(0x48C0C, 0, par);
 		/* Enable BCI and command overflow buffer */
-		savage_out32(0x48C18, savage_in32(0x48C18) | 0x0C);
+		savage_out32(0x48C18, savage_in32(0x48C18, par) | 0x0C, par);
 		break;
 	case S3_SAVAGE4:
 	case S3_PROSAVAGE:
 	case S3_SUPERSAVAGE:
 		/* Disable BCI */
-		savage_out32(0x48C18, savage_in32(0x48C18) & 0x3FF0);
+		savage_out32(0x48C18, savage_in32(0x48C18, par) & 0x3FF0, par);
 		/* Program shadow status update */
-		savage_out32(0x48C10, 0x00700040);
-		savage_out32(0x48C0C, 0);
+		savage_out32(0x48C10, 0x00700040, par);
+		savage_out32(0x48C0C, 0, par);
 		/* Enable BCI without the COB */
-		savage_out32(0x48C18, savage_in32(0x48C18) | 0x08);
+		savage_out32(0x48C18, savage_in32(0x48C18, par) | 0x08, par);
 		break;
 	case S3_SAVAGE2000:
 		/* Disable BCI */
-		savage_out32(0x48C18, 0);
+		savage_out32(0x48C18, 0, par);
 		/* Setup BCI command overflow buffer */
-		savage_out32(0x48C18, (par->cob_offset >> 7) | (par->cob_index));
+		savage_out32(0x48C18,
+			     (par->cob_offset >> 7) | (par->cob_index),
+			     par);
 		/* Disable shadow status update */
-		savage_out32(0x48A30, 0);
+		savage_out32(0x48A30, 0, par);
 		/* Enable BCI and command overflow buffer */
-		savage_out32(0x48C18, savage_in32(0x48C18) | 0x00280000 );
+		savage_out32(0x48C18, savage_in32(0x48C18, par) | 0x00280000,
+			     par);
 		break;
 	    default:
 		break;
 	}
 	/* Turn on 16-bit register access. */
-	vga_out8(0x3d4, 0x31);
-	vga_out8(0x3d5, 0x0c);
+	vga_out8(0x3d4, 0x31, par);
+	vga_out8(0x3d5, 0x0c, par);
 
 	/* Set stride to use GBD. */
-	vga_out8 (0x3d4, 0x50);
-	vga_out8 (0x3d5, vga_in8 (0x3d5 ) | 0xC1);
+	vga_out8 (0x3d4, 0x50, par);
+	vga_out8 (0x3d5, vga_in8(0x3d5, par) | 0xC1, par);
 
 	/* Enable 2D engine. */
-	vga_out8 (0x3d4, 0x40 );
-	vga_out8 (0x3d5, 0x01 );
+	vga_out8 (0x3d4, 0x40, par);
+	vga_out8 (0x3d5, 0x01, par);
 
-	savage_out32 (MONO_PAT_0, ~0);
-	savage_out32 (MONO_PAT_1, ~0);
+	savage_out32 (MONO_PAT_0, ~0, par);
+	savage_out32 (MONO_PAT_1, ~0, par);
 
 	/* Setup plane masks */
-	savage_out32 (0x8128, ~0 ); /* enable all write planes */
-	savage_out32 (0x812C, ~0 ); /* enable all read planes */
-	savage_out16 (0x8134, 0x27 );
-	savage_out16 (0x8136, 0x07 );
+	savage_out32 (0x8128, ~0, par); /* enable all write planes */
+	savage_out32 (0x812C, ~0, par); /* enable all read planes */
+	savage_out16 (0x8134, 0x27, par);
+	savage_out16 (0x8136, 0x07, par);
 
 	/* Now set the GBD */
 	par->bci_ptr = 0;
@@ -489,8 +493,8 @@
 	for( i = 0; i < 0x70; i++ ) {
 		if( !(i % 16) )
 			printk(KERN_DEBUG "\nSR%xx ", i >> 4 );
-		vga_out8( 0x3c4, i );
-		printk(KERN_DEBUG " %02x", vga_in8(0x3c5) );
+		vga_out8( 0x3c4, i, par);
+		printk(KERN_DEBUG " %02x", vga_in8(0x3c5, par) );
 	}
 
 	printk(KERN_DEBUG "\n\nCR    x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC "
@@ -499,8 +503,8 @@
 	for( i = 0; i < 0xB7; i++ ) {
 		if( !(i % 16) )
 			printk(KERN_DEBUG "\nCR%xx ", i >> 4 );
-		vga_out8( vgaCRIndex, i );
-		printk(KERN_DEBUG " %02x", vga_in8(vgaCRReg) );
+		vga_out8( vgaCRIndex, i, par);
+		printk(KERN_DEBUG " %02x", vga_in8(vgaCRReg, par) );
 	}
 
 	printk(KERN_DEBUG "\n\n");
@@ -513,152 +517,152 @@
 {
 	unsigned char cr3a, cr53, cr66;
 
-	vga_out16 (0x3d4, 0x4838);
-	vga_out16 (0x3d4, 0xa039);
-	vga_out16 (0x3c4, 0x0608);
+	vga_out16 (0x3d4, 0x4838, par);
+	vga_out16 (0x3d4, 0xa039, par);
+	vga_out16 (0x3c4, 0x0608, par);
 
-	vga_out8 (0x3d4, 0x66);
-	cr66 = vga_in8 (0x3d5);
-	vga_out8 (0x3d5, cr66 | 0x80);
-	vga_out8 (0x3d4, 0x3a);
-	cr3a = vga_in8 (0x3d5);
-	vga_out8 (0x3d5, cr3a | 0x80);
-	vga_out8 (0x3d4, 0x53);
-	cr53 = vga_in8 (0x3d5);
-	vga_out8 (0x3d5, cr53 & 0x7f);
+	vga_out8 (0x3d4, 0x66, par);
+	cr66 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d5, cr66 | 0x80, par);
+	vga_out8 (0x3d4, 0x3a, par);
+	cr3a = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d5, cr3a | 0x80, par);
+	vga_out8 (0x3d4, 0x53, par);
+	cr53 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d5, cr53 & 0x7f, par);
 
-	vga_out8 (0x3d4, 0x66);
-	vga_out8 (0x3d5, cr66);
-	vga_out8 (0x3d4, 0x3a);
-	vga_out8 (0x3d5, cr3a);
+	vga_out8 (0x3d4, 0x66, par);
+	vga_out8 (0x3d5, cr66, par);
+	vga_out8 (0x3d4, 0x3a, par);
+	vga_out8 (0x3d5, cr3a, par);
 
-	vga_out8 (0x3d4, 0x66);
-	vga_out8 (0x3d5, cr66);
-	vga_out8 (0x3d4, 0x3a);
-	vga_out8 (0x3d5, cr3a);
+	vga_out8 (0x3d4, 0x66, par);
+	vga_out8 (0x3d5, cr66, par);
+	vga_out8 (0x3d4, 0x3a, par);
+	vga_out8 (0x3d5, cr3a, par);
 
 	/* unlock extended seq regs */
-	vga_out8 (0x3c4, 0x08);
-	par->SR08 = vga_in8 (0x3c5);
-	vga_out8 (0x3c5, 0x06);
+	vga_out8 (0x3c4, 0x08, par);
+	par->SR08 = vga_in8 (0x3c5, par);
+	vga_out8 (0x3c5, 0x06, par);
 
 	/* now save all the extended regs we need */
-	vga_out8 (0x3d4, 0x31);
-	par->CR31 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x32);
-	par->CR32 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x34);
-	par->CR34 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x36);
-	par->CR36 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x3a);
-	par->CR3A = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x40);
-	par->CR40 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x42);
-	par->CR42 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x45);
-	par->CR45 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x50);
-	par->CR50 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x51);
-	par->CR51 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x53);
-	par->CR53 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x58);
-	par->CR58 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x60);
-	par->CR60 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x66);
-	par->CR66 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x67);
-	par->CR67 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x68);
-	par->CR68 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x69);
-	par->CR69 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x6f);
-	par->CR6F = vga_in8 (0x3d5);
+	vga_out8 (0x3d4, 0x31, par);
+	par->CR31 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x32, par);
+	par->CR32 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x34, par);
+	par->CR34 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x36, par);
+	par->CR36 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x3a, par);
+	par->CR3A = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x40, par);
+	par->CR40 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x42, par);
+	par->CR42 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x45, par);
+	par->CR45 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x50, par);
+	par->CR50 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x51, par);
+	par->CR51 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x53, par);
+	par->CR53 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x58, par);
+	par->CR58 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x60, par);
+	par->CR60 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x66, par);
+	par->CR66 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x67, par);
+	par->CR67 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x68, par);
+	par->CR68 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x69, par);
+	par->CR69 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x6f, par);
+	par->CR6F = vga_in8 (0x3d5, par);
 
-	vga_out8 (0x3d4, 0x33);
-	par->CR33 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x86);
-	par->CR86 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x88);
-	par->CR88 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x90);
-	par->CR90 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x91);
-	par->CR91 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0xb0);
-	par->CRB0 = vga_in8 (0x3d5) | 0x80;
+	vga_out8 (0x3d4, 0x33, par);
+	par->CR33 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x86, par);
+	par->CR86 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x88, par);
+	par->CR88 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x90, par);
+	par->CR90 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x91, par);
+	par->CR91 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0xb0, par);
+	par->CRB0 = vga_in8 (0x3d5, par) | 0x80;
 
 	/* extended mode timing regs */
-	vga_out8 (0x3d4, 0x3b);
-	par->CR3B = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x3c);
-	par->CR3C = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x43);
-	par->CR43 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x5d);
-	par->CR5D = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x5e);
-	par->CR5E = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x65);
-	par->CR65 = vga_in8 (0x3d5);
+	vga_out8 (0x3d4, 0x3b, par);
+	par->CR3B = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x3c, par);
+	par->CR3C = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x43, par);
+	par->CR43 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x5d, par);
+	par->CR5D = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x5e, par);
+	par->CR5E = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x65, par);
+	par->CR65 = vga_in8 (0x3d5, par);
 
 	/* save seq extended regs for DCLK PLL programming */
-	vga_out8 (0x3c4, 0x0e);
-	par->SR0E = vga_in8 (0x3c5);
-	vga_out8 (0x3c4, 0x0f);
-	par->SR0F = vga_in8 (0x3c5);
-	vga_out8 (0x3c4, 0x10);
-	par->SR10 = vga_in8 (0x3c5);
-	vga_out8 (0x3c4, 0x11);
-	par->SR11 = vga_in8 (0x3c5);
-	vga_out8 (0x3c4, 0x12);
-	par->SR12 = vga_in8 (0x3c5);
-	vga_out8 (0x3c4, 0x13);
-	par->SR13 = vga_in8 (0x3c5);
-	vga_out8 (0x3c4, 0x29);
-	par->SR29 = vga_in8 (0x3c5);
+	vga_out8 (0x3c4, 0x0e, par);
+	par->SR0E = vga_in8 (0x3c5, par);
+	vga_out8 (0x3c4, 0x0f, par);
+	par->SR0F = vga_in8 (0x3c5, par);
+	vga_out8 (0x3c4, 0x10, par);
+	par->SR10 = vga_in8 (0x3c5, par);
+	vga_out8 (0x3c4, 0x11, par);
+	par->SR11 = vga_in8 (0x3c5, par);
+	vga_out8 (0x3c4, 0x12, par);
+	par->SR12 = vga_in8 (0x3c5, par);
+	vga_out8 (0x3c4, 0x13, par);
+	par->SR13 = vga_in8 (0x3c5, par);
+	vga_out8 (0x3c4, 0x29, par);
+	par->SR29 = vga_in8 (0x3c5, par);
 
-	vga_out8 (0x3c4, 0x15);
-	par->SR15 = vga_in8 (0x3c5);
-	vga_out8 (0x3c4, 0x30);
-	par->SR30 = vga_in8 (0x3c5);
-	vga_out8 (0x3c4, 0x18);
-	par->SR18 = vga_in8 (0x3c5);
+	vga_out8 (0x3c4, 0x15, par);
+	par->SR15 = vga_in8 (0x3c5, par);
+	vga_out8 (0x3c4, 0x30, par);
+	par->SR30 = vga_in8 (0x3c5, par);
+	vga_out8 (0x3c4, 0x18, par);
+	par->SR18 = vga_in8 (0x3c5, par);
 
 	/* Save flat panel expansion regsters. */
 	if (par->chip == S3_SAVAGE_MX) {
 		int i;
 
 		for (i = 0; i < 8; i++) {
-			vga_out8 (0x3c4, 0x54+i);
-			par->SR54[i] = vga_in8 (0x3c5);
+			vga_out8 (0x3c4, 0x54+i, par);
+			par->SR54[i] = vga_in8 (0x3c5, par);
 		}
 	}
 
-	vga_out8 (0x3d4, 0x66);
-	cr66 = vga_in8 (0x3d5);
-	vga_out8 (0x3d5, cr66 | 0x80);
-	vga_out8 (0x3d4, 0x3a);
-	cr3a = vga_in8 (0x3d5);
-	vga_out8 (0x3d5, cr3a | 0x80);
+	vga_out8 (0x3d4, 0x66, par);
+	cr66 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d5, cr66 | 0x80, par);
+	vga_out8 (0x3d4, 0x3a, par);
+	cr3a = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d5, cr3a | 0x80, par);
 
 	/* now save MIU regs */
 	if (par->chip != S3_SAVAGE_MX) {
-		par->MMPR0 = savage_in32(FIFO_CONTROL_REG);
-		par->MMPR1 = savage_in32(MIU_CONTROL_REG);
-		par->MMPR2 = savage_in32(STREAMS_TIMEOUT_REG);
-		par->MMPR3 = savage_in32(MISC_TIMEOUT_REG);
+		par->MMPR0 = savage_in32(FIFO_CONTROL_REG, par);
+		par->MMPR1 = savage_in32(MIU_CONTROL_REG, par);
+		par->MMPR2 = savage_in32(STREAMS_TIMEOUT_REG, par);
+		par->MMPR3 = savage_in32(MISC_TIMEOUT_REG, par);
 	}
 
-	vga_out8 (0x3d4, 0x3a);
-	vga_out8 (0x3d5, cr3a);
-	vga_out8 (0x3d4, 0x66);
-	vga_out8 (0x3d5, cr66);
+	vga_out8 (0x3d4, 0x3a, par);
+	vga_out8 (0x3d5, cr3a, par);
+	vga_out8 (0x3d4, 0x66, par);
+	vga_out8 (0x3d5, cr66, par);
 }
 
 static void savage_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb)
@@ -868,8 +872,8 @@
 	 * match.  Fall back to traditional register-crunching.
 	 */
 
-	vga_out8 (0x3d4, 0x3a);
-	tmp = vga_in8 (0x3d5);
+	vga_out8 (0x3d4, 0x3a, par);
+	tmp = vga_in8 (0x3d5, par);
 	if (1 /*FIXME:psav->pci_burst*/)
 		par->CR3A = (tmp & 0x7f) | 0x15;
 	else
@@ -879,16 +883,16 @@
 	par->CR31 = 0x8c;
 	par->CR66 = 0x89;
 
-	vga_out8 (0x3d4, 0x58);
-	par->CR58 = vga_in8 (0x3d5) & 0x80;
+	vga_out8 (0x3d4, 0x58, par);
+	par->CR58 = vga_in8 (0x3d5, par) & 0x80;
 	par->CR58 |= 0x13;
 
 	par->SR15 = 0x03 | 0x80;
 	par->SR18 = 0x00;
 	par->CR43 = par->CR45 = par->CR65 = 0x00;
 
-	vga_out8 (0x3d4, 0x40);
-	par->CR40 = vga_in8 (0x3d5) & ~0x01;
+	vga_out8 (0x3d4, 0x40, par);
+	par->CR40 = vga_in8 (0x3d5, par) & ~0x01;
 
 	par->MMPR0 = 0x010400;
 	par->MMPR1 = 0x00;
@@ -992,19 +996,19 @@
 
 	par->CR67 |= 1;
 
-	vga_out8(0x3d4, 0x36);
-	par->CR36 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x68);
-	par->CR68 = vga_in8 (0x3d5);
+	vga_out8(0x3d4, 0x36, par);
+	par->CR36 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x68, par);
+	par->CR68 = vga_in8 (0x3d5, par);
 	par->CR69 = 0;
-	vga_out8 (0x3d4, 0x6f);
-	par->CR6F = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x86);
-	par->CR86 = vga_in8 (0x3d5);
-	vga_out8 (0x3d4, 0x88);
-	par->CR88 = vga_in8 (0x3d5) | 0x08;
-	vga_out8 (0x3d4, 0xb0);
-	par->CRB0 = vga_in8 (0x3d5) | 0x80;
+	vga_out8 (0x3d4, 0x6f, par);
+	par->CR6F = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x86, par);
+	par->CR86 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d4, 0x88, par);
+	par->CR88 = vga_in8 (0x3d5, par) | 0x08;
+	vga_out8 (0x3d4, 0xb0, par);
+	par->CRB0 = vga_in8 (0x3d5, par) | 0x80;
 
 	return 0;
 }
@@ -1033,11 +1037,11 @@
 
 	switch (info->var.bits_per_pixel) {
 	case 8:
-		vga_out8 (0x3c8, regno);
+		vga_out8 (0x3c8, regno, par);
 
-		vga_out8 (0x3c9, red   >> 10);
-		vga_out8 (0x3c9, green >> 10);
-		vga_out8 (0x3c9, blue  >> 10);
+		vga_out8 (0x3c9, red   >> 10, par);
+		vga_out8 (0x3c9, green >> 10, par);
+		vga_out8 (0x3c9, blue  >> 10, par);
 		break;
 
 	case 16:
@@ -1079,11 +1083,11 @@
 
 	par->SavageWaitIdle (par);
 
-	vga_out8 (0x3c2, 0x23);
+	vga_out8 (0x3c2, 0x23, par);
 
-	vga_out16 (0x3d4, 0x4838);
-	vga_out16 (0x3d4, 0xa539);
-	vga_out16 (0x3c4, 0x0608);
+	vga_out16 (0x3d4, 0x4838, par);
+	vga_out16 (0x3d4, 0xa539, par);
+	vga_out16 (0x3c4, 0x0608, par);
 
 	vgaHWProtect (par, 1);
 
@@ -1094,197 +1098,197 @@
 	 * switch to mode 3 here seems to eliminate the issue.
 	 */
 
-	VerticalRetraceWait();
-	vga_out8 (0x3d4, 0x67);
-	cr67 = vga_in8 (0x3d5);
-	vga_out8 (0x3d5, cr67/*par->CR67*/ & ~0x0c); /* no STREAMS yet */
+	VerticalRetraceWait(par);
+	vga_out8 (0x3d4, 0x67, par);
+	cr67 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d5, cr67/*par->CR67*/ & ~0x0c, par); /* no STREAMS yet */
 
-	vga_out8 (0x3d4, 0x23);
-	vga_out8 (0x3d5, 0x00);
-	vga_out8 (0x3d4, 0x26);
-	vga_out8 (0x3d5, 0x00);
+	vga_out8 (0x3d4, 0x23, par);
+	vga_out8 (0x3d5, 0x00, par);
+	vga_out8 (0x3d4, 0x26, par);
+	vga_out8 (0x3d5, 0x00, par);
 
 	/* restore extended regs */
-	vga_out8 (0x3d4, 0x66);
-	vga_out8 (0x3d5, par->CR66);
-	vga_out8 (0x3d4, 0x3a);
-	vga_out8 (0x3d5, par->CR3A);
-	vga_out8 (0x3d4, 0x31);
-	vga_out8 (0x3d5, par->CR31);
-	vga_out8 (0x3d4, 0x32);
-	vga_out8 (0x3d5, par->CR32);
-	vga_out8 (0x3d4, 0x58);
-	vga_out8 (0x3d5, par->CR58);
-	vga_out8 (0x3d4, 0x53);
-	vga_out8 (0x3d5, par->CR53 & 0x7f);
+	vga_out8 (0x3d4, 0x66, par);
+	vga_out8 (0x3d5, par->CR66, par);
+	vga_out8 (0x3d4, 0x3a, par);
+	vga_out8 (0x3d5, par->CR3A, par);
+	vga_out8 (0x3d4, 0x31, par);
+	vga_out8 (0x3d5, par->CR31, par);
+	vga_out8 (0x3d4, 0x32, par);
+	vga_out8 (0x3d5, par->CR32, par);
+	vga_out8 (0x3d4, 0x58, par);
+	vga_out8 (0x3d5, par->CR58, par);
+	vga_out8 (0x3d4, 0x53, par);
+	vga_out8 (0x3d5, par->CR53 & 0x7f, par);
 
-	vga_out16 (0x3c4, 0x0608);
+	vga_out16 (0x3c4, 0x0608, par);
 
 	/* Restore DCLK registers. */
 
-	vga_out8 (0x3c4, 0x0e);
-	vga_out8 (0x3c5, par->SR0E);
-	vga_out8 (0x3c4, 0x0f);
-	vga_out8 (0x3c5, par->SR0F);
-	vga_out8 (0x3c4, 0x29);
-	vga_out8 (0x3c5, par->SR29);
-	vga_out8 (0x3c4, 0x15);
-	vga_out8 (0x3c5, par->SR15);
+	vga_out8 (0x3c4, 0x0e, par);
+	vga_out8 (0x3c5, par->SR0E, par);
+	vga_out8 (0x3c4, 0x0f, par);
+	vga_out8 (0x3c5, par->SR0F, par);
+	vga_out8 (0x3c4, 0x29, par);
+	vga_out8 (0x3c5, par->SR29, par);
+	vga_out8 (0x3c4, 0x15, par);
+	vga_out8 (0x3c5, par->SR15, par);
 
 	/* Restore flat panel expansion regsters. */
 	if( par->chip == S3_SAVAGE_MX ) {
 		int i;
 
 		for( i = 0; i < 8; i++ ) {
-			vga_out8 (0x3c4, 0x54+i);
-			vga_out8 (0x3c5, par->SR54[i]);
+			vga_out8 (0x3c4, 0x54+i, par);
+			vga_out8 (0x3c5, par->SR54[i], par);
 		}
 	}
 
 	vgaHWRestore (par);
 
 	/* extended mode timing registers */
-	vga_out8 (0x3d4, 0x53);
-	vga_out8 (0x3d5, par->CR53);
-	vga_out8 (0x3d4, 0x5d);
-	vga_out8 (0x3d5, par->CR5D);
-	vga_out8 (0x3d4, 0x5e);
-	vga_out8 (0x3d5, par->CR5E);
-	vga_out8 (0x3d4, 0x3b);
-	vga_out8 (0x3d5, par->CR3B);
-	vga_out8 (0x3d4, 0x3c);
-	vga_out8 (0x3d5, par->CR3C);
-	vga_out8 (0x3d4, 0x43);
-	vga_out8 (0x3d5, par->CR43);
-	vga_out8 (0x3d4, 0x65);
-	vga_out8 (0x3d5, par->CR65);
+	vga_out8 (0x3d4, 0x53, par);
+	vga_out8 (0x3d5, par->CR53, par);
+	vga_out8 (0x3d4, 0x5d, par);
+	vga_out8 (0x3d5, par->CR5D, par);
+	vga_out8 (0x3d4, 0x5e, par);
+	vga_out8 (0x3d5, par->CR5E, par);
+	vga_out8 (0x3d4, 0x3b, par);
+	vga_out8 (0x3d5, par->CR3B, par);
+	vga_out8 (0x3d4, 0x3c, par);
+	vga_out8 (0x3d5, par->CR3C, par);
+	vga_out8 (0x3d4, 0x43, par);
+	vga_out8 (0x3d5, par->CR43, par);
+	vga_out8 (0x3d4, 0x65, par);
+	vga_out8 (0x3d5, par->CR65, par);
 
 	/* restore the desired video mode with cr67 */
-	vga_out8 (0x3d4, 0x67);
+	vga_out8 (0x3d4, 0x67, par);
 	/* following part not present in X11 driver */
-	cr67 = vga_in8 (0x3d5) & 0xf;
-	vga_out8 (0x3d5, 0x50 | cr67);
+	cr67 = vga_in8 (0x3d5, par) & 0xf;
+	vga_out8 (0x3d5, 0x50 | cr67, par);
 	udelay (10000);
-	vga_out8 (0x3d4, 0x67);
+	vga_out8 (0x3d4, 0x67, par);
 	/* end of part */
-	vga_out8 (0x3d5, par->CR67 & ~0x0c);
+	vga_out8 (0x3d5, par->CR67 & ~0x0c, par);
 
 	/* other mode timing and extended regs */
-	vga_out8 (0x3d4, 0x34);
-	vga_out8 (0x3d5, par->CR34);
-	vga_out8 (0x3d4, 0x40);
-	vga_out8 (0x3d5, par->CR40);
-	vga_out8 (0x3d4, 0x42);
-	vga_out8 (0x3d5, par->CR42);
-	vga_out8 (0x3d4, 0x45);
-	vga_out8 (0x3d5, par->CR45);
-	vga_out8 (0x3d4, 0x50);
-	vga_out8 (0x3d5, par->CR50);
-	vga_out8 (0x3d4, 0x51);
-	vga_out8 (0x3d5, par->CR51);
+	vga_out8 (0x3d4, 0x34, par);
+	vga_out8 (0x3d5, par->CR34, par);
+	vga_out8 (0x3d4, 0x40, par);
+	vga_out8 (0x3d5, par->CR40, par);
+	vga_out8 (0x3d4, 0x42, par);
+	vga_out8 (0x3d5, par->CR42, par);
+	vga_out8 (0x3d4, 0x45, par);
+	vga_out8 (0x3d5, par->CR45, par);
+	vga_out8 (0x3d4, 0x50, par);
+	vga_out8 (0x3d5, par->CR50, par);
+	vga_out8 (0x3d4, 0x51, par);
+	vga_out8 (0x3d5, par->CR51, par);
 
 	/* memory timings */
-	vga_out8 (0x3d4, 0x36);
-	vga_out8 (0x3d5, par->CR36);
-	vga_out8 (0x3d4, 0x60);
-	vga_out8 (0x3d5, par->CR60);
-	vga_out8 (0x3d4, 0x68);
-	vga_out8 (0x3d5, par->CR68);
-	vga_out8 (0x3d4, 0x69);
-	vga_out8 (0x3d5, par->CR69);
-	vga_out8 (0x3d4, 0x6f);
-	vga_out8 (0x3d5, par->CR6F);
+	vga_out8 (0x3d4, 0x36, par);
+	vga_out8 (0x3d5, par->CR36, par);
+	vga_out8 (0x3d4, 0x60, par);
+	vga_out8 (0x3d5, par->CR60, par);
+	vga_out8 (0x3d4, 0x68, par);
+	vga_out8 (0x3d5, par->CR68, par);
+	vga_out8 (0x3d4, 0x69, par);
+	vga_out8 (0x3d5, par->CR69, par);
+	vga_out8 (0x3d4, 0x6f, par);
+	vga_out8 (0x3d5, par->CR6F, par);
 
-	vga_out8 (0x3d4, 0x33);
-	vga_out8 (0x3d5, par->CR33);
-	vga_out8 (0x3d4, 0x86);
-	vga_out8 (0x3d5, par->CR86);
-	vga_out8 (0x3d4, 0x88);
-	vga_out8 (0x3d5, par->CR88);
-	vga_out8 (0x3d4, 0x90);
-	vga_out8 (0x3d5, par->CR90);
-	vga_out8 (0x3d4, 0x91);
-	vga_out8 (0x3d5, par->CR91);
+	vga_out8 (0x3d4, 0x33, par);
+	vga_out8 (0x3d5, par->CR33, par);
+	vga_out8 (0x3d4, 0x86, par);
+	vga_out8 (0x3d5, par->CR86, par);
+	vga_out8 (0x3d4, 0x88, par);
+	vga_out8 (0x3d5, par->CR88, par);
+	vga_out8 (0x3d4, 0x90, par);
+	vga_out8 (0x3d5, par->CR90, par);
+	vga_out8 (0x3d4, 0x91, par);
+	vga_out8 (0x3d5, par->CR91, par);
 
 	if (par->chip == S3_SAVAGE4) {
-		vga_out8 (0x3d4, 0xb0);
-		vga_out8 (0x3d5, par->CRB0);
+		vga_out8 (0x3d4, 0xb0, par);
+		vga_out8 (0x3d5, par->CRB0, par);
 	}
 
-	vga_out8 (0x3d4, 0x32);
-	vga_out8 (0x3d5, par->CR32);
+	vga_out8 (0x3d4, 0x32, par);
+	vga_out8 (0x3d5, par->CR32, par);
 
 	/* unlock extended seq regs */
-	vga_out8 (0x3c4, 0x08);
-	vga_out8 (0x3c5, 0x06);
+	vga_out8 (0x3c4, 0x08, par);
+	vga_out8 (0x3c5, 0x06, par);
 
 	/* Restore extended sequencer regs for MCLK. SR10 == 255 indicates
 	 * that we should leave the default SR10 and SR11 values there.
 	 */
 	if (par->SR10 != 255) {
-		vga_out8 (0x3c4, 0x10);
-		vga_out8 (0x3c5, par->SR10);
-		vga_out8 (0x3c4, 0x11);
-		vga_out8 (0x3c5, par->SR11);
+		vga_out8 (0x3c4, 0x10, par);
+		vga_out8 (0x3c5, par->SR10, par);
+		vga_out8 (0x3c4, 0x11, par);
+		vga_out8 (0x3c5, par->SR11, par);
 	}
 
 	/* restore extended seq regs for dclk */
-	vga_out8 (0x3c4, 0x0e);
-	vga_out8 (0x3c5, par->SR0E);
-	vga_out8 (0x3c4, 0x0f);
-	vga_out8 (0x3c5, par->SR0F);
-	vga_out8 (0x3c4, 0x12);
-	vga_out8 (0x3c5, par->SR12);
-	vga_out8 (0x3c4, 0x13);
-	vga_out8 (0x3c5, par->SR13);
-	vga_out8 (0x3c4, 0x29);
-	vga_out8 (0x3c5, par->SR29);
+	vga_out8 (0x3c4, 0x0e, par);
+	vga_out8 (0x3c5, par->SR0E, par);
+	vga_out8 (0x3c4, 0x0f, par);
+	vga_out8 (0x3c5, par->SR0F, par);
+	vga_out8 (0x3c4, 0x12, par);
+	vga_out8 (0x3c5, par->SR12, par);
+	vga_out8 (0x3c4, 0x13, par);
+	vga_out8 (0x3c5, par->SR13, par);
+	vga_out8 (0x3c4, 0x29, par);
+	vga_out8 (0x3c5, par->SR29, par);
 
-	vga_out8 (0x3c4, 0x18);
-	vga_out8 (0x3c5, par->SR18);
+	vga_out8 (0x3c4, 0x18, par);
+	vga_out8 (0x3c5, par->SR18, par);
 
 	/* load new m, n pll values for dclk & mclk */
-	vga_out8 (0x3c4, 0x15);
-	tmp = vga_in8 (0x3c5) & ~0x21;
+	vga_out8 (0x3c4, 0x15, par);
+	tmp = vga_in8 (0x3c5, par) & ~0x21;
 
-	vga_out8 (0x3c5, tmp | 0x03);
-	vga_out8 (0x3c5, tmp | 0x23);
-	vga_out8 (0x3c5, tmp | 0x03);
-	vga_out8 (0x3c5, par->SR15);
+	vga_out8 (0x3c5, tmp | 0x03, par);
+	vga_out8 (0x3c5, tmp | 0x23, par);
+	vga_out8 (0x3c5, tmp | 0x03, par);
+	vga_out8 (0x3c5, par->SR15, par);
 	udelay (100);
 
-	vga_out8 (0x3c4, 0x30);
-	vga_out8 (0x3c5, par->SR30);
-	vga_out8 (0x3c4, 0x08);
-	vga_out8 (0x3c5, par->SR08);
+	vga_out8 (0x3c4, 0x30, par);
+	vga_out8 (0x3c5, par->SR30, par);
+	vga_out8 (0x3c4, 0x08, par);
+	vga_out8 (0x3c5, par->SR08, par);
 
 	/* now write out cr67 in full, possibly starting STREAMS */
-	VerticalRetraceWait();
-	vga_out8 (0x3d4, 0x67);
-	vga_out8 (0x3d5, par->CR67);
+	VerticalRetraceWait(par);
+	vga_out8 (0x3d4, 0x67, par);
+	vga_out8 (0x3d5, par->CR67, par);
 
-	vga_out8 (0x3d4, 0x66);
-	cr66 = vga_in8 (0x3d5);
-	vga_out8 (0x3d5, cr66 | 0x80);
-	vga_out8 (0x3d4, 0x3a);
-	cr3a = vga_in8 (0x3d5);
-	vga_out8 (0x3d5, cr3a | 0x80);
+	vga_out8 (0x3d4, 0x66, par);
+	cr66 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d5, cr66 | 0x80, par);
+	vga_out8 (0x3d4, 0x3a, par);
+	cr3a = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d5, cr3a | 0x80, par);
 
 	if (par->chip != S3_SAVAGE_MX) {
-		VerticalRetraceWait();
-		savage_out32 (FIFO_CONTROL_REG, par->MMPR0);
+		VerticalRetraceWait(par);
+		savage_out32 (FIFO_CONTROL_REG, par->MMPR0, par);
 		par->SavageWaitIdle (par);
-		savage_out32 (MIU_CONTROL_REG, par->MMPR1);
+		savage_out32 (MIU_CONTROL_REG, par->MMPR1, par);
 		par->SavageWaitIdle (par);
-		savage_out32 (STREAMS_TIMEOUT_REG, par->MMPR2);
+		savage_out32 (STREAMS_TIMEOUT_REG, par->MMPR2, par);
 		par->SavageWaitIdle (par);
-		savage_out32 (MISC_TIMEOUT_REG, par->MMPR3);
+		savage_out32 (MISC_TIMEOUT_REG, par->MMPR3, par);
 	}
 
-	vga_out8 (0x3d4, 0x66);
-	vga_out8 (0x3d5, cr66);
-	vga_out8 (0x3d4, 0x3a);
-	vga_out8 (0x3d5, cr3a);
+	vga_out8 (0x3d4, 0x66, par);
+	vga_out8 (0x3d5, cr66, par);
+	vga_out8 (0x3d4, 0x3a, par);
+	vga_out8 (0x3d5, cr3a, par);
 
 	SavageSetup2DEngine (par);
 	vgaHWProtect (par, 0);
@@ -1299,10 +1303,10 @@
 		* ((var->bits_per_pixel+7) / 8)) >> 2;
 
 	/* now program the start address registers */
-	vga_out16(0x3d4, (base & 0x00ff00) | 0x0c);
-	vga_out16(0x3d4, ((base & 0x00ff) << 8) | 0x0d);
-	vga_out8 (0x3d4, 0x69);
-	vga_out8 (0x3d5, (base & 0x7f0000) >> 16);
+	vga_out16(0x3d4, (base & 0x00ff00) | 0x0c, par);
+	vga_out16(0x3d4, ((base & 0x00ff) << 8) | 0x0d, par);
+	vga_out8 (0x3d4, 0x69, par);
+	vga_out8 (0x3d5, (base & 0x7f0000) >> 16, par);
 }
 
 
@@ -1406,12 +1410,12 @@
 	u8 sr8 = 0, srd = 0;
 
 	if (par->display_type == DISP_CRT) {
-		vga_out8(0x3c4, 0x08);
-		sr8 = vga_in8(0x3c5);
+		vga_out8(0x3c4, 0x08, par);
+		sr8 = vga_in8(0x3c5, par);
 		sr8 |= 0x06;
-		vga_out8(0x3c5, sr8);
-		vga_out8(0x3c4, 0x0d);
-		srd = vga_in8(0x3c5);
+		vga_out8(0x3c5, sr8, par);
+		vga_out8(0x3c4, 0x0d, par);
+		srd = vga_in8(0x3c5, par);
 		srd &= 0x03;
 
 		switch (blank) {
@@ -1429,8 +1433,8 @@
 			break;
 		}
 
-		vga_out8(0x3c4, 0x0d);
-		vga_out8(0x3c5, srd);
+		vga_out8(0x3c4, 0x0d, par);
+		vga_out8(0x3c5, srd, par);
 	}
 
 	if (par->display_type == DISP_LCD ||
@@ -1438,14 +1442,14 @@
 		switch(blank) {
 		case FB_BLANK_UNBLANK:
 		case FB_BLANK_NORMAL:
-			vga_out8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */
-			vga_out8(0x3c5, vga_in8(0x3c5) | 0x10);
+			vga_out8(0x3c4, 0x31, par); /* SR31 bit 4 - FP enable */
+			vga_out8(0x3c5, vga_in8(0x3c5, par) | 0x10, par);
 			break;
 		case FB_BLANK_VSYNC_SUSPEND:
 		case FB_BLANK_HSYNC_SUSPEND:
 		case FB_BLANK_POWERDOWN:
-			vga_out8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */
-			vga_out8(0x3c5, vga_in8(0x3c5) & ~0x10);
+			vga_out8(0x3c4, 0x31, par); /* SR31 bit 4 - FP enable */
+			vga_out8(0x3c5, vga_in8(0x3c5, par) & ~0x10, par);
 			break;
 		}
 	}
@@ -1470,7 +1474,6 @@
 	.fb_copyarea    = cfb_copyarea,
 	.fb_imageblit   = cfb_imageblit,
 #endif
-	.fb_cursor      = soft_cursor,
 };
 
 /* --------------------------------------------------------------------- */
@@ -1499,15 +1502,15 @@
 
 	DBG ("savage_enable_mmio\n");
 
-	val = vga_in8 (0x3c3);
-	vga_out8 (0x3c3, val | 0x01);
-	val = vga_in8 (0x3cc);
-	vga_out8 (0x3c2, val | 0x01);
+	val = vga_in8 (0x3c3, par);
+	vga_out8 (0x3c3, val | 0x01, par);
+	val = vga_in8 (0x3cc, par);
+	vga_out8 (0x3c2, val | 0x01, par);
 
 	if (par->chip >= S3_SAVAGE4) {
-		vga_out8 (0x3d4, 0x40);
-		val = vga_in8 (0x3d5);
-		vga_out8 (0x3d5, val | 1);
+		vga_out8 (0x3d4, 0x40, par);
+		val = vga_in8 (0x3d5, par);
+		vga_out8 (0x3d5, val | 1, par);
 	}
 }
 
@@ -1519,9 +1522,9 @@
 	DBG ("savage_disable_mmio\n");
 
 	if(par->chip >= S3_SAVAGE4 ) {
-		vga_out8 (0x3d4, 0x40);
-		val = vga_in8 (0x3d5);
-		vga_out8 (0x3d5, val | 1);
+		vga_out8 (0x3d4, 0x40, par);
+		val = vga_in8 (0x3d5, par);
+		vga_out8 (0x3d5, val | 1, par);
 	}
 }
 
@@ -1641,30 +1644,30 @@
 	DBG("savage_init_hw");
 
 	/* unprotect CRTC[0-7] */
-	vga_out8(0x3d4, 0x11);
-	tmp = vga_in8(0x3d5);
-	vga_out8(0x3d5, tmp & 0x7f);
+	vga_out8(0x3d4, 0x11, par);
+	tmp = vga_in8(0x3d5, par);
+	vga_out8(0x3d5, tmp & 0x7f, par);
 
 	/* unlock extended regs */
-	vga_out16(0x3d4, 0x4838);
-	vga_out16(0x3d4, 0xa039);
-	vga_out16(0x3c4, 0x0608);
+	vga_out16(0x3d4, 0x4838, par);
+	vga_out16(0x3d4, 0xa039, par);
+	vga_out16(0x3c4, 0x0608, par);
 
-	vga_out8(0x3d4, 0x40);
-	tmp = vga_in8(0x3d5);
-	vga_out8(0x3d5, tmp & ~0x01);
+	vga_out8(0x3d4, 0x40, par);
+	tmp = vga_in8(0x3d5, par);
+	vga_out8(0x3d5, tmp & ~0x01, par);
 
 	/* unlock sys regs */
-	vga_out8(0x3d4, 0x38);
-	vga_out8(0x3d5, 0x48);
+	vga_out8(0x3d4, 0x38, par);
+	vga_out8(0x3d5, 0x48, par);
 
 	/* Unlock system registers. */
-	vga_out16(0x3d4, 0x4838);
+	vga_out16(0x3d4, 0x4838, par);
 
 	/* Next go on to detect amount of installed ram */
 
-	vga_out8(0x3d4, 0x36);            /* for register CR36 (CONFG_REG1), */
-	config1 = vga_in8(0x3d5);           /* get amount of vram installed */
+	vga_out8(0x3d4, 0x36, par);            /* for register CR36 (CONFG_REG1), */
+	config1 = vga_in8(0x3d5, par);    /* get amount of vram installed */
 
 	/* Compute the amount of video memory and offscreen memory. */
 
@@ -1680,8 +1683,8 @@
 		 * when it really means 8MB.  Why do it the same when you
 		 * can do it different...
 		 */
-		vga_out8(0x3d4, 0x68);	/* memory control 1 */
-		if( (vga_in8(0x3d5) & 0xC0) == (0x01 << 6) )
+		vga_out8(0x3d4, 0x68, par);	/* memory control 1 */
+		if( (vga_in8(0x3d5, par) & 0xC0) == (0x01 << 6) )
 			RamSavage4[1] = 8;
 
 		/*FALLTHROUGH*/
@@ -1710,13 +1713,13 @@
 	printk (KERN_INFO "savagefb: probed videoram:  %dk\n", videoRam);
 
 	/* reset graphics engine to avoid memory corruption */
-	vga_out8 (0x3d4, 0x66);
-	cr66 = vga_in8 (0x3d5);
-	vga_out8 (0x3d5, cr66 | 0x02);
+	vga_out8 (0x3d4, 0x66, par);
+	cr66 = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d5, cr66 | 0x02, par);
 	udelay (10000);
 
-	vga_out8 (0x3d4, 0x66);
-	vga_out8 (0x3d5, cr66 & ~0x02);	/* clear reset flag */
+	vga_out8 (0x3d4, 0x66, par);
+	vga_out8 (0x3d5, cr66 & ~0x02, par);	/* clear reset flag */
 	udelay (10000);
 
 
@@ -1724,13 +1727,13 @@
 	 * reset memory interface, 3D engine, AGP master, PCI master,
 	 * master engine unit, motion compensation/LPB
 	 */
-	vga_out8 (0x3d4, 0x3f);
-	cr3f = vga_in8 (0x3d5);
-	vga_out8 (0x3d5, cr3f | 0x08);
+	vga_out8 (0x3d4, 0x3f, par);
+	cr3f = vga_in8 (0x3d5, par);
+	vga_out8 (0x3d5, cr3f | 0x08, par);
 	udelay (10000);
 
-	vga_out8 (0x3d4, 0x3f);
-	vga_out8 (0x3d5, cr3f & ~0x08);	/* clear reset flags */
+	vga_out8 (0x3d4, 0x3f, par);
+	vga_out8 (0x3d5, cr3f & ~0x08, par);	/* clear reset flags */
 	udelay (10000);
 
 	/* Savage ramdac speeds */
@@ -1741,15 +1744,15 @@
 	par->clock[3] = 220000;
 
 	/* detect current mclk */
-	vga_out8(0x3c4, 0x08);
-	sr8 = vga_in8(0x3c5);
-	vga_out8(0x3c5, 0x06);
-	vga_out8(0x3c4, 0x10);
-	n = vga_in8(0x3c5);
-	vga_out8(0x3c4, 0x11);
-	m = vga_in8(0x3c5);
-	vga_out8(0x3c4, 0x08);
-	vga_out8(0x3c5, sr8);
+	vga_out8(0x3c4, 0x08, par);
+	sr8 = vga_in8(0x3c5, par);
+	vga_out8(0x3c5, 0x06, par);
+	vga_out8(0x3c4, 0x10, par);
+	n = vga_in8(0x3c5, par);
+	vga_out8(0x3c4, 0x11, par);
+	m = vga_in8(0x3c5, par);
+	vga_out8(0x3c4, 0x08, par);
+	vga_out8(0x3c5, sr8, par);
 	m &= 0x7f;
 	n1 = n & 0x1f;
 	n2 = (n >> 5) & 0x03;
@@ -1763,10 +1766,10 @@
 	if (par->chip == S3_SAVAGE4) {
 		unsigned char sr30 = 0x00;
 
-		vga_out8(0x3c4, 0x30);
+		vga_out8(0x3c4, 0x30, par);
 		/* clear bit 1 */
-		vga_out8(0x3c5, vga_in8(0x3c5) & ~0x02);
-		sr30 = vga_in8(0x3c5);
+		vga_out8(0x3c5, vga_in8(0x3c5, par) & ~0x02, par);
+		sr30 = vga_in8(0x3c5, par);
 		if (sr30 & 0x02 /*0x04 */) {
 			dvi = 1;
 			printk("savagefb: Digital Flat Panel Detected\n");
@@ -1783,12 +1786,12 @@
 	/* Check LCD panel parrmation */
 
 	if (par->display_type == DISP_LCD) {
-		unsigned char cr6b = VGArCR( 0x6b );
+		unsigned char cr6b = VGArCR( 0x6b, par);
 
-		int panelX = (VGArSEQ (0x61) +
-			      ((VGArSEQ (0x66) & 0x02) << 7) + 1) * 8;
-		int panelY = (VGArSEQ (0x69) +
-			      ((VGArSEQ (0x6e) & 0x70) << 4) + 1);
+		int panelX = (VGArSEQ (0x61, par) +
+			      ((VGArSEQ (0x66, par) & 0x02) << 7) + 1) * 8;
+		int panelY = (VGArSEQ (0x69, par) +
+			      ((VGArSEQ (0x6e, par) & 0x70) << 4) + 1);
 
 		char * sTechnology = "Unknown";
 
@@ -1810,9 +1813,9 @@
 			ActiveDUO = 0x80
 		};
 
-		if ((VGArSEQ (0x39) & 0x03) == 0) {
+		if ((VGArSEQ (0x39, par) & 0x03) == 0) {
 			sTechnology = "TFT";
-		} else if ((VGArSEQ (0x30) & 0x01) == 0) {
+		} else if ((VGArSEQ (0x30, par) & 0x01) == 0) {
 			sTechnology = "DSTN";
 		} else 	{
 			sTechnology = "STN";
@@ -2049,24 +2052,11 @@
 			     info->monspecs.modedb, info->monspecs.modedb_len,
 			     NULL, 8);
 	} else if (info->monspecs.modedb != NULL) {
-		struct fb_monspecs *specs = &info->monspecs;
-		struct fb_videomode modedb;
+		struct fb_videomode *modedb;
 
-		if (info->monspecs.misc & FB_MISC_1ST_DETAIL) {
-			int i;
-
-			for (i = 0; i < specs->modedb_len; i++) {
-				if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
-					modedb = specs->modedb[i];
-					break;
-				}
-			}
-		} else {
-			/* otherwise, get first mode in database */
-			modedb = specs->modedb[0];
-		}
-
-		savage_update_var(&info->var, &modedb);
+		modedb = fb_find_best_display(&info->monspecs,
+					      &info->modelist);
+		savage_update_var(&info->var, modedb);
 	}
 
 	/* maximize virtual vertical length */
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c
index 5ce81f4..2e8769d 100644
--- a/drivers/video/sgivwfb.c
+++ b/drivers/video/sgivwfb.c
@@ -126,7 +126,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 	.fb_mmap	= sgivwfb_mmap,
 };
 
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 42c54b6..dea1a46 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -2002,7 +2002,9 @@
 	.fb_fillrect	= fbcon_sis_fillrect,
 	.fb_copyarea	= fbcon_sis_copyarea,
 	.fb_imageblit	= cfb_imageblit,
+#ifdef CONFIG_FB_SOFT_CURSOR
 	.fb_cursor	= soft_cursor,
+#endif
 	.fb_sync	= fbcon_sis_sync,
 #ifdef SIS_NEW_CONFIG_COMPAT
 	.fb_compat_ioctl= sisfb_compat_ioctl,
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index 7b43716..a01e7ecc 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -457,11 +457,8 @@
 }
 
 /**
- *	xxxfb_cursor - 	REQUIRED function. If your hardware lacks support
- *			for a cursor you can use the default cursor whose
- *			function is called soft_cursor. It will always 
- *			work since it uses xxxfb_imageblit function which 
- *			is required. 	  	 
+ *	xxxfb_cursor - 	OPTIONAL. If your hardware lacks support
+ *			for a cursor, leave this field NULL.
  *
  *      @info: frame buffer structure that represents a single frame buffer
  *	@cursor: structure defining the cursor to draw.
@@ -663,7 +660,7 @@
 	.fb_fillrect	= xxxfb_fillrect, 	/* Needed !!! */ 
 	.fb_copyarea	= xxxfb_copyarea,	/* Needed !!! */ 
 	.fb_imageblit	= xxxfb_imageblit,	/* Needed !!! */
-	.fb_cursor	= xxxfb_cursor,		/* Needed !!! */
+	.fb_cursor	= xxxfb_cursor,		/* Optional !!! */
 	.fb_rotate	= xxxfb_rotate,
 	.fb_poll	= xxxfb_poll,
 	.fb_sync	= xxxfb_sync,
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index 663d536..e0f14df 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -1382,7 +1382,6 @@
 	.fb_fillrect	= cfb_fillrect, /* sstfb_fillrect */
 	.fb_copyarea	= cfb_copyarea, /* sstfb_copyarea */
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 	.fb_ioctl	= sstfb_ioctl,
 };
 
diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c
index 9e52794..fbb1733 100644
--- a/drivers/video/stifb.c
+++ b/drivers/video/stifb.c
@@ -1147,7 +1147,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor      = soft_cursor,
 };
 
 
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index 1986a8b..59fff29 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -52,7 +52,6 @@
 	.fb_imageblit		= cfb_imageblit,
 	.fb_mmap		= tcx_mmap,
 	.fb_ioctl		= tcx_ioctl,
-	.fb_cursor		= soft_cursor,
 };
 
 /* THC definitions */
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index 7044226..9d53387 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -184,7 +184,6 @@
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
 #endif
-	.fb_cursor	= soft_cursor,
 };
 
 /*
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index 9d9d200..7398bd4 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -63,7 +63,6 @@
 	.fb_fillrect		= tgafb_fillrect,
 	.fb_copyarea		= tgafb_copyarea,
 	.fb_imageblit		= tgafb_imageblit,
-	.fb_cursor		= soft_cursor,
 };
 
 
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index 81a6d9f..9ac2d31 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -1293,7 +1293,6 @@
 	.fb_fillrect = tridentfb_fillrect,
 	.fb_copyarea= tridentfb_copyarea,
 	.fb_imageblit = cfb_imageblit,
-	.fb_cursor = soft_cursor,
 };
 
 module_init(tridentfb_init);
diff --git a/drivers/video/tx3912fb.c b/drivers/video/tx3912fb.c
index 39d9ca7..d904da4 100644
--- a/drivers/video/tx3912fb.c
+++ b/drivers/video/tx3912fb.c
@@ -89,7 +89,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 static int tx3912fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
diff --git a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c
index 31a2bbc..ce97ec8 100644
--- a/drivers/video/valkyriefb.c
+++ b/drivers/video/valkyriefb.c
@@ -135,7 +135,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 /* Sets the video mode according to info->var */
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index 3cc2310..e25eae1 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -48,7 +48,7 @@
 };
 
 static int             inverse   = 0;
-static int             mtrr      = 3; /* default to write-combining */
+static int             mtrr      = 0; /* disable mtrr */
 static int	       vram_remap __initdata = 0; /* Set amount of memory to be used */
 static int	       vram_total __initdata = 0; /* Set total amount of memory */
 static int             pmi_setpal = 0;	/* pmi for palette changes ??? */
@@ -166,45 +166,39 @@
 	if (regno >= info->cmap.len)
 		return 1;
 
-	switch (info->var.bits_per_pixel) {
-	case 8:
+	if (info->var.bits_per_pixel == 8)
 		vesa_setpalette(regno,red,green,blue);
-		break;
-	case 16:
-		if (info->var.red.offset == 10) {
-			/* 1:5:5:5 */
-			((u32*) (info->pseudo_palette))[regno] =	
+	else if (regno < 16) {
+		switch (info->var.bits_per_pixel) {
+		case 16:
+			if (info->var.red.offset == 10) {
+				/* 1:5:5:5 */
+				((u32*) (info->pseudo_palette))[regno] =
 					((red   & 0xf800) >>  1) |
 					((green & 0xf800) >>  6) |
 					((blue  & 0xf800) >> 11);
-		} else {
-			/* 0:5:6:5 */
-			((u32*) (info->pseudo_palette))[regno] =	
+			} else {
+				/* 0:5:6:5 */
+				((u32*) (info->pseudo_palette))[regno] =
 					((red   & 0xf800)      ) |
 					((green & 0xfc00) >>  5) |
 					((blue  & 0xf800) >> 11);
+			}
+			break;
+		case 24:
+		case 32:
+			red   >>= 8;
+			green >>= 8;
+			blue  >>= 8;
+			((u32 *)(info->pseudo_palette))[regno] =
+				(red   << info->var.red.offset)   |
+				(green << info->var.green.offset) |
+				(blue  << info->var.blue.offset);
+			break;
 		}
-		break;
-	case 24:
-		red   >>= 8;
-		green >>= 8;
-		blue  >>= 8;
-		((u32 *)(info->pseudo_palette))[regno] =
-			(red   << info->var.red.offset)   |
-			(green << info->var.green.offset) |
-			(blue  << info->var.blue.offset);
-		break;
-	case 32:
-		red   >>= 8;
-		green >>= 8;
-		blue  >>= 8;
-		((u32 *)(info->pseudo_palette))[regno] =
-			(red   << info->var.red.offset)   |
-			(green << info->var.green.offset) |
-			(blue  << info->var.blue.offset);
-		break;
-    }
-    return 0;
+	}
+
+	return 0;
 }
 
 static struct fb_ops vesafb_ops = {
@@ -215,7 +209,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 };
 
 static int __init vesafb_setup(char *options)
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index 92d4655..8794dc5 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -92,7 +92,6 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,
 	.fb_mmap	= vfb_mmap,
 };
 
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index b46454c..690bb6f 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -1326,7 +1326,6 @@
 	.fb_fillrect	= vga16fb_fillrect,
 	.fb_copyarea	= vga16fb_copyarea,
 	.fb_imageblit	= vga16fb_imageblit,
-	.fb_cursor      = soft_cursor,
 };
 
 #ifndef MODULE
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
index cf8cdb1..48e70f1 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -397,7 +397,6 @@
 	.fb_fillrect  = cfb_fillrect,
 	.fb_copyarea  = cfb_copyarea,
 	.fb_imageblit = cfb_imageblit,
-	.fb_cursor    = soft_cursor,
 };
 
 #ifdef CONFIG_PM
diff --git a/drivers/w1/w1_ds2433.c b/drivers/w1/w1_ds2433.c
index 279e0e0..1e3d98a 100644
--- a/drivers/w1/w1_ds2433.c
+++ b/drivers/w1/w1_ds2433.c
@@ -299,10 +299,8 @@
 static void w1_f23_remove_slave(struct w1_slave *sl)
 {
 #ifdef CONFIG_W1_F23_CRC
-	if (sl->family_data) {
-		kfree(sl->family_data);
-		sl->family_data = NULL;
-	}
+	kfree(sl->family_data);
+	sl->family_data = NULL;
 #endif	/* CONFIG_W1_F23_CRC */
 	sysfs_remove_bin_file(&sl->dev.kobj, &w1_f23_bin_attr);
 }
diff --git a/fs/9p/error.c b/fs/9p/error.c
index fee5d19..834cb17 100644
--- a/fs/9p/error.c
+++ b/fs/9p/error.c
@@ -33,6 +33,7 @@
 
 #include <linux/list.h>
 #include <linux/jhash.h>
+#include <linux/string.h>
 
 #include "debug.h"
 #include "error.h"
diff --git a/fs/9p/trans_sock.c b/fs/9p/trans_sock.c
index 01e26f0..a93c2bf 100644
--- a/fs/9p/trans_sock.c
+++ b/fs/9p/trans_sock.c
@@ -269,8 +269,7 @@
 		dprintk(DEBUG_TRANS, "socket closed\n");
 	}
 
-	if (ts)
-		kfree(ts);
+	kfree(ts);
 
 	trans->priv = NULL;
 }
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 82303f3..418c374 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -266,7 +266,7 @@
 
 	v9ses->remotename = __getname();
 	if (!v9ses->remotename) {
-		putname(v9ses->name);
+		__putname(v9ses->name);
 		return -ENOMEM;
 	}
 
@@ -411,8 +411,8 @@
 	if (v9ses->transport)
 		v9ses->transport->close(v9ses->transport);
 
-	putname(v9ses->name);
-	putname(v9ses->remotename);
+	__putname(v9ses->name);
+	__putname(v9ses->remotename);
 }
 
 /**
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 2b696ae..be72881 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -1105,7 +1105,7 @@
 		}
 	}
 
-	putname(link);
+	__putname(link);
 	return retval;
 }
 
@@ -1129,7 +1129,7 @@
 		len = v9fs_readlink(dentry, link, strlen(link));
 
 		if (len < 0) {
-			putname(link);
+			__putname(link);
 			link = ERR_PTR(len);
 		} else
 			link[len] = 0;
@@ -1152,7 +1152,7 @@
 
 	dprintk(DEBUG_VFS, " %s %s\n", dentry->d_name.name, s);
 	if (!IS_ERR(s))
-		putname(s);
+		__putname(s);
 }
 
 /**
@@ -1228,7 +1228,7 @@
       FreeMem:
 	kfree(mistat);
 	kfree(fcall);
-	putname(symname);
+	__putname(symname);
 	return retval;
 }
 
@@ -1319,7 +1319,7 @@
       FreeMem:
 	kfree(mistat);
 	kfree(fcall);
-	putname(symname);
+	__putname(symname);
 
 	return retval;
 }
diff --git a/fs/Kconfig b/fs/Kconfig
index 01a2952..7cf36ca 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -898,6 +898,7 @@
 config HFS_FS
 	tristate "Apple Macintosh file system support (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
+	select NLS
 	help
 	  If you say Y here, you will be able to mount Macintosh-formatted
 	  floppy disks and hard drive partitions with full read-write access.
diff --git a/fs/affs/file.c b/fs/affs/file.c
index 6744924..f72fb77 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -22,14 +22,13 @@
 static struct buffer_head *affs_alloc_extblock(struct inode *inode, struct buffer_head *bh, u32 ext);
 static inline struct buffer_head *affs_get_extblock(struct inode *inode, u32 ext);
 static struct buffer_head *affs_get_extblock_slow(struct inode *inode, u32 ext);
-static ssize_t affs_file_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos);
 static int affs_file_open(struct inode *inode, struct file *filp);
 static int affs_file_release(struct inode *inode, struct file *filp);
 
 struct file_operations affs_file_operations = {
 	.llseek		= generic_file_llseek,
 	.read		= generic_file_read,
-	.write		= affs_file_write,
+	.write		= generic_file_write,
 	.mmap		= generic_file_mmap,
 	.open		= affs_file_open,
 	.release	= affs_file_release,
@@ -473,21 +472,6 @@
 	return ERR_PTR(err);
 }
 
-static ssize_t
-affs_file_write(struct file *file, const char __user *buf,
-		size_t count, loff_t *ppos)
-{
-	ssize_t retval;
-
-	retval = generic_file_write (file, buf, count, ppos);
-	if (retval >0) {
-		struct inode *inode = file->f_dentry->d_inode;
-		inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
-		mark_inode_dirty(inode);
-	}
-	return retval;
-}
-
 static int
 affs_do_readpage_ofs(struct file *file, struct page *page, unsigned from, unsigned to)
 {
diff --git a/fs/affs/super.c b/fs/affs/super.c
index 9c30807..aaec015 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -35,8 +35,7 @@
 		mark_buffer_dirty(sbi->s_root_bh);
 	}
 
-	if (sbi->s_prefix)
-		kfree(sbi->s_prefix);
+	kfree(sbi->s_prefix);
 	affs_free_bitmap(sb);
 	affs_brelse(sbi->s_root_bh);
 	kfree(sbi);
@@ -198,10 +197,9 @@
 			*mount_opts |= SF_MUFS;
 			break;
 		case Opt_prefix:
-			if (*prefix) {		/* Free any previous prefix */
-				kfree(*prefix);
-				*prefix = NULL;
-			}
+			/* Free any previous prefix */
+			kfree(*prefix);
+			*prefix = NULL;
 			*prefix = match_strdup(&args[0]);
 			if (!*prefix)
 				return 0;
@@ -462,11 +460,9 @@
 out_error:
 	if (root_inode)
 		iput(root_inode);
-	if (sbi->s_bitmap)
-		kfree(sbi->s_bitmap);
+	kfree(sbi->s_bitmap);
 	affs_brelse(root_bh);
-	if (sbi->s_prefix)
-		kfree(sbi->s_prefix);
+	kfree(sbi->s_prefix);
 	kfree(sbi);
 	sb->s_fs_info = NULL;
 	return -EINVAL;
diff --git a/fs/afs/file.c b/fs/afs/file.c
index 4975c9c..150b192 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -31,24 +31,10 @@
 static int afs_file_invalidatepage(struct page *page, unsigned long offset);
 static int afs_file_releasepage(struct page *page, gfp_t gfp_flags);
 
-static ssize_t afs_file_write(struct file *file, const char __user *buf,
-			      size_t size, loff_t *off);
-
 struct inode_operations afs_file_inode_operations = {
 	.getattr	= afs_inode_getattr,
 };
 
-struct file_operations afs_file_file_operations = {
-	.read		= generic_file_read,
-	.write		= afs_file_write,
-	.mmap		= generic_file_mmap,
-#if 0
-	.open		= afs_file_open,
-	.release	= afs_file_release,
-	.fsync		= afs_file_fsync,
-#endif
-};
-
 struct address_space_operations afs_fs_aops = {
 	.readpage	= afs_file_readpage,
 	.sync_page	= block_sync_page,
@@ -59,22 +45,6 @@
 
 /*****************************************************************************/
 /*
- * AFS file write
- */
-static ssize_t afs_file_write(struct file *file, const char __user *buf,
-			      size_t size, loff_t *off)
-{
-	struct afs_vnode *vnode;
-
-	vnode = AFS_FS_I(file->f_dentry->d_inode);
-	if (vnode->flags & AFS_VNODE_DELETED)
-		return -ESTALE;
-
-	return -EIO;
-} /* end afs_file_write() */
-
-/*****************************************************************************/
-/*
  * deal with notification that a page was read from the cache
  */
 #ifdef AFS_CACHING_SUPPORT
@@ -295,8 +265,7 @@
 		set_page_private(page, 0);
 		ClearPagePrivate(page);
 
-		if (pageio)
-			kfree(pageio);
+		kfree(pageio);
 	}
 
 	_leave(" = 0");
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index c476fde..4ebb30a 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -49,7 +49,7 @@
 	case AFS_FTYPE_FILE:
 		inode->i_mode	= S_IFREG | vnode->status.mode;
 		inode->i_op	= &afs_file_inode_operations;
-		inode->i_fop	= &afs_file_file_operations;
+		inode->i_fop	= &generic_ro_fops;
 		break;
 	case AFS_FTYPE_DIR:
 		inode->i_mode	= S_IFDIR | vnode->status.mode;
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index f09860b..ab8f87c 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -71,7 +71,6 @@
  */
 extern struct address_space_operations afs_fs_aops;
 extern struct inode_operations afs_file_inode_operations;
-extern struct file_operations afs_file_file_operations;
 
 #ifdef AFS_CACHING_SUPPORT
 extern int afs_cache_get_page_cookie(struct page *page,
diff --git a/fs/aio.c b/fs/aio.c
index edfca5b..20bb919 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -42,8 +42,9 @@
 #endif
 
 /*------ sysctl variables----*/
-atomic_t aio_nr = ATOMIC_INIT(0);	/* current system wide number of aio requests */
-unsigned aio_max_nr = 0x10000;	/* system wide maximum number of aio requests */
+static DEFINE_SPINLOCK(aio_nr_lock);
+unsigned long aio_nr;		/* current system wide number of aio requests */
+unsigned long aio_max_nr = 0x10000; /* system wide maximum number of aio requests */
 /*----end sysctl variables---*/
 
 static kmem_cache_t	*kiocb_cachep;
@@ -208,7 +209,7 @@
 		return ERR_PTR(-EINVAL);
 	}
 
-	if (nr_events > aio_max_nr)
+	if ((unsigned long)nr_events > aio_max_nr)
 		return ERR_PTR(-EAGAIN);
 
 	ctx = kmem_cache_alloc(kioctx_cachep, GFP_KERNEL);
@@ -233,8 +234,14 @@
 		goto out_freectx;
 
 	/* limit the number of system wide aios */
-	atomic_add(ctx->max_reqs, &aio_nr);	/* undone by __put_ioctx */
-	if (unlikely(atomic_read(&aio_nr) > aio_max_nr))
+	spin_lock(&aio_nr_lock);
+	if (aio_nr + ctx->max_reqs > aio_max_nr ||
+	    aio_nr + ctx->max_reqs < aio_nr)
+		ctx->max_reqs = 0;
+	else
+		aio_nr += ctx->max_reqs;
+	spin_unlock(&aio_nr_lock);
+	if (ctx->max_reqs == 0)
 		goto out_cleanup;
 
 	/* now link into global list.  kludge.  FIXME */
@@ -248,8 +255,6 @@
 	return ctx;
 
 out_cleanup:
-	atomic_sub(ctx->max_reqs, &aio_nr);
-	ctx->max_reqs = 0;	/* prevent __put_ioctx from sub'ing aio_nr */
 	__put_ioctx(ctx);
 	return ERR_PTR(-EAGAIN);
 
@@ -374,7 +379,12 @@
 	pr_debug("__put_ioctx: freeing %p\n", ctx);
 	kmem_cache_free(kioctx_cachep, ctx);
 
-	atomic_sub(nr_events, &aio_nr);
+	if (nr_events) {
+		spin_lock(&aio_nr_lock);
+		BUG_ON(aio_nr - nr_events > aio_nr);
+		aio_nr -= nr_events;
+		spin_unlock(&aio_nr_lock);
+	}
 }
 
 /* aio_get_req
@@ -1258,8 +1268,9 @@
 		goto out;
 
 	ret = -EINVAL;
-	if (unlikely(ctx || (int)nr_events <= 0)) {
-		pr_debug("EINVAL: io_setup: ctx or nr_events > max\n");
+	if (unlikely(ctx || nr_events == 0)) {
+		pr_debug("EINVAL: io_setup: ctx %lu nr_events %u\n",
+		         ctx, nr_events);
 		goto out;
 	}
 
diff --git a/fs/autofs/waitq.c b/fs/autofs/waitq.c
index 1fcaa15..633f628 100644
--- a/fs/autofs/waitq.c
+++ b/fs/autofs/waitq.c
@@ -150,10 +150,8 @@
 	if ( sbi->catatonic ) {
 		/* We might have slept, so check again for catatonic mode */
 		wq->status = -ENOENT;
-		if ( wq->name ) {
-			kfree(wq->name);
-			wq->name = NULL;
-		}
+		kfree(wq->name);
+		wq->name = NULL;
 	}
 
 	if ( wq->name ) {
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 0a3c05d..818b37b 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -22,10 +22,8 @@
 
 static void ino_lnkfree(struct autofs_info *ino)
 {
-	if (ino->u.symlink) {
-		kfree(ino->u.symlink);
-		ino->u.symlink = NULL;
-	}
+	kfree(ino->u.symlink);
+	ino->u.symlink = NULL;
 }
 
 struct autofs_info *autofs4_init_ino(struct autofs_info *ino,
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index 3df8628..394ff36 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -243,10 +243,8 @@
 	if ( sbi->catatonic ) {
 		/* We might have slept, so check again for catatonic mode */
 		wq->status = -ENOENT;
-		if ( wq->name ) {
-			kfree(wq->name);
-			wq->name = NULL;
-		}
+		kfree(wq->name);
+		wq->name = NULL;
 	}
 
 	if ( wq->name ) {
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index e0a6025..2d365cb 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -73,12 +73,6 @@
 	.lookup		= befs_lookup,
 };
 
-static struct file_operations befs_file_operations = {
-	.llseek		= default_llseek,
-	.read		= generic_file_read,
-	.mmap		= generic_file_readonly_mmap,
-};
-
 static struct address_space_operations befs_aops = {
 	.readpage	= befs_readpage,
 	.sync_page	= block_sync_page,
@@ -398,7 +392,7 @@
 	inode->i_mapping->a_ops = &befs_aops;
 
 	if (S_ISREG(inode->i_mode)) {
-		inode->i_fop = &befs_file_operations;
+		inode->i_fop = &generic_ro_fops;
 	} else if (S_ISDIR(inode->i_mode)) {
 		inode->i_op = &befs_dir_inode_operations;
 		inode->i_fop = &befs_dir_operations;
@@ -731,20 +725,16 @@
 static void
 befs_put_super(struct super_block *sb)
 {
-	if (BEFS_SB(sb)->mount_opts.iocharset) {
-		kfree(BEFS_SB(sb)->mount_opts.iocharset);
-		BEFS_SB(sb)->mount_opts.iocharset = NULL;
-	}
+	kfree(BEFS_SB(sb)->mount_opts.iocharset);
+	BEFS_SB(sb)->mount_opts.iocharset = NULL;
 
 	if (BEFS_SB(sb)->nls) {
 		unload_nls(BEFS_SB(sb)->nls);
 		BEFS_SB(sb)->nls = NULL;
 	}
 
-	if (sb->s_fs_info) {
-		kfree(sb->s_fs_info);
-		sb->s_fs_info = NULL;
-	}
+	kfree(sb->s_fs_info);
+	sb->s_fs_info = NULL;
 	return;
 }
 
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 6fa6adc..f36f221 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1006,8 +1006,7 @@
 	if (interpreter)
 		fput(interpreter);
 out_free_interp:
-	if (elf_interpreter)
-		kfree(elf_interpreter);
+	kfree(elf_interpreter);
 out_free_file:
 	sys_close(elf_exec_fileno);
 out_free_fh:
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index dda87c4..e0344f6 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -411,16 +411,11 @@
 		allow_write_access(interpreter);
 		fput(interpreter);
 	}
-	if (interpreter_name)
-		kfree(interpreter_name);
-	if (exec_params.phdrs)
-		kfree(exec_params.phdrs);
-	if (exec_params.loadmap)
-		kfree(exec_params.loadmap);
-	if (interp_params.phdrs)
-		kfree(interp_params.phdrs);
-	if (interp_params.loadmap)
-		kfree(interp_params.loadmap);
+	kfree(interpreter_name);
+	kfree(exec_params.phdrs);
+	kfree(exec_params.loadmap);
+	kfree(interp_params.phdrs);
+	kfree(interp_params.loadmap);
 	return retval;
 
 	/* unrecoverable error - kill the process */
diff --git a/fs/buffer.c b/fs/buffer.c
index 35fa349..5287be1 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -396,7 +396,7 @@
  * private_lock is contended then so is mapping->tree_lock).
  */
 static struct buffer_head *
-__find_get_block_slow(struct block_device *bdev, sector_t block, int unused)
+__find_get_block_slow(struct block_device *bdev, sector_t block)
 {
 	struct inode *bd_inode = bdev->bd_inode;
 	struct address_space *bd_mapping = bd_inode->i_mapping;
@@ -1438,7 +1438,7 @@
 	struct buffer_head *bh = lookup_bh_lru(bdev, block, size);
 
 	if (bh == NULL) {
-		bh = __find_get_block_slow(bdev, block, size);
+		bh = __find_get_block_slow(bdev, block);
 		if (bh)
 			bh_lru_install(bh);
 	}
@@ -1705,7 +1705,7 @@
 
 	might_sleep();
 
-	old_bh = __find_get_block_slow(bdev, block, 0);
+	old_bh = __find_get_block_slow(bdev, block);
 	if (old_bh) {
 		clear_buffer_dirty(old_bh);
 		wait_on_buffer(old_bh);
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c
index 98539e2..086ae8f 100644
--- a/fs/cifs/asn1.c
+++ b/fs/cifs/asn1.c
@@ -553,8 +553,7 @@
 					   *(oid + 3)));
 					rc = compare_oid(oid, oidlen, NTLMSSP_OID,
 						 NTLMSSP_OID_LEN);
-					if(oid)
-						kfree(oid);
+					kfree(oid);
 					if (rc)
 						use_ntlmssp = TRUE;
 				}
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index d74367a..450ab75 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1265,8 +1265,7 @@
 		the helper that resolves tcp names, mount to it, try to 
 		tcon to it unmount it if fail */
 
-	if(referrals)
-		kfree(referrals);
+	kfree(referrals);
 
 	return rc;
 }
@@ -1535,10 +1534,8 @@
 	
 	memset(&volume_info,0,sizeof(struct smb_vol));
 	if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
-		if(volume_info.UNC)
-			kfree(volume_info.UNC);
-		if(volume_info.password)
-			kfree(volume_info.password);
+		kfree(volume_info.UNC);
+		kfree(volume_info.password);
 		FreeXid(xid);
 		return -EINVAL;
 	}
@@ -1551,10 +1548,8 @@
 		cifserror("No username specified ");
         /* In userspace mount helper we can get user name from alternate
            locations such as env variables and files on disk */
-		if(volume_info.UNC)
-			kfree(volume_info.UNC);
-		if(volume_info.password)
-			kfree(volume_info.password);
+		kfree(volume_info.UNC);
+		kfree(volume_info.password);
 		FreeXid(xid);
 		return -EINVAL;
 	}
@@ -1573,10 +1568,8 @@
        
 		if(rc <= 0) {
 			/* we failed translating address */
-			if(volume_info.UNC)
-				kfree(volume_info.UNC);
-			if(volume_info.password)
-				kfree(volume_info.password);
+			kfree(volume_info.UNC);
+			kfree(volume_info.password);
 			FreeXid(xid);
 			return -EINVAL;
 		}
@@ -1587,19 +1580,15 @@
 	} else if (volume_info.UNCip){
 		/* BB using ip addr as server name connect to the DFS root below */
 		cERROR(1,("Connecting to DFS root not implemented yet"));
-		if(volume_info.UNC)
-			kfree(volume_info.UNC);
-		if(volume_info.password)
-			kfree(volume_info.password);
+		kfree(volume_info.UNC);
+		kfree(volume_info.password);
 		FreeXid(xid);
 		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  "));
-		if(volume_info.UNC)
-			kfree(volume_info.UNC);
-		if(volume_info.password)
-			kfree(volume_info.password);
+		kfree(volume_info.UNC);
+		kfree(volume_info.password);
 		FreeXid(xid);
 		return -EINVAL;
 	}
@@ -1612,10 +1601,8 @@
 		cifs_sb->local_nls = load_nls(volume_info.iocharset);
 		if(cifs_sb->local_nls == NULL) {
 			cERROR(1,("CIFS mount error: iocharset %s not found",volume_info.iocharset));
-			if(volume_info.UNC)
-				kfree(volume_info.UNC);
-			if(volume_info.password)
-				kfree(volume_info.password);
+			kfree(volume_info.UNC);
+			kfree(volume_info.password);
 			FreeXid(xid);
 			return -ELIBACC;
 		}
@@ -1630,10 +1617,8 @@
 			&sin_server6.sin6_addr,
 			volume_info.username, &srvTcp);
 	else {
-		if(volume_info.UNC)
-			kfree(volume_info.UNC);
-		if(volume_info.password)
-			kfree(volume_info.password);
+		kfree(volume_info.UNC);
+		kfree(volume_info.password);
 		FreeXid(xid);
 		return -EINVAL;
 	}
@@ -1654,10 +1639,8 @@
 			       ("Error connecting to IPv4 socket. Aborting operation"));
 			if(csocket != NULL)
 				sock_release(csocket);
-			if(volume_info.UNC)
-				kfree(volume_info.UNC);
-			if(volume_info.password)
-				kfree(volume_info.password);
+			kfree(volume_info.UNC);
+			kfree(volume_info.password);
 			FreeXid(xid);
 			return rc;
 		}
@@ -1666,10 +1649,8 @@
 		if (srvTcp == NULL) {
 			rc = -ENOMEM;
 			sock_release(csocket);
-			if(volume_info.UNC)
-				kfree(volume_info.UNC);
-			if(volume_info.password)
-				kfree(volume_info.password);
+			kfree(volume_info.UNC);
+			kfree(volume_info.password);
 			FreeXid(xid);
 			return rc;
 		} else {
@@ -1692,10 +1673,8 @@
 			if(rc < 0) {
 				rc = -ENOMEM;
 				sock_release(csocket);
-				if(volume_info.UNC)
-					kfree(volume_info.UNC);
-				if(volume_info.password)
-					kfree(volume_info.password);
+				kfree(volume_info.UNC);
+				kfree(volume_info.password);
 				FreeXid(xid);
 				return rc;
 			}
@@ -1710,8 +1689,7 @@
 	if (existingCifsSes) {
 		pSesInfo = existingCifsSes;
 		cFYI(1, ("Existing smb sess found "));
-		if(volume_info.password)
-			kfree(volume_info.password);
+		kfree(volume_info.password);
 		/* volume_info.UNC freed at end of function */
 	} else if (!rc) {
 		cFYI(1, ("Existing smb sess not found "));
@@ -1741,8 +1719,7 @@
 			if(!rc)
 				atomic_inc(&srvTcp->socketUseCount);
 		} else
-			if(volume_info.password)
-				kfree(volume_info.password);
+			kfree(volume_info.password);
 	}
     
 	/* search for existing tcon to this server share */
@@ -1821,8 +1798,7 @@
 							"", cifs_sb->local_nls,
 							cifs_sb->mnt_cifs_flags & 
 							  CIFS_MOUNT_MAP_SPECIAL_CHR);
-					if(volume_info.UNC)
-						kfree(volume_info.UNC);
+					kfree(volume_info.UNC);
 					FreeXid(xid);
 					return -ENODEV;
 				} else {
@@ -1925,8 +1901,7 @@
 	(in which case it is not needed anymore) but when new sesion is created
 	the password ptr is put in the new session structure (in which case the
 	password will be freed at unmount time) */
-	if(volume_info.UNC)
-		kfree(volume_info.UNC);
+	kfree(volume_info.UNC);
 	FreeXid(xid);
 	return rc;
 }
@@ -3283,8 +3258,7 @@
 			if ((bcc_ptr + (2 * length)) -
 			     pByteArea(smb_buffer_response) <=
 			    BCC(smb_buffer_response)) {
-				if(tcon->nativeFileSystem)
-					kfree(tcon->nativeFileSystem);
+				kfree(tcon->nativeFileSystem);
 				tcon->nativeFileSystem =
 				    kzalloc(length + 2, GFP_KERNEL);
 				cifs_strfromUCS_le(tcon->nativeFileSystem,
@@ -3301,8 +3275,7 @@
 			if ((bcc_ptr + length) -
 			    pByteArea(smb_buffer_response) <=
 			    BCC(smb_buffer_response)) {
-				if(tcon->nativeFileSystem)
-					kfree(tcon->nativeFileSystem);
+				kfree(tcon->nativeFileSystem);
 				tcon->nativeFileSystem =
 				    kzalloc(length + 1, GFP_KERNEL);
 				strncpy(tcon->nativeFileSystem, bcc_ptr,
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index b43e071..0f99aae 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -84,10 +84,8 @@
 	cifsInode->time = 0;	/* will force revalidate to go get info when needed */
 
 cifs_hl_exit:
-	if (fromName)
-		kfree(fromName);
-	if (toName)
-		kfree(toName);
+	kfree(fromName);
+	kfree(toName);
 	FreeXid(xid);
 	return rc;
 }
@@ -206,8 +204,7 @@
 		}
 	}
 
-	if (full_path)
-		kfree(full_path);
+	kfree(full_path);
 	FreeXid(xid);
 	return rc;
 }
@@ -253,8 +250,7 @@
 		len = buflen;
 	tmpbuffer = kmalloc(len,GFP_KERNEL);   
 	if(tmpbuffer == NULL) {
-		if (full_path)
-			kfree(full_path);
+		kfree(full_path);
 		FreeXid(xid);
 		return -ENOMEM;
 	}
@@ -303,8 +299,7 @@
 							strncpy(tmpbuffer, referrals, len-1);                            
 						}
 					}
-					if(referrals)
-						kfree(referrals);
+					kfree(referrals);
 					kfree(tmp_path);
 }
 				/* BB add code like else decode referrals then memcpy to
@@ -323,12 +318,8 @@
 		      rc));
 	}
 
-	if (tmpbuffer) {
-		kfree(tmpbuffer);
-	}
-	if (full_path) {
-		kfree(full_path);
-	}
+	kfree(tmpbuffer);
+	kfree(full_path);
 	FreeXid(xid);
 	return rc;
 }
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index eba1de9..34a0669 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -98,14 +98,10 @@
 	atomic_dec(&sesInfoAllocCount);
 	list_del(&buf_to_free->cifsSessionList);
 	write_unlock(&GlobalSMBSeslock);
-	if (buf_to_free->serverOS)
-		kfree(buf_to_free->serverOS);
-	if (buf_to_free->serverDomain)
-		kfree(buf_to_free->serverDomain);
-	if (buf_to_free->serverNOS)
-		kfree(buf_to_free->serverNOS);
-	if (buf_to_free->password)
-		kfree(buf_to_free->password);
+	kfree(buf_to_free->serverOS);
+	kfree(buf_to_free->serverDomain);
+	kfree(buf_to_free->serverNOS);
+	kfree(buf_to_free->password);
 	kfree(buf_to_free);
 }
 
@@ -144,8 +140,7 @@
 	atomic_dec(&tconInfoAllocCount);
 	list_del(&buf_to_free->cifsConnectionList);
 	write_unlock(&GlobalSMBSeslock);
-	if (buf_to_free->nativeFileSystem)
-		kfree(buf_to_free->nativeFileSystem);
+	kfree(buf_to_free->nativeFileSystem);
 	kfree(buf_to_free);
 }
 
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index c1e02ef..f375f87 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -87,8 +87,7 @@
 			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 	}
 remove_ea_exit:
-	if (full_path)
-		kfree(full_path);
+	kfree(full_path);
 	FreeXid(xid);
 #endif
 	return rc;
@@ -132,8 +131,7 @@
 		returns as xattrs */
 	if(value_size > MAX_EA_VALUE_SIZE) {
 		cFYI(1,("size of EA value too large"));
-		if(full_path)
-			kfree(full_path);
+		kfree(full_path);
 		FreeXid(xid);
 		return -EOPNOTSUPP;
 	}
@@ -195,8 +193,7 @@
 	}
 
 set_ea_exit:
-	if (full_path)
-		kfree(full_path);
+	kfree(full_path);
 	FreeXid(xid);
 #endif
 	return rc;
@@ -298,8 +295,7 @@
 		rc = -EOPNOTSUPP; 
 
 get_ea_exit:
-	if (full_path)
-		kfree(full_path);
+	kfree(full_path);
 	FreeXid(xid);
 #endif
 	return rc;
@@ -345,8 +341,7 @@
 				cifs_sb->mnt_cifs_flags & 
 					CIFS_MOUNT_MAP_SPECIAL_CHR);
 
-	if (full_path)
-		kfree(full_path);
+	kfree(full_path);
 	FreeXid(xid);
 #endif
 	return rc;
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 43dbcb0..4909754 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -2235,7 +2235,8 @@
 	if (err)
 		err = -EFAULT;
 
-out:	if (karg) kfree(karg);
+out:
+	kfree(karg);
 	return err;
 }
 
diff --git a/fs/dcache.c b/fs/dcache.c
index e90512e..17e43913 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -644,7 +644,7 @@
  *
  * Prune the dentries that are anonymous
  *
- * parsing d_hash list does not hlist_for_each_rcu() as it
+ * parsing d_hash list does not hlist_for_each_entry_rcu() as it
  * done under dcache_lock.
  *
  */
@@ -1043,15 +1043,13 @@
 	struct hlist_head *head = d_hash(parent,hash);
 	struct dentry *found = NULL;
 	struct hlist_node *node;
+	struct dentry *dentry;
 
 	rcu_read_lock();
 	
-	hlist_for_each_rcu(node, head) {
-		struct dentry *dentry; 
+	hlist_for_each_entry_rcu(dentry, node, head, d_hash) {
 		struct qstr *qstr;
 
-		dentry = hlist_entry(node, struct dentry, d_hash);
-
 		if (dentry->d_name.hash != hash)
 			continue;
 		if (dentry->d_parent != parent)
@@ -1123,7 +1121,7 @@
 	spin_lock(&dcache_lock);
 	base = d_hash(dparent, dentry->d_name.hash);
 	hlist_for_each(lhp,base) { 
-		/* hlist_for_each_rcu() not required for d_hash list
+		/* hlist_for_each_entry_rcu() not required for d_hash list
 		 * as it is parsed under dcache_lock
 		 */
 		if (dentry == hlist_entry(lhp, struct dentry, d_hash)) {
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
index 8b679b6..1274422 100644
--- a/fs/devfs/base.c
+++ b/fs/devfs/base.c
@@ -2738,10 +2738,8 @@
 	entry = fs_info->devfsd_first_event;
 	fs_info->devfsd_first_event = NULL;
 	fs_info->devfsd_last_event = NULL;
-	if (fs_info->devfsd_info) {
-		kfree(fs_info->devfsd_info);
-		fs_info->devfsd_info = NULL;
-	}
+	kfree(fs_info->devfsd_info);
+	fs_info->devfsd_info = NULL;
 	spin_unlock(&fs_info->devfsd_buffer_lock);
 	fs_info->devfsd_pgrp = 0;
 	fs_info->devfsd_task = NULL;
diff --git a/fs/dquot.c b/fs/dquot.c
index ea76442..afa06a8 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -77,6 +77,7 @@
 #include <linux/kmod.h>
 #include <linux/namei.h>
 #include <linux/buffer_head.h>
+#include <linux/quotaops.h>
 
 #include <asm/uaccess.h>
 
diff --git a/fs/exec.c b/fs/exec.c
index 10d493f..cd6c574 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -48,6 +48,7 @@
 #include <linux/syscalls.h>
 #include <linux/rmap.h>
 #include <linux/acct.h>
+#include <linux/cn_proc.h>
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
@@ -1096,6 +1097,7 @@
 					fput(bprm->file);
 				bprm->file = NULL;
 				current->did_exec = 1;
+				proc_exec_connector(current);
 				return retval;
 			}
 			read_lock(&binfmt_lock);
@@ -1509,7 +1511,7 @@
 		goto close_fail;
 	if (!file->f_op->write)
 		goto close_fail;
-	if (do_truncate(file->f_dentry, 0) != 0)
+	if (do_truncate(file->f_dentry, 0, file) != 0)
 		goto close_fail;
 
 	retval = binfmt->core_dump(signr, regs, file);
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c
index 213148c..6af2f41 100644
--- a/fs/ext2/acl.c
+++ b/fs/ext2/acl.c
@@ -194,8 +194,7 @@
 		acl = NULL;
 	else
 		acl = ERR_PTR(retval);
-	if (value)
-		kfree(value);
+	kfree(value);
 
 	if (!IS_ERR(acl)) {
 		switch(type) {
@@ -262,8 +261,7 @@
 
 	error = ext2_xattr_set(inode, name_index, "", value, size, 0);
 
-	if (value)
-		kfree(value);
+	kfree(value);
 	if (!error) {
 		switch(type) {
 			case ACL_TYPE_ACCESS:
diff --git a/fs/file_table.c b/fs/file_table.c
index 4dc2055..c3a5e2f 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -35,7 +35,7 @@
  * context and must be fully threaded - use a local spinlock
  * to protect files_stat.nr_files
  */
-void filp_ctor(void * objp, struct kmem_cache_s *cachep, unsigned long cflags)
+void filp_ctor(void *objp, struct kmem_cache *cachep, unsigned long cflags)
 {
 	if ((cflags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
 	    SLAB_CTOR_CONSTRUCTOR) {
@@ -46,7 +46,7 @@
 	}
 }
 
-void filp_dtor(void * objp, struct kmem_cache_s *cachep, unsigned long dflags)
+void filp_dtor(void *objp, struct kmem_cache *cachep, unsigned long dflags)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&filp_count_lock, flags);
diff --git a/fs/freevxfs/vxfs_extern.h b/fs/freevxfs/vxfs_extern.h
index d8be917..927acf7 100644
--- a/fs/freevxfs/vxfs_extern.h
+++ b/fs/freevxfs/vxfs_extern.h
@@ -38,7 +38,7 @@
  */
 
 
-struct kmem_cache_s;
+struct kmem_cache;
 struct super_block;
 struct vxfs_inode_info;
 struct inode;
@@ -51,7 +51,7 @@
 extern int			vxfs_read_fshead(struct super_block *);
 
 /* vxfs_inode.c */
-extern struct kmem_cache_s	*vxfs_inode_cachep;
+extern struct kmem_cache	*vxfs_inode_cachep;
 extern void			vxfs_dumpi(struct vxfs_inode_info *, ino_t);
 extern struct inode *		vxfs_get_fake_inode(struct super_block *,
 					struct vxfs_inode_info *);
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
index 9672d2f..f544aae 100644
--- a/fs/freevxfs/vxfs_inode.c
+++ b/fs/freevxfs/vxfs_inode.c
@@ -46,15 +46,6 @@
 
 extern struct inode_operations vxfs_immed_symlink_iops;
 
-static struct file_operations vxfs_file_operations = {
-	.open =			generic_file_open,
-	.llseek =		generic_file_llseek,
-	.read =			generic_file_read,
-	.mmap =			generic_file_mmap,
-	.sendfile =		generic_file_sendfile,
-};
-
-
 kmem_cache_t		*vxfs_inode_cachep;
 
 
@@ -318,7 +309,7 @@
 		aops = &vxfs_aops;
 
 	if (S_ISREG(ip->i_mode)) {
-		ip->i_fop = &vxfs_file_operations;
+		ip->i_fop = &generic_ro_fops;
 		ip->i_mapping->a_ops = aops;
 	} else if (S_ISDIR(ip->i_mode)) {
 		ip->i_op = &vxfs_dir_inode_ops;
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index c27f8d4..785c721 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -562,7 +562,7 @@
 	};
 
 	if (!mapping_cap_writeback_dirty(inode->i_mapping))
-		return 0;
+		wbc.nr_to_write = 0;
 
 	might_sleep();
 	spin_lock(&inode_lock);
@@ -606,7 +606,7 @@
  * O_SYNC flag set, to flush dirty writes to disk.
  *
  * @what is a bitmask, specifying which part of the inode's data should be
- * written and waited upon:
+ * written and waited upon.
  *
  *    OSYNC_DATA:     i_mapping's dirty data
  *    OSYNC_METADATA: the buffers at i_mapping->private_list
@@ -672,8 +672,9 @@
 
 /**
  * writeback_in_progress: determine whether there is writeback in progress
- *                        against a backing device.
  * @bdi: the device's backing_dev_info structure.
+ *
+ * Determine whether there is writeback in progress against a backing device.
  */
 int writeback_in_progress(struct backing_dev_info *bdi)
 {
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index a6f90a6..8f873e62 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -184,6 +184,13 @@
 		   fuse_putback_request() */
 		for (i = 1; i < FUSE_MAX_OUTSTANDING; i++)
 			up(&fc->outstanding_sem);
+	} else if (req->in.h.opcode == FUSE_RELEASE && req->inode == NULL) {
+		/* Special case for failed iget in CREATE */
+		u64 nodeid = req->in.h.nodeid;
+		__fuse_get_request(req);
+		fuse_reset_request(req);
+		fuse_send_forget(fc, req, nodeid, 1);
+		putback = 0;
 	}
 	if (putback)
 		fuse_putback_request(fc, req);
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 70dba72..c045cc7 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -13,6 +13,7 @@
 #include <linux/gfp.h>
 #include <linux/sched.h>
 #include <linux/namei.h>
+#include <linux/mount.h>
 
 static inline unsigned long time_to_jiffies(unsigned long sec,
 					    unsigned long nsec)
@@ -134,6 +135,101 @@
 	entry->d_time = jiffies - 1;
 }
 
+static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
+			    struct nameidata *nd)
+{
+	int err;
+	struct inode *inode;
+	struct fuse_conn *fc = get_fuse_conn(dir);
+	struct fuse_req *req;
+	struct fuse_open_in inarg;
+	struct fuse_open_out outopen;
+	struct fuse_entry_out outentry;
+	struct fuse_inode *fi;
+	struct fuse_file *ff;
+	struct file *file;
+	int flags = nd->intent.open.flags - 1;
+
+	err = -ENOSYS;
+	if (fc->no_create)
+		goto out;
+
+	err = -ENAMETOOLONG;
+	if (entry->d_name.len > FUSE_NAME_MAX)
+		goto out;
+
+	err = -EINTR;
+	req = fuse_get_request(fc);
+	if (!req)
+		goto out;
+
+	ff = fuse_file_alloc();
+	if (!ff)
+		goto out_put_request;
+
+	flags &= ~O_NOCTTY;
+	memset(&inarg, 0, sizeof(inarg));
+	inarg.flags = flags;
+	inarg.mode = mode;
+	req->in.h.opcode = FUSE_CREATE;
+	req->in.h.nodeid = get_node_id(dir);
+	req->inode = dir;
+	req->in.numargs = 2;
+	req->in.args[0].size = sizeof(inarg);
+	req->in.args[0].value = &inarg;
+	req->in.args[1].size = entry->d_name.len + 1;
+	req->in.args[1].value = entry->d_name.name;
+	req->out.numargs = 2;
+	req->out.args[0].size = sizeof(outentry);
+	req->out.args[0].value = &outentry;
+	req->out.args[1].size = sizeof(outopen);
+	req->out.args[1].value = &outopen;
+	request_send(fc, req);
+	err = req->out.h.error;
+	if (err) {
+		if (err == -ENOSYS)
+			fc->no_create = 1;
+		goto out_free_ff;
+	}
+
+	err = -EIO;
+	if (!S_ISREG(outentry.attr.mode))
+		goto out_free_ff;
+
+	inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
+			  &outentry.attr);
+	err = -ENOMEM;
+	if (!inode) {
+		flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
+		ff->fh = outopen.fh;
+		fuse_send_release(fc, ff, outentry.nodeid, NULL, flags, 0);
+		goto out_put_request;
+	}
+	fuse_put_request(fc, req);
+	entry->d_time =	time_to_jiffies(outentry.entry_valid,
+					outentry.entry_valid_nsec);
+	fi = get_fuse_inode(inode);
+	fi->i_time = time_to_jiffies(outentry.attr_valid,
+				     outentry.attr_valid_nsec);
+
+	d_instantiate(entry, inode);
+	file = lookup_instantiate_filp(nd, entry, generic_file_open);
+	if (IS_ERR(file)) {
+		ff->fh = outopen.fh;
+		fuse_send_release(fc, ff, outentry.nodeid, inode, flags, 0);
+		return PTR_ERR(file);
+	}
+	fuse_finish_open(inode, file, ff, &outopen);
+	return 0;
+
+ out_free_ff:
+	fuse_file_free(ff);
+ out_put_request:
+	fuse_put_request(fc, req);
+ out:
+	return err;
+}
+
 static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
 			    struct inode *dir, struct dentry *entry,
 			    int mode)
@@ -208,6 +304,12 @@
 static int fuse_create(struct inode *dir, struct dentry *entry, int mode,
 		       struct nameidata *nd)
 {
+	if (nd && (nd->flags & LOOKUP_CREATE)) {
+		int err = fuse_create_open(dir, entry, mode, nd);
+		if (err != -ENOSYS)
+			return err;
+		/* Fall back on mknod */
+	}
 	return fuse_mknod(dir, entry, mode, 0);
 }
 
@@ -461,6 +563,38 @@
 	return fuse_do_getattr(inode);
 }
 
+static int fuse_access(struct inode *inode, int mask)
+{
+	struct fuse_conn *fc = get_fuse_conn(inode);
+	struct fuse_req *req;
+	struct fuse_access_in inarg;
+	int err;
+
+	if (fc->no_access)
+		return 0;
+
+	req = fuse_get_request(fc);
+	if (!req)
+		return -EINTR;
+
+	memset(&inarg, 0, sizeof(inarg));
+	inarg.mask = mask;
+	req->in.h.opcode = FUSE_ACCESS;
+	req->in.h.nodeid = get_node_id(inode);
+	req->inode = inode;
+	req->in.numargs = 1;
+	req->in.args[0].size = sizeof(inarg);
+	req->in.args[0].value = &inarg;
+	request_send(fc, req);
+	err = req->out.h.error;
+	fuse_put_request(fc, req);
+	if (err == -ENOSYS) {
+		fc->no_access = 1;
+		err = 0;
+	}
+	return err;
+}
+
 static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
 {
 	struct fuse_conn *fc = get_fuse_conn(inode);
@@ -491,11 +625,11 @@
 		return err;
 	} else {
 		int mode = inode->i_mode;
-		if ((mask & MAY_WRITE) && IS_RDONLY(inode) &&
-                    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
-                        return -EROFS;
 		if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
 			return -EACCES;
+
+		if (nd && (nd->flags & LOOKUP_ACCESS))
+			return fuse_access(inode, mask);
 		return 0;
 	}
 }
@@ -629,29 +763,29 @@
 	return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
 }
 
-static unsigned iattr_to_fattr(struct iattr *iattr, struct fuse_attr *fattr)
+static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
 {
 	unsigned ivalid = iattr->ia_valid;
-	unsigned fvalid = 0;
-
-	memset(fattr, 0, sizeof(*fattr));
 
 	if (ivalid & ATTR_MODE)
-		fvalid |= FATTR_MODE,   fattr->mode = iattr->ia_mode;
+		arg->valid |= FATTR_MODE,   arg->mode = iattr->ia_mode;
 	if (ivalid & ATTR_UID)
-		fvalid |= FATTR_UID,    fattr->uid = iattr->ia_uid;
+		arg->valid |= FATTR_UID,    arg->uid = iattr->ia_uid;
 	if (ivalid & ATTR_GID)
-		fvalid |= FATTR_GID,    fattr->gid = iattr->ia_gid;
+		arg->valid |= FATTR_GID,    arg->gid = iattr->ia_gid;
 	if (ivalid & ATTR_SIZE)
-		fvalid |= FATTR_SIZE,   fattr->size = iattr->ia_size;
+		arg->valid |= FATTR_SIZE,   arg->size = iattr->ia_size;
 	/* You can only _set_ these together (they may change by themselves) */
 	if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) {
-		fvalid |= FATTR_ATIME | FATTR_MTIME;
-		fattr->atime = iattr->ia_atime.tv_sec;
-		fattr->mtime = iattr->ia_mtime.tv_sec;
+		arg->valid |= FATTR_ATIME | FATTR_MTIME;
+		arg->atime = iattr->ia_atime.tv_sec;
+		arg->mtime = iattr->ia_mtime.tv_sec;
 	}
-
-	return fvalid;
+	if (ivalid & ATTR_FILE) {
+		struct fuse_file *ff = iattr->ia_file->private_data;
+		arg->valid |= FATTR_FH;
+		arg->fh = ff->fh;
+	}
 }
 
 static int fuse_setattr(struct dentry *entry, struct iattr *attr)
@@ -686,7 +820,7 @@
 		return -EINTR;
 
 	memset(&inarg, 0, sizeof(inarg));
-	inarg.valid = iattr_to_fattr(attr, &inarg.attr);
+	iattr_to_fattr(attr, &inarg);
 	req->in.h.opcode = FUSE_SETATTR;
 	req->in.h.nodeid = get_node_id(inode);
 	req->inode = inode;
@@ -735,7 +869,9 @@
 				  struct nameidata *nd)
 {
 	struct inode *inode;
-	int err = fuse_lookup_iget(dir, entry, &inode);
+	int err;
+
+	err = fuse_lookup_iget(dir, entry, &inode);
 	if (err)
 		return ERR_PTR(err);
 	if (inode && S_ISDIR(inode->i_mode)) {
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 657ab11..2ca8614 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -14,11 +14,69 @@
 
 static struct file_operations fuse_direct_io_file_operations;
 
-int fuse_open_common(struct inode *inode, struct file *file, int isdir)
+static int fuse_send_open(struct inode *inode, struct file *file, int isdir,
+			  struct fuse_open_out *outargp)
 {
 	struct fuse_conn *fc = get_fuse_conn(inode);
-	struct fuse_req *req;
 	struct fuse_open_in inarg;
+	struct fuse_req *req;
+	int err;
+
+	req = fuse_get_request(fc);
+	if (!req)
+		return -EINTR;
+
+	memset(&inarg, 0, sizeof(inarg));
+	inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
+	req->in.h.opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN;
+	req->in.h.nodeid = get_node_id(inode);
+	req->inode = inode;
+	req->in.numargs = 1;
+	req->in.args[0].size = sizeof(inarg);
+	req->in.args[0].value = &inarg;
+	req->out.numargs = 1;
+	req->out.args[0].size = sizeof(*outargp);
+	req->out.args[0].value = outargp;
+	request_send(fc, req);
+	err = req->out.h.error;
+	fuse_put_request(fc, req);
+
+	return err;
+}
+
+struct fuse_file *fuse_file_alloc(void)
+{
+	struct fuse_file *ff;
+	ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL);
+	if (ff) {
+		ff->release_req = fuse_request_alloc();
+		if (!ff->release_req) {
+			kfree(ff);
+			ff = NULL;
+		}
+	}
+	return ff;
+}
+
+void fuse_file_free(struct fuse_file *ff)
+{
+	fuse_request_free(ff->release_req);
+	kfree(ff);
+}
+
+void fuse_finish_open(struct inode *inode, struct file *file,
+		      struct fuse_file *ff, struct fuse_open_out *outarg)
+{
+	if (outarg->open_flags & FOPEN_DIRECT_IO)
+		file->f_op = &fuse_direct_io_file_operations;
+	if (!(outarg->open_flags & FOPEN_KEEP_CACHE))
+		invalidate_inode_pages(inode->i_mapping);
+	ff->fh = outarg->fh;
+	file->private_data = ff;
+}
+
+int fuse_open_common(struct inode *inode, struct file *file, int isdir)
+{
 	struct fuse_open_out outarg;
 	struct fuse_file *ff;
 	int err;
@@ -34,73 +92,53 @@
 	/* If opening the root node, no lookup has been performed on
 	   it, so the attributes must be refreshed */
 	if (get_node_id(inode) == FUSE_ROOT_ID) {
-		int err = fuse_do_getattr(inode);
+		err = fuse_do_getattr(inode);
 		if (err)
 		 	return err;
 	}
 
-	req = fuse_get_request(fc);
-	if (!req)
-		return -EINTR;
-
-	err = -ENOMEM;
-	ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL);
+	ff = fuse_file_alloc();
 	if (!ff)
-		goto out_put_request;
+		return -ENOMEM;
 
-	ff->release_req = fuse_request_alloc();
-	if (!ff->release_req) {
-		kfree(ff);
-		goto out_put_request;
+	err = fuse_send_open(inode, file, isdir, &outarg);
+	if (err)
+		fuse_file_free(ff);
+	else {
+		if (isdir)
+			outarg.open_flags &= ~FOPEN_DIRECT_IO;
+		fuse_finish_open(inode, file, ff, &outarg);
 	}
 
-	memset(&inarg, 0, sizeof(inarg));
-	inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
-	req->in.h.opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN;
-	req->in.h.nodeid = get_node_id(inode);
-	req->inode = inode;
-	req->in.numargs = 1;
-	req->in.args[0].size = sizeof(inarg);
-	req->in.args[0].value = &inarg;
-	req->out.numargs = 1;
-	req->out.args[0].size = sizeof(outarg);
-	req->out.args[0].value = &outarg;
-	request_send(fc, req);
-	err = req->out.h.error;
-	if (err) {
-		fuse_request_free(ff->release_req);
-		kfree(ff);
-	} else {
-		if (!isdir && (outarg.open_flags & FOPEN_DIRECT_IO))
-			file->f_op = &fuse_direct_io_file_operations;
-		if (!(outarg.open_flags & FOPEN_KEEP_CACHE))
-			invalidate_inode_pages(inode->i_mapping);
-		ff->fh = outarg.fh;
-		file->private_data = ff;
-	}
-
- out_put_request:
-	fuse_put_request(fc, req);
 	return err;
 }
 
-int fuse_release_common(struct inode *inode, struct file *file, int isdir)
+void fuse_send_release(struct fuse_conn *fc, struct fuse_file *ff,
+		       u64 nodeid, struct inode *inode, int flags, int isdir)
 {
-	struct fuse_conn *fc = get_fuse_conn(inode);
-	struct fuse_file *ff = file->private_data;
-	struct fuse_req *req = ff->release_req;
+	struct fuse_req * req = ff->release_req;
 	struct fuse_release_in *inarg = &req->misc.release_in;
 
 	inarg->fh = ff->fh;
-	inarg->flags = file->f_flags & ~O_EXCL;
+	inarg->flags = flags;
 	req->in.h.opcode = isdir ? FUSE_RELEASEDIR : FUSE_RELEASE;
-	req->in.h.nodeid = get_node_id(inode);
+	req->in.h.nodeid = nodeid;
 	req->inode = inode;
 	req->in.numargs = 1;
 	req->in.args[0].size = sizeof(struct fuse_release_in);
 	req->in.args[0].value = inarg;
 	request_send_background(fc, req);
 	kfree(ff);
+}
+
+int fuse_release_common(struct inode *inode, struct file *file, int isdir)
+{
+	struct fuse_file *ff = file->private_data;
+	if (ff) {
+		struct fuse_conn *fc = get_fuse_conn(inode);
+		u64 nodeid = get_node_id(inode);
+		fuse_send_release(fc, ff, nodeid, inode, file->f_flags, isdir);
+	}
 
 	/* Return value is ignored by VFS */
 	return 0;
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 5cb456f5..0ea5301 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -266,6 +266,12 @@
 	/** Is removexattr not implemented by fs? */
 	unsigned no_removexattr : 1;
 
+	/** Is access not implemented by fs? */
+	unsigned no_access : 1;
+
+	/** Is create not implemented by fs? */
+	unsigned no_create : 1;
+
 	/** Backing dev info */
 	struct backing_dev_info bdi;
 };
@@ -337,6 +343,17 @@
  */
 int fuse_open_common(struct inode *inode, struct file *file, int isdir);
 
+struct fuse_file *fuse_file_alloc(void);
+void fuse_file_free(struct fuse_file *ff);
+void fuse_finish_open(struct inode *inode, struct file *file,
+		      struct fuse_file *ff, struct fuse_open_out *outarg);
+
+/**
+ * Send a RELEASE request
+ */
+void fuse_send_release(struct fuse_conn *fc, struct fuse_file *ff,
+		       u64 nodeid, struct inode *inode, int flags, int isdir);
+
 /**
  * Send RELEASE or RELEASEDIR request
  */
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index dd71131..a33fb1d 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -294,8 +294,7 @@
 
 static void hostfs_destroy_inode(struct inode *inode)
 {
-	if(HOSTFS_I(inode)->host_filename)
-		kfree(HOSTFS_I(inode)->host_filename);
+	kfree(HOSTFS_I(inode)->host_filename);
 
 	/*XXX: This should not happen, probably. The check is here for
 	 * additional safety.*/
diff --git a/fs/hpfs/dnode.c b/fs/hpfs/dnode.c
index 1d21307..229ff2f 100644
--- a/fs/hpfs/dnode.c
+++ b/fs/hpfs/dnode.c
@@ -244,12 +244,12 @@
 	go_up:
 	if (namelen >= 256) {
 		hpfs_error(i->i_sb, "hpfs_add_to_dnode: namelen == %d", namelen);
-		if (nd) kfree(nd);
+		kfree(nd);
 		kfree(nname);
 		return 1;
 	}
 	if (!(d = hpfs_map_dnode(i->i_sb, dno, &qbh))) {
-		if (nd) kfree(nd);
+		kfree(nd);
 		kfree(nname);
 		return 1;
 	}
@@ -257,7 +257,7 @@
 	if (hpfs_sb(i->i_sb)->sb_chk)
 		if (hpfs_stop_cycles(i->i_sb, dno, &c1, &c2, "hpfs_add_to_dnode")) {
 			hpfs_brelse4(&qbh);
-			if (nd) kfree(nd);
+			kfree(nd);
 			kfree(nname);
 			return 1;
 		}
@@ -270,7 +270,7 @@
 		for_all_poss(i, hpfs_pos_subst, 5, t + 1);
 		hpfs_mark_4buffers_dirty(&qbh);
 		hpfs_brelse4(&qbh);
-		if (nd) kfree(nd);
+		kfree(nd);
 		kfree(nname);
 		return 0;
 	}
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index 8eefa63..63e88d7 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -75,7 +75,7 @@
 		} else if (s->s_flags & MS_RDONLY) printk("; going on - but anything won't be destroyed because it's read-only\n");
 		else printk("; corrupted filesystem mounted read/write - your computer will explode within 20 seconds ... but you wanted it so!\n");
 	} else printk("\n");
-	if (buf) kfree(buf);
+	kfree(buf);
 	hpfs_sb(s)->sb_was_error = 1;
 }
 
@@ -102,8 +102,8 @@
 static void hpfs_put_super(struct super_block *s)
 {
 	struct hpfs_sb_info *sbi = hpfs_sb(s);
-	if (sbi->sb_cp_table) kfree(sbi->sb_cp_table);
-	if (sbi->sb_bmp_dir) kfree(sbi->sb_bmp_dir);
+	kfree(sbi->sb_cp_table);
+	kfree(sbi->sb_bmp_dir);
 	unmark_dirty(s);
 	s->s_fs_info = NULL;
 	kfree(sbi);
@@ -654,8 +654,8 @@
 bail2:	brelse(bh0);
 bail1:
 bail0:
-	if (sbi->sb_bmp_dir) kfree(sbi->sb_bmp_dir);
-	if (sbi->sb_cp_table) kfree(sbi->sb_cp_table);
+	kfree(sbi->sb_bmp_dir);
+	kfree(sbi->sb_cp_table);
 	s->s_fs_info = NULL;
 	kfree(sbi);
 	return -EINVAL;
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 1652de1..298f08b 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -855,8 +855,7 @@
 	if (opt.check == 'r') table++;
 	s->s_root->d_op = &isofs_dentry_ops[table];
 
-	if (opt.iocharset)
-		kfree(opt.iocharset);
+	kfree(opt.iocharset);
 
 	return 0;
 
@@ -895,8 +894,7 @@
 out_freebh:
 	brelse(bh);
 out_freesbi:
-	if (opt.iocharset)
-		kfree(opt.iocharset);
+	kfree(opt.iocharset);
 	kfree(sbi);
 	s->s_fs_info = NULL;
 	return -EINVAL;
@@ -1164,8 +1162,7 @@
 
 out_noread:
 	printk(KERN_INFO "ISOFS: unable to read i-node block %lu\n", block);
-	if (tmpde)
-		kfree(tmpde);
+	kfree(tmpde);
 	return -EIO;
 
 out_toomany:
@@ -1334,8 +1331,7 @@
 		init_special_inode(inode, inode->i_mode, inode->i_rdev);
 
 out:
-	if (tmpde)
-		kfree(tmpde);
+	kfree(tmpde);
 	if (bh)
 		brelse(bh);
 	return;
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index 2a3e310..002ad2b 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -261,10 +261,8 @@
 			struct buffer_head *bh = jh2bh(jh);
 
 			jbd_lock_bh_state(bh);
-			if (jh->b_committed_data) {
-				kfree(jh->b_committed_data);
-				jh->b_committed_data = NULL;
-			}
+			kfree(jh->b_committed_data);
+			jh->b_committed_data = NULL;
 			jbd_unlock_bh_state(bh);
 		}
 		journal_refile_buffer(journal, jh);
diff --git a/fs/jbd/recovery.c b/fs/jbd/recovery.c
index 103c34e..80d7f53 100644
--- a/fs/jbd/recovery.c
+++ b/fs/jbd/recovery.c
@@ -210,7 +210,7 @@
 } while (0)
 
 /**
- * int journal_recover(journal_t *journal) - recovers a on-disk journal
+ * journal_recover - recovers a on-disk journal
  * @journal: the journal to recover
  * 
  * The primary function for recovering the log contents when mounting a
@@ -266,7 +266,7 @@
 }
 
 /**
- * int journal_skip_recovery() - Start journal and wipe exiting records 
+ * journal_skip_recovery - Start journal and wipe exiting records
  * @journal: journal to startup
  * 
  * Locate any valid recovery information from the journal and set up the
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index 13cb05b..429f4b2 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -227,8 +227,7 @@
 	spin_unlock(&transaction->t_handle_lock);
 	spin_unlock(&journal->j_state_lock);
 out:
-	if (new_transaction)
-		kfree(new_transaction);
+	kfree(new_transaction);
 	return ret;
 }
 
@@ -725,8 +724,7 @@
 	journal_cancel_revoke(handle, jh);
 
 out:
-	if (frozen_buffer)
-		kfree(frozen_buffer);
+	kfree(frozen_buffer);
 
 	JBUFFER_TRACE(jh, "exit");
 	return error;
@@ -905,8 +903,7 @@
 	jbd_unlock_bh_state(bh);
 out:
 	journal_put_journal_head(jh);
-	if (committed_data)
-		kfree(committed_data);
+	kfree(committed_data);
 	return err;
 }
 
diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c
index 27f199e..b2e9542 100644
--- a/fs/jffs/intrep.c
+++ b/fs/jffs/intrep.c
@@ -462,7 +462,7 @@
 	}
 
 	/* Free read buffer */
-	kfree (read_buf);
+	kfree(read_buf);
 
 	/* Return result */
 	D3(printk("checksum result: 0x%08x\n", sum));
@@ -1011,12 +1011,12 @@
 						       offset , fmc->sector_size);
 
 						flash_safe_release(fmc->mtd);
-						kfree (read_buf);
+						kfree(read_buf);
 						return -1; /* bad, bad, bad! */
 
 					}
 					flash_safe_release(fmc->mtd);
-					kfree (read_buf);
+					kfree(read_buf);
 
 					return -EAGAIN; /* erased offending sector. Try mount one more time please. */
 				}
@@ -1112,7 +1112,7 @@
 		if (!node) {
 			if (!(node = jffs_alloc_node())) {
 				/* Free read buffer */
-				kfree (read_buf);
+				kfree(read_buf);
 
 				/* Release the flash device */
 				flash_safe_release(fmc->mtd);
@@ -1269,7 +1269,7 @@
 				DJM(no_jffs_node--);
 
 				/* Free read buffer */
-				kfree (read_buf);
+				kfree(read_buf);
 
 				/* Release the flash device */
 				flash_safe_release(fmc->mtd);
@@ -1296,7 +1296,7 @@
 					flash_safe_release(fmc->flash_part);
 
 					/* Free read buffer */
-					kfree (read_buf);
+					kfree(read_buf);
 
 					return -ENOMEM;
 				}
@@ -1324,7 +1324,7 @@
 	jffs_build_end(fmc);
 
 	/* Free read buffer */
-	kfree (read_buf);
+	kfree(read_buf);
 
 	if(!num_free_space){
 	        printk(KERN_WARNING "jffs_scan_flash(): Did not find even a single "
@@ -1747,9 +1747,7 @@
 		}
 		printk("jffs_find_child(): Didn't find the file \"%s\".\n",
 		       (copy ? copy : ""));
-		if (copy) {
-			kfree(copy);
-		}
+		kfree(copy);
 	});
 
 	return f;
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index 5b2a835..1a96903 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -490,7 +490,7 @@
 		up(&f->sem);
 		jffs2_do_clear_inode(c, f);
 	}
-	kfree (f);
+	kfree(f);
 	return ret;
 }
 
@@ -742,10 +742,8 @@
 
 	/* For symlink inodes we us f->dents to store the target path name */
 	if (S_ISLNK(OFNI_EDONI_2SFFJ(f)->i_mode)) {
-		if (f->dents) {
-			kfree(f->dents);
-			f->dents = NULL;
-		}
+		kfree(f->dents);
+		f->dents = NULL;
 	} else {
 		fds = f->dents;
 
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index 316133c..7bc7f2d 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -327,8 +327,7 @@
 		c->wbuf_ofs = ofs + towrite;
 		memmove(c->wbuf, rewrite_buf + towrite, c->wbuf_len);
 		/* Don't muck about with c->wbuf_inodes. False positives are harmless. */
-		if (buf)
-			kfree(buf);
+		kfree(buf);
 	} else {
 		/* OK, now we're left with the dregs in whichever buffer we're using */
 		if (buf) {
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index 87332f3..c5a3364 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -112,8 +112,7 @@
 		}
 	}
 	spin_unlock(&host->h_lock);
-	if (new != NULL)
-		kfree(new);
+	kfree(new);
 	return res;
 }
 
diff --git a/fs/mbcache.c b/fs/mbcache.c
index 298997f..0f1e453 100644
--- a/fs/mbcache.c
+++ b/fs/mbcache.c
@@ -301,8 +301,7 @@
 	if (cache) {
 		while (--m >= 0)
 			kfree(cache->c_indexes_hash[m]);
-		if (cache->c_block_hash)
-			kfree(cache->c_block_hash);
+		kfree(cache->c_block_hash);
 		kfree(cache);
 	}
 	return NULL;
diff --git a/fs/namei.c b/fs/namei.c
index c5769c4..b3f8a19 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1459,7 +1459,7 @@
 		if (!error) {
 			DQUOT_INIT(inode);
 			
-			error = do_truncate(dentry, 0);
+			error = do_truncate(dentry, 0, NULL);
 		}
 		put_write_access(inode);
 		if (error)
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 3976c17..618a327 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -149,8 +149,7 @@
 		}
 	}
 	spin_unlock(&clp->cl_lock);
-	if (delegation != NULL)
-		kfree(delegation);
+	kfree(delegation);
 	return status;
 }
 
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 24d2fbf..6391d89 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1688,8 +1688,7 @@
 
 	rpciod_down();		/* release rpciod */
 
-	if (server->hostname != NULL)
-		kfree(server->hostname);
+	kfree(server->hostname);
 	kfree(server);
 }
 
@@ -1908,8 +1907,7 @@
 			return ERR_PTR(-ENOMEM);
 	}
 	if (copy_from_user(dst, src->data, maxlen)) {
-		if (p != NULL)
-			kfree(p);
+		kfree(p);
 		return ERR_PTR(-EFAULT);
 	}
 	dst[maxlen] = '\0';
@@ -2000,10 +1998,8 @@
 out_err:
 	s = (struct super_block *)p;
 out_free:
-	if (server->mnt_path)
-		kfree(server->mnt_path);
-	if (server->hostname)
-		kfree(server->hostname);
+	kfree(server->mnt_path);
+	kfree(server->hostname);
 	kfree(server);
 	return s;
 }
@@ -2023,8 +2019,7 @@
 
 	destroy_nfsv4_state(server);
 
-	if (server->hostname != NULL)
-		kfree(server->hostname);
+	kfree(server->hostname);
 	kfree(server);
 }
 
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 52a26ba..0675f32 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -69,10 +69,8 @@
 void
 destroy_nfsv4_state(struct nfs_server *server)
 {
-	if (server->mnt_path) {
-		kfree(server->mnt_path);
-		server->mnt_path = NULL;
-	}
+	kfree(server->mnt_path);
+	server->mnt_path = NULL;
 	if (server->nfs4_state) {
 		nfs4_put_client(server->nfs4_state);
 		server->nfs4_state = NULL;
@@ -311,8 +309,7 @@
 		new = NULL;
 	}
 	spin_unlock(&clp->cl_lock);
-	if (new)
-		kfree(new);
+	kfree(new);
 	if (sp != NULL)
 		return sp;
 	put_rpccred(cred);
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index f732541..d639d17 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -52,8 +52,7 @@
 {
 	if (--data->count == 0) {
 		nfs_detach_unlinkdata(data);
-		if (data->name.name != NULL)
-			kfree(data->name.name);
+		kfree(data->name.name);
 		kfree(data);
 	}
 }
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 057aff7..417ec02 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -190,8 +190,7 @@
  out:
 	if (dom)
 		auth_domain_put(dom);
-	if (buf)
-		kfree(buf);
+	kfree(buf);
 	return err;
 }
 
@@ -428,8 +427,7 @@
 		path_release(&nd);
 	if (dom)
 		auth_domain_put(dom);
-	if (buf)
-		kfree(buf);
+	kfree(buf);
 	return err;
 }
 
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index e0e134d..9147b85 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -366,7 +366,8 @@
 	len = args->len = ntohl(*p++);
 
 	hdr = (void*)p - rqstp->rq_arg.head[0].iov_base;
-	if (rqstp->rq_arg.len < len + hdr)
+	if (rqstp->rq_arg.len < hdr ||
+	    rqstp->rq_arg.len - hdr < len)
 		return 0;
 
 	args->vec[0].iov_base = (void*)p;
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 4c41463..dcd6731 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -151,8 +151,7 @@
 	if (nbytes <= sizeof(argp->tmp))
 		p = argp->tmp;
 	else {
-		if (argp->tmpp)
-			kfree(argp->tmpp);
+		kfree(argp->tmpp);
 		p = argp->tmpp = kmalloc(nbytes, GFP_KERNEL);
 		if (!p)
 			return NULL;
@@ -2476,10 +2475,8 @@
 		kfree(args->ops);
 		args->ops = args->iops;
 	}
-	if (args->tmpp) {
-		kfree(args->tmpp);
-		args->tmpp = NULL;
-	}
+	kfree(args->tmpp);
+	args->tmpp = NULL;
 	while (args->to_free) {
 		struct tmpbuf *tb = args->to_free;
 		args->to_free = tb->next;
diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c
index 119e4d4..d852ebb 100644
--- a/fs/nfsd/nfscache.c
+++ b/fs/nfsd/nfscache.c
@@ -93,8 +93,7 @@
 
 	cache_disabled = 1;
 
-	if (hash_list)
-		kfree (hash_list);
+	kfree (hash_list);
 	hash_list = NULL;
 }
 
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 841c562..a0871b3 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -23,6 +23,7 @@
 #include <linux/seq_file.h>
 #include <linux/pagemap.h>
 #include <linux/init.h>
+#include <linux/string.h>
 
 #include <linux/nfs.h>
 #include <linux/nfsd_idmap.h>
@@ -35,6 +36,8 @@
 
 #include <asm/uaccess.h>
 
+unsigned int nfsd_versbits = ~0;
+
 /*
  *	We have a single directory with 9 nodes in it.
  */
@@ -50,8 +53,15 @@
 	NFSD_List,
 	NFSD_Fh,
 	NFSD_Threads,
+	NFSD_Versions,
+	/*
+	 * The below MUST come last.  Otherwise we leave a hole in nfsd_files[]
+	 * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops
+	 */
+#ifdef CONFIG_NFSD_V4
 	NFSD_Leasetime,
 	NFSD_RecoveryDir,
+#endif
 };
 
 /*
@@ -66,8 +76,11 @@
 static ssize_t write_getfs(struct file *file, char *buf, size_t size);
 static ssize_t write_filehandle(struct file *file, char *buf, size_t size);
 static ssize_t write_threads(struct file *file, char *buf, size_t size);
+static ssize_t write_versions(struct file *file, char *buf, size_t size);
+#ifdef CONFIG_NFSD_V4
 static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
 static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
+#endif
 
 static ssize_t (*write_op[])(struct file *, char *, size_t) = {
 	[NFSD_Svc] = write_svc,
@@ -79,8 +92,11 @@
 	[NFSD_Getfs] = write_getfs,
 	[NFSD_Fh] = write_filehandle,
 	[NFSD_Threads] = write_threads,
+	[NFSD_Versions] = write_versions,
+#ifdef CONFIG_NFSD_V4
 	[NFSD_Leasetime] = write_leasetime,
 	[NFSD_RecoveryDir] = write_recoverydir,
+#endif
 };
 
 static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
@@ -104,9 +120,23 @@
 	return rv;
 }
 
+static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size_t size, loff_t *pos)
+{
+	if (! file->private_data) {
+		/* An attempt to read a transaction file without writing
+		 * causes a 0-byte write so that the file can return
+		 * state information
+		 */
+		ssize_t rv = nfsctl_transaction_write(file, buf, 0, pos);
+		if (rv < 0)
+			return rv;
+	}
+	return simple_transaction_read(file, buf, size, pos);
+}
+
 static struct file_operations transaction_ops = {
 	.write		= nfsctl_transaction_write,
-	.read		= simple_transaction_read,
+	.read		= nfsctl_transaction_read,
 	.release	= simple_transaction_release,
 };
 
@@ -329,6 +359,70 @@
 	return strlen(buf);
 }
 
+static ssize_t write_versions(struct file *file, char *buf, size_t size)
+{
+	/*
+	 * Format:
+	 *   [-/+]vers [-/+]vers ...
+	 */
+	char *mesg = buf;
+	char *vers, sign;
+	int len, num;
+	ssize_t tlen = 0;
+	char *sep;
+
+	if (size>0) {
+		if (nfsd_serv)
+			return -EBUSY;
+		if (buf[size-1] != '\n')
+			return -EINVAL;
+		buf[size-1] = 0;
+
+		vers = mesg;
+		len = qword_get(&mesg, vers, size);
+		if (len <= 0) return -EINVAL;
+		do {
+			sign = *vers;
+			if (sign == '+' || sign == '-')
+				num = simple_strtol((vers+1), NULL, 0);
+			else
+				num = simple_strtol(vers, NULL, 0);
+			switch(num) {
+			case 2:
+			case 3:
+			case 4:
+				if (sign != '-')
+					NFSCTL_VERSET(nfsd_versbits, num);
+				else
+					NFSCTL_VERUNSET(nfsd_versbits, num);
+				break;
+			default:
+				return -EINVAL;
+			}
+			vers += len + 1;
+			tlen += len;
+		} while ((len = qword_get(&mesg, vers, size)) > 0);
+		/* If all get turned off, turn them back on, as
+		 * having no versions is BAD
+		 */
+		if ((nfsd_versbits & NFSCTL_VERALL)==0)
+			nfsd_versbits = NFSCTL_VERALL;
+	}
+	/* Now write current state into reply buffer */
+	len = 0;
+	sep = "";
+	for (num=2 ; num <= 4 ; num++)
+		if (NFSCTL_VERISSET(NFSCTL_VERALL, num)) {
+			len += sprintf(buf+len, "%s%c%d", sep,
+				       NFSCTL_VERISSET(nfsd_versbits, num)?'+':'-',
+				       num);
+			sep = " ";
+		}
+	len += sprintf(buf+len, "\n");
+	return len;
+}
+
+#ifdef CONFIG_NFSD_V4
 extern time_t nfs4_leasetime(void);
 
 static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
@@ -370,6 +464,7 @@
 	status = nfs4_reset_recoverydir(recdir);
 	return strlen(buf);
 }
+#endif
 
 /*----------------------------------------------------------------------------*/
 /*
@@ -389,6 +484,7 @@
 		[NFSD_List] = {"exports", &exports_operations, S_IRUGO},
 		[NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR},
 		[NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
+		[NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
 #ifdef CONFIG_NFSD_V4
 		[NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
 		[NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 1697539..89ed046 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -30,6 +30,7 @@
 #include <linux/nfsd/nfsd.h>
 #include <linux/nfsd/stats.h>
 #include <linux/nfsd/cache.h>
+#include <linux/nfsd/syscall.h>
 #include <linux/lockd/bind.h>
 #include <linux/nfsacl.h>
 
@@ -52,7 +53,7 @@
 extern struct svc_program	nfsd_program;
 static void			nfsd(struct svc_rqst *rqstp);
 struct timeval			nfssvc_boot;
-static struct svc_serv 		*nfsd_serv;
+       struct svc_serv 		*nfsd_serv;
 static atomic_t			nfsd_busy;
 static unsigned long		nfsd_last_call;
 static DEFINE_SPINLOCK(nfsd_call_lock);
@@ -63,6 +64,31 @@
 };
 static struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list);
 
+static struct svc_version *	nfsd_version[] = {
+	[2] = &nfsd_version2,
+#if defined(CONFIG_NFSD_V3)
+	[3] = &nfsd_version3,
+#endif
+#if defined(CONFIG_NFSD_V4)
+	[4] = &nfsd_version4,
+#endif
+};
+
+#define NFSD_MINVERS    	2
+#define NFSD_NRVERS		(sizeof(nfsd_version)/sizeof(nfsd_version[0]))
+static struct svc_version *nfsd_versions[NFSD_NRVERS];
+
+struct svc_program		nfsd_program = {
+	.pg_prog		= NFS_PROGRAM,		/* program number */
+	.pg_nvers		= NFSD_NRVERS,		/* nr of entries in nfsd_version */
+	.pg_vers		= nfsd_versions,	/* version table */
+	.pg_name		= "nfsd",		/* program name */
+	.pg_class		= "nfsd",		/* authentication class */
+	.pg_stats		= &nfsd_svcstats,	/* version table */
+	.pg_authenticate	= &svc_set_client,	/* export authentication */
+
+};
+
 /*
  * Maximum number of nfsd processes
  */
@@ -80,11 +106,12 @@
 nfsd_svc(unsigned short port, int nrservs)
 {
 	int	error;
-	int	none_left;	
+	int	none_left, found_one, i;
 	struct list_head *victim;
 	
 	lock_kernel();
-	dprintk("nfsd: creating service\n");
+	dprintk("nfsd: creating service: vers 0x%x\n",
+		nfsd_versbits);
 	error = -EINVAL;
 	if (nrservs <= 0)
 		nrservs = 0;
@@ -99,6 +126,27 @@
 	if (error<0)
 		goto out;
 	if (!nfsd_serv) {
+		/*
+		 * Use the nfsd_ctlbits to define which
+		 * versions that will be advertised.
+		 * If nfsd_ctlbits doesn't list any version,
+		 * export them all.
+		 */
+		found_one = 0;
+
+		for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
+			if (NFSCTL_VERISSET(nfsd_versbits, i)) {
+				nfsd_program.pg_vers[i] = nfsd_version[i];
+				found_one = 1;
+			} else
+				nfsd_program.pg_vers[i] = NULL;
+		}
+
+		if (!found_one) {
+			for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++)
+				nfsd_program.pg_vers[i] = nfsd_version[i];
+		}
+
 		atomic_set(&nfsd_busy, 0);
 		error = -ENOMEM;
 		nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE);
@@ -379,6 +427,7 @@
 	.pg_name		= "nfsd",
 	.pg_class		= "nfsd",
 	.pg_stats		= &nfsd_acl_svcstats,
+	.pg_authenticate	= &svc_set_client,
 };
 
 static struct svc_stat	nfsd_acl_svcstats = {
@@ -389,28 +438,3 @@
 #else
 #define nfsd_acl_program_p	NULL
 #endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
-
-extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4;
-
-static struct svc_version *	nfsd_version[] = {
-	[2] = &nfsd_version2,
-#if defined(CONFIG_NFSD_V3)
-	[3] = &nfsd_version3,
-#endif
-#if defined(CONFIG_NFSD_V4)
-	[4] = &nfsd_version4,
-#endif
-};
-
-#define NFSD_NRVERS		(sizeof(nfsd_version)/sizeof(nfsd_version[0]))
-struct svc_program		nfsd_program = {
-	.pg_next		= nfsd_acl_program_p,
-	.pg_prog		= NFS_PROGRAM,		/* program number */
-	.pg_nvers		= NFSD_NRVERS,		/* nr of entries in nfsd_version */
-	.pg_vers		= nfsd_version,		/* version table */
-	.pg_name		= "nfsd",		/* program name */
-	.pg_class		= "nfsd",		/* authentication class */
-	.pg_stats		= &nfsd_svcstats,	/* version table */
-	.pg_authenticate	= &svc_set_client,	/* export authentication */
-
-};
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 4f2cd3d..af7c3c3 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -254,12 +254,19 @@
 
 	/* Get inode */
 	err = fh_verify(rqstp, fhp, ftype, accmode);
-	if (err || !iap->ia_valid)
+	if (err)
 		goto out;
 
 	dentry = fhp->fh_dentry;
 	inode = dentry->d_inode;
 
+	/* Ignore any mode updates on symlinks */
+	if (S_ISLNK(inode->i_mode))
+		iap->ia_valid &= ~ATTR_MODE;
+
+	if (!iap->ia_valid)
+		goto out;
+
 	/* NFSv2 does not differentiate between "set-[ac]time-to-now"
 	 * which only requires access, and "set-[ac]time-to-X" which
 	 * requires ownership.
diff --git a/fs/open.c b/fs/open.c
index 8d06ec9..6e81367 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -194,7 +194,7 @@
 	return error;
 }
 
-int do_truncate(struct dentry *dentry, loff_t length)
+int do_truncate(struct dentry *dentry, loff_t length, struct file *filp)
 {
 	int err;
 	struct iattr newattrs;
@@ -205,6 +205,10 @@
 
 	newattrs.ia_size = length;
 	newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
+	if (filp) {
+		newattrs.ia_file = filp;
+		newattrs.ia_valid |= ATTR_FILE;
+	}
 
 	down(&dentry->d_inode->i_sem);
 	err = notify_change(dentry, &newattrs);
@@ -262,7 +266,7 @@
 	error = locks_verify_truncate(inode, NULL, length);
 	if (!error) {
 		DQUOT_INIT(inode);
-		error = do_truncate(nd.dentry, length);
+		error = do_truncate(nd.dentry, length, NULL);
 	}
 	put_write_access(inode);
 
@@ -314,7 +318,7 @@
 
 	error = locks_verify_truncate(inode, file, length);
 	if (!error)
-		error = do_truncate(dentry, length);
+		error = do_truncate(dentry, length, file);
 out_putf:
 	fput(file);
 out:
@@ -887,6 +891,10 @@
 	return filp;
 }
 
+/*
+ * dentry_open() will have done dput(dentry) and mntput(mnt) if it returns an
+ * error.
+ */
 struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
 {
 	int error;
@@ -894,8 +902,11 @@
 
 	error = -ENFILE;
 	f = get_empty_filp();
-	if (f == NULL)
+	if (f == NULL) {
+		dput(dentry);
+		mntput(mnt);
 		return ERR_PTR(error);
+	}
 
 	return __dentry_open(dentry, mnt, flags, f, NULL);
 }
diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c
index 1be11ce..aeb0106 100644
--- a/fs/openpromfs/inode.c
+++ b/fs/openpromfs/inode.c
@@ -1088,8 +1088,7 @@
 	unregister_filesystem(&openprom_fs_type);
 	free_pages ((unsigned long)nodes, alloced);
 	for (i = 0; i < aliases_nodes; i++)
-		if (alias_names [i])
-			kfree (alias_names [i]);
+		kfree (alias_names [i]);
 	nodes = NULL;
 }
 
diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c
index d59dcbf..6327bcb 100644
--- a/fs/partitions/ibm.c
+++ b/fs/partitions/ibm.c
@@ -29,7 +29,7 @@
  * cyl-cyl-head-head structure
  */
 static inline int
-cchh2blk (cchh_t *ptr, struct hd_geometry *geo) {
+cchh2blk (struct vtoc_cchh *ptr, struct hd_geometry *geo) {
         return ptr->cc * geo->heads * geo->sectors +
 	       ptr->hh * geo->sectors;
 }
@@ -40,7 +40,7 @@
  * cyl-cyl-head-head-block structure
  */
 static inline int
-cchhb2blk (cchhb_t *ptr, struct hd_geometry *geo) {
+cchhb2blk (struct vtoc_cchhb *ptr, struct hd_geometry *geo) {
         return ptr->cc * geo->heads * geo->sectors +
 		ptr->hh * geo->sectors +
 		ptr->b;
@@ -56,7 +56,7 @@
 	struct hd_geometry *geo;
 	char type[5] = {0,};
 	char name[7] = {0,};
-	volume_label_t *vlabel;
+	struct vtoc_volume_label *vlabel;
 	unsigned char *data;
 	Sector sect;
 
@@ -64,7 +64,8 @@
 		goto out_noinfo;
 	if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL)
 		goto out_nogeo;
-	if ((vlabel = kmalloc(sizeof(volume_label_t), GFP_KERNEL)) == NULL)
+	if ((vlabel = kmalloc(sizeof(struct vtoc_volume_label),
+			      GFP_KERNEL)) == NULL)
 		goto out_novlab;
 	
 	if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 ||
@@ -86,7 +87,7 @@
 		strncpy(name, data + 8, 6);
 	else
 		strncpy(name, data + 4, 6);
-	memcpy (vlabel, data, sizeof(volume_label_t));
+	memcpy (vlabel, data, sizeof(struct vtoc_volume_label));
 	put_dev_sector(sect);
 
 	EBCASC(type, 4);
@@ -129,9 +130,9 @@
 		counter = 0;
 		while ((data = read_dev_sector(bdev, blk*(blocksize/512),
 					       &sect)) != NULL) {
-			format1_label_t f1;
+			struct vtoc_format1_label f1;
 
-			memcpy(&f1, data, sizeof(format1_label_t));
+			memcpy(&f1, data, sizeof(struct vtoc_format1_label));
 			put_dev_sector(sect);
 
 			/* skip FMT4 / FMT5 / FMT7 labels */
diff --git a/fs/quota.c b/fs/quota.c
index 1df7832..612e04d 100644
--- a/fs/quota.c
+++ b/fs/quota.c
@@ -15,6 +15,7 @@
 #include <linux/security.h>
 #include <linux/syscalls.h>
 #include <linux/buffer_head.h>
+#include <linux/quotaops.h>
 
 /* Check validity of generic quotactl commands */
 static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
diff --git a/fs/smbfs/request.c b/fs/smbfs/request.c
index 2d85dd7..a0f296d 100644
--- a/fs/smbfs/request.c
+++ b/fs/smbfs/request.c
@@ -786,8 +786,7 @@
 		/* We should never be called with any of these states */
 	case SMB_RECV_END:
 	case SMB_RECV_REQUEST:
-		server->rstate = SMB_RECV_END;
-		break;
+		BUG();
 	}
 
 	if (result < 0) {
diff --git a/fs/smbfs/symlink.c b/fs/smbfs/symlink.c
index 0c64bc3..cdc53c4 100644
--- a/fs/smbfs/symlink.c
+++ b/fs/smbfs/symlink.c
@@ -45,7 +45,7 @@
 		int len = smb_proc_read_link(server_from_dentry(dentry),
 						dentry, link, PATH_MAX - 1);
 		if (len < 0) {
-			putname(link);
+			__putname(link);
 			link = ERR_PTR(len);
 		} else {
 			link[len] = 0;
@@ -59,7 +59,7 @@
 {
 	char *s = nd_get_link(nd);
 	if (!IS_ERR(s))
-		putname(s);
+		__putname(s);
 }
 
 struct inode_operations smb_link_inode_operations =
diff --git a/fs/super.c b/fs/super.c
index f60155e..eed6c31 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -474,8 +474,6 @@
 	return NULL;
 }
 
-EXPORT_SYMBOL(user_get_super);
-
 asmlinkage long sys_ustat(unsigned dev, struct ustat __user * ubuf)
 {
         struct super_block *s;
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h
index 0e54922..6636698 100644
--- a/fs/udf/udf_sb.h
+++ b/fs/udf/udf_sb.h
@@ -39,8 +39,7 @@
 {\
 	if (UDF_SB(X))\
 	{\
-		if (UDF_SB_PARTMAPS(X))\
-			kfree(UDF_SB_PARTMAPS(X));\
+		kfree(UDF_SB_PARTMAPS(X));\
 		UDF_SB_PARTMAPS(X) = NULL;\
 	}\
 }
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index f036d69..54828eb 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -472,13 +472,14 @@
 	return 1;
 
 failed:
-	if (base) kfree (base);
+	kfree (base);
 	if (sbi->s_ucg) {
 		for (i = 0; i < uspi->s_ncg; i++)
-			if (sbi->s_ucg[i]) brelse (sbi->s_ucg[i]);
+			if (sbi->s_ucg[i])
+				brelse (sbi->s_ucg[i]);
 		kfree (sbi->s_ucg);
 		for (i = 0; i < UFS_MAX_GROUP_LOADED; i++)
-			if (sbi->s_ucpi[i]) kfree (sbi->s_ucpi[i]);
+			kfree (sbi->s_ucpi[i]);
 	}
 	UFSD(("EXIT (FAILED)\n"))
 	return 0;
@@ -981,9 +982,10 @@
 dalloc_failed:
 	iput(inode);
 failed:
-	if (ubh) ubh_brelse_uspi (uspi);
-	if (uspi) kfree (uspi);
-	if (sbi) kfree(sbi);
+	if (ubh)
+		ubh_brelse_uspi (uspi);
+	kfree (uspi);
+	kfree(sbi);
 	sb->s_fs_info = NULL;
 	UFSD(("EXIT (FAILED)\n"))
 	return -EINVAL;
diff --git a/fs/xattr.c b/fs/xattr.c
index f6e00c0..a9db225 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -74,8 +74,7 @@
 	}
 out:
 	up(&d->d_inode->i_sem);
-	if (kvalue)
-		kfree(kvalue);
+	kfree(kvalue);
 	return error;
 }
 
@@ -173,8 +172,7 @@
 		error = -E2BIG;
 	}
 out:
-	if (kvalue)
-		kfree(kvalue);
+	kfree(kvalue);
 	return error;
 }
 
@@ -259,8 +257,7 @@
 		error = -E2BIG;
 	}
 out:
-	if (klist)
-		kfree(klist);
+	kfree(klist);
 	return error;
 }
 
diff --git a/fs/xfs/linux-2.6/kmem.h b/fs/xfs/linux-2.6/kmem.h
index 8f82c1a..c64a29cd 100644
--- a/fs/xfs/linux-2.6/kmem.h
+++ b/fs/xfs/linux-2.6/kmem.h
@@ -30,8 +30,8 @@
 #define KM_NOFS		0x0004u
 #define KM_MAYFAIL	0x0008u
 
-#define	kmem_zone	kmem_cache_s
-#define kmem_zone_t	kmem_cache_t
+#define	kmem_zone	kmem_cache
+#define kmem_zone_t	struct kmem_cache
 
 typedef unsigned long xfs_pflags_t;
 
diff --git a/include/asm-alpha/pgtable.h b/include/asm-alpha/pgtable.h
index 8393bf3..a985cd2 100644
--- a/include/asm-alpha/pgtable.h
+++ b/include/asm-alpha/pgtable.h
@@ -17,6 +17,9 @@
 #include <asm/processor.h>	/* For TASK_SIZE */
 #include <asm/machvec.h>
 
+struct mm_struct;
+struct vm_area_struct;
+
 /* Certain architectures need to do special things when PTEs
  * within a page table are directly modified.  Thus, the following
  * hook is made available.
diff --git a/include/asm-alpha/ptrace.h b/include/asm-alpha/ptrace.h
index d462c5e..072375c 100644
--- a/include/asm-alpha/ptrace.h
+++ b/include/asm-alpha/ptrace.h
@@ -67,6 +67,9 @@
 };
 
 #ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE	1
+
 #define user_mode(regs) (((regs)->ps & 8) != 0)
 #define instruction_pointer(regs) ((regs)->pc)
 #define profile_pc(regs) instruction_pointer(regs)
diff --git a/include/asm-cris/arch-v10/byteorder.h b/include/asm-cris/arch-v10/byteorder.h
index e24465d..255b646 100644
--- a/include/asm-cris/arch-v10/byteorder.h
+++ b/include/asm-cris/arch-v10/byteorder.h
@@ -9,14 +9,14 @@
  * them together into ntohl etc.
  */
 
-extern __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
+static inline __attribute_const__ __u32 ___arch__swab32(__u32 x)
 {
 	__asm__ ("swapwb %0" : "=r" (x) : "0" (x));
   
 	return(x);
 }
 
-extern __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x)
+static inline __attribute_const__ __u16 ___arch__swab16(__u16 x)
 {
 	__asm__ ("swapb %0" : "=r" (x) : "0" (x));
 	
diff --git a/include/asm-cris/arch-v10/checksum.h b/include/asm-cris/arch-v10/checksum.h
index fde1d00..633f234 100644
--- a/include/asm-cris/arch-v10/checksum.h
+++ b/include/asm-cris/arch-v10/checksum.h
@@ -8,7 +8,7 @@
  * to split all of those into 16-bit components, then add.
  */
 
-extern inline unsigned int
+static inline unsigned int
 csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len,
 		   unsigned short proto, unsigned int sum)
 {
diff --git a/include/asm-cris/arch-v10/delay.h b/include/asm-cris/arch-v10/delay.h
index cfedae0..39481f6 100644
--- a/include/asm-cris/arch-v10/delay.h
+++ b/include/asm-cris/arch-v10/delay.h
@@ -1,7 +1,7 @@
 #ifndef _CRIS_ARCH_DELAY_H
 #define _CRIS_ARCH_DELAY_H
 
-extern __inline__ void __delay(int loops)
+static inline void __delay(int loops)
 {
 	__asm__ __volatile__ (
 			      "move.d %0,$r9\n\t"
diff --git a/include/asm-cris/arch-v10/ide.h b/include/asm-cris/arch-v10/ide.h
index 8cf2d7c..78b301e 100644
--- a/include/asm-cris/arch-v10/ide.h
+++ b/include/asm-cris/arch-v10/ide.h
@@ -25,7 +25,7 @@
 
 #define MAX_HWIFS	4
 
-extern __inline__ int ide_default_irq(unsigned long base)
+static inline int ide_default_irq(unsigned long base)
 {
 	/* all IDE busses share the same IRQ, number 4.
 	 * this has the side-effect that ide-probe.c will cluster our 4 interfaces
@@ -35,7 +35,7 @@
 	return 4;
 }
 
-extern __inline__ unsigned long ide_default_io_base(int index)
+static inline unsigned long ide_default_io_base(int index)
 {
 	/* we have no real I/O base address per interface, since all go through the
 	 * same register. but in a bitfield in that register, we have the i/f number.
@@ -54,7 +54,7 @@
  * of the ide_default_io_base call above. ctrl_port will be 0, but that is don't care for us.
  */
 
-extern __inline__ void ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port, unsigned long ctrl_port, int *irq)
+static inline void ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port, unsigned long ctrl_port, int *irq)
 {
 	int i;
 
@@ -77,7 +77,7 @@
 	hw->io_ports[IDE_IRQ_OFFSET] = 0;
 }
 
-extern __inline__ void ide_init_default_hwifs(void)
+static inline void ide_init_default_hwifs(void)
 {
 	hw_regs_t hw;
 	int index;
diff --git a/include/asm-cris/arch-v10/system.h b/include/asm-cris/arch-v10/system.h
index 6cc3564..1ac7b63 100644
--- a/include/asm-cris/arch-v10/system.h
+++ b/include/asm-cris/arch-v10/system.h
@@ -5,7 +5,7 @@
 
 /* read the CPU version register */
 
-extern inline unsigned long rdvr(void) { 
+static inline unsigned long rdvr(void) {
 	unsigned char vr;
 	__asm__ volatile ("move $vr,%0" : "=rm" (vr));
 	return vr;
@@ -15,7 +15,7 @@
 
 /* read/write the user-mode stackpointer */
 
-extern inline unsigned long rdusp(void) {
+static inline unsigned long rdusp(void) {
 	unsigned long usp;
 	__asm__ __volatile__("move $usp,%0" : "=rm" (usp));
 	return usp;
@@ -26,13 +26,13 @@
 
 /* read the current stackpointer */
 
-extern inline unsigned long rdsp(void) {
+static inline unsigned long rdsp(void) {
 	unsigned long sp;
 	__asm__ __volatile__("move.d $sp,%0" : "=rm" (sp));
 	return sp;
 }
 
-extern inline unsigned long _get_base(char * addr)
+static inline unsigned long _get_base(char * addr)
 {
   return 0;
 }
diff --git a/include/asm-cris/arch-v10/thread_info.h b/include/asm-cris/arch-v10/thread_info.h
index 357f5df..218f415 100644
--- a/include/asm-cris/arch-v10/thread_info.h
+++ b/include/asm-cris/arch-v10/thread_info.h
@@ -2,7 +2,7 @@
 #define _ASM_ARCH_THREAD_INFO_H
 
 /* how to get the thread information struct from C */
-extern inline struct thread_info *current_thread_info(void)
+static inline struct thread_info *current_thread_info(void)
 {
 	struct thread_info *ti;
         __asm__("and.d $sp,%0; ":"=r" (ti) : "0" (~8191UL));
diff --git a/include/asm-cris/arch-v10/timex.h b/include/asm-cris/arch-v10/timex.h
index ecfc553..e48447d 100644
--- a/include/asm-cris/arch-v10/timex.h
+++ b/include/asm-cris/arch-v10/timex.h
@@ -22,7 +22,7 @@
 
 unsigned long get_ns_in_jiffie(void);
 
-extern inline unsigned long get_us_in_jiffie_highres(void)
+static inline unsigned long get_us_in_jiffie_highres(void)
 {
 	return get_ns_in_jiffie()/1000;
 }
diff --git a/include/asm-cris/arch-v10/uaccess.h b/include/asm-cris/arch-v10/uaccess.h
index 787d2e6..65b02d9 100644
--- a/include/asm-cris/arch-v10/uaccess.h
+++ b/include/asm-cris/arch-v10/uaccess.h
@@ -87,7 +87,7 @@
  * bytes copied		if we hit a null byte
  * (without the null byte)
  */
-extern inline long         
+static inline long
 __do_strncpy_from_user(char *dst, const char *src, long count)
 {
 	long res;
@@ -602,7 +602,7 @@
  * or 0 for error.  Return a value greater than N if too long.
  */
 
-extern inline long
+static inline long
 strnlen_user(const char *s, long n)
 {
 	long res, tmp1;
diff --git a/include/asm-cris/arch-v32/bitops.h b/include/asm-cris/arch-v32/bitops.h
index e40a58d..147689d6 100644
--- a/include/asm-cris/arch-v32/bitops.h
+++ b/include/asm-cris/arch-v32/bitops.h
@@ -8,7 +8,7 @@
  * inverts all bits in the input.
  */
 
-extern inline unsigned long
+static inline unsigned long
 cris_swapnwbrlz(unsigned long w)
 {
 	unsigned long res;
@@ -20,7 +20,7 @@
 	return res;
 }
 
-extern inline unsigned long
+static inline unsigned long
 cris_swapwbrlz(unsigned long w)
 {
 	unsigned long res;
@@ -36,7 +36,7 @@
  * Find First Zero in word. Undefined if no zero exist, so the caller should
  * check against ~0 first.
  */
-extern inline unsigned long
+static inline unsigned long
 ffz(unsigned long w)
 {
 	return cris_swapnwbrlz(w);
@@ -46,7 +46,7 @@
  * Find First Set bit in word. Undefined if no 1 exist, so the caller
  * should check against 0 first.
  */
-extern inline unsigned long
+static inline unsigned long
 __ffs(unsigned long w)
 {
 	return cris_swapnwbrlz(~w);
@@ -55,7 +55,7 @@
 /*
  * Find First Bit that is set.
  */
-extern inline unsigned long
+static inline unsigned long
 kernel_ffs(unsigned long w)
 {
 	return w ? cris_swapwbrlz (w) + 1 : 0;
diff --git a/include/asm-cris/arch-v32/byteorder.h b/include/asm-cris/arch-v32/byteorder.h
index 74846ee..6ef8fb4 100644
--- a/include/asm-cris/arch-v32/byteorder.h
+++ b/include/asm-cris/arch-v32/byteorder.h
@@ -3,14 +3,14 @@
 
 #include <asm/types.h>
 
-extern __inline__ __const__ __u32
+static inline __const__ __u32
 ___arch__swab32(__u32 x)
 {
 	__asm__ __volatile__ ("swapwb %0" : "=r" (x) : "0" (x));
 	return (x);
 }
 
-extern __inline__ __const__ __u16
+static inline __const__ __u16
 ___arch__swab16(__u16 x)
 {
 	__asm__ __volatile__ ("swapb %0" : "=r" (x) : "0" (x));
diff --git a/include/asm-cris/arch-v32/checksum.h b/include/asm-cris/arch-v32/checksum.h
index a1d6b2a..97ef89e 100644
--- a/include/asm-cris/arch-v32/checksum.h
+++ b/include/asm-cris/arch-v32/checksum.h
@@ -9,7 +9,7 @@
  * checksum. Which means it would be necessary to split all those into
  * 16-bit components and then add.
  */
-extern inline unsigned int
+static inline unsigned int
 csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr,
 		   unsigned short len, unsigned short proto, unsigned int sum)
 {
diff --git a/include/asm-cris/arch-v32/delay.h b/include/asm-cris/arch-v32/delay.h
index f36f7f7..b6e941e 100644
--- a/include/asm-cris/arch-v32/delay.h
+++ b/include/asm-cris/arch-v32/delay.h
@@ -1,7 +1,7 @@
 #ifndef _ASM_CRIS_ARCH_DELAY_H
 #define _ASM_CRIS_ARCH_DELAY_H
 
-extern __inline__ void
+static inline void
 __delay(int loops)
 {
 	__asm__ __volatile__ (
diff --git a/include/asm-cris/arch-v32/ide.h b/include/asm-cris/arch-v32/ide.h
index 24f5604..6590f65 100644
--- a/include/asm-cris/arch-v32/ide.h
+++ b/include/asm-cris/arch-v32/ide.h
@@ -26,7 +26,7 @@
 
 #define MAX_HWIFS	4
 
-extern __inline__ int ide_default_irq(unsigned long base)
+static inline int ide_default_irq(unsigned long base)
 {
 	/* all IDE busses share the same IRQ,
 	 * this has the side-effect that ide-probe.c will cluster our 4 interfaces
@@ -36,7 +36,7 @@
 	return ATA_INTR_VECT;
 }
 
-extern __inline__ unsigned long ide_default_io_base(int index)
+static inline unsigned long ide_default_io_base(int index)
 {
 	reg_ata_rw_ctrl2 ctrl2 = {.sel = index};
 	/* we have no real I/O base address per interface, since all go through the
diff --git a/include/asm-cris/arch-v32/io.h b/include/asm-cris/arch-v32/io.h
index 4c80263..043c9ce 100644
--- a/include/asm-cris/arch-v32/io.h
+++ b/include/asm-cris/arch-v32/io.h
@@ -35,7 +35,7 @@
 extern struct crisv32_iopin crisv32_led3_green;
 extern struct crisv32_iopin crisv32_led3_red;
 
-extern inline void crisv32_io_set(struct crisv32_iopin* iopin,
+static inline void crisv32_io_set(struct crisv32_iopin* iopin,
 			   int val)
 {
 	if (val)
@@ -44,7 +44,7 @@
 		*iopin->port->data &= ~iopin->bit;
 }
 
-extern inline void crisv32_io_set_dir(struct crisv32_iopin* iopin,
+static inline void crisv32_io_set_dir(struct crisv32_iopin* iopin,
 			       enum crisv32_io_dir dir)
 {
 	if (dir == crisv32_io_dir_in)
@@ -53,7 +53,7 @@
 		*iopin->port->oe |= iopin->bit;
 }
 
-extern inline int crisv32_io_rd(struct crisv32_iopin* iopin)
+static inline int crisv32_io_rd(struct crisv32_iopin* iopin)
 {
 	return ((*iopin->port->data_in & iopin->bit) ? 1 : 0);
 }
diff --git a/include/asm-cris/arch-v32/system.h b/include/asm-cris/arch-v32/system.h
index b9afbb9..a3d75d5 100644
--- a/include/asm-cris/arch-v32/system.h
+++ b/include/asm-cris/arch-v32/system.h
@@ -4,7 +4,7 @@
 #include <linux/config.h>
 
 /* Read the CPU version register. */
-extern inline unsigned long rdvr(void)
+static inline unsigned long rdvr(void)
 {
 	unsigned char vr;
 
@@ -15,7 +15,7 @@
 #define cris_machine_name "crisv32"
 
 /* Read the user-mode stack pointer. */
-extern inline unsigned long rdusp(void)
+static inline unsigned long rdusp(void)
 {
 	unsigned long usp;
 
@@ -24,7 +24,7 @@
 }
 
 /* Read the current stack pointer. */
-extern inline unsigned long rdsp(void)
+static inline unsigned long rdsp(void)
 {
 	unsigned long sp;
 
diff --git a/include/asm-cris/arch-v32/thread_info.h b/include/asm-cris/arch-v32/thread_info.h
index a7a1823..d693695 100644
--- a/include/asm-cris/arch-v32/thread_info.h
+++ b/include/asm-cris/arch-v32/thread_info.h
@@ -2,7 +2,7 @@
 #define _ASM_CRIS_ARCH_THREAD_INFO_H
 
 /* Return a thread_info struct. */
-extern inline struct thread_info *current_thread_info(void)
+static inline struct thread_info *current_thread_info(void)
 {
 	struct thread_info *ti;
 
diff --git a/include/asm-cris/arch-v32/timex.h b/include/asm-cris/arch-v32/timex.h
index 4d0fd23..5a4aa28 100644
--- a/include/asm-cris/arch-v32/timex.h
+++ b/include/asm-cris/arch-v32/timex.h
@@ -22,7 +22,7 @@
 
 extern unsigned long get_ns_in_jiffie(void);
 
-extern inline unsigned long get_us_in_jiffie_highres(void)
+static inline unsigned long get_us_in_jiffie_highres(void)
 {
 	return get_ns_in_jiffie() / 1000;
 }
diff --git a/include/asm-cris/arch-v32/uaccess.h b/include/asm-cris/arch-v32/uaccess.h
index 055a0bd..6b207f1b 100644
--- a/include/asm-cris/arch-v32/uaccess.h
+++ b/include/asm-cris/arch-v32/uaccess.h
@@ -93,7 +93,7 @@
  * bytes copied		if we hit a null byte
  * (without the null byte)
  */
-extern inline long
+static inline long
 __do_strncpy_from_user(char *dst, const char *src, long count)
 {
 	long res;
@@ -695,7 +695,7 @@
  * or 0 for error.  Return a value greater than N if too long.
  */
 
-extern inline long
+static inline long
 strnlen_user(const char *s, long n)
 {
 	long res, tmp1;
diff --git a/include/asm-cris/atomic.h b/include/asm-cris/atomic.h
index 70605b0..8c2e783 100644
--- a/include/asm-cris/atomic.h
+++ b/include/asm-cris/atomic.h
@@ -20,7 +20,7 @@
 
 /* These should be written in asm but we do it in C for now. */
 
-extern __inline__ void atomic_add(int i, volatile atomic_t *v)
+static inline void atomic_add(int i, volatile atomic_t *v)
 {
 	unsigned long flags;
 	cris_atomic_save(v, flags);
@@ -28,7 +28,7 @@
 	cris_atomic_restore(v, flags);
 }
 
-extern __inline__ void atomic_sub(int i, volatile atomic_t *v)
+static inline void atomic_sub(int i, volatile atomic_t *v)
 {
 	unsigned long flags;
 	cris_atomic_save(v, flags);
@@ -36,7 +36,7 @@
 	cris_atomic_restore(v, flags);
 }
 
-extern __inline__ int atomic_add_return(int i, volatile atomic_t *v)
+static inline int atomic_add_return(int i, volatile atomic_t *v)
 {
 	unsigned long flags;
 	int retval;
@@ -48,7 +48,7 @@
 
 #define atomic_add_negative(a, v)	(atomic_add_return((a), (v)) < 0)
 
-extern __inline__ int atomic_sub_return(int i, volatile atomic_t *v)
+static inline int atomic_sub_return(int i, volatile atomic_t *v)
 {
 	unsigned long flags;
 	int retval;
@@ -58,7 +58,7 @@
 	return retval;
 }
 
-extern __inline__ int atomic_sub_and_test(int i, volatile atomic_t *v)
+static inline int atomic_sub_and_test(int i, volatile atomic_t *v)
 {
 	int retval;
 	unsigned long flags;
@@ -68,7 +68,7 @@
 	return retval;
 }
 
-extern __inline__ void atomic_inc(volatile atomic_t *v)
+static inline void atomic_inc(volatile atomic_t *v)
 {
 	unsigned long flags;
 	cris_atomic_save(v, flags);
@@ -76,7 +76,7 @@
 	cris_atomic_restore(v, flags);
 }
 
-extern __inline__ void atomic_dec(volatile atomic_t *v)
+static inline void atomic_dec(volatile atomic_t *v)
 {
 	unsigned long flags;
 	cris_atomic_save(v, flags);
@@ -84,7 +84,7 @@
 	cris_atomic_restore(v, flags);
 }
 
-extern __inline__ int atomic_inc_return(volatile atomic_t *v)
+static inline int atomic_inc_return(volatile atomic_t *v)
 {
 	unsigned long flags;
 	int retval;
@@ -94,7 +94,7 @@
 	return retval;
 }
 
-extern __inline__ int atomic_dec_return(volatile atomic_t *v)
+static inline int atomic_dec_return(volatile atomic_t *v)
 {
 	unsigned long flags;
 	int retval;
@@ -103,7 +103,7 @@
 	cris_atomic_restore(v, flags);
 	return retval;
 }
-extern __inline__ int atomic_dec_and_test(volatile atomic_t *v)
+static inline int atomic_dec_and_test(volatile atomic_t *v)
 {
 	int retval;
 	unsigned long flags;
@@ -113,7 +113,7 @@
 	return retval;
 }
 
-extern __inline__ int atomic_inc_and_test(volatile atomic_t *v)
+static inline int atomic_inc_and_test(volatile atomic_t *v)
 {
 	int retval;
 	unsigned long flags;
diff --git a/include/asm-cris/bitops.h b/include/asm-cris/bitops.h
index e3da57f..1bddb3f 100644
--- a/include/asm-cris/bitops.h
+++ b/include/asm-cris/bitops.h
@@ -89,7 +89,7 @@
  * It also implies a memory barrier.
  */
 
-extern inline int test_and_set_bit(int nr, volatile unsigned long *addr)
+static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
 {
 	unsigned int mask, retval;
 	unsigned long flags;
@@ -105,7 +105,7 @@
 	return retval;
 }
 
-extern inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
+static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
 {
 	unsigned int mask, retval;
 	unsigned int *adr = (unsigned int *)addr;
@@ -132,7 +132,7 @@
  * It also implies a memory barrier.
  */
 
-extern inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
+static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
 {
 	unsigned int mask, retval;
 	unsigned long flags;
@@ -157,7 +157,7 @@
  * but actually fail.  You must protect multiple accesses with a lock.
  */
 
-extern inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
+static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
 {
 	unsigned int mask, retval;
 	unsigned int *adr = (unsigned int *)addr;
@@ -177,7 +177,7 @@
  * It also implies a memory barrier.
  */
 
-extern inline int test_and_change_bit(int nr, volatile unsigned long *addr)
+static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
 {
 	unsigned int mask, retval;
 	unsigned long flags;
@@ -193,7 +193,7 @@
 
 /* WARNING: non atomic and it can be reordered! */
 
-extern inline int __test_and_change_bit(int nr, volatile unsigned long *addr)
+static inline int __test_and_change_bit(int nr, volatile unsigned long *addr)
 {
 	unsigned int mask, retval;
 	unsigned int *adr = (unsigned int *)addr;
@@ -214,7 +214,7 @@
  * This routine doesn't need to be atomic.
  */
 
-extern inline int test_bit(int nr, const volatile unsigned long *addr)
+static inline int test_bit(int nr, const volatile unsigned long *addr)
 {
 	unsigned int mask;
 	unsigned int *adr = (unsigned int *)addr;
@@ -258,7 +258,7 @@
  * @offset: The bitnumber to start searching at
  * @size: The maximum size to search
  */
-extern inline int find_next_zero_bit (const unsigned long * addr, int size, int offset)
+static inline int find_next_zero_bit (const unsigned long * addr, int size, int offset)
 {
 	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
 	unsigned long result = offset & ~31UL;
@@ -366,7 +366,7 @@
 #define minix_test_bit(nr,addr) test_bit(nr,addr)
 #define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
 
-extern inline int sched_find_first_bit(const unsigned long *b)
+static inline int sched_find_first_bit(const unsigned long *b)
 {
 	if (unlikely(b[0]))
 		return __ffs(b[0]);
diff --git a/include/asm-cris/checksum.h b/include/asm-cris/checksum.h
index 15ca8ae..26a7719 100644
--- a/include/asm-cris/checksum.h
+++ b/include/asm-cris/checksum.h
@@ -34,7 +34,7 @@
  *	Fold a partial checksum into a word
  */
 
-extern inline unsigned int csum_fold(unsigned int sum)
+static inline unsigned int csum_fold(unsigned int sum)
 {
 	/* the while loop is unnecessary really, it's always enough with two
 	   iterations */
@@ -55,7 +55,7 @@
  *
  */
 
-extern inline unsigned short ip_fast_csum(unsigned char * iph,
+static inline unsigned short ip_fast_csum(unsigned char * iph,
 					  unsigned int ihl)
 {
 	return csum_fold(csum_partial(iph, ihl * 4, 0));
@@ -66,7 +66,7 @@
  * returns a 16-bit checksum, already complemented
  */
 
-extern inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
+static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
 						   unsigned long daddr,
 						   unsigned short len,
 						   unsigned short proto,
@@ -80,7 +80,7 @@
  * in icmp.c
  */
 
-extern inline unsigned short ip_compute_csum(unsigned char * buff, int len) {
+static inline unsigned short ip_compute_csum(unsigned char * buff, int len) {
 	return csum_fold (csum_partial(buff, len, 0));
 }
 
diff --git a/include/asm-cris/current.h b/include/asm-cris/current.h
index dce69c9..5f5c0ef 100644
--- a/include/asm-cris/current.h
+++ b/include/asm-cris/current.h
@@ -5,7 +5,7 @@
 
 struct task_struct;
 
-extern inline struct task_struct * get_current(void)
+static inline struct task_struct * get_current(void)
 {
         return current_thread_info()->task;
 }
diff --git a/include/asm-cris/delay.h b/include/asm-cris/delay.h
index efc41aa..d3a3978 100644
--- a/include/asm-cris/delay.h
+++ b/include/asm-cris/delay.h
@@ -13,7 +13,7 @@
 
 extern unsigned long loops_per_usec; /* arch/cris/mm/init.c */
 
-extern __inline__ void udelay(unsigned long usecs)
+static inline void udelay(unsigned long usecs)
 {
 	__delay(usecs * loops_per_usec);
 }
diff --git a/include/asm-cris/io.h b/include/asm-cris/io.h
index 16e791b..716c69b 100644
--- a/include/asm-cris/io.h
+++ b/include/asm-cris/io.h
@@ -23,12 +23,12 @@
  * Change virtual addresses to physical addresses and vv.
  */
 
-extern inline unsigned long virt_to_phys(volatile void * address)
+static inline unsigned long virt_to_phys(volatile void * address)
 {
 	return __pa(address);
 }
 
-extern inline void * phys_to_virt(unsigned long address)
+static inline void * phys_to_virt(unsigned long address)
 {
 	return __va(address);
 }
@@ -36,7 +36,7 @@
 extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
 extern void __iomem * __ioremap_prot(unsigned long phys_addr, unsigned long size, pgprot_t prot);
 
-extern inline void __iomem * ioremap (unsigned long offset, unsigned long size)
+static inline void __iomem * ioremap (unsigned long offset, unsigned long size)
 {
 	return __ioremap(offset, size, 0);
 }
diff --git a/include/asm-cris/irq.h b/include/asm-cris/irq.h
index 4fab5c3..4b33879 100644
--- a/include/asm-cris/irq.h
+++ b/include/asm-cris/irq.h
@@ -8,7 +8,7 @@
 
 #include <asm/arch/irq.h>
 
-extern __inline__ int irq_canonicalize(int irq)
+static inline int irq_canonicalize(int irq)
 {  
   return irq; 
 }
diff --git a/include/asm-cris/pgalloc.h b/include/asm-cris/pgalloc.h
index a131776..deaddfe 100644
--- a/include/asm-cris/pgalloc.h
+++ b/include/asm-cris/pgalloc.h
@@ -11,35 +11,35 @@
  * Allocate and free page tables.
  */
 
-extern inline pgd_t *pgd_alloc (struct mm_struct *mm)
+static inline pgd_t *pgd_alloc (struct mm_struct *mm)
 {
 	return (pgd_t *)get_zeroed_page(GFP_KERNEL);
 }
 
-extern inline void pgd_free (pgd_t *pgd)
+static inline void pgd_free (pgd_t *pgd)
 {
 	free_page((unsigned long)pgd);
 }
 
-extern inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
 {
   	pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
  	return pte;
 }
 
-extern inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
+static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
 {
 	struct page *pte;
 	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
 	return pte;
 }
 
-extern inline void pte_free_kernel(pte_t *pte)
+static inline void pte_free_kernel(pte_t *pte)
 {
 	free_page((unsigned long)pte);
 }
 
-extern inline void pte_free(struct page *pte)
+static inline void pte_free(struct page *pte)
 {
 	__free_page(pte);
 }
diff --git a/include/asm-cris/pgtable.h b/include/asm-cris/pgtable.h
index a9143be..70a8325 100644
--- a/include/asm-cris/pgtable.h
+++ b/include/asm-cris/pgtable.h
@@ -112,44 +112,44 @@
  * Undefined behaviour if not..
  */
 
-extern inline int pte_read(pte_t pte)           { return pte_val(pte) & _PAGE_READ; }
-extern inline int pte_write(pte_t pte)          { return pte_val(pte) & _PAGE_WRITE; }
-extern inline int pte_exec(pte_t pte)           { return pte_val(pte) & _PAGE_READ; }
-extern inline int pte_dirty(pte_t pte)          { return pte_val(pte) & _PAGE_MODIFIED; }
-extern inline int pte_young(pte_t pte)          { return pte_val(pte) & _PAGE_ACCESSED; }
-extern inline int pte_file(pte_t pte)           { return pte_val(pte) & _PAGE_FILE; }
+static inline int pte_read(pte_t pte)           { return pte_val(pte) & _PAGE_READ; }
+static inline int pte_write(pte_t pte)          { return pte_val(pte) & _PAGE_WRITE; }
+static inline int pte_exec(pte_t pte)           { return pte_val(pte) & _PAGE_READ; }
+static inline int pte_dirty(pte_t pte)          { return pte_val(pte) & _PAGE_MODIFIED; }
+static inline int pte_young(pte_t pte)          { return pte_val(pte) & _PAGE_ACCESSED; }
+static inline int pte_file(pte_t pte)           { return pte_val(pte) & _PAGE_FILE; }
 
-extern inline pte_t pte_wrprotect(pte_t pte)
+static inline pte_t pte_wrprotect(pte_t pte)
 {
         pte_val(pte) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
         return pte;
 }
 
-extern inline pte_t pte_rdprotect(pte_t pte)
+static inline pte_t pte_rdprotect(pte_t pte)
 {
         pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ);
 	return pte;
 }
 
-extern inline pte_t pte_exprotect(pte_t pte)
+static inline pte_t pte_exprotect(pte_t pte)
 {
         pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ);
 	return pte;
 }
 
-extern inline pte_t pte_mkclean(pte_t pte)
+static inline pte_t pte_mkclean(pte_t pte)
 {
 	pte_val(pte) &= ~(_PAGE_MODIFIED | _PAGE_SILENT_WRITE); 
 	return pte; 
 }
 
-extern inline pte_t pte_mkold(pte_t pte)
+static inline pte_t pte_mkold(pte_t pte)
 {
 	pte_val(pte) &= ~(_PAGE_ACCESSED | _PAGE_SILENT_READ);
 	return pte;
 }
 
-extern inline pte_t pte_mkwrite(pte_t pte)
+static inline pte_t pte_mkwrite(pte_t pte)
 {
         pte_val(pte) |= _PAGE_WRITE;
         if (pte_val(pte) & _PAGE_MODIFIED)
@@ -157,7 +157,7 @@
         return pte;
 }
 
-extern inline pte_t pte_mkread(pte_t pte)
+static inline pte_t pte_mkread(pte_t pte)
 {
         pte_val(pte) |= _PAGE_READ;
         if (pte_val(pte) & _PAGE_ACCESSED)
@@ -165,7 +165,7 @@
         return pte;
 }
 
-extern inline pte_t pte_mkexec(pte_t pte)
+static inline pte_t pte_mkexec(pte_t pte)
 {
         pte_val(pte) |= _PAGE_READ;
         if (pte_val(pte) & _PAGE_ACCESSED)
@@ -173,7 +173,7 @@
         return pte;
 }
 
-extern inline pte_t pte_mkdirty(pte_t pte)
+static inline pte_t pte_mkdirty(pte_t pte)
 {
         pte_val(pte) |= _PAGE_MODIFIED;
         if (pte_val(pte) & _PAGE_WRITE)
@@ -181,7 +181,7 @@
         return pte;
 }
 
-extern inline pte_t pte_mkyoung(pte_t pte)
+static inline pte_t pte_mkyoung(pte_t pte)
 {
         pte_val(pte) |= _PAGE_ACCESSED;
         if (pte_val(pte) & _PAGE_READ)
@@ -205,7 +205,7 @@
  * addresses (the 0xc0xxxxxx's) goes as void *'s.
  */
 
-extern inline pte_t __mk_pte(void * page, pgprot_t pgprot)
+static inline pte_t __mk_pte(void * page, pgprot_t pgprot)
 {
 	pte_t pte;
 	/* the PTE needs a physical address */
@@ -223,7 +223,7 @@
         __pte;                                                          \
 })
 
-extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
 
 
@@ -232,7 +232,7 @@
  * pte_pagenr refers to the page-number counted starting from the virtual DRAM start
  */
 
-extern inline unsigned long __pte_page(pte_t pte)
+static inline unsigned long __pte_page(pte_t pte)
 {
 	/* the PTE contains a physical address */
 	return (unsigned long)__va(pte_val(pte) & PAGE_MASK);
@@ -250,7 +250,7 @@
  * don't need the __pa and __va transformations.
  */
 
-extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
+static inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
 { pmd_val(*pmdp) = _PAGE_TABLE | (unsigned long) ptep; }
 
 #define pmd_page(pmd)		(pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
@@ -260,7 +260,7 @@
 #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
 
 /* to find an entry in a page-table-directory */
-extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
+static inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
 {
 	return mm->pgd + pgd_index(address);
 }
@@ -296,7 +296,7 @@
  * 
  * Actually I am not sure on what this could be used for.
  */
-extern inline void update_mmu_cache(struct vm_area_struct * vma,
+static inline void update_mmu_cache(struct vm_area_struct * vma,
 	unsigned long address, pte_t pte)
 {
 }
diff --git a/include/asm-cris/processor.h b/include/asm-cris/processor.h
index 0dc2181..dce4100 100644
--- a/include/asm-cris/processor.h
+++ b/include/asm-cris/processor.h
@@ -16,6 +16,8 @@
 #include <asm/ptrace.h>
 #include <asm/arch/processor.h>
 
+struct task_struct;
+
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
@@ -45,7 +47,7 @@
 
 #define current_regs() user_regs(current->thread_info)
 
-extern inline void prepare_to_copy(struct task_struct *tsk)
+static inline void prepare_to_copy(struct task_struct *tsk)
 {
 }
 
@@ -58,7 +60,7 @@
 extern unsigned long thread_saved_pc(struct task_struct *tsk);
 
 /* Free all resources held by a thread. */
-extern inline void release_thread(struct task_struct *dead_task)
+static inline void release_thread(struct task_struct *dead_task)
 {
         /* Nothing needs to be done.  */
 }
diff --git a/include/asm-cris/semaphore.h b/include/asm-cris/semaphore.h
index 39faf69..53f548b 100644
--- a/include/asm-cris/semaphore.h
+++ b/include/asm-cris/semaphore.h
@@ -18,8 +18,6 @@
  * CRIS semaphores, implemented in C-only so far. 
  */
 
-int printk(const char *fmt, ...);
-
 struct semaphore {
 	atomic_t count;
 	atomic_t waking;
@@ -39,17 +37,17 @@
 #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
 #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
 
-extern inline void sema_init(struct semaphore *sem, int val)
+static inline void sema_init(struct semaphore *sem, int val)
 {
 	*sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
 }
 
-extern inline void init_MUTEX (struct semaphore *sem)
+static inline void init_MUTEX (struct semaphore *sem)
 {
         sema_init(sem, 1);
 }
 
-extern inline void init_MUTEX_LOCKED (struct semaphore *sem)
+static inline void init_MUTEX_LOCKED (struct semaphore *sem)
 {
         sema_init(sem, 0);
 }
@@ -61,7 +59,7 @@
 
 /* notice - we probably can do cli/sti here instead of saving */
 
-extern inline void down(struct semaphore * sem)
+static inline void down(struct semaphore * sem)
 {
 	unsigned long flags;
 	int failed;
@@ -83,7 +81,7 @@
  * returns negative for signalled and zero for semaphore acquired.
  */
 
-extern inline int down_interruptible(struct semaphore * sem)
+static inline int down_interruptible(struct semaphore * sem)
 {
 	unsigned long flags;
 	int failed;
@@ -99,7 +97,7 @@
 	return(failed);
 }
 
-extern inline int down_trylock(struct semaphore * sem)
+static inline int down_trylock(struct semaphore * sem)
 {
 	unsigned long flags;
 	int failed;
@@ -119,7 +117,7 @@
  * The default case (no contention) will result in NO
  * jumps for both down() and up().
  */
-extern inline void up(struct semaphore * sem)
+static inline void up(struct semaphore * sem)
 {  
 	unsigned long flags;
 	int wakeup;
diff --git a/include/asm-cris/system.h b/include/asm-cris/system.h
index e067398..d486701 100644
--- a/include/asm-cris/system.h
+++ b/include/asm-cris/system.h
@@ -41,7 +41,7 @@
 void disable_hlt(void);
 void enable_hlt(void);
 
-extern inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
 {
   /* since Etrax doesn't have any atomic xchg instructions, we need to disable
      irq's (if enabled) and do it with move.d's */
diff --git a/include/asm-cris/timex.h b/include/asm-cris/timex.h
index 3fb069a..b92e0e8 100644
--- a/include/asm-cris/timex.h
+++ b/include/asm-cris/timex.h
@@ -16,7 +16,7 @@
 
 typedef unsigned long long cycles_t;
 
-extern inline cycles_t get_cycles(void)
+static inline cycles_t get_cycles(void)
 {
         return 0;
 }
diff --git a/include/asm-cris/tlbflush.h b/include/asm-cris/tlbflush.h
index 6ed7d9a..c522380 100644
--- a/include/asm-cris/tlbflush.h
+++ b/include/asm-cris/tlbflush.h
@@ -39,14 +39,14 @@
 	flush_tlb_mm(vma->vm_mm);
 }
 
-extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+static inline void flush_tlb_pgtables(struct mm_struct *mm,
                                       unsigned long start, unsigned long end)
 {
         /* CRIS does not keep any page table caches in TLB */
 }
 
 
-extern inline void flush_tlb(void) 
+static inline void flush_tlb(void)
 {
 	flush_tlb_mm(current->mm);
 }
diff --git a/include/asm-cris/uaccess.h b/include/asm-cris/uaccess.h
index 7d50086..69d48a2 100644
--- a/include/asm-cris/uaccess.h
+++ b/include/asm-cris/uaccess.h
@@ -213,7 +213,7 @@
 extern unsigned long __copy_user_zeroing(void *to, const void *from, unsigned long n);
 extern unsigned long __do_clear_user(void *to, unsigned long n);
 
-extern inline unsigned long
+static inline unsigned long
 __generic_copy_to_user(void __user *to, const void *from, unsigned long n)
 {
 	if (access_ok(VERIFY_WRITE, to, n))
@@ -221,7 +221,7 @@
 	return n;
 }
 
-extern inline unsigned long
+static inline unsigned long
 __generic_copy_from_user(void *to, const void __user *from, unsigned long n)
 {
 	if (access_ok(VERIFY_READ, from, n))
@@ -229,7 +229,7 @@
 	return n;
 }
 
-extern inline unsigned long
+static inline unsigned long
 __generic_clear_user(void __user *to, unsigned long n)
 {
 	if (access_ok(VERIFY_WRITE, to, n))
@@ -237,13 +237,13 @@
 	return n;
 }
 
-extern inline long
+static inline long
 __strncpy_from_user(char *dst, const char __user *src, long count)
 {
 	return __do_strncpy_from_user(dst, src, count);
 }
 
-extern inline long
+static inline long
 strncpy_from_user(char *dst, const char __user *src, long count)
 {
 	long res = -EFAULT;
@@ -256,7 +256,7 @@
 /* Note that if these expand awfully if made into switch constructs, so
    don't do that.  */
 
-extern inline unsigned long
+static inline unsigned long
 __constant_copy_from_user(void *to, const void __user *from, unsigned long n)
 {
 	unsigned long ret = 0;
@@ -306,7 +306,7 @@
 
 /* Ditto, don't make a switch out of this.  */
 
-extern inline unsigned long
+static inline unsigned long
 __constant_copy_to_user(void __user *to, const void *from, unsigned long n)
 {
 	unsigned long ret = 0;
@@ -356,7 +356,7 @@
 
 /* No switch, please.  */
 
-extern inline unsigned long
+static inline unsigned long
 __constant_clear_user(void __user *to, unsigned long n)
 {
 	unsigned long ret = 0;
@@ -406,19 +406,19 @@
  * used in fast paths and have only a small space overhead.
  */
 
-extern inline unsigned long
+static inline unsigned long
 __generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
 {
 	return __copy_user_zeroing(to,from,n);
 }
 
-extern inline unsigned long
+static inline unsigned long
 __generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
 {
 	return __copy_user(to,from,n);
 }
 
-extern inline unsigned long
+static inline unsigned long
 __generic_clear_user_nocheck(void *to, unsigned long n)
 {
 	return __do_clear_user(to,n);
diff --git a/include/asm-cris/unistd.h b/include/asm-cris/unistd.h
index 156a34b..2627bbd 100644
--- a/include/asm-cris/unistd.h
+++ b/include/asm-cris/unistd.h
@@ -343,14 +343,14 @@
  * some others too.
  */
 #define __NR__exit __NR_exit
-extern inline _syscall0(pid_t,setsid)
-extern inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
-extern inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
-extern inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-extern inline _syscall1(int,dup,int,fd)
-extern inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-extern inline _syscall3(int,open,const char *,file,int,flag,int,mode)
-extern inline _syscall1(int,close,int,fd)
+static inline _syscall0(pid_t,setsid)
+static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
+static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
+static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
+static inline _syscall1(int,dup,int,fd)
+static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
+static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
+static inline _syscall1(int,close,int,fd)
 
 struct pt_regs;
 asmlinkage long sys_mmap2(
@@ -382,8 +382,8 @@
 #ifdef __KERNEL__
 #define _exit kernel_syscall_exit
 #endif
-extern inline _syscall1(int,_exit,int,exitcode)
-extern inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+static inline _syscall1(int,_exit,int,exitcode)
+static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
 #endif
 
 
diff --git a/include/asm-frv/pgtable.h b/include/asm-frv/pgtable.h
index b247e99..8446663 100644
--- a/include/asm-frv/pgtable.h
+++ b/include/asm-frv/pgtable.h
@@ -26,6 +26,8 @@
 #include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
+struct mm_struct;
+struct vm_area_struct;
 #endif
 
 #ifndef __ASSEMBLY__
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index 7dca30a..358e4d3 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -128,6 +128,7 @@
 #endif
 
 #ifndef __HAVE_ARCH_PTEP_SET_WRPROTECT
+struct mm_struct;
 static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long address, pte_t *ptep)
 {
 	pte_t old_pte = *ptep;
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index a9c5549..094d491 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -35,6 +35,13 @@
 		VMLINUX_SYMBOL(__end_pci_fixups_enable) = .;		\
 	}								\
 									\
+	/* RapidIO route ops */						\
+	.rio_route        : AT(ADDR(.rio_route) - LOAD_OFFSET) {	\
+		VMLINUX_SYMBOL(__start_rio_route_ops) = .;		\
+		*(.rio_route_ops)					\
+		VMLINUX_SYMBOL(__end_rio_route_ops) = .;		\
+	}								\
+									\
 	/* Kernel symbol table: Normal symbols */			\
 	__ksymtab         : AT(ADDR(__ksymtab) - LOAD_OFFSET) {		\
 		VMLINUX_SYMBOL(__start___ksymtab) = .;			\
diff --git a/include/asm-i386/elf.h b/include/asm-i386/elf.h
index fa11117..4153d80 100644
--- a/include/asm-i386/elf.h
+++ b/include/asm-i386/elf.h
@@ -119,6 +119,8 @@
  */
 #define elf_read_implies_exec(ex, executable_stack)	(executable_stack != EXSTACK_DISABLE_X)
 
+struct task_struct;
+
 extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
 extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
 extern int dump_task_extended_fpu (struct task_struct *, struct user_fxsr_struct *);
diff --git a/include/asm-i386/kprobes.h b/include/asm-i386/kprobes.h
index 8b6d3a9..ca916a8 100644
--- a/include/asm-i386/kprobes.h
+++ b/include/asm-i386/kprobes.h
@@ -49,6 +49,23 @@
 	kprobe_opcode_t insn[MAX_INSN_SIZE];
 };
 
+struct prev_kprobe {
+	struct kprobe *kp;
+	unsigned long status;
+	unsigned long old_eflags;
+	unsigned long saved_eflags;
+};
+
+/* per-cpu kprobe control block */
+struct kprobe_ctlblk {
+	unsigned long kprobe_status;
+	unsigned long kprobe_old_eflags;
+	unsigned long kprobe_saved_eflags;
+	long *jprobe_saved_esp;
+	struct pt_regs jprobe_saved_regs;
+	kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
+	struct prev_kprobe prev_kprobe;
+};
 
 /* trap3/1 are intr gates for kprobes.  So, restore the status of IF,
  * if necessary, before executing the original int3/1 (trap) handler.
diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h
index 03f3c8a..088a945 100644
--- a/include/asm-i386/pgtable.h
+++ b/include/asm-i386/pgtable.h
@@ -25,6 +25,9 @@
 #include <linux/list.h>
 #include <linux/spinlock.h>
 
+struct mm_struct;
+struct vm_area_struct;
+
 /*
  * ZERO_PAGE is a global shared page that is always zero: used
  * for zero-mapped memory areas etc..
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index 0a4ec76..8c02b03 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -718,4 +718,10 @@
 #define mtrr_bp_init() do {} while (0)
 #endif
 
+#ifdef CONFIG_X86_MCE
+extern void mcheck_init(struct cpuinfo_x86 *c);
+#else
+#define mcheck_init(c) do {} while(0)
+#endif
+
 #endif /* __ASM_I386_PROCESSOR_H */
diff --git a/include/asm-ia64/dma-mapping.h b/include/asm-ia64/dma-mapping.h
index 6347c98..df67d40 100644
--- a/include/asm-ia64/dma-mapping.h
+++ b/include/asm-ia64/dma-mapping.h
@@ -48,12 +48,7 @@
 	return 0;
 }
 
-static inline int
-dma_get_cache_alignment (void)
-{
-	extern int ia64_max_cacheline_size;
-	return ia64_max_cacheline_size;
-}
+extern int dma_get_cache_alignment(void);
 
 static inline void
 dma_cache_sync (void *vaddr, size_t size, enum dma_data_direction dir)
diff --git a/include/asm-ia64/kprobes.h b/include/asm-ia64/kprobes.h
index 573a357..592abb0 100644
--- a/include/asm-ia64/kprobes.h
+++ b/include/asm-ia64/kprobes.h
@@ -26,6 +26,7 @@
  */
 #include <linux/types.h>
 #include <linux/ptrace.h>
+#include <linux/percpu.h>
 #include <asm/break.h>
 
 #define MAX_INSN_SIZE   16
@@ -62,6 +63,18 @@
 	} quad1;
 } __attribute__((__aligned__(16)))  bundle_t;
 
+struct prev_kprobe {
+	struct kprobe *kp;
+	unsigned long status;
+};
+
+/* per-cpu kprobe control block */
+struct kprobe_ctlblk {
+	unsigned long kprobe_status;
+	struct pt_regs jprobe_saved_regs;
+	struct prev_kprobe prev_kprobe;
+};
+
 #define JPROBE_ENTRY(pentry)	(kprobe_opcode_t *)pentry
 
 #define ARCH_SUPPORTS_KRETPROBES
diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
index 21e32a0..c34ba80 100644
--- a/include/asm-ia64/pgtable.h
+++ b/include/asm-ia64/pgtable.h
@@ -127,6 +127,7 @@
 
 # ifndef __ASSEMBLY__
 
+#include <linux/sched.h>	/* for mm_struct */
 #include <asm/bitops.h>
 #include <asm/cacheflush.h>
 #include <asm/mmu_context.h>
diff --git a/include/asm-ia64/ptrace.h b/include/asm-ia64/ptrace.h
index a79d1a7..2c703d6 100644
--- a/include/asm-ia64/ptrace.h
+++ b/include/asm-ia64/ptrace.h
@@ -229,6 +229,9 @@
 };
 
 #ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE	1
+
 /*
  * We use the ia64_psr(regs)->ri to determine which of the three
  * instructions in bundle (16 bytes) took the sample. Generate
diff --git a/include/asm-m32r/pgtable.h b/include/asm-m32r/pgtable.h
index 1cd5fd4..75740de 100644
--- a/include/asm-m32r/pgtable.h
+++ b/include/asm-m32r/pgtable.h
@@ -27,6 +27,9 @@
 #include <asm/bitops.h>
 #include <asm/page.h>
 
+struct mm_struct;
+struct vm_area_struct;
+
 extern pgd_t swapper_pg_dir[1024];
 extern void paging_init(void);
 
diff --git a/include/asm-m32r/ptrace.h b/include/asm-m32r/ptrace.h
index 9764171..55cd7ec 100644
--- a/include/asm-m32r/ptrace.h
+++ b/include/asm-m32r/ptrace.h
@@ -145,6 +145,9 @@
 #define PTRACE_O_TRACESYSGOOD	0x00000001
 
 #ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE	1
+
 #if defined(CONFIG_ISA_M32R2) || defined(CONFIG_CHIP_VDEC2)
 #define user_mode(regs) ((M32R_PSW_BPM & (regs)->psw) != 0)
 #elif defined(CONFIG_ISA_M32R)
diff --git a/include/asm-m68knommu/cacheflush.h b/include/asm-m68knommu/cacheflush.h
index 026bbc9..49925e9 100644
--- a/include/asm-m68knommu/cacheflush.h
+++ b/include/asm-m68knommu/cacheflush.h
@@ -25,7 +25,7 @@
 #define copy_from_user_page(vma, page, vaddr, dst, src, len) \
 	memcpy(dst, src, len)
 
-extern inline void __flush_cache_all(void)
+static inline void __flush_cache_all(void)
 {
 #ifdef CONFIG_M5407
 	/*
@@ -64,7 +64,7 @@
 		"nop\n\t"
 		: : : "d0" );
 #endif /* CONFIG_M5272 */
-#if CONFIG_M5249
+#ifdef CONFIG_M5249
 	__asm__ __volatile__ (
         	"movel	#0xa1000200, %%d0\n\t"
         	"movec	%%d0, %%CACR\n\t"
diff --git a/include/asm-m68knommu/irq.h b/include/asm-m68knommu/irq.h
index 208ccd9..a08fa9b 100644
--- a/include/asm-m68knommu/irq.h
+++ b/include/asm-m68knommu/irq.h
@@ -2,7 +2,6 @@
 #define _M68K_IRQ_H_
 
 #include <linux/config.h>
-#include <linux/interrupt.h>
 #include <asm/ptrace.h>
 
 #ifdef CONFIG_COLDFIRE
@@ -83,36 +82,6 @@
 #endif /* CONFIG_M68360 */
 
 /*
- * This structure is used to chain together the ISRs for a particular
- * interrupt source (if it supports chaining).
- */
-typedef struct irq_node {
-	irqreturn_t	(*handler)(int, void *, struct pt_regs *);
-	unsigned long	flags;
-	void		*dev_id;
-	const char	*devname;
-	struct irq_node *next;
-} irq_node_t;
-
-/*
- * This structure has only 4 elements for speed reasons
- */
-typedef struct irq_handler {
-	irqreturn_t	(*handler)(int, void *, struct pt_regs *);
-	unsigned long	flags;
-	void		*dev_id;
-	const char	*devname;
-} irq_handler_t;
-
-/* count of spurious interrupts */
-extern volatile unsigned int num_spurious;
-
-/*
- * This function returns a new irq_node_t
- */
-extern irq_node_t *new_irq_node(void);
-
-/*
  * Some drivers want these entry points
  */
 #define enable_irq(x)	(mach_enable_irq  ? (*mach_enable_irq)(x)  : 0)
diff --git a/include/asm-m68knommu/irqnode.h b/include/asm-m68knommu/irqnode.h
new file mode 100644
index 0000000..a2503df
--- /dev/null
+++ b/include/asm-m68knommu/irqnode.h
@@ -0,0 +1,36 @@
+#ifndef _M68K_IRQNODE_H_
+#define _M68K_IRQNODE_H_
+
+#include <linux/interrupt.h>
+
+/*
+ * This structure is used to chain together the ISRs for a particular
+ * interrupt source (if it supports chaining).
+ */
+typedef struct irq_node {
+	irqreturn_t	(*handler)(int, void *, struct pt_regs *);
+	unsigned long	flags;
+	void		*dev_id;
+	const char	*devname;
+	struct irq_node *next;
+} irq_node_t;
+
+/*
+ * This structure has only 4 elements for speed reasons
+ */
+typedef struct irq_handler {
+	irqreturn_t	(*handler)(int, void *, struct pt_regs *);
+	unsigned long	flags;
+	void		*dev_id;
+	const char	*devname;
+} irq_handler_t;
+
+/* count of spurious interrupts */
+extern volatile unsigned int num_spurious;
+
+/*
+ * This function returns a new irq_node_t
+ */
+extern irq_node_t *new_irq_node(void);
+
+#endif /* _M68K_IRQNODE_H_ */
diff --git a/include/asm-mips/elf.h b/include/asm-mips/elf.h
index 7420f12..d2c9a25 100644
--- a/include/asm-mips/elf.h
+++ b/include/asm-mips/elf.h
@@ -275,6 +275,8 @@
 
 #endif /* CONFIG_64BIT */
 
+struct task_struct;
+
 extern void dump_regs(elf_greg_t *, struct pt_regs *regs);
 extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
 extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h
index 34facd9..702a28f 100644
--- a/include/asm-mips/pgtable.h
+++ b/include/asm-mips/pgtable.h
@@ -19,6 +19,9 @@
 #include <asm/io.h>
 #include <asm/pgtable-bits.h>
 
+struct mm_struct;
+struct vm_area_struct;
+
 #define PAGE_NONE	__pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT)
 #define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
 			PAGE_CACHABLE_DEFAULT)
diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h
index c28fb6f..b455471 100644
--- a/include/asm-parisc/pgtable.h
+++ b/include/asm-parisc/pgtable.h
@@ -12,6 +12,7 @@
  */
 
 #include <linux/spinlock.h>
+#include <linux/mm.h>		/* for vm_area_struct */
 #include <asm/processor.h>
 #include <asm/cache.h>
 #include <asm/bitops.h>
@@ -418,7 +419,6 @@
 
 #define PG_dcache_dirty         PG_arch_1
 
-struct vm_area_struct; /* forward declaration (include/linux/mm.h) */
 extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
 
 /* Encode and de-code a swap entry */
@@ -464,6 +464,7 @@
 
 extern spinlock_t pa_dbit_lock;
 
+struct mm_struct;
 static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 {
 	pte_t old_pte;
diff --git a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h
index d140577..feac345 100644
--- a/include/asm-powerpc/elf.h
+++ b/include/asm-powerpc/elf.h
@@ -1,11 +1,13 @@
 #ifndef _ASM_POWERPC_ELF_H
 #define _ASM_POWERPC_ELF_H
 
+#include <linux/sched.h>	/* for task_struct */
 #include <asm/types.h>
 #include <asm/ptrace.h>
 #include <asm/cputable.h>
 #include <asm/auxvec.h>
 #include <asm/page.h>
+#include <asm/string.h>
 
 /* PowerPC relocations defined by the ABIs */
 #define R_PPC_NONE		0
diff --git a/include/asm-powerpc/kprobes.h b/include/asm-powerpc/kprobes.h
index b2f09f1..6cd0a3b 100644
--- a/include/asm-powerpc/kprobes.h
+++ b/include/asm-powerpc/kprobes.h
@@ -27,6 +27,7 @@
  */
 #include <linux/types.h>
 #include <linux/ptrace.h>
+#include <linux/percpu.h>
 
 struct pt_regs;
 
@@ -53,6 +54,20 @@
 	kprobe_opcode_t *insn;
 };
 
+struct prev_kprobe {
+	struct kprobe *kp;
+	unsigned long status;
+	unsigned long saved_msr;
+};
+
+/* per-cpu kprobe control block */
+struct kprobe_ctlblk {
+	unsigned long kprobe_status;
+	unsigned long kprobe_saved_msr;
+	struct pt_regs jprobe_saved_regs;
+	struct prev_kprobe prev_kprobe;
+};
+
 #ifdef CONFIG_KPROBES
 extern int kprobe_exceptions_notify(struct notifier_block *self,
 				    unsigned long val, void *data);
diff --git a/include/asm-ppc/ibm44x.h b/include/asm-ppc/ibm44x.h
index e5374be..f835066 100644
--- a/include/asm-ppc/ibm44x.h
+++ b/include/asm-ppc/ibm44x.h
@@ -34,12 +34,20 @@
 /* Lowest TLB slot consumed by the default pinned TLBs */
 #define PPC44x_LOW_SLOT		63
 
-/* LS 32-bits of UART0 physical address location for early serial text debug */
+/*
+ * Least significant 32-bits and extended real page number (ERPN) of
+ * UART0 physical address location for early serial text debug
+ */
 #if defined(CONFIG_440SP)
+#define UART0_PHYS_ERPN		1
+#define UART0_PHYS_IO_BASE	0xf0000200
+#elif defined(CONFIG_440SPE)
+#define UART0_PHYS_ERPN		4
 #define UART0_PHYS_IO_BASE	0xf0000200
 #elif defined(CONFIG_440EP)
 #define UART0_PHYS_IO_BASE	0xe0000000
 #else
+#define UART0_PHYS_ERPN		1
 #define UART0_PHYS_IO_BASE	0x40000200
 #endif
 
@@ -56,6 +64,11 @@
 #define	PPC44x_PCICFG_PAGE	0x0000000900000000ULL
 #define	PPC44x_PCIIO_PAGE	PPC44x_PCICFG_PAGE
 #define	PPC44x_PCIMEM_PAGE	0x0000000a00000000ULL
+#elif defined(CONFIG_440SPE)
+#define	PPC44x_IO_PAGE		0x0000000400000000ULL
+#define	PPC44x_PCICFG_PAGE	0x0000000c00000000ULL
+#define	PPC44x_PCIIO_PAGE	PPC44x_PCICFG_PAGE
+#define	PPC44x_PCIMEM_PAGE	0x0000000d00000000ULL
 #elif defined(CONFIG_440EP)
 #define PPC44x_IO_PAGE		0x0000000000000000ULL
 #define PPC44x_PCICFG_PAGE	0x0000000000000000ULL
@@ -71,7 +84,7 @@
 /*
  * 36-bit trap ranges
  */
-#if defined(CONFIG_440SP)
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
 #define PPC44x_IO_LO		0xf0000000UL
 #define PPC44x_IO_HI		0xf0000fffUL
 #define PPC44x_PCI0CFG_LO	0x0ec00000UL
@@ -109,7 +122,7 @@
  */
 
 
-/* CPRs (440GX and 440SP) */
+/* CPRs (440GX and 440SP/440SPe) */
 #define DCRN_CPR_CONFIG_ADDR	0xc
 #define DCRN_CPR_CONFIG_DATA	0xd
 
@@ -130,7 +143,7 @@
 	mtdcr(DCRN_CPR_CONFIG_ADDR, offset); \
 	mtdcr(DCRN_CPR_CONFIG_DATA, data);})
 
-/* SDRs (440GX and 440SP) */
+/* SDRs (440GX and 440SP/440SPe) */
 #define DCRN_SDR_CONFIG_ADDR 	0xe
 #define DCRN_SDR_CONFIG_DATA	0xf
 #define DCRN_SDR_PFC0		0x4100
@@ -180,7 +193,7 @@
 	mtdcr(DCRN_SDR_CONFIG_ADDR, offset); \
 	mtdcr(DCRN_SDR_CONFIG_DATA,data);})
 
-/* DMA (excluding 440SP) */
+/* DMA (excluding 440SP/440SPe) */
 #define DCRN_DMA0_BASE		0x100
 #define DCRN_DMA1_BASE		0x108
 #define DCRN_DMA2_BASE		0x110
@@ -200,12 +213,20 @@
 /* UIC */
 #define DCRN_UIC0_BASE	0xc0
 #define DCRN_UIC1_BASE	0xd0
-#define DCRN_UIC2_BASE	0x210
-#define DCRN_UICB_BASE	0x200
 #define UIC0		DCRN_UIC0_BASE
 #define UIC1		DCRN_UIC1_BASE
+
+#ifdef CONFIG_440SPE
+#define DCRN_UIC2_BASE	0xe0
+#define DCRN_UIC3_BASE	0xf0
+#define UIC2		DCRN_UIC2_BASE
+#define UIC3		DCRN_UIC3_BASE
+#else
+#define DCRN_UIC2_BASE	0x210
+#define DCRN_UICB_BASE	0x200
 #define UIC2		DCRN_UIC2_BASE
 #define UICB		DCRN_UICB_BASE
+#endif
 
 #define DCRN_UIC_SR(base)       (base + 0x0)
 #define DCRN_UIC_ER(base)       (base + 0x2)
@@ -218,6 +239,12 @@
 
 #define UIC0_UIC1NC      	0x00000002
 
+#ifdef CONFIG_440SPE
+#define UIC0_UIC1NC      0x00000002
+#define UIC0_UIC2NC      0x00200000
+#define UIC0_UIC3NC      0x00008000
+#endif
+
 #define UICB_UIC0NC		0x40000000
 #define UICB_UIC1NC		0x10000000
 #define UICB_UIC2NC		0x04000000
@@ -297,6 +324,23 @@
 #define MALOBISR_CH0		0x80000000	/* EOB channel 1 bit */
 #define MALOBISR_CH2		0x40000000	/* EOB channel 2 bit */
 
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+/* 440SP/440SPe PLB Arbiter DCRs */
+#define DCRN_PLB_REVID	       0x080		/* PLB Revision ID */
+#define DCRN_PLB_CCR	       0x088		/* PLB Crossbar Control */
+
+#define DCRN_PLB0_ACR	       0x081		/* PLB Arbiter Control */
+#define DCRN_PLB0_BESRL	       0x082		/* PLB Error Status */
+#define DCRN_PLB0_BESRH	       0x083		/* PLB Error Status */
+#define DCRN_PLB0_BEARL	       0x084		/* PLB Error Address Low */
+#define DCRN_PLB0_BEARH	       0x085		/* PLB Error Address High */
+
+#define DCRN_PLB1_ACR		0x089		/* PLB Arbiter Control */
+#define DCRN_PLB1_BESRL		0x08a		/* PLB Error Status */
+#define DCRN_PLB1_BESRH		0x08b		/* PLB Error Status */
+#define DCRN_PLB1_BEARL		0x08c		/* PLB Error Address Low */
+#define DCRN_PLB1_BEARH		0x08d		/* PLB Error Address High */
+#else
 /* 440GP/GX PLB Arbiter DCRs */
 #define DCRN_PLB0_REVID		0x082		/* PLB Arbiter Revision ID */
 #define DCRN_PLB0_ACR		0x083		/* PLB Arbiter Control */
@@ -304,6 +348,7 @@
 #define DCRN_PLB0_BEARL		0x086		/* PLB Error Address Low */
 #define DCRN_PLB0_BEAR		DCRN_PLB0_BEARL	/* 40x compatibility */
 #define DCRN_PLB0_BEARH		0x087		/* PLB Error Address High */
+#endif
 
 /* 440GP/GX PLB to OPB bridge DCRs */
 #define DCRN_POB0_BESR0		0x090
@@ -407,9 +452,13 @@
 #define PPC44x_MEM_SIZE_1G		0x40000000
 #define PPC44x_MEM_SIZE_2G		0x80000000
 
-/* 440SP memory controller DCRs */
+/* 440SP/440SPe memory controller DCRs */
 #define DCRN_MQ0_BS0BAS			0x40
-#define DCRN_MQ0_BS1BAS			0x41
+#if defined(CONFIG_440SP)
+#define MQ0_NUM_BANKS			2
+#elif defined(CONFIG_440SPE)
+#define MQ0_NUM_BANKS			4
+#endif
 
 #define MQ0_CONFIG_SIZE_MASK		0x0000fff0
 #define MQ0_CONFIG_SIZE_8M		0x0000ffc0
@@ -421,8 +470,9 @@
 #define MQ0_CONFIG_SIZE_512M		0x0000f000
 #define MQ0_CONFIG_SIZE_1G		0x0000e000
 #define MQ0_CONFIG_SIZE_2G		0x0000c000
+#define MQ0_CONFIG_SIZE_4G		0x00008000
 
-/* Internal SRAM Controller 440GX/440SP */
+/* Internal SRAM Controller 440GX/440SP/440SPe */
 #define DCRN_SRAM0_BASE		0x000
 
 #define DCRN_SRAM0_SB0CR	(DCRN_SRAM0_BASE + 0x020)
@@ -446,7 +496,7 @@
 #define DCRN_SRAM0_DPC		(DCRN_SRAM0_BASE + 0x02a)
 #define  SRAM_DPC_ENABLE	0x80000000
 
-/* L2 Cache Controller 440GX/440SP */
+/* L2 Cache Controller 440GX/440SP/440SPe */
 #define DCRN_L2C0_CFG		0x030
 #define  L2C_CFG_L2M		0x80000000
 #define  L2C_CFG_ICU		0x40000000
@@ -610,8 +660,10 @@
 #define IIC_CLOCK		50
 
 #undef NR_UICS
-#ifdef CONFIG_440GX
+#if defined(CONFIG_440GX)
 #define NR_UICS 3
+#elif defined(CONFIG_440SPE)
+#define NR_UICS 4
 #else
 #define NR_UICS 2
 #endif
diff --git a/include/asm-ppc/ibm4xx.h b/include/asm-ppc/ibm4xx.h
index e992369..6c28ae7 100644
--- a/include/asm-ppc/ibm4xx.h
+++ b/include/asm-ppc/ibm4xx.h
@@ -97,6 +97,10 @@
 #include <platforms/4xx/luan.h>
 #endif
 
+#if defined(CONFIG_YUCCA)
+#include <platforms/4xx/yucca.h>
+#endif
+
 #if defined(CONFIG_OCOTEA)
 #include <platforms/4xx/ocotea.h>
 #endif
diff --git a/include/asm-ppc/ibm_ocp.h b/include/asm-ppc/ibm_ocp.h
index 6f10a25..9c21de1 100644
--- a/include/asm-ppc/ibm_ocp.h
+++ b/include/asm-ppc/ibm_ocp.h
@@ -131,9 +131,22 @@
 	/* Copy MAC addresses to EMAC additions */
 	for (i=start; i<=end; i++) {
 		def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, i);
-		memcpy(((struct ocp_func_emac_data *)def->additions)->mac_addr,
-				&__res.bi_enetaddr[i],
-				6);
+		if (i == 0)
+			memcpy(((struct ocp_func_emac_data *)def->additions)->mac_addr,
+			       __res.bi_enetaddr, 6);
+#if defined(CONFIG_405EP) || defined(CONFIG_44x)
+		else if (i == 1)
+			memcpy(((struct ocp_func_emac_data *)def->additions)->mac_addr,
+			       __res.bi_enet1addr, 6);
+#endif
+#if defined(CONFIG_440GX)
+		else if (i == 2)
+			memcpy(((struct ocp_func_emac_data *)def->additions)->mac_addr,
+			       __res.bi_enet2addr, 6);
+		else if (i == 3)
+			memcpy(((struct ocp_func_emac_data *)def->additions)->mac_addr,
+			       __res.bi_enet3addr, 6);
+#endif
 	}
 }
 #endif
diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h
index b28a713..6d1c39e 100644
--- a/include/asm-ppc/pgtable.h
+++ b/include/asm-ppc/pgtable.h
@@ -12,6 +12,7 @@
 #include <asm/processor.h>		/* For TASK_SIZE */
 #include <asm/mmu.h>
 #include <asm/page.h>
+struct mm_struct;
 
 extern unsigned long va_to_phys(unsigned long address);
 extern pte_t *va_to_pte(unsigned long address);
diff --git a/include/asm-ppc/ppcboot.h b/include/asm-ppc/ppcboot.h
index fe24e45..6b7b63f 100644
--- a/include/asm-ppc/ppcboot.h
+++ b/include/asm-ppc/ppcboot.h
@@ -73,8 +73,8 @@
 #if defined(CONFIG_HYMOD)
 	hymod_conf_t	bi_hymod_conf;	/* hymod configuration information */
 #endif
-#if defined(CONFIG_EVB64260) || defined(CONFIG_44x) || defined(CONFIG_85xx) ||\
-	defined(CONFIG_83xx)
+#if defined(CONFIG_EVB64260) || defined(CONFIG_405EP) || defined(CONFIG_44x) || \
+	defined(CONFIG_85xx) ||	defined(CONFIG_83xx)
 	/* second onboard ethernet port */
 	unsigned char	bi_enet1addr[6];
 #endif
@@ -96,5 +96,7 @@
 #endif
 } bd_t;
 
+#define bi_tbfreq	bi_intfreq
+
 #endif /* __ASSEMBLY__ */
 #endif	/* __ASM_PPCBOOT_H__ */
diff --git a/include/asm-ppc/rio.h b/include/asm-ppc/rio.h
new file mode 100644
index 0000000..0018bf8
--- /dev/null
+++ b/include/asm-ppc/rio.h
@@ -0,0 +1,18 @@
+/*
+ * RapidIO architecture support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef ASM_PPC_RIO_H
+#define ASM_PPC_RIO_H
+
+extern void platform_rio_init(void);
+
+#endif				/* ASM_PPC_RIO_H */
diff --git a/include/asm-ppc64/pgtable-4k.h b/include/asm-ppc64/pgtable-4k.h
index c883a27..e9590c0 100644
--- a/include/asm-ppc64/pgtable-4k.h
+++ b/include/asm-ppc64/pgtable-4k.h
@@ -23,6 +23,9 @@
 #define PMD_SIZE	(1UL << PMD_SHIFT)
 #define PMD_MASK	(~(PMD_SIZE-1))
 
+/* With 4k base page size, hugepage PTEs go at the PMD level */
+#define MIN_HUGEPTE_SHIFT	PMD_SHIFT
+
 /* PUD_SHIFT determines what a third-level page table entry can map */
 #define PUD_SHIFT	(PMD_SHIFT + PMD_INDEX_SIZE)
 #define PUD_SIZE	(1UL << PUD_SHIFT)
diff --git a/include/asm-ppc64/pgtable-64k.h b/include/asm-ppc64/pgtable-64k.h
index c5f437c..154f184 100644
--- a/include/asm-ppc64/pgtable-64k.h
+++ b/include/asm-ppc64/pgtable-64k.h
@@ -14,6 +14,9 @@
 #define PTRS_PER_PMD	(1 << PMD_INDEX_SIZE)
 #define PTRS_PER_PGD	(1 << PGD_INDEX_SIZE)
 
+/* With 4k base page size, hugepage PTEs go at the PMD level */
+#define MIN_HUGEPTE_SHIFT	PAGE_SHIFT
+
 /* PMD_SHIFT determines what a second-level page table entry can map */
 #define PMD_SHIFT	(PAGE_SHIFT + PTE_INDEX_SIZE)
 #define PMD_SIZE	(1UL << PMD_SHIFT)
diff --git a/include/asm-ppc64/pgtable.h b/include/asm-ppc64/pgtable.h
index fde93ec..a9783ba 100644
--- a/include/asm-ppc64/pgtable.h
+++ b/include/asm-ppc64/pgtable.h
@@ -13,6 +13,7 @@
 #include <asm/mmu.h>
 #include <asm/page.h>
 #include <asm/tlbflush.h>
+struct mm_struct;
 #endif /* __ASSEMBLY__ */
 
 #ifdef CONFIG_PPC_64K_PAGES
diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h
index 8651524..b07c578 100644
--- a/include/asm-s390/bitops.h
+++ b/include/asm-s390/bitops.h
@@ -518,8 +518,8 @@
 
 static inline int 
 __constant_test_bit(unsigned long nr, const volatile unsigned long *addr) {
-    return (((volatile char *) addr)
-	    [(nr^(__BITOPS_WORDSIZE-8))>>3] & (1<<(nr&7)));
+    return ((((volatile char *) addr)
+	    [(nr^(__BITOPS_WORDSIZE-8))>>3] & (1<<(nr&7)))) != 0;
 }
 
 #define test_bit(nr,addr) \
diff --git a/include/asm-s390/elf.h b/include/asm-s390/elf.h
index 3b8bd46..372d51c 100644
--- a/include/asm-s390/elf.h
+++ b/include/asm-s390/elf.h
@@ -96,6 +96,7 @@
  * ELF register definitions..
  */
 
+#include <linux/sched.h>	/* for task_struct */
 #include <asm/ptrace.h>
 #include <asm/user.h>
 #include <asm/system.h>		/* for save_access_regs */
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h
index df94f89..9be741b 100644
--- a/include/asm-s390/pgtable.h
+++ b/include/asm-s390/pgtable.h
@@ -36,6 +36,7 @@
 #include <linux/threads.h>
 
 struct vm_area_struct; /* forward declaration (include/linux/mm.h) */
+struct mm_struct;
 
 extern pgd_t swapper_pg_dir[] __attribute__ ((aligned (4096)));
 extern void paging_init(void);
diff --git a/include/asm-s390/ptrace.h b/include/asm-s390/ptrace.h
index fc7c96e..a949cc0 100644
--- a/include/asm-s390/ptrace.h
+++ b/include/asm-s390/ptrace.h
@@ -468,6 +468,8 @@
 };
 
 #ifdef __KERNEL__
+#define __ARCH_SYS_PTRACE	1
+
 #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
 #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
 #define profile_pc(regs) instruction_pointer(regs)
diff --git a/include/asm-s390/uaccess.h b/include/asm-s390/uaccess.h
index 38a5cf8..10a619d 100644
--- a/include/asm-s390/uaccess.h
+++ b/include/asm-s390/uaccess.h
@@ -200,21 +200,37 @@
 
 #define __get_user(x, ptr)					\
 ({								\
-	__typeof__(*(ptr)) __x;					\
 	int __gu_err;						\
         __chk_user_ptr(ptr);                                    \
 	switch (sizeof(*(ptr))) {				\
-	case 1:							\
-	case 2:							\
-	case 4:							\
-	case 8:							\
+	case 1: {						\
+		unsigned char __x;				\
 		__get_user_asm(__x, ptr, __gu_err);		\
+		(x) = (__typeof__(*(ptr))) __x;			\
 		break;						\
+	};							\
+	case 2: {						\
+		unsigned short __x;				\
+		__get_user_asm(__x, ptr, __gu_err);		\
+		(x) = (__typeof__(*(ptr))) __x;			\
+		break;						\
+	};							\
+	case 4: {						\
+		unsigned int __x;				\
+		__get_user_asm(__x, ptr, __gu_err);		\
+		(x) = (__typeof__(*(ptr))) __x;			\
+		break;						\
+	};							\
+	case 8: {						\
+		unsigned long long __x;				\
+		__get_user_asm(__x, ptr, __gu_err);		\
+		(x) = (__typeof__(*(ptr))) __x;			\
+		break;						\
+	};							\
 	default:						\
 		__get_user_bad();				\
 		break;						\
 	}							\
-	(x) = __x;						\
 	__gu_err;						\
 })
 
diff --git a/include/asm-s390/vtoc.h b/include/asm-s390/vtoc.h
index a14e34e..41d369f 100644
--- a/include/asm-s390/vtoc.h
+++ b/include/asm-s390/vtoc.h
@@ -1,372 +1,179 @@
-#ifndef __KERNEL__
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <ctype.h>
-#include <time.h>
-#include <fcntl.h>
-#include <unistd.h>
+/*
+ * include/asm-s390/vtoc.h
+ *
+ * This file contains volume label definitions for DASD devices.
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Author(s): Volker Sameske <sameske@de.ibm.com>
+ *
+ */
 
-#include <sys/stat.h>
-#include <sys/ioctl.h>
+#ifndef _ASM_S390_VTOC_H
+#define _ASM_S390_VTOC_H
 
-#include <linux/fs.h>
 #include <linux/types.h>
-#include <linux/hdreg.h>
-#include <asm/dasd.h>
-#endif
 
-
-#define LINE_LENGTH 80
-#define VTOC_START_CC 0x0
-#define VTOC_START_HH 0x1
-#define FIRST_USABLE_CYL 1
-#define FIRST_USABLE_TRK 2
-
-#define DASD_3380_TYPE 13148
-#define DASD_3390_TYPE 13200
-#define DASD_9345_TYPE 37701
-
-#define DASD_3380_VALUE 0xbb60
-#define DASD_3390_VALUE 0xe5a2
-#define DASD_9345_VALUE 0xbc98
-
-#define VOLSER_LENGTH 6
-#define BIG_DISK_SIZE 0x10000
-
-#define VTOC_ERROR "VTOC error:"
-
-
-typedef struct ttr 
+struct vtoc_ttr
 {
-        __u16 tt;
-        __u8  r;
-} __attribute__ ((packed)) ttr_t;
+	__u16 tt;
+	__u8 r;
+} __attribute__ ((packed));
 
-typedef struct cchhb 
+struct vtoc_cchhb
 {
-        __u16 cc;
-        __u16 hh;
-        __u8 b;
-} __attribute__ ((packed)) cchhb_t;
+	__u16 cc;
+	__u16 hh;
+	__u8 b;
+} __attribute__ ((packed));
 
-typedef struct cchh 
+struct vtoc_cchh
 {
-        __u16 cc;
-        __u16 hh;
-} __attribute__ ((packed)) cchh_t;
+	__u16 cc;
+	__u16 hh;
+} __attribute__ ((packed));
 
-typedef struct labeldate 
+struct vtoc_labeldate
 {
-        __u8  year;
-        __u16 day;
-} __attribute__ ((packed)) labeldate_t;
+	__u8 year;
+	__u16 day;
+} __attribute__ ((packed));
 
-
-typedef struct volume_label 
+struct vtoc_volume_label
 {
-        char volkey[4];         /* volume key = volume label                 */
-	char vollbl[4];	        /* volume label                              */
-	char volid[6];	        /* volume identifier                         */
-	__u8 security;	        /* security byte                             */
-	cchhb_t vtoc;           /* VTOC address                              */
-	char res1[5];	        /* reserved                                  */
-        char cisize[4];	        /* CI-size for FBA,...                       */
-                                /* ...blanks for CKD                         */
-	char blkperci[4];       /* no of blocks per CI (FBA), blanks for CKD */
-	char labperci[4];       /* no of labels per CI (FBA), blanks for CKD */
-	char res2[4];	        /* reserved                                  */
-	char lvtoc[14];	        /* owner code for LVTOC                      */
-	char res3[29];	        /* reserved                                  */
-} __attribute__ ((packed)) volume_label_t;
+	char volkey[4];		/* volume key = volume label */
+	char vollbl[4];		/* volume label */
+	char volid[6];		/* volume identifier */
+	__u8 security;		/* security byte */
+	struct vtoc_cchhb vtoc;	/* VTOC address */
+	char res1[5];		/* reserved */
+	char cisize[4];		/* CI-size for FBA,... */
+				/* ...blanks for CKD */
+	char blkperci[4];	/* no of blocks per CI (FBA), blanks for CKD */
+	char labperci[4];	/* no of labels per CI (FBA), blanks for CKD */
+	char res2[4];		/* reserved */
+	char lvtoc[14];		/* owner code for LVTOC */
+	char res3[29];		/* reserved */
+} __attribute__ ((packed));
 
-
-typedef struct extent 
+struct vtoc_extent
 {
-        __u8  typeind;          /* extent type indicator                     */
-        __u8  seqno;            /* extent sequence number                    */
-        cchh_t llimit;          /* starting point of this extent             */
-        cchh_t ulimit;          /* ending point of this extent               */
-} __attribute__ ((packed)) extent_t;
+	__u8 typeind;			/* extent type indicator */
+	__u8 seqno;			/* extent sequence number */
+	struct vtoc_cchh llimit;	/* starting point of this extent */
+	struct vtoc_cchh ulimit;	/* ending point of this extent */
+} __attribute__ ((packed));
 
-
-typedef struct dev_const 
+struct vtoc_dev_const
 {
-        __u16 DS4DSCYL;           /* number of logical cyls                  */
-        __u16 DS4DSTRK;           /* number of tracks in a logical cylinder  */
-        __u16 DS4DEVTK;           /* device track length                     */
-        __u8  DS4DEVI;            /* non-last keyed record overhead          */
-        __u8  DS4DEVL;            /* last keyed record overhead              */
-        __u8  DS4DEVK;            /* non-keyed record overhead differential  */
-        __u8  DS4DEVFG;           /* flag byte                               */
-        __u16 DS4DEVTL;           /* device tolerance                        */
-        __u8  DS4DEVDT;           /* number of DSCB's per track              */
-        __u8  DS4DEVDB;           /* number of directory blocks per track    */
-} __attribute__ ((packed)) dev_const_t;
+	__u16 DS4DSCYL;	/* number of logical cyls */
+	__u16 DS4DSTRK;	/* number of tracks in a logical cylinder */
+	__u16 DS4DEVTK;	/* device track length */
+	__u8 DS4DEVI;	/* non-last keyed record overhead */
+	__u8 DS4DEVL;	/* last keyed record overhead */
+	__u8 DS4DEVK;	/* non-keyed record overhead differential */
+	__u8 DS4DEVFG;	/* flag byte */
+	__u16 DS4DEVTL;	/* device tolerance */
+	__u8 DS4DEVDT;	/* number of DSCB's per track */
+	__u8 DS4DEVDB;	/* number of directory blocks per track */
+} __attribute__ ((packed));
 
-
-typedef struct format1_label 
+struct vtoc_format1_label
 {
-	char  DS1DSNAM[44];       /* data set name                           */
-	__u8  DS1FMTID;           /* format identifier                       */
-	char  DS1DSSN[6];         /* data set serial number                  */
-	__u16 DS1VOLSQ;           /* volume sequence number                  */
-	labeldate_t DS1CREDT;     /* creation date: ydd                      */
-	labeldate_t DS1EXPDT;     /* expiration date                         */
-	__u8  DS1NOEPV;           /* number of extents on volume             */
-        __u8  DS1NOBDB;           /* no. of bytes used in last direction blk */
-	__u8  DS1FLAG1;           /* flag 1                                  */
-	char  DS1SYSCD[13];       /* system code                             */
-	labeldate_t DS1REFD;      /* date last referenced                    */
-        __u8  DS1SMSFG;           /* system managed storage indicators       */
-        __u8  DS1SCXTF;           /* sec. space extension flag byte          */
-        __u16 DS1SCXTV;           /* secondary space extension value         */
-        __u8  DS1DSRG1;           /* data set organisation byte 1            */
-        __u8  DS1DSRG2;           /* data set organisation byte 2            */
-  	__u8  DS1RECFM;           /* record format                           */
-	__u8  DS1OPTCD;           /* option code                             */
-	__u16 DS1BLKL;            /* block length                            */
-	__u16 DS1LRECL;           /* record length                           */
-	__u8  DS1KEYL;            /* key length                              */
-	__u16 DS1RKP;             /* relative key position                   */
-	__u8  DS1DSIND;           /* data set indicators                     */
-        __u8  DS1SCAL1;           /* secondary allocation flag byte          */
-  	char DS1SCAL3[3];         /* secondary allocation quantity           */
-	ttr_t DS1LSTAR;           /* last used track and block on track      */
-	__u16 DS1TRBAL;           /* space remaining on last used track      */
-        __u16 res1;               /* reserved                                */
-	extent_t DS1EXT1;         /* first extent description                */
-	extent_t DS1EXT2;         /* second extent description               */
-	extent_t DS1EXT3;         /* third extent description                */
-	cchhb_t DS1PTRDS;         /* possible pointer to f2 or f3 DSCB       */
-} __attribute__ ((packed)) format1_label_t;
+	char DS1DSNAM[44];	/* data set name */
+	__u8 DS1FMTID;		/* format identifier */
+	char DS1DSSN[6];	/* data set serial number */
+	__u16 DS1VOLSQ;		/* volume sequence number */
+	struct vtoc_labeldate DS1CREDT; /* creation date: ydd */
+	struct vtoc_labeldate DS1EXPDT; /* expiration date */
+	__u8 DS1NOEPV;		/* number of extents on volume */
+	__u8 DS1NOBDB;		/* no. of bytes used in last direction blk */
+	__u8 DS1FLAG1;		/* flag 1 */
+	char DS1SYSCD[13];	/* system code */
+	struct vtoc_labeldate DS1REFD; /* date last referenced	*/
+	__u8 DS1SMSFG;		/* system managed storage indicators */
+	__u8 DS1SCXTF;		/* sec. space extension flag byte */
+	__u16 DS1SCXTV;		/* secondary space extension value */
+	__u8 DS1DSRG1;		/* data set organisation byte 1 */
+	__u8 DS1DSRG2;		/* data set organisation byte 2 */
+	__u8 DS1RECFM;		/* record format */
+	__u8 DS1OPTCD;		/* option code */
+	__u16 DS1BLKL;		/* block length */
+	__u16 DS1LRECL;		/* record length */
+	__u8 DS1KEYL;		/* key length */
+	__u16 DS1RKP;		/* relative key position */
+	__u8 DS1DSIND;		/* data set indicators */
+	__u8 DS1SCAL1;		/* secondary allocation flag byte */
+	char DS1SCAL3[3];	/* secondary allocation quantity */
+	struct vtoc_ttr DS1LSTAR; /* last used track and block on track */
+	__u16 DS1TRBAL;		/* space remaining on last used track */
+	__u16 res1;		/* reserved */
+	struct vtoc_extent DS1EXT1; /* first extent description */
+	struct vtoc_extent DS1EXT2; /* second extent description */
+	struct vtoc_extent DS1EXT3; /* third extent description */
+	struct vtoc_cchhb DS1PTRDS; /* possible pointer to f2 or f3 DSCB */
+} __attribute__ ((packed));
 
-
-typedef struct format4_label 
+struct vtoc_format4_label
 {
-	char  DS4KEYCD[44];       /* key code for VTOC labels: 44 times 0x04 */
-        __u8  DS4IDFMT;           /* format identifier                       */
-	cchhb_t DS4HPCHR;         /* highest address of a format 1 DSCB      */
-        __u16 DS4DSREC;           /* number of available DSCB's              */
-        cchh_t DS4HCCHH;          /* CCHH of next available alternate track  */
-        __u16 DS4NOATK;           /* number of remaining alternate tracks    */
-        __u8  DS4VTOCI;           /* VTOC indicators                         */
-        __u8  DS4NOEXT;           /* number of extents in VTOC               */
-        __u8  DS4SMSFG;           /* system managed storage indicators       */
-        __u8  DS4DEVAC;           /* number of alternate cylinders. 
-                                     Subtract from first two bytes of 
-                                     DS4DEVSZ to get number of usable
-				     cylinders. can be zero. valid
-				     only if DS4DEVAV on.                    */
-        dev_const_t DS4DEVCT;     /* device constants                        */
-        char DS4AMTIM[8];         /* VSAM time stamp                         */
-        char DS4AMCAT[3];         /* VSAM catalog indicator                  */
-        char DS4R2TIM[8];         /* VSAM volume/catalog match time stamp    */
-        char res1[5];             /* reserved                                */
-        char DS4F6PTR[5];         /* pointer to first format 6 DSCB          */
-        extent_t DS4VTOCE;        /* VTOC extent description                 */
-        char res2[10];            /* reserved                                */
-        __u8 DS4EFLVL;            /* extended free-space management level    */
-        cchhb_t DS4EFPTR;         /* pointer to extended free-space info     */
-        char res3[9];             /* reserved                                */
-} __attribute__ ((packed)) format4_label_t;
+	char DS4KEYCD[44];	/* key code for VTOC labels: 44 times 0x04 */
+	__u8 DS4IDFMT;		/* format identifier */
+	struct vtoc_cchhb DS4HPCHR; /* highest address of a format 1 DSCB */
+	__u16 DS4DSREC;		/* number of available DSCB's */
+	struct vtoc_cchh DS4HCCHH; /* CCHH of next available alternate track */
+	__u16 DS4NOATK;		/* number of remaining alternate tracks */
+	__u8 DS4VTOCI;		/* VTOC indicators */
+	__u8 DS4NOEXT;		/* number of extents in VTOC */
+	__u8 DS4SMSFG;		/* system managed storage indicators */
+	__u8 DS4DEVAC;		/* number of alternate cylinders.
+				 * Subtract from first two bytes of
+				 * DS4DEVSZ to get number of usable
+				 * cylinders. can be zero. valid
+				 * only if DS4DEVAV on. */
+	struct vtoc_dev_const DS4DEVCT;	/* device constants */
+	char DS4AMTIM[8];	/* VSAM time stamp */
+	char DS4AMCAT[3];	/* VSAM catalog indicator */
+	char DS4R2TIM[8];	/* VSAM volume/catalog match time stamp */
+	char res1[5];		/* reserved */
+	char DS4F6PTR[5];	/* pointer to first format 6 DSCB */
+	struct vtoc_extent DS4VTOCE; /* VTOC extent description */
+	char res2[10];		/* reserved */
+	__u8 DS4EFLVL;		/* extended free-space management level */
+	struct vtoc_cchhb DS4EFPTR; /* pointer to extended free-space info */
+	char res3[9];		/* reserved */
+} __attribute__ ((packed));
 
-
-typedef struct ds5ext 
+struct vtoc_ds5ext
 {
-	__u16 t;                  /* RTA of the first track of free extent   */
-	__u16 fc;                 /* number of whole cylinders in free ext.  */
-	__u8  ft;                 /* number of remaining free tracks         */
-} __attribute__ ((packed)) ds5ext_t;
+	__u16 t;	/* RTA of the first track of free extent */
+	__u16 fc;	/* number of whole cylinders in free ext. */
+	__u8 ft;	/* number of remaining free tracks */
+} __attribute__ ((packed));
 
-
-typedef struct format5_label 
+struct vtoc_format5_label
 {
-	char DS5KEYID[4];         /* key identifier                          */
-	ds5ext_t DS5AVEXT;        /* first available (free-space) extent.    */
-	ds5ext_t DS5EXTAV[7];     /* seven available extents                 */
-	__u8 DS5FMTID;            /* format identifier                       */
-	ds5ext_t DS5MAVET[18];    /* eighteen available extents              */
-	cchhb_t DS5PTRDS;         /* pointer to next format5 DSCB            */
-} __attribute__ ((packed)) format5_label_t;
+	char DS5KEYID[4];	/* key identifier */
+	struct vtoc_ds5ext DS5AVEXT; /* first available (free-space) extent. */
+	struct vtoc_ds5ext DS5EXTAV[7]; /* seven available extents */
+	__u8 DS5FMTID;		/* format identifier */
+	struct vtoc_ds5ext DS5MAVET[18]; /* eighteen available extents */
+	struct vtoc_cchhb DS5PTRDS; /* pointer to next format5 DSCB */
+} __attribute__ ((packed));
 
-
-typedef struct ds7ext 
+struct vtoc_ds7ext
 {
-	__u32 a;                  /* starting RTA value                      */
-	__u32 b;                  /* ending RTA value + 1                    */
-} __attribute__ ((packed)) ds7ext_t;
+	__u32 a; /* starting RTA value */
+	__u32 b; /* ending RTA value + 1 */
+} __attribute__ ((packed));
 
-
-typedef struct format7_label 
+struct vtoc_format7_label
 {
-	char DS7KEYID[4];         /* key identifier                          */
-	ds7ext_t DS7EXTNT[5];     /* space for 5 extent descriptions         */
-	__u8 DS7FMTID;            /* format identifier                       */
-	ds7ext_t DS7ADEXT[11];    /* space for 11 extent descriptions        */
-	char res1[2];             /* reserved                                */
-	cchhb_t DS7PTRDS;         /* pointer to next FMT7 DSCB               */
-} __attribute__ ((packed)) format7_label_t;
+	char DS7KEYID[4];	/* key identifier */
+	struct vtoc_ds7ext DS7EXTNT[5]; /* space for 5 extent descriptions */
+	__u8 DS7FMTID;		/* format identifier */
+	struct vtoc_ds7ext DS7ADEXT[11]; /* space for 11 extent descriptions */
+	char res1[2];		/* reserved */
+	struct vtoc_cchhb DS7PTRDS; /* pointer to next FMT7 DSCB */
+} __attribute__ ((packed));
 
-
-char * vtoc_ebcdic_enc (
-        unsigned char source[LINE_LENGTH],
-        unsigned char target[LINE_LENGTH],
-	int l);
-char * vtoc_ebcdic_dec (
-        unsigned char source[LINE_LENGTH],
-	unsigned char target[LINE_LENGTH],
-	int l);
-void vtoc_set_extent (
-        extent_t * ext,
-        __u8 typeind,
-        __u8 seqno,
-        cchh_t * lower,
-        cchh_t * upper);
-void vtoc_set_cchh (
-        cchh_t * addr,
-	__u16 cc,
-	__u16 hh);
-void vtoc_set_cchhb (
-        cchhb_t * addr,
-        __u16 cc,
-        __u16 hh,
-        __u8 b);
-void vtoc_set_date (
-        labeldate_t * d,
-        __u8 year,
-        __u16 day);
-
-void vtoc_volume_label_init (
-	volume_label_t *vlabel);
-
-int vtoc_read_volume_label (
-        char * device,
-        unsigned long vlabel_start,
-        volume_label_t * vlabel);
-
-int vtoc_write_volume_label (
-        char *device,
-        unsigned long vlabel_start,
-        volume_label_t *vlabel);
-
-void vtoc_volume_label_set_volser (
-	volume_label_t *vlabel,
-	char *volser);
-
-char *vtoc_volume_label_get_volser (
-	volume_label_t *vlabel,
-	char *volser);
-
-void vtoc_volume_label_set_key (
-        volume_label_t *vlabel,
-        char *key);     
-
-void vtoc_volume_label_set_label (
-	volume_label_t *vlabel,
-	char *lbl);
-
-char *vtoc_volume_label_get_label (
-	volume_label_t *vlabel,
-	char *lbl);
-
-void vtoc_read_label (
-        char *device,
-        unsigned long position,
-        format1_label_t *f1,
-        format4_label_t *f4,
-        format5_label_t *f5,
-        format7_label_t *f7);
-
-void vtoc_write_label (
-        char *device,
-        unsigned long position,
-        format1_label_t *f1,
-	format4_label_t *f4,
-	format5_label_t *f5,
-	format7_label_t *f7);
-
-
-void vtoc_init_format1_label (
-        char *volid,
-        unsigned int blksize,
-        extent_t *part_extent,
-        format1_label_t *f1);
-
-
-void vtoc_init_format4_label (
-        format4_label_t *f4lbl,
-	unsigned int usable_partitions,
-	unsigned int cylinders,
-	unsigned int tracks,
-	unsigned int blocks,
-	unsigned int blksize,
-	__u16 dev_type);
-
-void vtoc_update_format4_label (
-	format4_label_t *f4,
-	cchhb_t *highest_f1,
-	__u16 unused_update);
-
-
-void vtoc_init_format5_label (
-	format5_label_t *f5);
-
-void vtoc_update_format5_label_add (
-	format5_label_t *f5,
-	int verbose,
-	int cyl,
-	int trk,
-	__u16 a, 
-	__u16 b, 
-	__u8 c);
- 
-void vtoc_update_format5_label_del (
-	format5_label_t *f5,
-	int verbose,
-	int cyl,
-	int trk,
-	__u16 a, 
-	__u16 b, 
-	__u8 c);
-
-
-void vtoc_init_format7_label (
-	format7_label_t *f7);
-
-void vtoc_update_format7_label_add (
-	format7_label_t *f7,
-	int verbose,
-	__u32 a, 
-	__u32 b);
-
-void vtoc_update_format7_label_del (
-	format7_label_t *f7, 
-	int verbose,
-	__u32 a, 
-	__u32 b);
-
-
-void vtoc_set_freespace(
-	format4_label_t *f4,
-	format5_label_t *f5,
-	format7_label_t *f7,
-	char ch,
-	int verbose,
-	__u32 start,
-	__u32 stop,
-	int cyl,
-	int trk);
-
-
-
-
-
-
-
-
-
-
-
-
+#endif /* _ASM_S390_VTOC_H */
diff --git a/include/asm-sh/elf.h b/include/asm-sh/elf.h
index 8fe00a1..1b63dfe 100644
--- a/include/asm-sh/elf.h
+++ b/include/asm-sh/elf.h
@@ -111,6 +111,7 @@
 
 #ifdef __KERNEL__
 #define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
+struct task_struct;
 extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
 extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
 
diff --git a/include/asm-sh/mmzone.h b/include/asm-sh/mmzone.h
deleted file mode 100644
index 0e74066..0000000
--- a/include/asm-sh/mmzone.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *  linux/include/asm-sh/mmzone.h
- *
- * 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.
- */
-#ifndef __ASM_SH_MMZONE_H
-#define __ASM_SH_MMZONE_H
-
-#include <linux/config.h>
-
-#ifdef CONFIG_DISCONTIGMEM
-
-/* Currently, just for HP690 */
-#define PHYSADDR_TO_NID(phys)	((((phys) - __MEMORY_START) >= 0x01000000)?1:0)
-
-extern pg_data_t discontig_page_data[MAX_NUMNODES];
-extern bootmem_data_t discontig_node_bdata[MAX_NUMNODES];
-
-/*
- * Following are macros that each numa implmentation must define.
- */
-
-/*
- * Given a kernel address, find the home node of the underlying memory.
- */
-#define KVADDR_TO_NID(kaddr)	PHYSADDR_TO_NID(__pa(kaddr))
-
-/*
- * Return a pointer to the node data for node n.
- */
-#define NODE_DATA(nid)		(&discontig_page_data[nid])
-
-/*
- * NODE_MEM_MAP gives the kaddr for the mem_map of the node.
- */
-#define NODE_MEM_MAP(nid)	(NODE_DATA(nid)->node_mem_map)
-
-#define phys_to_page(phys)						\
-({ unsigned int node = PHYSADDR_TO_NID(phys); 		      		\
-   NODE_MEM_MAP(node)				 		 	\
-     + (((phys) - NODE_DATA(node)->node_start_paddr) >> PAGE_SHIFT); })
-
-static inline int is_valid_page(struct page *page)
-{
-	unsigned int i;
-
-	for (i = 0; i < MAX_NUMNODES; i++) {
-		if (page >= NODE_MEM_MAP(i) &&
-		    page < NODE_MEM_MAP(i) + NODE_DATA(i)->node_size)
-			return 1;
-	}
-	return 0;
-}
-
-#define VALID_PAGE(page)	is_valid_page(page)
-#define page_to_phys(page)	PHYSADDR(page_address(page))
-
-#endif /* CONFIG_DISCONTIGMEM */
-#endif
diff --git a/include/asm-sh/page.h b/include/asm-sh/page.h
index 324e6cc..972c3f6 100644
--- a/include/asm-sh/page.h
+++ b/include/asm-sh/page.h
@@ -93,11 +93,6 @@
 
 #define __MEMORY_START		CONFIG_MEMORY_START
 #define __MEMORY_SIZE		CONFIG_MEMORY_SIZE
-#ifdef CONFIG_DISCONTIGMEM
-/* Just for HP690, for now.. */
-#define __MEMORY_START_2ND	(__MEMORY_START+0x02000000)
-#define __MEMORY_SIZE_2ND	0x001000000 /* 16MB */
-#endif
 
 #define PAGE_OFFSET		(0x80000000UL)
 #define __pa(x)			((unsigned long)(x)-PAGE_OFFSET)
@@ -105,10 +100,8 @@
 
 #define MAP_NR(addr)		(((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)
 
-#ifndef CONFIG_DISCONTIGMEM
 #define phys_to_page(phys)	(mem_map + (((phys)-__MEMORY_START) >> PAGE_SHIFT))
 #define page_to_phys(page)	(((page - mem_map) << PAGE_SHIFT) + __MEMORY_START)
-#endif
 
 /* PFN start number, because of __MEMORY_START */
 #define PFN_START		(__MEMORY_START >> PAGE_SHIFT)
diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h
index aef8ae4..bb0efb3 100644
--- a/include/asm-sh/pgtable.h
+++ b/include/asm-sh/pgtable.h
@@ -196,7 +196,9 @@
 static inline pte_t pte_mkdirty(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
 static inline pte_t pte_mkyoung(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
 static inline pte_t pte_mkwrite(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; }
+#ifdef CONFIG_HUGETLB_PAGE
 static inline pte_t pte_mkhuge(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_SZHUGE)); return pte; }
+#endif
 
 /*
  * Macro and implementation to make a page protection as uncachable.
@@ -282,6 +284,8 @@
 #define GET_IOSPACE(pfn)		0
 #define GET_PFN(pfn)			(pfn)
 
+struct mm_struct;
+
 /*
  * No page table caches to initialise
  */
diff --git a/include/asm-sh64/pgtable.h b/include/asm-sh64/pgtable.h
index 51b0581..a1906a7 100644
--- a/include/asm-sh64/pgtable.h
+++ b/include/asm-sh64/pgtable.h
@@ -24,6 +24,8 @@
 #include <linux/threads.h>
 #include <linux/config.h>
 
+struct vm_area_struct;
+
 extern void paging_init(void);
 
 /* We provide our own get_unmapped_area to avoid cache synonym issue */
diff --git a/include/asm-sparc/ptrace.h b/include/asm-sparc/ptrace.h
index a8ecb2d..7144970 100644
--- a/include/asm-sparc/ptrace.h
+++ b/include/asm-sparc/ptrace.h
@@ -60,6 +60,9 @@
 #define STACKFRAME_SZ sizeof(struct sparc_stackf)
 
 #ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE	1
+
 #define user_mode(regs) (!((regs)->psr & PSR_PS))
 #define instruction_pointer(regs) ((regs)->pc)
 unsigned long profile_pc(struct pt_regs *);
diff --git a/include/asm-sparc64/kprobes.h b/include/asm-sparc64/kprobes.h
index a8d326a..7ba8453 100644
--- a/include/asm-sparc64/kprobes.h
+++ b/include/asm-sparc64/kprobes.h
@@ -3,6 +3,7 @@
 
 #include <linux/config.h>
 #include <linux/types.h>
+#include <linux/percpu.h>
 
 typedef u32 kprobe_opcode_t;
 
@@ -18,6 +19,25 @@
 	kprobe_opcode_t insn[MAX_INSN_SIZE];
 };
 
+struct prev_kprobe {
+	struct kprobe *kp;
+	unsigned int status;
+	unsigned long orig_tnpc;
+	unsigned long orig_tstate_pil;
+};
+
+/* per-cpu kprobe control block */
+struct kprobe_ctlblk {
+	unsigned long kprobe_status;
+	unsigned long kprobe_orig_tnpc;
+	unsigned long kprobe_orig_tstate_pil;
+	long *jprobe_saved_esp;
+	struct pt_regs jprobe_saved_regs;
+	struct pt_regs *jprobe_saved_regs_location;
+	struct sparc_stackf jprobe_saved_stack;
+	struct prev_kprobe prev_kprobe;
+};
+
 #ifdef CONFIG_KPROBES
 extern int kprobe_exceptions_notify(struct notifier_block *self,
 				    unsigned long val, void *data);
diff --git a/include/asm-sparc64/ptrace.h b/include/asm-sparc64/ptrace.h
index 6194f77..7eba90c 100644
--- a/include/asm-sparc64/ptrace.h
+++ b/include/asm-sparc64/ptrace.h
@@ -94,6 +94,9 @@
 #define STACKFRAME32_SZ	sizeof(struct sparc_stackf32)
 
 #ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE	1
+
 #define force_successful_syscall_return()	    \
 do {	current_thread_info()->syscall_noerror = 1; \
 } while (0)
diff --git a/include/asm-um/ldt-i386.h b/include/asm-um/ldt-i386.h
new file mode 100644
index 0000000..b426629
--- /dev/null
+++ b/include/asm-um/ldt-i386.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
+ * Licensed under the GPL
+ *
+ * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
+ */
+
+#ifndef __ASM_LDT_I386_H
+#define __ASM_LDT_I386_H
+
+#include "asm/semaphore.h"
+#include "asm/arch/ldt.h"
+
+struct mmu_context_skas;
+extern void ldt_host_info(void);
+extern long init_new_ldt(struct mmu_context_skas * to_mm,
+			 struct mmu_context_skas * from_mm);
+extern void free_ldt(struct mmu_context_skas * mm);
+
+#define LDT_PAGES_MAX \
+	((LDT_ENTRIES * LDT_ENTRY_SIZE)/PAGE_SIZE)
+#define LDT_ENTRIES_PER_PAGE \
+	(PAGE_SIZE/LDT_ENTRY_SIZE)
+#define LDT_DIRECT_ENTRIES \
+	((LDT_PAGES_MAX*sizeof(void *))/LDT_ENTRY_SIZE)
+
+struct ldt_entry {
+	__u32 a;
+	__u32 b;
+};
+
+typedef struct uml_ldt {
+	int entry_count;
+	struct semaphore semaphore;
+	union {
+		struct ldt_entry * pages[LDT_PAGES_MAX];
+		struct ldt_entry entries[LDT_DIRECT_ENTRIES];
+	};
+} uml_ldt_t;
+
+/*
+ * macros stolen from include/asm-i386/desc.h
+ */
+#define LDT_entry_a(info) \
+	((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
+
+#define LDT_entry_b(info) \
+	(((info)->base_addr & 0xff000000) | \
+	(((info)->base_addr & 0x00ff0000) >> 16) | \
+	((info)->limit & 0xf0000) | \
+	(((info)->read_exec_only ^ 1) << 9) | \
+	((info)->contents << 10) | \
+	(((info)->seg_not_present ^ 1) << 15) | \
+	((info)->seg_32bit << 22) | \
+	((info)->limit_in_pages << 23) | \
+	((info)->useable << 20) | \
+	0x7000)
+
+#define LDT_empty(info) (\
+	(info)->base_addr	== 0	&& \
+	(info)->limit		== 0	&& \
+	(info)->contents	== 0	&& \
+	(info)->read_exec_only	== 1	&& \
+	(info)->seg_32bit	== 0	&& \
+	(info)->limit_in_pages	== 0	&& \
+	(info)->seg_not_present	== 1	&& \
+	(info)->useable		== 0	)
+
+#endif
diff --git a/include/asm-um/ldt.h b/include/asm-um/ldt.h
index e908439..4466ff6 100644
--- a/include/asm-um/ldt.h
+++ b/include/asm-um/ldt.h
@@ -1,3 +1,72 @@
+/*
+ * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
+ * Licensed under the GPL
+ *
+ * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
+ */
+
+#ifndef __ASM_LDT_I386_H
+#define __ASM_LDT_I386_H
+
+#include "asm/semaphore.h"
+#include "asm/arch/ldt.h"
+
+struct mmu_context_skas;
+extern void ldt_host_info(void);
+extern long init_new_ldt(struct mmu_context_skas * to_mm,
+			 struct mmu_context_skas * from_mm);
+extern void free_ldt(struct mmu_context_skas * mm);
+
+#define LDT_PAGES_MAX \
+	((LDT_ENTRIES * LDT_ENTRY_SIZE)/PAGE_SIZE)
+#define LDT_ENTRIES_PER_PAGE \
+	(PAGE_SIZE/LDT_ENTRY_SIZE)
+#define LDT_DIRECT_ENTRIES \
+	((LDT_PAGES_MAX*sizeof(void *))/LDT_ENTRY_SIZE)
+
+struct ldt_entry {
+	__u32 a;
+	__u32 b;
+};
+
+typedef struct uml_ldt {
+	int entry_count;
+	struct semaphore semaphore;
+	union {
+		struct ldt_entry * pages[LDT_PAGES_MAX];
+		struct ldt_entry entries[LDT_DIRECT_ENTRIES];
+	};
+} uml_ldt_t;
+
+/*
+ * macros stolen from include/asm-i386/desc.h
+ */
+#define LDT_entry_a(info) \
+	((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
+
+#define LDT_entry_b(info) \
+	(((info)->base_addr & 0xff000000) | \
+	(((info)->base_addr & 0x00ff0000) >> 16) | \
+	((info)->limit & 0xf0000) | \
+	(((info)->read_exec_only ^ 1) << 9) | \
+	((info)->contents << 10) | \
+	(((info)->seg_not_present ^ 1) << 15) | \
+	((info)->seg_32bit << 22) | \
+	((info)->limit_in_pages << 23) | \
+	((info)->useable << 20) | \
+	0x7000)
+
+#define LDT_empty(info) (\
+	(info)->base_addr	== 0	&& \
+	(info)->limit		== 0	&& \
+	(info)->contents	== 0	&& \
+	(info)->read_exec_only	== 1	&& \
+	(info)->seg_32bit	== 0	&& \
+	(info)->limit_in_pages	== 0	&& \
+	(info)->seg_not_present	== 1	&& \
+	(info)->useable		== 0	)
+
+#endif
 #ifndef __UM_LDT_H
 #define __UM_LDT_H
 
diff --git a/include/asm-um/mmu_context.h b/include/asm-um/mmu_context.h
index 2edb4f1..9a0e48e 100644
--- a/include/asm-um/mmu_context.h
+++ b/include/asm-um/mmu_context.h
@@ -29,7 +29,8 @@
 	 * possible.
 	 */
 	if (old != new && (current->flags & PF_BORROWED_MM))
-		force_flush_all();
+		CHOOSE_MODE(force_flush_all(),
+			    switch_mm_skas(&new->context.skas.id));
 }
 
 static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
diff --git a/include/asm-v850/atomic.h b/include/asm-v850/atomic.h
index 8284aa7..395268a 100644
--- a/include/asm-v850/atomic.h
+++ b/include/asm-v850/atomic.h
@@ -31,7 +31,7 @@
 #define atomic_read(v)		((v)->counter)
 #define atomic_set(v,i)		(((v)->counter) = (i))
 
-extern __inline__ int atomic_add_return (int i, volatile atomic_t *v)
+static inline int atomic_add_return (int i, volatile atomic_t *v)
 {
 	unsigned long flags;
 	int res;
diff --git a/include/asm-v850/bitops.h b/include/asm-v850/bitops.h
index 0e5c2f2..b91e799 100644
--- a/include/asm-v850/bitops.h
+++ b/include/asm-v850/bitops.h
@@ -30,7 +30,7 @@
  * ffz = Find First Zero in word. Undefined if no zero exists,
  * so code should check against ~0UL first..
  */
-extern __inline__ unsigned long ffz (unsigned long word)
+static inline unsigned long ffz (unsigned long word)
 {
 	unsigned long result = 0;
 
@@ -135,7 +135,7 @@
 			     "m" (*((const char *)(addr) + ((nr) >> 3))));    \
      __test_bit_res;							      \
   })
-extern __inline__ int __test_bit (int nr, const void *addr)
+static inline int __test_bit (int nr, const void *addr)
 {
 	int res;
 	__asm__ __volatile__ ("tst1 %1, [%2]; setf nz, %0"
@@ -157,7 +157,7 @@
 #define find_first_zero_bit(addr, size) \
   find_next_zero_bit ((addr), (size), 0)
 
-extern __inline__ int find_next_zero_bit(const void *addr, int size, int offset)
+static inline int find_next_zero_bit(const void *addr, int size, int offset)
 {
 	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
 	unsigned long result = offset & ~31UL;
diff --git a/include/asm-v850/delay.h b/include/asm-v850/delay.h
index 1ce65d48..6d028e6 100644
--- a/include/asm-v850/delay.h
+++ b/include/asm-v850/delay.h
@@ -16,7 +16,7 @@
 
 #include <asm/param.h>
 
-extern __inline__ void __delay(unsigned long loops)
+static inline void __delay(unsigned long loops)
 {
 	if (loops)
 		__asm__ __volatile__ ("1: add -1, %0; bnz 1b"
@@ -33,7 +33,7 @@
 
 extern unsigned long loops_per_jiffy;
 
-extern __inline__ void udelay(unsigned long usecs)
+static inline void udelay(unsigned long usecs)
 {
 	register unsigned long full_loops, part_loops;
 
diff --git a/include/asm-v850/hw_irq.h b/include/asm-v850/hw_irq.h
index 4bdc98e..a8aab43 100644
--- a/include/asm-v850/hw_irq.h
+++ b/include/asm-v850/hw_irq.h
@@ -1,7 +1,7 @@
 #ifndef __V850_HW_IRQ_H__
 #define __V850_HW_IRQ_H__
 
-extern inline void hw_resend_irq (struct hw_interrupt_type *h, unsigned int i)
+static inline void hw_resend_irq (struct hw_interrupt_type *h, unsigned int i)
 {
 }
 
diff --git a/include/asm-v850/processor.h b/include/asm-v850/processor.h
index d41f925..98f9294 100644
--- a/include/asm-v850/processor.h
+++ b/include/asm-v850/processor.h
@@ -59,7 +59,7 @@
 
 
 /* Do necessary setup to start up a newly executed thread.  */
-extern inline void start_thread (struct pt_regs *regs,
+static inline void start_thread (struct pt_regs *regs,
 				 unsigned long pc, unsigned long usp)
 {
 	regs->pc = pc;
@@ -68,7 +68,7 @@
 }
 
 /* Free all resources held by a thread. */
-extern inline void release_thread (struct task_struct *dead_task)
+static inline void release_thread (struct task_struct *dead_task)
 {
 }
 
diff --git a/include/asm-v850/semaphore.h b/include/asm-v850/semaphore.h
index df6cdec..735baaf 100644
--- a/include/asm-v850/semaphore.h
+++ b/include/asm-v850/semaphore.h
@@ -24,7 +24,7 @@
 #define DECLARE_MUTEX(name)		__DECLARE_SEMAPHORE_GENERIC (name,1)
 #define DECLARE_MUTEX_LOCKED(name)	__DECLARE_SEMAPHORE_GENERIC (name,0)
 
-extern inline void sema_init (struct semaphore *sem, int val)
+static inline void sema_init (struct semaphore *sem, int val)
 {
 	*sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
 }
@@ -52,14 +52,14 @@
 extern int  __down_trylock (struct semaphore * sem);
 extern void __up (struct semaphore * sem);
 
-extern inline void down (struct semaphore * sem)
+static inline void down (struct semaphore * sem)
 {
 	might_sleep();
 	if (atomic_dec_return (&sem->count) < 0)
 		__down (sem);
 }
 
-extern inline int down_interruptible (struct semaphore * sem)
+static inline int down_interruptible (struct semaphore * sem)
 {
 	int ret = 0;
 	might_sleep();
@@ -68,7 +68,7 @@
 	return ret;
 }
 
-extern inline int down_trylock (struct semaphore *sem)
+static inline int down_trylock (struct semaphore *sem)
 {
 	int ret = 0;
 	if (atomic_dec_return (&sem->count) < 0)
@@ -76,7 +76,7 @@
 	return ret;
 }
 
-extern inline void up (struct semaphore * sem)
+static inline void up (struct semaphore * sem)
 {
 	if (atomic_inc_return (&sem->count) <= 0)
 		__up (sem);
diff --git a/include/asm-v850/system.h b/include/asm-v850/system.h
index 20f4c73..107decb 100644
--- a/include/asm-v850/system.h
+++ b/include/asm-v850/system.h
@@ -81,7 +81,7 @@
   ((__typeof__ (*(ptr)))__xchg ((unsigned long)(with), (ptr), sizeof (*(ptr))))
 #define tas(ptr) (xchg ((ptr), 1))
 
-extern inline unsigned long __xchg (unsigned long with,
+static inline unsigned long __xchg (unsigned long with,
 				    __volatile__ void *ptr, int size)
 {
 	unsigned long tmp, flags;
diff --git a/include/asm-v850/tlbflush.h b/include/asm-v850/tlbflush.h
index 501e449..5f2f85f 100644
--- a/include/asm-v850/tlbflush.h
+++ b/include/asm-v850/tlbflush.h
@@ -56,12 +56,12 @@
 	BUG ();
 }
 
-extern inline void flush_tlb_kernel_page(unsigned long addr)
+static inline void flush_tlb_kernel_page(unsigned long addr)
 {
 	BUG ();
 }
 
-extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+static inline void flush_tlb_pgtables(struct mm_struct *mm,
 				      unsigned long start, unsigned long end)
 {
 	BUG ();
diff --git a/include/asm-v850/uaccess.h b/include/asm-v850/uaccess.h
index 188b285..64563c4 100644
--- a/include/asm-v850/uaccess.h
+++ b/include/asm-v850/uaccess.h
@@ -14,7 +14,7 @@
 #define VERIFY_READ	0
 #define VERIFY_WRITE	1
 
-extern inline int access_ok (int type, const void *addr, unsigned long size)
+static inline int access_ok (int type, const void *addr, unsigned long size)
 {
 	/* XXX I guess we should check against real ram bounds at least, and
 	   possibly make sure ADDR is not within the kernel.
diff --git a/include/asm-v850/unaligned.h b/include/asm-v850/unaligned.h
index 65e3836..e30b186 100644
--- a/include/asm-v850/unaligned.h
+++ b/include/asm-v850/unaligned.h
@@ -82,19 +82,19 @@
 	})
 
 
-extern inline void __put_unaligned_2(__u32 __v, register __u8 *__p)
+static inline void __put_unaligned_2(__u32 __v, register __u8 *__p)
 {
 	*__p++ = __v;
 	*__p++ = __v >> 8;
 }
 
-extern inline void __put_unaligned_4(__u32 __v, register __u8 *__p)
+static inline void __put_unaligned_4(__u32 __v, register __u8 *__p)
 {
 	__put_unaligned_2(__v >> 16, __p + 2);
 	__put_unaligned_2(__v, __p);
 }
 
-extern inline void __put_unaligned_8(const unsigned long long __v, register __u8 *__p)
+static inline void __put_unaligned_8(const unsigned long long __v, register __u8 *__p)
 {
 	/*
 	 * tradeoff: 8 bytes of stack for all unaligned puts (2
diff --git a/include/asm-x86_64/elf.h b/include/asm-x86_64/elf.h
index a60a35e..43862cd 100644
--- a/include/asm-x86_64/elf.h
+++ b/include/asm-x86_64/elf.h
@@ -149,6 +149,8 @@
  */
 #define elf_read_implies_exec(ex, executable_stack)	(executable_stack != EXSTACK_DISABLE_X)
 
+struct task_struct;
+
 extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
 extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
 
diff --git a/include/asm-x86_64/kprobes.h b/include/asm-x86_64/kprobes.h
index 6d6d883..4dd7a7e 100644
--- a/include/asm-x86_64/kprobes.h
+++ b/include/asm-x86_64/kprobes.h
@@ -25,6 +25,7 @@
  */
 #include <linux/types.h>
 #include <linux/ptrace.h>
+#include <linux/percpu.h>
 
 struct pt_regs;
 
@@ -48,6 +49,24 @@
 	kprobe_opcode_t *insn;
 };
 
+struct prev_kprobe {
+	struct kprobe *kp;
+	unsigned long status;
+	unsigned long old_rflags;
+	unsigned long saved_rflags;
+};
+
+/* per-cpu kprobe control block */
+struct kprobe_ctlblk {
+	unsigned long kprobe_status;
+	unsigned long kprobe_old_rflags;
+	unsigned long kprobe_saved_rflags;
+	long *jprobe_saved_rsp;
+	struct pt_regs jprobe_saved_regs;
+	kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
+	struct prev_kprobe prev_kprobe;
+};
+
 /* trap3/1 are intr gates for kprobes.  So, restore the status of IF,
  * if necessary, before executing the original int3/1 (trap) handler.
  */
diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h
index 7a07196..7309fff 100644
--- a/include/asm-x86_64/pgtable.h
+++ b/include/asm-x86_64/pgtable.h
@@ -105,6 +105,8 @@
 
 #define ptep_get_and_clear(mm,addr,xp)	__pte(xchg(&(xp)->pte, 0))
 
+struct mm_struct;
+
 static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long addr, pte_t *ptep, int full)
 {
 	pte_t pte;
diff --git a/include/asm-xtensa/elf.h b/include/asm-xtensa/elf.h
index 64f1f53..de06674 100644
--- a/include/asm-xtensa/elf.h
+++ b/include/asm-xtensa/elf.h
@@ -209,6 +209,8 @@
 
 #define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
 
+struct task_struct;
+
 extern void do_copy_regs (xtensa_gregset_t*, struct pt_regs*,
 			  struct task_struct*);
 extern void do_restore_regs (xtensa_gregset_t*, struct pt_regs*,
diff --git a/include/asm-xtensa/pgtable.h b/include/asm-xtensa/pgtable.h
index 987e3b8..7b15afb 100644
--- a/include/asm-xtensa/pgtable.h
+++ b/include/asm-xtensa/pgtable.h
@@ -278,6 +278,8 @@
 #endif
 }
 
+struct mm_struct;
+
 static inline void
 set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval)
 {
@@ -294,6 +296,7 @@
 #endif
 }
 
+struct vm_area_struct;
 
 static inline int
 ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr,
diff --git a/include/asm-xtensa/semaphore.h b/include/asm-xtensa/semaphore.h
index 2a10e19..f10c348 100644
--- a/include/asm-xtensa/semaphore.h
+++ b/include/asm-xtensa/semaphore.h
@@ -38,6 +38,7 @@
 static inline void sema_init (struct semaphore *sem, int val)
 {
 	atomic_set(&sem->count, val);
+	sem->sleepers = 0;
 	init_waitqueue_head(&sem->wait);
 }
 
diff --git a/include/linux/aio.h b/include/linux/aio.h
index 0decf66..403d71d 100644
--- a/include/linux/aio.h
+++ b/include/linux/aio.h
@@ -183,6 +183,7 @@
 	struct list_head	active_reqs;	/* used for cancellation */
 	struct list_head	run_list;	/* used for kicked reqs */
 
+	/* sys_io_setup currently limits this to an unsigned int */
 	unsigned		max_reqs;
 
 	struct aio_ring_info	ring_info;
@@ -234,7 +235,7 @@
 }
 
 /* for sysctl: */
-extern atomic_t aio_nr;
-extern unsigned aio_max_nr;
+extern unsigned long aio_nr;
+extern unsigned long aio_max_nr;
 
 #endif /* __LINUX__AIO_H */
diff --git a/include/linux/cn_proc.h b/include/linux/cn_proc.h
new file mode 100644
index 0000000..70ab563
--- /dev/null
+++ b/include/linux/cn_proc.h
@@ -0,0 +1,127 @@
+/*
+ * cn_proc.h - process events connector
+ *
+ * Copyright (C) Matt Helsley, IBM Corp. 2005
+ * Based on cn_fork.h by Nguyen Anh Quynh and Guillaume Thouvenin
+ * Original copyright notice follows:
+ * Copyright (C) 2005 Nguyen Anh Quynh <aquynh@gmail.com>
+ * Copyright (C) 2005 Guillaume Thouvenin <guillaume.thouvenin@bull.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef CN_PROC_H
+#define CN_PROC_H
+
+#include <linux/types.h>
+#include <linux/connector.h>
+
+/*
+ * Userspace sends this enum to register with the kernel that it is listening
+ * for events on the connector.
+ */
+enum proc_cn_mcast_op {
+	PROC_CN_MCAST_LISTEN = 1,
+	PROC_CN_MCAST_IGNORE = 2
+};
+
+/*
+ * From the user's point of view, the process
+ * ID is the thread group ID and thread ID is the internal
+ * kernel "pid". So, fields are assigned as follow:
+ *
+ *  In user space     -  In  kernel space
+ *
+ * parent process ID  =  parent->tgid
+ * parent thread  ID  =  parent->pid
+ * child  process ID  =  child->tgid
+ * child  thread  ID  =  child->pid
+ */
+
+struct proc_event {
+	enum what {
+		/* Use successive bits so the enums can be used to record
+		 * sets of events as well
+		 */
+		PROC_EVENT_NONE = 0x00000000,
+		PROC_EVENT_FORK = 0x00000001,
+		PROC_EVENT_EXEC = 0x00000002,
+		PROC_EVENT_UID  = 0x00000004,
+		PROC_EVENT_GID  = 0x00000040,
+		/* "next" should be 0x00000400 */
+		/* "last" is the last process event: exit */
+		PROC_EVENT_EXIT = 0x80000000
+	} what;
+	__u32 cpu;
+	union { /* must be last field of proc_event struct */
+		struct {
+			__u32 err;
+		} ack;
+
+		struct fork_proc_event {
+			pid_t parent_pid;
+			pid_t parent_tgid;
+			pid_t child_pid;
+			pid_t child_tgid;
+		} fork;
+
+		struct exec_proc_event {
+			pid_t process_pid;
+			pid_t process_tgid;
+		} exec;
+
+		struct id_proc_event {
+			pid_t process_pid;
+			pid_t process_tgid;
+			union {
+				uid_t ruid; /* current->uid */
+				gid_t rgid; /* current->gid */
+			} r;
+			union {
+				uid_t euid;
+				gid_t egid;
+			} e;
+		} id;
+
+		struct exit_proc_event {
+			pid_t process_pid;
+			pid_t process_tgid;
+			__u32 exit_code, exit_signal;
+		} exit;
+	} event_data;
+};
+
+#ifdef __KERNEL__
+#ifdef CONFIG_PROC_EVENTS
+void proc_fork_connector(struct task_struct *task);
+void proc_exec_connector(struct task_struct *task);
+void proc_id_connector(struct task_struct *task, int which_id);
+void proc_exit_connector(struct task_struct *task);
+#else
+static inline void proc_fork_connector(struct task_struct *task)
+{}
+
+static inline void proc_exec_connector(struct task_struct *task)
+{}
+
+static inline void proc_id_connector(struct task_struct *task,
+				     int which_id)
+{}
+
+static inline void proc_exit_connector(struct task_struct *task)
+{}
+#endif	/* CONFIG_PROC_EVENTS */
+#endif	/* __KERNEL__ */
+#endif	/* CN_PROC_H */
diff --git a/include/linux/connector.h b/include/linux/connector.h
index 95952cc..c5769c6 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -27,6 +27,12 @@
 #define CN_IDX_CONNECTOR		0xffffffff
 #define CN_VAL_CONNECTOR		0xffffffff
 
+/*
+ * Process Events connector unique ids -- used for message routing
+ */
+#define CN_IDX_PROC			0x1
+#define CN_VAL_PROC			0x1
+
 #define CN_NETLINK_USERS		1
 
 /*
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index 725be90..f8e5587 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -9,6 +9,8 @@
  * to achieve effects such as fast scrolling by changing the origin.
  */
 
+#include <linux/vt.h>
+
 struct vt_struct;
 
 #define NPAR 16
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index d2c390e..93535f0 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -453,10 +453,11 @@
  * it was foced up into this mode or autonegotiated.
  */
 
-/* The forced speed, 10Mb, 100Mb, gigabit, 10GbE. */
+/* The forced speed, 10Mb, 100Mb, gigabit, 2.5Gb, 10GbE. */
 #define SPEED_10		10
 #define SPEED_100		100
 #define SPEED_1000		1000
+#define SPEED_2500		2500
 #define SPEED_10000		10000
 
 /* Duplex, half or full. */
diff --git a/include/linux/fb.h b/include/linux/fb.h
index c698055..e7ff98e 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -810,7 +810,6 @@
 extern int fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var); 
 extern int fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var); 
 extern int fb_blank(struct fb_info *info, int blank);
-extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
 extern void cfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect); 
 extern void cfb_copyarea(struct fb_info *info, const struct fb_copyarea *area); 
 extern void cfb_imageblit(struct fb_info *info, const struct fb_image *image);
@@ -898,11 +897,13 @@
 					  struct list_head *head);
 extern struct fb_videomode *fb_find_best_mode(struct fb_var_screeninfo *var,
 					      struct list_head *head);
-extern struct fb_videomode *fb_find_nearest_mode(struct fb_var_screeninfo *var,
+extern struct fb_videomode *fb_find_nearest_mode(struct fb_videomode *mode,
 						 struct list_head *head);
 extern void fb_destroy_modelist(struct list_head *head);
 extern void fb_videomode_to_modelist(struct fb_videomode *modedb, int num,
 				     struct list_head *head);
+extern struct fb_videomode *fb_find_best_display(struct fb_monspecs *specs,
+						 struct list_head *head);
 
 /* drivers/video/fbcmap.c */
 extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp);
diff --git a/include/linux/file.h b/include/linux/file.h
index f5bbd4c..d3b1a15 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -59,9 +59,9 @@
 extern void put_filp(struct file *);
 extern int get_unused_fd(void);
 extern void FASTCALL(put_unused_fd(unsigned int fd));
-struct kmem_cache_s;
-extern void filp_ctor(void * objp, struct kmem_cache_s *cachep, unsigned long cflags);
-extern void filp_dtor(void * objp, struct kmem_cache_s *cachep, unsigned long dflags);
+struct kmem_cache;
+extern void filp_ctor(void * objp, struct kmem_cache *cachep, unsigned long cflags);
+extern void filp_dtor(void * objp, struct kmem_cache *cachep, unsigned long dflags);
 
 extern struct file ** alloc_fd_array(int);
 extern void free_fd_array(struct file **, int);
diff --git a/include/linux/font.h b/include/linux/font.h
index 53b129f..8aac48c 100644
--- a/include/linux/font.h
+++ b/include/linux/font.h
@@ -31,6 +31,7 @@
 #define SUN12x22_IDX	7
 #define ACORN8x8_IDX	8
 #define	MINI4x6_IDX	9
+#define	RL_IDX	10
 
 extern const struct font_desc	font_vga_8x8,
 			font_vga_8x16,
@@ -41,6 +42,7 @@
 			font_sun_8x16,
 			font_sun_12x22,
 			font_acorn_8x8,
+			font_rl,
 			font_mini_4x6;
 
 /* Find a font with a specific name */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6d62267..9a593ef 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -264,6 +264,7 @@
 #define ATTR_ATTR_FLAG	1024
 #define ATTR_KILL_SUID	2048
 #define ATTR_KILL_SGID	4096
+#define ATTR_FILE	8192
 
 /*
  * This is the Inode Attributes structure, used for notify_change().  It
@@ -283,6 +284,13 @@
 	struct timespec	ia_atime;
 	struct timespec	ia_mtime;
 	struct timespec	ia_ctime;
+
+	/*
+	 * Not an attribute, but an auxilary info for filesystems wanting to
+	 * implement an ftruncate() like method.  NOTE: filesystem should
+	 * check for (ia_valid & ATTR_FILE), and not for (ia_file != NULL).
+	 */
+	struct file	*ia_file;
 };
 
 /*
@@ -1088,6 +1096,8 @@
  * @get_name:       find the name for a given inode in a given directory
  * @get_parent:     find the parent of a given directory
  * @get_dentry:     find a dentry for the inode given a file handle sub-fragment
+ * @find_exported_dentry:
+ *	set by the exporting module to a standard helper function.
  *
  * Description:
  *    The export_operations structure provides a means for nfsd to communicate
@@ -1288,7 +1298,7 @@
 
 /* fs/open.c */
 
-extern int do_truncate(struct dentry *, loff_t start);
+extern int do_truncate(struct dentry *, loff_t start, struct file *filp);
 extern long do_sys_open(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);
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index f98854c..b76b558 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 2
+#define FUSE_KERNEL_MINOR_VERSION 3
 
 /** The node ID of the root inode */
 #define FUSE_ROOT_ID 1
@@ -61,6 +61,7 @@
 #define FATTR_SIZE	(1 << 3)
 #define FATTR_ATIME	(1 << 4)
 #define FATTR_MTIME	(1 << 5)
+#define FATTR_FH	(1 << 6)
 
 /**
  * Flags returned by the OPEN request
@@ -99,7 +100,9 @@
 	FUSE_OPENDIR       = 27,
 	FUSE_READDIR       = 28,
 	FUSE_RELEASEDIR    = 29,
-	FUSE_FSYNCDIR      = 30
+	FUSE_FSYNCDIR      = 30,
+	FUSE_ACCESS        = 34,
+	FUSE_CREATE        = 35
 };
 
 /* Conservative buffer size for the client */
@@ -152,12 +155,25 @@
 struct fuse_setattr_in {
 	__u32	valid;
 	__u32	padding;
-	struct fuse_attr attr;
+	__u64	fh;
+	__u64	size;
+	__u64	unused1;
+	__u64	atime;
+	__u64	mtime;
+	__u64	unused2;
+	__u32	atimensec;
+	__u32	mtimensec;
+	__u32	unused3;
+	__u32	mode;
+	__u32	unused4;
+	__u32	uid;
+	__u32	gid;
+	__u32	unused5;
 };
 
 struct fuse_open_in {
 	__u32	flags;
-	__u32	padding;
+	__u32	mode;
 };
 
 struct fuse_open_out {
@@ -222,6 +238,11 @@
 	__u32	padding;
 };
 
+struct fuse_access_in {
+	__u32	mask;
+	__u32	padding;
+};
+
 struct fuse_init_in_out {
 	__u32	major;
 	__u32	minor;
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 18d010b..cd6bd00 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -94,7 +94,7 @@
 extern int request_resource(struct resource *root, struct resource *new);
 extern struct resource * ____request_resource(struct resource *root, struct resource *new);
 extern int release_resource(struct resource *new);
-extern int insert_resource(struct resource *parent, struct resource *new);
+extern __deprecated_for_modules int insert_resource(struct resource *parent, struct resource *new);
 extern int allocate_resource(struct resource *root, struct resource *new,
 			     unsigned long size,
 			     unsigned long min, unsigned long max,
diff --git a/include/linux/ipmi.h b/include/linux/ipmi.h
index 938d55b..d6276e6 100644
--- a/include/linux/ipmi.h
+++ b/include/linux/ipmi.h
@@ -256,10 +256,7 @@
 };
 
 /* Allocate and free the receive message. */
-static inline void ipmi_free_recv_msg(struct ipmi_recv_msg *msg)
-{
-	msg->done(msg);
-}
+void ipmi_free_recv_msg(struct ipmi_recv_msg *msg);
 
 struct ipmi_user_hndl
 {
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 69681c3..c516382 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -10,6 +10,7 @@
  */
 
 #include <linux/config.h>
+#include <asm/smp.h>		/* cpu_online_map */
 
 #if !defined(CONFIG_ARCH_S390)
 
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index be197eb..aa56172 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -611,6 +611,9 @@
  * @j_revoke: The revoke table - maintains the list of revoked blocks in the
  *     current transaction.
  * @j_revoke_table: alternate revoke tables for j_revoke
+ * @j_wbuf: array of buffer_heads for journal_commit_transaction
+ * @j_wbufsize: maximum number of buffer_heads allowed in j_wbuf, the
+ *	number that will fit in j_blocksize
  * @j_private: An opaque pointer to fs-private information.
  */
 
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index f1925cc..b1e407a 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -168,7 +168,7 @@
 
 extern void bust_spinlocks(int yes);
 extern int oops_in_progress;		/* If set, an oops, panic(), BUG() or die() is in progress */
-extern int panic_timeout;
+extern __deprecated_for_modules int panic_timeout;
 extern int panic_on_oops;
 extern int tainted;
 extern const char *print_tainted(void);
@@ -266,7 +266,6 @@
 
 /**
  * container_of - cast a member of a structure out to the containing structure
- *
  * @ptr:	the pointer to the member.
  * @type:	the type of the container struct this is embedded in.
  * @member:	the name of the member within the struct.
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
index dba2774..a484572 100644
--- a/include/linux/kernel_stat.h
+++ b/include/linux/kernel_stat.h
@@ -6,6 +6,7 @@
 #include <linux/smp.h>
 #include <linux/threads.h>
 #include <linux/percpu.h>
+#include <linux/cpumask.h>
 #include <asm/cputime.h>
 
 /*
@@ -43,11 +44,10 @@
  */
 static inline int kstat_irqs(int irq)
 {
-	int i, sum=0;
+	int cpu, sum = 0;
 
-	for (i = 0; i < NR_CPUS; i++)
-		if (cpu_possible(i))
-			sum += kstat_cpu(i).irqs[irq];
+	for_each_cpu(cpu)
+		sum += kstat_cpu(cpu).irqs[irq];
 
 	return sum;
 }
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index e30afdc..e373c4a 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -33,6 +33,9 @@
 #include <linux/list.h>
 #include <linux/notifier.h>
 #include <linux/smp.h>
+#include <linux/percpu.h>
+#include <linux/spinlock.h>
+#include <linux/rcupdate.h>
 
 #include <asm/kprobes.h>
 
@@ -106,6 +109,9 @@
 	kprobe_opcode_t *entry;	/* probe handling code to jump to */
 };
 
+DECLARE_PER_CPU(struct kprobe *, current_kprobe);
+DECLARE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+
 #ifdef ARCH_SUPPORTS_KRETPROBES
 extern void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs);
 #else /* ARCH_SUPPORTS_KRETPROBES */
@@ -142,17 +148,7 @@
 };
 
 #ifdef CONFIG_KPROBES
-/* Locks kprobe: irq must be disabled */
-void lock_kprobes(void);
-void unlock_kprobes(void);
-
-/* kprobe running now on this CPU? */
-static inline int kprobe_running(void)
-{
-	extern unsigned int kprobe_cpu;
-	return kprobe_cpu == smp_processor_id();
-}
-
+extern spinlock_t kretprobe_lock;
 extern int arch_prepare_kprobe(struct kprobe *p);
 extern void arch_copy_kprobe(struct kprobe *p);
 extern void arch_arm_kprobe(struct kprobe *p);
@@ -163,10 +159,26 @@
 extern kprobe_opcode_t *get_insn_slot(void);
 extern void free_insn_slot(kprobe_opcode_t *slot);
 
-/* Get the kprobe at this addr (if any).  Must have called lock_kprobes */
+/* Get the kprobe at this addr (if any) - called with preemption disabled */
 struct kprobe *get_kprobe(void *addr);
 struct hlist_head * kretprobe_inst_table_head(struct task_struct *tsk);
 
+/* kprobe_running() will just return the current_kprobe on this CPU */
+static inline struct kprobe *kprobe_running(void)
+{
+	return (__get_cpu_var(current_kprobe));
+}
+
+static inline void reset_current_kprobe(void)
+{
+	__get_cpu_var(current_kprobe) = NULL;
+}
+
+static inline struct kprobe_ctlblk *get_kprobe_ctlblk(void)
+{
+	return (&__get_cpu_var(kprobe_ctlblk));
+}
+
 int register_kprobe(struct kprobe *p);
 void unregister_kprobe(struct kprobe *p);
 int setjmp_pre_handler(struct kprobe *, struct pt_regs *);
@@ -183,9 +195,9 @@
 void kprobe_flush_task(struct task_struct *tk);
 void recycle_rp_inst(struct kretprobe_instance *ri);
 #else /* CONFIG_KPROBES */
-static inline int kprobe_running(void)
+static inline struct kprobe *kprobe_running(void)
 {
-	return 0;
+	return NULL;
 }
 static inline int register_kprobe(struct kprobe *p)
 {
diff --git a/include/linux/list.h b/include/linux/list.h
index 084971f..fbfca73 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -601,7 +601,7 @@
  * or hlist_del_rcu(), running on this same list.
  * However, it is perfectly legal to run concurrently with
  * the _rcu list-traversal primitives, such as
- * hlist_for_each_rcu(), used to prevent memory-consistency
+ * hlist_for_each_entry_rcu(), used to prevent memory-consistency
  * problems on Alpha CPUs.  Regardless of the type of CPU, the
  * list-traversal primitive must be guarded by rcu_read_lock().
  */
@@ -650,7 +650,7 @@
  * or hlist_del_rcu(), running on this same list.
  * However, it is perfectly legal to run concurrently with
  * the _rcu list-traversal primitives, such as
- * hlist_for_each_rcu(), used to prevent memory-consistency
+ * hlist_for_each_entry_rcu(), used to prevent memory-consistency
  * problems on Alpha CPUs.
  */
 static inline void hlist_add_before_rcu(struct hlist_node *n,
@@ -675,7 +675,7 @@
  * or hlist_del_rcu(), running on this same list.
  * However, it is perfectly legal to run concurrently with
  * the _rcu list-traversal primitives, such as
- * hlist_for_each_rcu(), used to prevent memory-consistency
+ * hlist_for_each_entry_rcu(), used to prevent memory-consistency
  * problems on Alpha CPUs.
  */
 static inline void hlist_add_after_rcu(struct hlist_node *prev,
@@ -699,11 +699,6 @@
 	for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
 	     pos = n)
 
-#define hlist_for_each_rcu(pos, head) \
-	for ((pos) = (head)->first; \
-		rcu_dereference((pos)) && ({ prefetch((pos)->next); 1; }); \
-		(pos) = (pos)->next)
-
 /**
  * hlist_for_each_entry	- iterate over list of given type
  * @tpos:	the type * to use as a loop counter.
@@ -756,7 +751,7 @@
 
 /**
  * hlist_for_each_entry_rcu - iterate over rcu list of given type
- * @pos:	the type * to use as a loop counter.
+ * @tpos:	the type * to use as a loop counter.
  * @pos:	the &struct hlist_node to use as a loop counter.
  * @head:	the head for your list.
  * @member:	the name of the hlist_node within the struct.
diff --git a/include/linux/memory.h b/include/linux/memory.h
index 0def328..9a42438 100644
--- a/include/linux/memory.h
+++ b/include/linux/memory.h
@@ -54,6 +54,9 @@
  */
 #define	MEM_MAPPING_INVALID	(1<<3)
 
+struct notifier_block;
+struct mem_section;
+
 #ifndef CONFIG_MEMORY_HOTPLUG
 static inline int memory_dev_init(void)
 {
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 5c1fb0a..7b115fe 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -932,13 +932,13 @@
 					 * turning readahead off */
 
 int do_page_cache_readahead(struct address_space *mapping, struct file *filp,
-			unsigned long offset, unsigned long nr_to_read);
+			pgoff_t offset, unsigned long nr_to_read);
 int force_page_cache_readahead(struct address_space *mapping, struct file *filp,
-			unsigned long offset, unsigned long nr_to_read);
-unsigned long  page_cache_readahead(struct address_space *mapping,
+			pgoff_t offset, unsigned long nr_to_read);
+unsigned long page_cache_readahead(struct address_space *mapping,
 			  struct file_ra_state *ra,
 			  struct file *filp,
-			  unsigned long offset,
+			  pgoff_t offset,
 			  unsigned long size);
 void handle_ra_miss(struct address_space *mapping, 
 		    struct file_ra_state *ra, pgoff_t offset);
diff --git a/include/linux/net.h b/include/linux/net.h
index 4e98158..d6a41e6 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -71,6 +71,7 @@
  * @SOCK_RAW: raw socket
  * @SOCK_RDM: reliably-delivered message
  * @SOCK_SEQPACKET: sequential packet socket
+ * @SOCK_DCCP: Datagram Congestion Control Protocol socket
  * @SOCK_PACKET: linux specific way of getting packets at the dev level.
  *		  For writing rarp and other similar things on the user level.
  *
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index 6d5a24f..51c231a 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -60,7 +60,7 @@
 extern struct svc_program	nfsd_program;
 extern struct svc_version	nfsd_version2, nfsd_version3,
 				nfsd_version4;
-
+extern struct svc_serv		*nfsd_serv;
 /*
  * Function prototypes.
  */
diff --git a/include/linux/nfsd/syscall.h b/include/linux/nfsd/syscall.h
index e65c9db..781efbf 100644
--- a/include/linux/nfsd/syscall.h
+++ b/include/linux/nfsd/syscall.h
@@ -39,6 +39,21 @@
 #define NFSCTL_GETFD		7	/* get an fh by path (used by mountd) */
 #define	NFSCTL_GETFS		8	/* get an fh by path with max FH len */
 
+/*
+ * Macros used to set version
+ */
+#define NFSCTL_VERSET(_cltbits, _v)   ((_cltbits) |=  (1 << (_v)))
+#define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << (_v)))
+#define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << (_v)))
+
+#if defined(CONFIG_NFSD_V4)
+#define	NFSCTL_VERALL	(0x1c /* 0b011100 */)
+#elif defined(CONFIG_NFSD_V3)
+#define	NFSCTL_VERALL	(0x0c /* 0b001100 */)
+#else
+#define	NFSCTL_VERALL	(0x04 /* 0b000100 */)
+#endif
+
 /* SVC */
 struct nfsctl_svc {
 	unsigned short		svc_port;
@@ -120,6 +135,8 @@
 extern int		exp_export(struct nfsctl_export *nxp);
 extern int		exp_unexport(struct nfsctl_export *nxp);
 
+extern unsigned int nfsd_versbits;
+
 #endif /* __KERNEL__ */
 
 #endif /* NFSD_SYSCALL_H */
diff --git a/include/linux/nfsd/xdr3.h b/include/linux/nfsd/xdr3.h
index 21e18ce..3c2a71b 100644
--- a/include/linux/nfsd/xdr3.h
+++ b/include/linux/nfsd/xdr3.h
@@ -42,7 +42,7 @@
 	__u64			offset;
 	__u32			count;
 	int			stable;
-	int			len;
+	__u32			len;
 	struct kvec		vec[RPCSVC_MAXPAGES];
 	int			vlen;
 };
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 88de3f8..9a96f05 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -519,6 +519,7 @@
 #define PCI_DEVICE_ID_MATROX_MIL	0x0519
 #define PCI_DEVICE_ID_MATROX_MYS	0x051A
 #define PCI_DEVICE_ID_MATROX_MIL_2	0x051b
+#define PCI_DEVICE_ID_MATROX_MYS_AGP	0x051e
 #define PCI_DEVICE_ID_MATROX_MIL_2_AGP	0x051f
 #define PCI_DEVICE_ID_MATROX_MGA_IMP	0x0d10
 #define PCI_DEVICE_ID_MATROX_G100_MM	0x1000
@@ -1785,6 +1786,7 @@
 #define PCI_DEVICE_ID_TIGON3_5704	0x1648
 #define PCI_DEVICE_ID_TIGON3_5704S_2	0x1649
 #define PCI_DEVICE_ID_NX2_5706		0x164a
+#define PCI_DEVICE_ID_NX2_5708		0x164c
 #define PCI_DEVICE_ID_TIGON3_5702FE	0x164d
 #define PCI_DEVICE_ID_TIGON3_5705	0x1653
 #define PCI_DEVICE_ID_TIGON3_5705_2	0x1654
@@ -1809,6 +1811,7 @@
 #define PCI_DEVICE_ID_TIGON3_5703X	0x16a7
 #define PCI_DEVICE_ID_TIGON3_5704S	0x16a8
 #define PCI_DEVICE_ID_NX2_5706S		0x16aa
+#define PCI_DEVICE_ID_NX2_5708S		0x16ac
 #define PCI_DEVICE_ID_TIGON3_5702A3	0x16c6
 #define PCI_DEVICE_ID_TIGON3_5703A3	0x16c7
 #define PCI_DEVICE_ID_TIGON3_5781	0x16dd
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
index 60ffcb9..e87b233 100644
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -93,6 +93,7 @@
 /* PRIO section */
 
 #define TCQ_PRIO_BANDS	16
+#define TCQ_MIN_PRIO_BANDS 2
 
 struct tc_prio_qopt
 {
@@ -169,6 +170,7 @@
 	unsigned char   Scell_log;	/* cell size for idle damping */
 	unsigned char	flags;
 #define TC_RED_ECN	1
+#define TC_RED_HARDDROP	2
 };
 
 struct tc_red_xstats
@@ -194,38 +196,34 @@
 
 #define TCA_GRED_MAX (__TCA_GRED_MAX - 1)
 
-#define TCA_SET_OFF TCA_GRED_PARMS
 struct tc_gred_qopt
 {
-       __u32           limit;          /* HARD maximal queue length (bytes)    
-*/
-       __u32           qth_min;        /* Min average length threshold (bytes) 
-*/
-       __u32           qth_max;        /* Max average length threshold (bytes) 
-*/
-       __u32           DP;             /* upto 2^32 DPs */
-       __u32           backlog;        
-       __u32           qave;   
-       __u32           forced; 
-       __u32           early;  
-       __u32           other;  
-       __u32           pdrop;  
-
-       unsigned char   Wlog;           /* log(W)               */
-       unsigned char   Plog;           /* log(P_max/(qth_max-qth_min)) */
-       unsigned char   Scell_log;      /* cell size for idle damping */
-       __u8            prio;		/* prio of this VQ */
-       __u32	packets;
-       __u32	bytesin;
+	__u32		limit;        /* HARD maximal queue length (bytes)    */
+	__u32		qth_min;      /* Min average length threshold (bytes) */
+	__u32		qth_max;      /* Max average length threshold (bytes) */
+	__u32		DP;           /* upto 2^32 DPs */
+	__u32		backlog;
+	__u32		qave;
+	__u32		forced;
+	__u32		early;
+	__u32		other;
+	__u32		pdrop;
+	__u8		Wlog;         /* log(W)               */
+	__u8		Plog;         /* log(P_max/(qth_max-qth_min)) */
+	__u8		Scell_log;    /* cell size for idle damping */
+	__u8		prio;         /* prio of this VQ */
+	__u32		packets;
+	__u32		bytesin;
 };
+
 /* gred setup */
 struct tc_gred_sopt
 {
-       __u32		DPs;
-       __u32		def_DP;
-       __u8		grio;
-       __u8		pad1;
-       __u16		pad2;
+	__u32		DPs;
+	__u32		def_DP;
+	__u8		grio;
+	__u8		flags;
+	__u16		pad1;
 };
 
 /* HTB section */
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index aadbac2..584d57c 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -353,7 +353,6 @@
 int pnp_register_protocol(struct pnp_protocol *protocol);
 void pnp_unregister_protocol(struct pnp_protocol *protocol);
 int pnp_add_device(struct pnp_dev *dev);
-void pnp_remove_device(struct pnp_dev *dev);
 int pnp_device_attach(struct pnp_dev *pnp_dev);
 void pnp_device_detach(struct pnp_dev *pnp_dev);
 extern struct list_head pnp_global;
@@ -399,7 +398,6 @@
 static inline void pnp_unregister_protocol(struct pnp_protocol *protocol) { }
 static inline int pnp_init_device(struct pnp_dev *dev) { return -ENODEV; }
 static inline int pnp_add_device(struct pnp_dev *dev) { return -ENODEV; }
-static inline void pnp_remove_device(struct pnp_dev *dev) { }
 static inline int pnp_device_attach(struct pnp_dev *pnp_dev) { return -ENODEV; }
 static inline void pnp_device_detach(struct pnp_dev *pnp_dev) { ; }
 
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index dc6f364..b2b3dba 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -78,6 +78,8 @@
 #include <linux/compiler.h>		/* For unlikely.  */
 #include <linux/sched.h>		/* For struct task_struct.  */
 
+
+extern long arch_ptrace(struct task_struct *child, long request, long addr, long data);
 extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len);
 extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len);
 extern int ptrace_attach(struct task_struct *tsk);
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index d211507..4f34d3d 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -198,38 +198,38 @@
 #define DQUOT_SYNC(sb)				do { } while(0)
 #define DQUOT_OFF(sb)				do { } while(0)
 #define DQUOT_TRANSFER(inode, iattr)		(0)
-extern __inline__ int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
+static inline int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
 {
 	inode_add_bytes(inode, nr);
 	return 0;
 }
 
-extern __inline__ int DQUOT_PREALLOC_SPACE(struct inode *inode, qsize_t nr)
+static inline int DQUOT_PREALLOC_SPACE(struct inode *inode, qsize_t nr)
 {
 	DQUOT_PREALLOC_SPACE_NODIRTY(inode, nr);
 	mark_inode_dirty(inode);
 	return 0;
 }
 
-extern __inline__ int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
+static inline int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
 {
 	inode_add_bytes(inode, nr);
 	return 0;
 }
 
-extern __inline__ int DQUOT_ALLOC_SPACE(struct inode *inode, qsize_t nr)
+static inline int DQUOT_ALLOC_SPACE(struct inode *inode, qsize_t nr)
 {
 	DQUOT_ALLOC_SPACE_NODIRTY(inode, nr);
 	mark_inode_dirty(inode);
 	return 0;
 }
 
-extern __inline__ void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
+static inline void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
 {
 	inode_sub_bytes(inode, nr);
 }
 
-extern __inline__ void DQUOT_FREE_SPACE(struct inode *inode, qsize_t nr)
+static inline void DQUOT_FREE_SPACE(struct inode *inode, qsize_t nr)
 {
 	DQUOT_FREE_SPACE_NODIRTY(inode, nr);
 	mark_inode_dirty(inode);
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
index 9f0f928..36e5d26 100644
--- a/include/linux/radix-tree.h
+++ b/include/linux/radix-tree.h
@@ -46,6 +46,7 @@
 
 int radix_tree_insert(struct radix_tree_root *, unsigned long, void *);
 void *radix_tree_lookup(struct radix_tree_root *, unsigned long);
+void **radix_tree_lookup_slot(struct radix_tree_root *, unsigned long);
 void *radix_tree_delete(struct radix_tree_root *, unsigned long);
 unsigned int
 radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
diff --git a/include/linux/rio.h b/include/linux/rio.h
new file mode 100644
index 0000000..c7e907f
--- /dev/null
+++ b/include/linux/rio.h
@@ -0,0 +1,325 @@
+/*
+ * RapidIO interconnect services
+ * (RapidIO Interconnect Specification, http://www.rapidio.org)
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef LINUX_RIO_H
+#define LINUX_RIO_H
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/ioport.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/rio_regs.h>
+
+#define RIO_ANY_DESTID		0xff
+#define RIO_NO_HOPCOUNT		-1
+
+#define RIO_MAX_MPORT_RESOURCES	16
+#define RIO_MAX_DEV_RESOURCES	16
+
+#define RIO_GLOBAL_TABLE	0xff	/* Indicates access of a switch's
+					   global routing table if it
+					   has multiple (or per port)
+					   tables */
+
+#define RIO_INVALID_ROUTE	0xff	/* Indicates that a route table
+					   entry is invalid (no route
+					   exists for the device ID) */
+
+#ifdef CONFIG_RAPIDIO_8_BIT_TRANSPORT
+#define RIO_MAX_ROUTE_ENTRIES	(1 << 8)
+#else
+#define RIO_MAX_ROUTE_ENTRIES	(1 << 16)
+#endif
+
+#define RIO_MAX_MBOX		4
+#define RIO_MAX_MSG_SIZE	0x1000
+
+/*
+ * Error values that may be returned by RIO functions.
+ */
+#define RIO_SUCCESSFUL			0x00
+#define RIO_BAD_SIZE			0x81
+
+/*
+ * For RIO devices, the region numbers are assigned this way:
+ *
+ *	0	RapidIO outbound doorbells
+ *      1-15	RapidIO memory regions
+ *
+ * For RIO master ports, the region number are assigned this way:
+ *
+ *	0	RapidIO inbound doorbells
+ *	1	RapidIO inbound mailboxes
+ *	1	RapidIO outbound mailboxes
+ */
+#define RIO_DOORBELL_RESOURCE	0
+#define RIO_INB_MBOX_RESOURCE	1
+#define RIO_OUTB_MBOX_RESOURCE	2
+
+extern struct bus_type rio_bus_type;
+extern struct list_head rio_devices;	/* list of all devices */
+
+struct rio_mport;
+
+/**
+ * struct rio_dev - RIO device info
+ * @global_list: Node in list of all RIO devices
+ * @net_list: Node in list of RIO devices in a network
+ * @net: Network this device is a part of
+ * @did: Device ID
+ * @vid: Vendor ID
+ * @device_rev: Device revision
+ * @asm_did: Assembly device ID
+ * @asm_vid: Assembly vendor ID
+ * @asm_rev: Assembly revision
+ * @efptr: Extended feature pointer
+ * @pef: Processing element features
+ * @swpinfo: Switch port info
+ * @src_ops: Source operation capabilities
+ * @dst_ops: Destination operation capabilities
+ * @dma_mask: Mask of bits of RIO address this device implements
+ * @rswitch: Pointer to &struct rio_switch if valid for this device
+ * @driver: Driver claiming this device
+ * @dev: Device model device
+ * @riores: RIO resources this device owns
+ * @destid: Network destination ID
+ */
+struct rio_dev {
+	struct list_head global_list;	/* node in list of all RIO devices */
+	struct list_head net_list;	/* node in per net list */
+	struct rio_net *net;	/* RIO net this device resides in */
+	u16 did;
+	u16 vid;
+	u32 device_rev;
+	u16 asm_did;
+	u16 asm_vid;
+	u16 asm_rev;
+	u16 efptr;
+	u32 pef;
+	u32 swpinfo;		/* Only used for switches */
+	u32 src_ops;
+	u32 dst_ops;
+	u64 dma_mask;
+	struct rio_switch *rswitch;	/* RIO switch info */
+	struct rio_driver *driver;	/* RIO driver claiming this device */
+	struct device dev;	/* LDM device structure */
+	struct resource riores[RIO_MAX_DEV_RESOURCES];
+	u16 destid;
+};
+
+#define rio_dev_g(n) list_entry(n, struct rio_dev, global_list)
+#define rio_dev_f(n) list_entry(n, struct rio_dev, net_list)
+#define	to_rio_dev(n) container_of(n, struct rio_dev, dev)
+
+/**
+ * struct rio_msg - RIO message event
+ * @res: Mailbox resource
+ * @mcback: Message event callback
+ */
+struct rio_msg {
+	struct resource *res;
+	void (*mcback) (struct rio_mport * mport, void *dev_id, int mbox, int slot);
+};
+
+/**
+ * struct rio_dbell - RIO doorbell event
+ * @node: Node in list of doorbell events
+ * @res: Doorbell resource
+ * @dinb: Doorbell event callback
+ * @dev_id: Device specific pointer to pass on event
+ */
+struct rio_dbell {
+	struct list_head node;
+	struct resource *res;
+	void (*dinb) (struct rio_mport *mport, void *dev_id, u16 src, u16 dst, u16 info);
+	void *dev_id;
+};
+
+/**
+ * struct rio_mport - RIO master port info
+ * @dbells: List of doorbell events
+ * @node: Node in global list of master ports
+ * @nnode: Node in network list of master ports
+ * @iores: I/O mem resource that this master port interface owns
+ * @riores: RIO resources that this master port interfaces owns
+ * @inb_msg: RIO inbound message event descriptors
+ * @outb_msg: RIO outbound message event descriptors
+ * @host_deviceid: Host device ID associated with this master port
+ * @ops: configuration space functions
+ * @id: Port ID, unique among all ports
+ * @index: Port index, unique among all port interfaces of the same type
+ * @name: Port name string
+ */
+struct rio_mport {
+	struct list_head dbells;	/* list of doorbell events */
+	struct list_head node;	/* node in global list of ports */
+	struct list_head nnode;	/* node in net list of ports */
+	struct resource iores;
+	struct resource riores[RIO_MAX_MPORT_RESOURCES];
+	struct rio_msg inb_msg[RIO_MAX_MBOX];
+	struct rio_msg outb_msg[RIO_MAX_MBOX];
+	int host_deviceid;	/* Host device ID */
+	struct rio_ops *ops;	/* maintenance transaction functions */
+	unsigned char id;	/* port ID, unique among all ports */
+	unsigned char index;	/* port index, unique among all port
+				   interfaces of the same type */
+	unsigned char name[40];
+};
+
+/**
+ * struct rio_net - RIO network info
+ * @node: Node in global list of RIO networks
+ * @devices: List of devices in this network
+ * @mports: List of master ports accessing this network
+ * @hport: Default port for accessing this network
+ * @id: RIO network ID
+ */
+struct rio_net {
+	struct list_head node;	/* node in list of networks */
+	struct list_head devices;	/* list of devices in this net */
+	struct list_head mports;	/* list of ports accessing net */
+	struct rio_mport *hport;	/* primary port for accessing net */
+	unsigned char id;	/* RIO network ID */
+};
+
+/**
+ * struct rio_switch - RIO switch info
+ * @node: Node in global list of switches
+ * @switchid: Switch ID that is unique across a network
+ * @hopcount: Hopcount to this switch
+ * @destid: Associated destid in the path
+ * @route_table: Copy of switch routing table
+ * @add_entry: Callback for switch-specific route add function
+ * @get_entry: Callback for switch-specific route get function
+ */
+struct rio_switch {
+	struct list_head node;
+	u16 switchid;
+	u16 hopcount;
+	u16 destid;
+	u8 route_table[RIO_MAX_ROUTE_ENTRIES];
+	int (*add_entry) (struct rio_mport * mport, u16 destid, u8 hopcount,
+			  u16 table, u16 route_destid, u8 route_port);
+	int (*get_entry) (struct rio_mport * mport, u16 destid, u8 hopcount,
+			  u16 table, u16 route_destid, u8 * route_port);
+};
+
+/* Low-level architecture-dependent routines */
+
+/**
+ * struct rio_ops - Low-level RIO configuration space operations
+ * @lcread: Callback to perform local (master port) read of config space.
+ * @lcwrite: Callback to perform local (master port) write of config space.
+ * @cread: Callback to perform network read of config space.
+ * @cwrite: Callback to perform network write of config space.
+ * @dsend: Callback to send a doorbell message.
+ */
+struct rio_ops {
+	int (*lcread) (int index, u32 offset, int len, u32 * data);
+	int (*lcwrite) (int index, u32 offset, int len, u32 data);
+	int (*cread) (int index, u16 destid, u8 hopcount, u32 offset, int len,
+		      u32 * data);
+	int (*cwrite) (int index, u16 destid, u8 hopcount, u32 offset, int len,
+		       u32 data);
+	int (*dsend) (int index, u16 destid, u16 data);
+};
+
+#define RIO_RESOURCE_MEM	0x00000100
+#define RIO_RESOURCE_DOORBELL	0x00000200
+#define RIO_RESOURCE_MAILBOX	0x00000400
+
+#define RIO_RESOURCE_CACHEABLE	0x00010000
+#define RIO_RESOURCE_PCI	0x00020000
+
+#define RIO_RESOURCE_BUSY	0x80000000
+
+/**
+ * struct rio_driver - RIO driver info
+ * @node: Node in list of drivers
+ * @name: RIO driver name
+ * @id_table: RIO device ids to be associated with this driver
+ * @probe: RIO device inserted
+ * @remove: RIO device removed
+ * @suspend: RIO device suspended
+ * @resume: RIO device awakened
+ * @enable_wake: RIO device enable wake event
+ * @driver: LDM driver struct
+ *
+ * Provides info on a RIO device driver for insertion/removal and
+ * power management purposes.
+ */
+struct rio_driver {
+	struct list_head node;
+	char *name;
+	const struct rio_device_id *id_table;
+	int (*probe) (struct rio_dev * dev, const struct rio_device_id * id);
+	void (*remove) (struct rio_dev * dev);
+	int (*suspend) (struct rio_dev * dev, u32 state);
+	int (*resume) (struct rio_dev * dev);
+	int (*enable_wake) (struct rio_dev * dev, u32 state, int enable);
+	struct device_driver driver;
+};
+
+#define	to_rio_driver(drv) container_of(drv,struct rio_driver, driver)
+
+/**
+ * struct rio_device_id - RIO device identifier
+ * @did: RIO device ID
+ * @vid: RIO vendor ID
+ * @asm_did: RIO assembly device ID
+ * @asm_vid: RIO assembly vendor ID
+ *
+ * Identifies a RIO device based on both the device/vendor IDs and
+ * the assembly device/vendor IDs.
+ */
+struct rio_device_id {
+	u16 did, vid;
+	u16 asm_did, asm_vid;
+};
+
+/**
+ * struct rio_route_ops - Per-switch route operations
+ * @vid: RIO vendor ID
+ * @did: RIO device ID
+ * @add_hook: Callback that adds a route entry
+ * @get_hook: Callback that gets a route entry
+ *
+ * Defines the operations that are necessary to manipulate the route
+ * tables for a particular RIO switch device.
+ */
+struct rio_route_ops {
+	u16 vid, did;
+	int (*add_hook) (struct rio_mport * mport, u16 destid, u8 hopcount,
+			 u16 table, u16 route_destid, u8 route_port);
+	int (*get_hook) (struct rio_mport * mport, u16 destid, u8 hopcount,
+			 u16 table, u16 route_destid, u8 * route_port);
+};
+
+/* Architecture and hardware-specific functions */
+extern int rio_init_mports(void);
+extern void rio_register_mport(struct rio_mport *);
+extern int rio_hw_add_outb_message(struct rio_mport *, struct rio_dev *, int,
+				   void *, size_t);
+extern int rio_hw_add_inb_buffer(struct rio_mport *, int, void *);
+extern void *rio_hw_get_inb_message(struct rio_mport *, int);
+extern int rio_open_inb_mbox(struct rio_mport *, void *, int, int);
+extern void rio_close_inb_mbox(struct rio_mport *, int);
+extern int rio_open_outb_mbox(struct rio_mport *, void *, int, int);
+extern void rio_close_outb_mbox(struct rio_mport *, int);
+
+#endif				/* __KERNEL__ */
+#endif				/* LINUX_RIO_H */
diff --git a/include/linux/rio_drv.h b/include/linux/rio_drv.h
new file mode 100644
index 0000000..3bd7cce
--- /dev/null
+++ b/include/linux/rio_drv.h
@@ -0,0 +1,469 @@
+/*
+ * RapidIO driver services
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef LINUX_RIO_DRV_H
+#define LINUX_RIO_DRV_H
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/ioport.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/rio.h>
+
+extern int __rio_local_read_config_32(struct rio_mport *port, u32 offset,
+				      u32 * data);
+extern int __rio_local_write_config_32(struct rio_mport *port, u32 offset,
+				       u32 data);
+extern int __rio_local_read_config_16(struct rio_mport *port, u32 offset,
+				      u16 * data);
+extern int __rio_local_write_config_16(struct rio_mport *port, u32 offset,
+				       u16 data);
+extern int __rio_local_read_config_8(struct rio_mport *port, u32 offset,
+				     u8 * data);
+extern int __rio_local_write_config_8(struct rio_mport *port, u32 offset,
+				      u8 data);
+
+extern int rio_mport_read_config_32(struct rio_mport *port, u16 destid,
+				    u8 hopcount, u32 offset, u32 * data);
+extern int rio_mport_write_config_32(struct rio_mport *port, u16 destid,
+				     u8 hopcount, u32 offset, u32 data);
+extern int rio_mport_read_config_16(struct rio_mport *port, u16 destid,
+				    u8 hopcount, u32 offset, u16 * data);
+extern int rio_mport_write_config_16(struct rio_mport *port, u16 destid,
+				     u8 hopcount, u32 offset, u16 data);
+extern int rio_mport_read_config_8(struct rio_mport *port, u16 destid,
+				   u8 hopcount, u32 offset, u8 * data);
+extern int rio_mport_write_config_8(struct rio_mport *port, u16 destid,
+				    u8 hopcount, u32 offset, u8 data);
+
+/**
+ * rio_local_read_config_32 - Read 32 bits from local configuration space
+ * @port: Master port
+ * @offset: Offset into local configuration space
+ * @data: Pointer to read data into
+ *
+ * Reads 32 bits of data from the specified offset within the local
+ * device's configuration space.
+ */
+static inline int rio_local_read_config_32(struct rio_mport *port, u32 offset,
+					   u32 * data)
+{
+	return __rio_local_read_config_32(port, offset, data);
+}
+
+/**
+ * rio_local_write_config_32 - Write 32 bits to local configuration space
+ * @port: Master port
+ * @offset: Offset into local configuration space
+ * @data: Data to be written
+ *
+ * Writes 32 bits of data to the specified offset within the local
+ * device's configuration space.
+ */
+static inline int rio_local_write_config_32(struct rio_mport *port, u32 offset,
+					    u32 data)
+{
+	return __rio_local_write_config_32(port, offset, data);
+}
+
+/**
+ * rio_local_read_config_16 - Read 16 bits from local configuration space
+ * @port: Master port
+ * @offset: Offset into local configuration space
+ * @data: Pointer to read data into
+ *
+ * Reads 16 bits of data from the specified offset within the local
+ * device's configuration space.
+ */
+static inline int rio_local_read_config_16(struct rio_mport *port, u32 offset,
+					   u16 * data)
+{
+	return __rio_local_read_config_16(port, offset, data);
+}
+
+/**
+ * rio_local_write_config_16 - Write 16 bits to local configuration space
+ * @port: Master port
+ * @offset: Offset into local configuration space
+ * @data: Data to be written
+ *
+ * Writes 16 bits of data to the specified offset within the local
+ * device's configuration space.
+ */
+
+static inline int rio_local_write_config_16(struct rio_mport *port, u32 offset,
+					    u16 data)
+{
+	return __rio_local_write_config_16(port, offset, data);
+}
+
+/**
+ * rio_local_read_config_8 - Read 8 bits from local configuration space
+ * @port: Master port
+ * @offset: Offset into local configuration space
+ * @data: Pointer to read data into
+ *
+ * Reads 8 bits of data from the specified offset within the local
+ * device's configuration space.
+ */
+static inline int rio_local_read_config_8(struct rio_mport *port, u32 offset,
+					  u8 * data)
+{
+	return __rio_local_read_config_8(port, offset, data);
+}
+
+/**
+ * rio_local_write_config_8 - Write 8 bits to local configuration space
+ * @port: Master port
+ * @offset: Offset into local configuration space
+ * @data: Data to be written
+ *
+ * Writes 8 bits of data to the specified offset within the local
+ * device's configuration space.
+ */
+static inline int rio_local_write_config_8(struct rio_mport *port, u32 offset,
+					   u8 data)
+{
+	return __rio_local_write_config_8(port, offset, data);
+}
+
+/**
+ * rio_read_config_32 - Read 32 bits from configuration space
+ * @rdev: RIO device
+ * @offset: Offset into device configuration space
+ * @data: Pointer to read data into
+ *
+ * Reads 32 bits of data from the specified offset within the
+ * RIO device's configuration space.
+ */
+static inline int rio_read_config_32(struct rio_dev *rdev, u32 offset,
+				     u32 * data)
+{
+	u8 hopcount = 0xff;
+	u16 destid = rdev->destid;
+
+	if (rdev->rswitch) {
+		destid = rdev->rswitch->destid;
+		hopcount = rdev->rswitch->hopcount;
+	}
+
+	return rio_mport_read_config_32(rdev->net->hport, destid, hopcount,
+					offset, data);
+};
+
+/**
+ * rio_write_config_32 - Write 32 bits to configuration space
+ * @rdev: RIO device
+ * @offset: Offset into device configuration space
+ * @data: Data to be written
+ *
+ * Writes 32 bits of data to the specified offset within the
+ * RIO device's configuration space.
+ */
+static inline int rio_write_config_32(struct rio_dev *rdev, u32 offset,
+				      u32 data)
+{
+	u8 hopcount = 0xff;
+	u16 destid = rdev->destid;
+
+	if (rdev->rswitch) {
+		destid = rdev->rswitch->destid;
+		hopcount = rdev->rswitch->hopcount;
+	}
+
+	return rio_mport_write_config_32(rdev->net->hport, destid, hopcount,
+					 offset, data);
+};
+
+/**
+ * rio_read_config_16 - Read 16 bits from configuration space
+ * @rdev: RIO device
+ * @offset: Offset into device configuration space
+ * @data: Pointer to read data into
+ *
+ * Reads 16 bits of data from the specified offset within the
+ * RIO device's configuration space.
+ */
+static inline int rio_read_config_16(struct rio_dev *rdev, u32 offset,
+				     u16 * data)
+{
+	u8 hopcount = 0xff;
+	u16 destid = rdev->destid;
+
+	if (rdev->rswitch) {
+		destid = rdev->rswitch->destid;
+		hopcount = rdev->rswitch->hopcount;
+	}
+
+	return rio_mport_read_config_16(rdev->net->hport, destid, hopcount,
+					offset, data);
+};
+
+/**
+ * rio_write_config_16 - Write 16 bits to configuration space
+ * @rdev: RIO device
+ * @offset: Offset into device configuration space
+ * @data: Data to be written
+ *
+ * Writes 16 bits of data to the specified offset within the
+ * RIO device's configuration space.
+ */
+static inline int rio_write_config_16(struct rio_dev *rdev, u32 offset,
+				      u16 data)
+{
+	u8 hopcount = 0xff;
+	u16 destid = rdev->destid;
+
+	if (rdev->rswitch) {
+		destid = rdev->rswitch->destid;
+		hopcount = rdev->rswitch->hopcount;
+	}
+
+	return rio_mport_write_config_16(rdev->net->hport, destid, hopcount,
+					 offset, data);
+};
+
+/**
+ * rio_read_config_8 - Read 8 bits from configuration space
+ * @rdev: RIO device
+ * @offset: Offset into device configuration space
+ * @data: Pointer to read data into
+ *
+ * Reads 8 bits of data from the specified offset within the
+ * RIO device's configuration space.
+ */
+static inline int rio_read_config_8(struct rio_dev *rdev, u32 offset, u8 * data)
+{
+	u8 hopcount = 0xff;
+	u16 destid = rdev->destid;
+
+	if (rdev->rswitch) {
+		destid = rdev->rswitch->destid;
+		hopcount = rdev->rswitch->hopcount;
+	}
+
+	return rio_mport_read_config_8(rdev->net->hport, destid, hopcount,
+				       offset, data);
+};
+
+/**
+ * rio_write_config_8 - Write 8 bits to configuration space
+ * @rdev: RIO device
+ * @offset: Offset into device configuration space
+ * @data: Data to be written
+ *
+ * Writes 8 bits of data to the specified offset within the
+ * RIO device's configuration space.
+ */
+static inline int rio_write_config_8(struct rio_dev *rdev, u32 offset, u8 data)
+{
+	u8 hopcount = 0xff;
+	u16 destid = rdev->destid;
+
+	if (rdev->rswitch) {
+		destid = rdev->rswitch->destid;
+		hopcount = rdev->rswitch->hopcount;
+	}
+
+	return rio_mport_write_config_8(rdev->net->hport, destid, hopcount,
+					offset, data);
+};
+
+extern int rio_mport_send_doorbell(struct rio_mport *mport, u16 destid,
+				   u16 data);
+
+/**
+ * rio_send_doorbell - Send a doorbell message to a device
+ * @rdev: RIO device
+ * @data: Doorbell message data
+ *
+ * Send a doorbell message to a RIO device. The doorbell message
+ * has a 16-bit info field provided by the @data argument.
+ */
+static inline int rio_send_doorbell(struct rio_dev *rdev, u16 data)
+{
+	return rio_mport_send_doorbell(rdev->net->hport, rdev->destid, data);
+};
+
+/**
+ * rio_init_mbox_res - Initialize a RIO mailbox resource
+ * @res: resource struct
+ * @start: start of mailbox range
+ * @end: end of mailbox range
+ *
+ * This function is used to initialize the fields of a resource
+ * for use as a mailbox resource.  It initializes a range of
+ * mailboxes using the start and end arguments.
+ */
+static inline void rio_init_mbox_res(struct resource *res, int start, int end)
+{
+	memset(res, 0, sizeof(struct resource));
+	res->start = start;
+	res->end = end;
+	res->flags = RIO_RESOURCE_MAILBOX;
+}
+
+/**
+ * rio_init_dbell_res - Initialize a RIO doorbell resource
+ * @res: resource struct
+ * @start: start of doorbell range
+ * @end: end of doorbell range
+ *
+ * This function is used to initialize the fields of a resource
+ * for use as a doorbell resource.  It initializes a range of
+ * doorbell messages using the start and end arguments.
+ */
+static inline void rio_init_dbell_res(struct resource *res, u16 start, u16 end)
+{
+	memset(res, 0, sizeof(struct resource));
+	res->start = start;
+	res->end = end;
+	res->flags = RIO_RESOURCE_DOORBELL;
+}
+
+/**
+ * RIO_DEVICE - macro used to describe a specific RIO device
+ * @vid: the 16 bit RIO vendor ID
+ * @did: the 16 bit RIO device ID
+ *
+ * This macro is used to create a struct rio_device_id that matches a
+ * specific device.  The assembly vendor and assembly device fields
+ * will be set to %RIO_ANY_ID.
+ */
+#define RIO_DEVICE(dev,ven) \
+	.did = (dev), .vid = (ven), \
+	.asm_did = RIO_ANY_ID, .asm_vid = RIO_ANY_ID
+
+/* Mailbox management */
+extern int rio_request_outb_mbox(struct rio_mport *, void *, int, int,
+				 void (*)(struct rio_mport *, void *,int, int));
+extern int rio_release_outb_mbox(struct rio_mport *, int);
+
+/**
+ * rio_add_outb_message - Add RIO message to an outbound mailbox queue
+ * @mport: RIO master port containing the outbound queue
+ * @rdev: RIO device the message is be sent to
+ * @mbox: The outbound mailbox queue
+ * @buffer: Pointer to the message buffer
+ * @len: Length of the message buffer
+ *
+ * Adds a RIO message buffer to an outbound mailbox queue for
+ * transmission. Returns 0 on success.
+ */
+static inline int rio_add_outb_message(struct rio_mport *mport,
+				       struct rio_dev *rdev, int mbox,
+				       void *buffer, size_t len)
+{
+	return rio_hw_add_outb_message(mport, rdev, mbox, buffer, len);
+}
+
+extern int rio_request_inb_mbox(struct rio_mport *, void *, int, int,
+				void (*)(struct rio_mport *, void *, int, int));
+extern int rio_release_inb_mbox(struct rio_mport *, int);
+
+/**
+ * rio_add_inb_buffer - Add buffer to an inbound mailbox queue
+ * @mport: Master port containing the inbound mailbox
+ * @mbox: The inbound mailbox number
+ * @buffer: Pointer to the message buffer
+ *
+ * Adds a buffer to an inbound mailbox queue for reception. Returns
+ * 0 on success.
+ */
+static inline int rio_add_inb_buffer(struct rio_mport *mport, int mbox,
+				     void *buffer)
+{
+	return rio_hw_add_inb_buffer(mport, mbox, buffer);
+}
+
+/**
+ * rio_get_inb_message - Get A RIO message from an inbound mailbox queue
+ * @mport: Master port containing the inbound mailbox
+ * @mbox: The inbound mailbox number
+ * @buffer: Pointer to the message buffer
+ *
+ * Get a RIO message from an inbound mailbox queue. Returns 0 on success.
+ */
+static inline void *rio_get_inb_message(struct rio_mport *mport, int mbox)
+{
+	return rio_hw_get_inb_message(mport, mbox);
+}
+
+/* Doorbell management */
+extern int rio_request_inb_dbell(struct rio_mport *, void *, u16, u16,
+				 void (*)(struct rio_mport *, void *, u16, u16, u16));
+extern int rio_release_inb_dbell(struct rio_mport *, u16, u16);
+extern struct resource *rio_request_outb_dbell(struct rio_dev *, u16, u16);
+extern int rio_release_outb_dbell(struct rio_dev *, struct resource *);
+
+/* Memory region management */
+int rio_claim_resource(struct rio_dev *, int);
+int rio_request_regions(struct rio_dev *, char *);
+void rio_release_regions(struct rio_dev *);
+int rio_request_region(struct rio_dev *, int, char *);
+void rio_release_region(struct rio_dev *, int);
+
+/* LDM support */
+int rio_register_driver(struct rio_driver *);
+void rio_unregister_driver(struct rio_driver *);
+struct rio_dev *rio_dev_get(struct rio_dev *);
+void rio_dev_put(struct rio_dev *);
+
+/**
+ * rio_name - Get the unique RIO device identifier
+ * @rdev: RIO device
+ *
+ * Get the unique RIO device identifier. Returns the device
+ * identifier string.
+ */
+static inline char *rio_name(struct rio_dev *rdev)
+{
+	return rdev->dev.bus_id;
+}
+
+/**
+ * rio_get_drvdata - Get RIO driver specific data
+ * @rdev: RIO device
+ *
+ * Get RIO driver specific data. Returns a pointer to the
+ * driver specific data.
+ */
+static inline void *rio_get_drvdata(struct rio_dev *rdev)
+{
+	return dev_get_drvdata(&rdev->dev);
+}
+
+/**
+ * rio_set_drvdata - Set RIO driver specific data
+ * @rdev: RIO device
+ * @data: Pointer to driver specific data
+ *
+ * Set RIO driver specific data. device struct driver data pointer
+ * is set to the @data argument.
+ */
+static inline void rio_set_drvdata(struct rio_dev *rdev, void *data)
+{
+	dev_set_drvdata(&rdev->dev, data);
+}
+
+/* Misc driver helpers */
+extern u16 rio_local_get_device_id(struct rio_mport *port);
+extern struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from);
+extern struct rio_dev *rio_get_asm(u16 vid, u16 did, u16 asm_vid, u16 asm_did,
+				   struct rio_dev *from);
+
+#endif				/* __KERNEL__ */
+#endif				/* LINUX_RIO_DRV_H */
diff --git a/include/linux/rio_ids.h b/include/linux/rio_ids.h
new file mode 100644
index 0000000..919d4e0
--- /dev/null
+++ b/include/linux/rio_ids.h
@@ -0,0 +1,24 @@
+/*
+ * RapidIO devices
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef LINUX_RIO_IDS_H
+#define LINUX_RIO_IDS_H
+
+#define RIO_ANY_ID			0xffff
+
+#define RIO_VID_FREESCALE		0x0002
+#define RIO_DID_MPC8560			0x0003
+
+#define RIO_VID_TUNDRA			0x000d
+#define RIO_DID_TSI500			0x0500
+
+#endif				/* LINUX_RIO_IDS_H */
diff --git a/include/linux/rio_regs.h b/include/linux/rio_regs.h
new file mode 100644
index 0000000..326540f
--- /dev/null
+++ b/include/linux/rio_regs.h
@@ -0,0 +1,215 @@
+/*
+ * RapidIO register definitions
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef LINUX_RIO_REGS_H
+#define LINUX_RIO_REGS_H
+
+/*
+ * In RapidIO, each device has a 2MB configuration space that is
+ * accessed via maintenance transactions.  Portions of configuration
+ * space are standardized and/or reserved.
+ */
+#define RIO_DEV_ID_CAR		0x00	/* [I] Device Identity CAR */
+#define RIO_DEV_INFO_CAR	0x04	/* [I] Device Information CAR */
+#define RIO_ASM_ID_CAR		0x08	/* [I] Assembly Identity CAR */
+#define  RIO_ASM_ID_MASK		0xffff0000	/* [I] Asm ID Mask */
+#define  RIO_ASM_VEN_ID_MASK		0x0000ffff	/* [I] Asm Vend Mask */
+
+#define RIO_ASM_INFO_CAR	0x0c	/* [I] Assembly Information CAR */
+#define  RIO_ASM_REV_MASK		0xffff0000	/* [I] Asm Rev Mask */
+#define  RIO_EXT_FTR_PTR_MASK		0x0000ffff	/* [I] EF_PTR Mask */
+
+#define RIO_PEF_CAR		0x10	/* [I] Processing Element Features CAR */
+#define  RIO_PEF_BRIDGE			0x80000000	/* [I] Bridge */
+#define  RIO_PEF_MEMORY			0x40000000	/* [I] MMIO */
+#define  RIO_PEF_PROCESSOR		0x20000000	/* [I] Processor */
+#define  RIO_PEF_SWITCH			0x10000000	/* [I] Switch */
+#define  RIO_PEF_INB_MBOX		0x00f00000	/* [II] Mailboxes */
+#define  RIO_PEF_INB_MBOX0		0x00800000	/* [II] Mailbox 0 */
+#define  RIO_PEF_INB_MBOX1		0x00400000	/* [II] Mailbox 1 */
+#define  RIO_PEF_INB_MBOX2		0x00200000	/* [II] Mailbox 2 */
+#define  RIO_PEF_INB_MBOX3		0x00100000	/* [II] Mailbox 3 */
+#define  RIO_PEF_INB_DOORBELL		0x00080000	/* [II] Doorbells */
+#define  RIO_PEF_CTLS			0x00000010	/* [III] CTLS */
+#define  RIO_PEF_EXT_FEATURES		0x00000008	/* [I] EFT_PTR valid */
+#define  RIO_PEF_ADDR_66		0x00000004	/* [I] 66 bits */
+#define  RIO_PEF_ADDR_50		0x00000002	/* [I] 50 bits */
+#define  RIO_PEF_ADDR_34		0x00000001	/* [I] 34 bits */
+
+#define RIO_SWP_INFO_CAR	0x14	/* [I] Switch Port Information CAR */
+#define  RIO_SWP_INFO_PORT_TOTAL_MASK	0x0000ff00	/* [I] Total number of ports */
+#define  RIO_SWP_INFO_PORT_NUM_MASK	0x000000ff	/* [I] Maintenance transaction port number */
+#define  RIO_GET_TOTAL_PORTS(x)		((x & RIO_SWP_INFO_PORT_TOTAL_MASK) >> 8)
+
+#define RIO_SRC_OPS_CAR		0x18	/* [I] Source Operations CAR */
+#define  RIO_SRC_OPS_READ		0x00008000	/* [I] Read op */
+#define  RIO_SRC_OPS_WRITE		0x00004000	/* [I] Write op */
+#define  RIO_SRC_OPS_STREAM_WRITE	0x00002000	/* [I] Str-write op */
+#define  RIO_SRC_OPS_WRITE_RESPONSE	0x00001000	/* [I] Write/resp op */
+#define  RIO_SRC_OPS_DATA_MSG		0x00000800	/* [II] Data msg op */
+#define  RIO_SRC_OPS_DOORBELL		0x00000400	/* [II] Doorbell op */
+#define  RIO_SRC_OPS_ATOMIC_TST_SWP	0x00000100	/* [I] Atomic TAS op */
+#define  RIO_SRC_OPS_ATOMIC_INC		0x00000080	/* [I] Atomic inc op */
+#define  RIO_SRC_OPS_ATOMIC_DEC		0x00000040	/* [I] Atomic dec op */
+#define  RIO_SRC_OPS_ATOMIC_SET		0x00000020	/* [I] Atomic set op */
+#define  RIO_SRC_OPS_ATOMIC_CLR		0x00000010	/* [I] Atomic clr op */
+#define  RIO_SRC_OPS_PORT_WRITE		0x00000004	/* [I] Port-write op */
+
+#define RIO_DST_OPS_CAR		0x1c	/* Destination Operations CAR */
+#define  RIO_DST_OPS_READ		0x00008000	/* [I] Read op */
+#define  RIO_DST_OPS_WRITE		0x00004000	/* [I] Write op */
+#define  RIO_DST_OPS_STREAM_WRITE	0x00002000	/* [I] Str-write op */
+#define  RIO_DST_OPS_WRITE_RESPONSE	0x00001000	/* [I] Write/resp op */
+#define  RIO_DST_OPS_DATA_MSG		0x00000800	/* [II] Data msg op */
+#define  RIO_DST_OPS_DOORBELL		0x00000400	/* [II] Doorbell op */
+#define  RIO_DST_OPS_ATOMIC_TST_SWP	0x00000100	/* [I] Atomic TAS op */
+#define  RIO_DST_OPS_ATOMIC_INC		0x00000080	/* [I] Atomic inc op */
+#define  RIO_DST_OPS_ATOMIC_DEC		0x00000040	/* [I] Atomic dec op */
+#define  RIO_DST_OPS_ATOMIC_SET		0x00000020	/* [I] Atomic set op */
+#define  RIO_DST_OPS_ATOMIC_CLR		0x00000010	/* [I] Atomic clr op */
+#define  RIO_DST_OPS_PORT_WRITE		0x00000004	/* [I] Port-write op */
+
+#define  RIO_OPS_READ			0x00008000	/* [I] Read op */
+#define  RIO_OPS_WRITE			0x00004000	/* [I] Write op */
+#define  RIO_OPS_STREAM_WRITE		0x00002000	/* [I] Str-write op */
+#define  RIO_OPS_WRITE_RESPONSE		0x00001000	/* [I] Write/resp op */
+#define  RIO_OPS_DATA_MSG		0x00000800	/* [II] Data msg op */
+#define  RIO_OPS_DOORBELL		0x00000400	/* [II] Doorbell op */
+#define  RIO_OPS_ATOMIC_TST_SWP		0x00000100	/* [I] Atomic TAS op */
+#define  RIO_OPS_ATOMIC_INC		0x00000080	/* [I] Atomic inc op */
+#define  RIO_OPS_ATOMIC_DEC		0x00000040	/* [I] Atomic dec op */
+#define  RIO_OPS_ATOMIC_SET		0x00000020	/* [I] Atomic set op */
+#define  RIO_OPS_ATOMIC_CLR		0x00000010	/* [I] Atomic clr op */
+#define  RIO_OPS_PORT_WRITE		0x00000004	/* [I] Port-write op */
+
+					/* 0x20-0x3c *//* Reserved */
+
+#define RIO_MBOX_CSR		0x40	/* [II] Mailbox CSR */
+#define  RIO_MBOX0_AVAIL		0x80000000	/* [II] Mbox 0 avail */
+#define  RIO_MBOX0_FULL			0x40000000	/* [II] Mbox 0 full */
+#define  RIO_MBOX0_EMPTY		0x20000000	/* [II] Mbox 0 empty */
+#define  RIO_MBOX0_BUSY			0x10000000	/* [II] Mbox 0 busy */
+#define  RIO_MBOX0_FAIL			0x08000000	/* [II] Mbox 0 fail */
+#define  RIO_MBOX0_ERROR		0x04000000	/* [II] Mbox 0 error */
+#define  RIO_MBOX1_AVAIL		0x00800000	/* [II] Mbox 1 avail */
+#define  RIO_MBOX1_FULL			0x00200000	/* [II] Mbox 1 full */
+#define  RIO_MBOX1_EMPTY		0x00200000	/* [II] Mbox 1 empty */
+#define  RIO_MBOX1_BUSY			0x00100000	/* [II] Mbox 1 busy */
+#define  RIO_MBOX1_FAIL			0x00080000	/* [II] Mbox 1 fail */
+#define  RIO_MBOX1_ERROR		0x00040000	/* [II] Mbox 1 error */
+#define  RIO_MBOX2_AVAIL		0x00008000	/* [II] Mbox 2 avail */
+#define  RIO_MBOX2_FULL			0x00004000	/* [II] Mbox 2 full */
+#define  RIO_MBOX2_EMPTY		0x00002000	/* [II] Mbox 2 empty */
+#define  RIO_MBOX2_BUSY			0x00001000	/* [II] Mbox 2 busy */
+#define  RIO_MBOX2_FAIL			0x00000800	/* [II] Mbox 2 fail */
+#define  RIO_MBOX2_ERROR		0x00000400	/* [II] Mbox 2 error */
+#define  RIO_MBOX3_AVAIL		0x00000080	/* [II] Mbox 3 avail */
+#define  RIO_MBOX3_FULL			0x00000040	/* [II] Mbox 3 full */
+#define  RIO_MBOX3_EMPTY		0x00000020	/* [II] Mbox 3 empty */
+#define  RIO_MBOX3_BUSY			0x00000010	/* [II] Mbox 3 busy */
+#define  RIO_MBOX3_FAIL			0x00000008	/* [II] Mbox 3 fail */
+#define  RIO_MBOX3_ERROR		0x00000004	/* [II] Mbox 3 error */
+
+#define RIO_WRITE_PORT_CSR	0x44	/* [I] Write Port CSR */
+#define RIO_DOORBELL_CSR	0x44	/* [II] Doorbell CSR */
+#define  RIO_DOORBELL_AVAIL		0x80000000	/* [II] Doorbell avail */
+#define  RIO_DOORBELL_FULL		0x40000000	/* [II] Doorbell full */
+#define  RIO_DOORBELL_EMPTY		0x20000000	/* [II] Doorbell empty */
+#define  RIO_DOORBELL_BUSY		0x10000000	/* [II] Doorbell busy */
+#define  RIO_DOORBELL_FAILED		0x08000000	/* [II] Doorbell failed */
+#define  RIO_DOORBELL_ERROR		0x04000000	/* [II] Doorbell error */
+#define  RIO_WRITE_PORT_AVAILABLE	0x00000080	/* [I] Write Port Available */
+#define  RIO_WRITE_PORT_FULL		0x00000040	/* [I] Write Port Full */
+#define  RIO_WRITE_PORT_EMPTY		0x00000020	/* [I] Write Port Empty */
+#define  RIO_WRITE_PORT_BUSY		0x00000010	/* [I] Write Port Busy */
+#define  RIO_WRITE_PORT_FAILED		0x00000008	/* [I] Write Port Failed */
+#define  RIO_WRITE_PORT_ERROR		0x00000004	/* [I] Write Port Error */
+
+					/* 0x48 *//* Reserved */
+
+#define RIO_PELL_CTRL_CSR	0x4c	/* [I] PE Logical Layer Control CSR */
+#define   RIO_PELL_ADDR_66		0x00000004	/* [I] 66-bit addr */
+#define   RIO_PELL_ADDR_50		0x00000002	/* [I] 50-bit addr */
+#define   RIO_PELL_ADDR_34		0x00000001	/* [I] 34-bit addr */
+
+					/* 0x50-0x54 *//* Reserved */
+
+#define RIO_LCSH_BA		0x58	/* [I] LCS High Base Address */
+#define RIO_LCSL_BA		0x5c	/* [I] LCS Base Address */
+
+#define RIO_DID_CSR		0x60	/* [III] Base Device ID CSR */
+
+					/* 0x64 *//* Reserved */
+
+#define RIO_HOST_DID_LOCK_CSR	0x68	/* [III] Host Base Device ID Lock CSR */
+#define RIO_COMPONENT_TAG_CSR	0x6c	/* [III] Component Tag CSR */
+
+					/* 0x70-0xf8 *//* Reserved */
+					/* 0x100-0xfff8 *//* [I] Extended Features Space */
+					/* 0x10000-0xfffff8 *//* [I] Implementation-defined Space */
+
+/*
+ * Extended Features Space is a configuration space area where
+ * functionality is mapped into extended feature blocks via a
+ * singly linked list of extended feature pointers (EFT_PTR).
+ *
+ * Each extended feature block can be identified/located in
+ * Extended Features Space by walking the extended feature
+ * list starting with the Extended Feature Pointer located
+ * in the Assembly Information CAR.
+ *
+ * Extended Feature Blocks (EFBs) are identified with an assigned
+ * EFB ID. Extended feature block offsets in the definitions are
+ * relative to the offset of the EFB within the  Extended Features
+ * Space.
+ */
+
+/* Helper macros to parse the Extended Feature Block header */
+#define RIO_EFB_PTR_MASK	0xffff0000
+#define RIO_EFB_ID_MASK		0x0000ffff
+#define RIO_GET_BLOCK_PTR(x)	((x & RIO_EFB_PTR_MASK) >> 16)
+#define RIO_GET_BLOCK_ID(x)	(x & RIO_EFB_ID_MASK)
+
+/* Extended Feature Block IDs */
+#define RIO_EFB_PAR_EP_ID	0x0001	/* [IV] LP/LVDS EP Devices */
+#define RIO_EFB_PAR_EP_REC_ID	0x0002	/* [IV] LP/LVDS EP Recovery Devices */
+#define RIO_EFB_PAR_EP_FREE_ID	0x0003	/* [IV] LP/LVDS EP Free Devices */
+#define RIO_EFB_SER_EP_ID	0x0004	/* [VI] LP/Serial EP Devices */
+#define RIO_EFB_SER_EP_REC_ID	0x0005	/* [VI] LP/Serial EP Recovery Devices */
+#define RIO_EFB_SER_EP_FREE_ID	0x0006	/* [VI] LP/Serial EP Free Devices */
+
+/*
+ * Physical 8/16 LP-LVDS
+ * ID=0x0001, Generic End Point Devices
+ * ID=0x0002, Generic End Point Devices, software assisted recovery option
+ * ID=0x0003, Generic End Point Free Devices
+ *
+ * Physical LP-Serial
+ * ID=0x0004, Generic End Point Devices
+ * ID=0x0005, Generic End Point Devices, software assisted recovery option
+ * ID=0x0006, Generic End Point Free Devices
+ */
+#define RIO_PORT_MNT_HEADER		0x0000
+#define RIO_PORT_REQ_CTL_CSR		0x0020
+#define RIO_PORT_RSP_CTL_CSR		0x0024	/* 0x0001/0x0002 */
+#define RIO_PORT_GEN_CTL_CSR		0x003c
+#define  RIO_PORT_GEN_HOST		0x80000000
+#define  RIO_PORT_GEN_MASTER		0x40000000
+#define  RIO_PORT_GEN_DISCOVERED	0x20000000
+#define RIO_PORT_N_MNT_REQ_CSR(x)	(0x0040 + x*0x20)	/* 0x0002 */
+#define RIO_PORT_N_MNT_RSP_CSR(x)	(0x0044 + x*0x20)	/* 0x0002 */
+#define RIO_PORT_N_ACK_STS_CSR(x)	(0x0048 + x*0x20)	/* 0x0002 */
+#define RIO_PORT_N_ERR_STS_CSR(x)	(0x58 + x*0x20)
+#define PORT_N_ERR_STS_PORT_OK	0x00000002
+#define RIO_PORT_N_CTL_CSR(x)		(0x5c + x*0x20)
+
+#endif				/* LINUX_RIO_REGS_H */
diff --git a/include/linux/sem.h b/include/linux/sem.h
index 106f975..3c1f112 100644
--- a/include/linux/sem.h
+++ b/include/linux/sem.h
@@ -79,6 +79,8 @@
 
 #ifdef __KERNEL__
 
+struct task_struct;
+
 /* One semaphore structure for each semaphore in the system. */
 struct sem {
 	int	semval;		/* current value */
diff --git a/include/linux/shm.h b/include/linux/shm.h
index 80113a1..a2c896a 100644
--- a/include/linux/shm.h
+++ b/include/linux/shm.h
@@ -92,6 +92,7 @@
 #define	SHM_DEST	01000	/* segment will be destroyed on last detach */
 #define SHM_LOCKED      02000   /* segment will not be swapped */
 #define SHM_HUGETLB     04000   /* segment will use huge TLB pages */
+#define SHM_NORESERVE   010000  /* don't check for reservations */
 
 #ifdef CONFIG_SYSVIPC
 long do_shmat(int shmid, char __user *shmaddr, int shmflg, unsigned long *addr);
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 4286d83..fdfb8fe 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -603,6 +603,30 @@
  */
 
 /**
+ *	__skb_queue_after - queue a buffer at the list head
+ *	@list: list to use
+ *	@prev: place after this buffer
+ *	@newsk: buffer to queue
+ *
+ *	Queue a buffer int the middle of a list. This function takes no locks
+ *	and you must therefore hold required locks before calling it.
+ *
+ *	A buffer cannot be placed on two lists at the same time.
+ */
+static inline void __skb_queue_after(struct sk_buff_head *list,
+				     struct sk_buff *prev,
+				     struct sk_buff *newsk)
+{
+	struct sk_buff *next;
+	list->qlen++;
+
+	next = prev->next;
+	newsk->next = next;
+	newsk->prev = prev;
+	next->prev  = prev->next = newsk;
+}
+
+/**
  *	__skb_queue_head - queue a buffer at the list head
  *	@list: list to use
  *	@newsk: buffer to queue
@@ -616,14 +640,7 @@
 static inline void __skb_queue_head(struct sk_buff_head *list,
 				    struct sk_buff *newsk)
 {
-	struct sk_buff *prev, *next;
-
-	list->qlen++;
-	prev = (struct sk_buff *)list;
-	next = prev->next;
-	newsk->next = next;
-	newsk->prev = prev;
-	next->prev  = prev->next = newsk;
+	__skb_queue_after(list, (struct sk_buff *)list, newsk);
 }
 
 /**
@@ -1203,6 +1220,11 @@
 		     prefetch(skb->next), (skb != (struct sk_buff *)(queue));	\
 		     skb = skb->next)
 
+#define skb_queue_reverse_walk(queue, skb) \
+		for (skb = (queue)->prev;					\
+		     prefetch(skb->prev), (skb != (struct sk_buff *)(queue));	\
+		     skb = skb->prev)
+
 
 extern struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
 					 int noblock, int *err);
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 09b9aa6..d1ea405 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -9,7 +9,7 @@
 
 #if	defined(__KERNEL__)
 
-typedef struct kmem_cache_s kmem_cache_t;
+typedef struct kmem_cache kmem_cache_t;
 
 #include	<linux/config.h>	/* kmalloc_sizes.h needs CONFIG_ options */
 #include	<linux/gfp.h>
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 5af8800..e4086ec 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -171,7 +171,8 @@
 {
 	char *cp = (char *)p;
 	struct kvec *vec = &rqstp->rq_arg.head[0];
-	return cp - (char*)vec->iov_base <= vec->iov_len;
+	return cp >= (char*)vec->iov_base
+		&& cp <= (char*)vec->iov_base + vec->iov_len;
 }
 
 static inline int
diff --git a/include/linux/superhyway.h b/include/linux/superhyway.h
index c906c5a..17ea468 100644
--- a/include/linux/superhyway.h
+++ b/include/linux/superhyway.h
@@ -19,7 +19,7 @@
  */
 #define SUPERHYWAY_DEVICE_ID_SH5_DMAC	0x0183
 
-struct vcr_info {
+struct superhyway_vcr_info {
 	u8	perr_flags;	/* P-port Error flags */
 	u8	merr_flags;	/* Module Error flags */
 	u16	mod_vers;	/* Module Version */
@@ -28,6 +28,17 @@
 	u8	top_mb;		/* Top Memory block */
 };
 
+struct superhyway_ops {
+	int (*read_vcr)(unsigned long base, struct superhyway_vcr_info *vcr);
+	int (*write_vcr)(unsigned long base, struct superhyway_vcr_info vcr);
+};
+
+struct superhyway_bus {
+	struct superhyway_ops *ops;
+};
+
+extern struct superhyway_bus superhyway_channels[];
+
 struct superhyway_device_id {
 	unsigned int id;
 	unsigned long driver_data;
@@ -55,9 +66,11 @@
 
 	struct superhyway_device_id id;
 	struct superhyway_driver *drv;
+	struct superhyway_bus *bus;
 
-	struct resource resource;
-	struct vcr_info vcr;
+	int num_resources;
+	struct resource *resource;
+	struct superhyway_vcr_info vcr;
 };
 
 #define to_superhyway_device(d)	container_of((d), struct superhyway_device, dev)
@@ -65,12 +78,27 @@
 #define superhyway_get_drvdata(d)	dev_get_drvdata(&(d)->dev)
 #define superhyway_set_drvdata(d,p)	dev_set_drvdata(&(d)->dev, (p))
 
-extern int superhyway_scan_bus(void);
+static inline int
+superhyway_read_vcr(struct superhyway_device *dev, unsigned long base,
+		    struct superhyway_vcr_info *vcr)
+{
+	return dev->bus->ops->read_vcr(base, vcr);
+}
+
+static inline int
+superhyway_write_vcr(struct superhyway_device *dev, unsigned long base,
+		     struct superhyway_vcr_info vcr)
+{
+	return dev->bus->ops->write_vcr(base, vcr);
+}
+
+extern int superhyway_scan_bus(struct superhyway_bus *);
 
 /* drivers/sh/superhyway/superhyway.c */
 int superhyway_register_driver(struct superhyway_driver *);
 void superhyway_unregister_driver(struct superhyway_driver *);
-int superhyway_add_device(unsigned int, unsigned long, unsigned long long);
+int superhyway_add_device(unsigned long base, struct superhyway_device *, struct superhyway_bus *);
+int superhyway_add_devices(struct superhyway_bus *bus, struct superhyway_device **devices, int nr_devices);
 
 /* drivers/sh/superhyway/superhyway-sysfs.c */
 extern struct device_attribute superhyway_dev_attrs[];
diff --git a/include/linux/wait.h b/include/linux/wait.h
index d38c9fe..d285182 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -54,6 +54,7 @@
 };
 typedef struct __wait_queue_head wait_queue_head_t;
 
+struct task_struct;
 
 /*
  * Macros for declaration and initialisaton of the datatypes
diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h
index f87845e..b0c47e2 100644
--- a/include/net/inet_ecn.h
+++ b/include/net/inet_ecn.h
@@ -2,6 +2,7 @@
 #define _INET_ECN_H_
 
 #include <linux/ip.h>
+#include <linux/skbuff.h>
 #include <net/dsfield.h>
 
 enum {
@@ -48,7 +49,7 @@
 		(label) |= __constant_htons(INET_ECN_ECT_0 << 4);	\
     } while (0)
 
-static inline void IP_ECN_set_ce(struct iphdr *iph)
+static inline int IP_ECN_set_ce(struct iphdr *iph)
 {
 	u32 check = iph->check;
 	u32 ecn = (iph->tos + 1) & INET_ECN_MASK;
@@ -61,7 +62,7 @@
 	 * INET_ECN_CE      => 00
 	 */
 	if (!(ecn & 2))
-		return;
+		return !ecn;
 
 	/*
 	 * The following gives us:
@@ -72,6 +73,7 @@
 
 	iph->check = check + (check>=0xFFFF);
 	iph->tos |= INET_ECN_CE;
+	return 1;
 }
 
 static inline void IP_ECN_clear(struct iphdr *iph)
@@ -87,11 +89,12 @@
 
 struct ipv6hdr;
 
-static inline void IP6_ECN_set_ce(struct ipv6hdr *iph)
+static inline int IP6_ECN_set_ce(struct ipv6hdr *iph)
 {
 	if (INET_ECN_is_not_ect(ipv6_get_dsfield(iph)))
-		return;
+		return 0;
 	*(u32*)iph |= htonl(INET_ECN_CE << 20);
+	return 1;
 }
 
 static inline void IP6_ECN_clear(struct ipv6hdr *iph)
@@ -105,4 +108,21 @@
 	ipv6_change_dsfield(inner, INET_ECN_MASK, dscp);
 }
 
+static inline int INET_ECN_set_ce(struct sk_buff *skb)
+{
+	switch (skb->protocol) {
+	case __constant_htons(ETH_P_IP):
+		if (skb->nh.raw + sizeof(struct iphdr) <= skb->tail)
+			return IP_ECN_set_ce(skb->nh.iph);
+		break;
+
+	case __constant_htons(ETH_P_IPV6):
+		if (skb->nh.raw + sizeof(struct ipv6hdr) <= skb->tail)
+			return IP6_ECN_set_ce(skb->nh.ipv6h);
+		break;
+	}
+
+	return 0;
+}
+
 #endif
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index f50f959..07840ba 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -125,9 +125,7 @@
 	rwlock_t			lhash_lock ____cacheline_aligned;
 	atomic_t			lhash_users;
 	wait_queue_head_t		lhash_wait;
-	spinlock_t			portalloc_lock;
 	kmem_cache_t			*bind_bucket_cachep;
-	int				port_rover;
 };
 
 static inline unsigned int inet_ehashfn(const __u32 laddr, const __u16 lport,
diff --git a/include/net/red.h b/include/net/red.h
new file mode 100644
index 0000000..2ed4358
--- /dev/null
+++ b/include/net/red.h
@@ -0,0 +1,325 @@
+#ifndef __NET_SCHED_RED_H
+#define __NET_SCHED_RED_H
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <net/pkt_sched.h>
+#include <net/inet_ecn.h>
+#include <net/dsfield.h>
+
+/*	Random Early Detection (RED) algorithm.
+	=======================================
+
+	Source: Sally Floyd and Van Jacobson, "Random Early Detection Gateways
+	for Congestion Avoidance", 1993, IEEE/ACM Transactions on Networking.
+
+	This file codes a "divisionless" version of RED algorithm
+	as written down in Fig.17 of the paper.
+
+	Short description.
+	------------------
+
+	When a new packet arrives we calculate the average queue length:
+
+	avg = (1-W)*avg + W*current_queue_len,
+
+	W is the filter time constant (chosen as 2^(-Wlog)), it controls
+	the inertia of the algorithm. To allow larger bursts, W should be
+	decreased.
+
+	if (avg > th_max) -> packet marked (dropped).
+	if (avg < th_min) -> packet passes.
+	if (th_min < avg < th_max) we calculate probability:
+
+	Pb = max_P * (avg - th_min)/(th_max-th_min)
+
+	and mark (drop) packet with this probability.
+	Pb changes from 0 (at avg==th_min) to max_P (avg==th_max).
+	max_P should be small (not 1), usually 0.01..0.02 is good value.
+
+	max_P is chosen as a number, so that max_P/(th_max-th_min)
+	is a negative power of two in order arithmetics to contain
+	only shifts.
+
+
+	Parameters, settable by user:
+	-----------------------------
+
+	qth_min		- bytes (should be < qth_max/2)
+	qth_max		- bytes (should be at least 2*qth_min and less limit)
+	Wlog	       	- bits (<32) log(1/W).
+	Plog	       	- bits (<32)
+
+	Plog is related to max_P by formula:
+
+	max_P = (qth_max-qth_min)/2^Plog;
+
+	F.e. if qth_max=128K and qth_min=32K, then Plog=22
+	corresponds to max_P=0.02
+
+	Scell_log
+	Stab
+
+	Lookup table for log((1-W)^(t/t_ave).
+
+
+	NOTES:
+
+	Upper bound on W.
+	-----------------
+
+	If you want to allow bursts of L packets of size S,
+	you should choose W:
+
+	L + 1 - th_min/S < (1-(1-W)^L)/W
+
+	th_min/S = 32         th_min/S = 4
+
+	log(W)	L
+	-1	33
+	-2	35
+	-3	39
+	-4	46
+	-5	57
+	-6	75
+	-7	101
+	-8	135
+	-9	190
+	etc.
+ */
+
+#define RED_STAB_SIZE	256
+#define RED_STAB_MASK	(RED_STAB_SIZE - 1)
+
+struct red_stats
+{
+	u32		prob_drop;	/* Early probability drops */
+	u32		prob_mark;	/* Early probability marks */
+	u32		forced_drop;	/* Forced drops, qavg > max_thresh */
+	u32		forced_mark;	/* Forced marks, qavg > max_thresh */
+	u32		pdrop;          /* Drops due to queue limits */
+	u32		other;          /* Drops due to drop() calls */
+	u32		backlog;
+};
+
+struct red_parms
+{
+	/* Parameters */
+	u32		qth_min;	/* Min avg length threshold: A scaled */
+	u32		qth_max;	/* Max avg length threshold: A scaled */
+	u32		Scell_max;
+	u32		Rmask;		/* Cached random mask, see red_rmask */
+	u8		Scell_log;
+	u8		Wlog;		/* log(W)		*/
+	u8		Plog;		/* random number bits	*/
+	u8		Stab[RED_STAB_SIZE];
+
+	/* Variables */
+	int		qcount;		/* Number of packets since last random
+					   number generation */
+	u32		qR;		/* Cached random number */
+
+	unsigned long	qavg;		/* Average queue length: A scaled */
+	psched_time_t	qidlestart;	/* Start of current idle period */
+};
+
+static inline u32 red_rmask(u8 Plog)
+{
+	return Plog < 32 ? ((1 << Plog) - 1) : ~0UL;
+}
+
+static inline void red_set_parms(struct red_parms *p,
+				 u32 qth_min, u32 qth_max, u8 Wlog, u8 Plog,
+				 u8 Scell_log, u8 *stab)
+{
+	/* Reset average queue length, the value is strictly bound
+	 * to the parameters below, reseting hurts a bit but leaving
+	 * it might result in an unreasonable qavg for a while. --TGR
+	 */
+	p->qavg		= 0;
+
+	p->qcount	= -1;
+	p->qth_min	= qth_min << Wlog;
+	p->qth_max	= qth_max << Wlog;
+	p->Wlog		= Wlog;
+	p->Plog		= Plog;
+	p->Rmask	= red_rmask(Plog);
+	p->Scell_log	= Scell_log;
+	p->Scell_max	= (255 << Scell_log);
+
+	memcpy(p->Stab, stab, sizeof(p->Stab));
+}
+
+static inline int red_is_idling(struct red_parms *p)
+{
+	return !PSCHED_IS_PASTPERFECT(p->qidlestart);
+}
+
+static inline void red_start_of_idle_period(struct red_parms *p)
+{
+	PSCHED_GET_TIME(p->qidlestart);
+}
+
+static inline void red_end_of_idle_period(struct red_parms *p)
+{
+	PSCHED_SET_PASTPERFECT(p->qidlestart);
+}
+
+static inline void red_restart(struct red_parms *p)
+{
+	red_end_of_idle_period(p);
+	p->qavg = 0;
+	p->qcount = -1;
+}
+
+static inline unsigned long red_calc_qavg_from_idle_time(struct red_parms *p)
+{
+	psched_time_t now;
+	long us_idle;
+	int  shift;
+
+	PSCHED_GET_TIME(now);
+	us_idle = PSCHED_TDIFF_SAFE(now, p->qidlestart, p->Scell_max);
+
+	/*
+	 * The problem: ideally, average length queue recalcultion should
+	 * be done over constant clock intervals. This is too expensive, so
+	 * that the calculation is driven by outgoing packets.
+	 * When the queue is idle we have to model this clock by hand.
+	 *
+	 * SF+VJ proposed to "generate":
+	 *
+	 *	m = idletime / (average_pkt_size / bandwidth)
+	 *
+	 * dummy packets as a burst after idle time, i.e.
+	 *
+	 * 	p->qavg *= (1-W)^m
+	 *
+	 * This is an apparently overcomplicated solution (f.e. we have to
+	 * precompute a table to make this calculation in reasonable time)
+	 * I believe that a simpler model may be used here,
+	 * but it is field for experiments.
+	 */
+
+	shift = p->Stab[(us_idle >> p->Scell_log) & RED_STAB_MASK];
+
+	if (shift)
+		return p->qavg >> shift;
+	else {
+		/* Approximate initial part of exponent with linear function:
+		 *
+		 * 	(1-W)^m ~= 1-mW + ...
+		 *
+		 * Seems, it is the best solution to
+		 * problem of too coarse exponent tabulation.
+		 */
+		us_idle = (p->qavg * us_idle) >> p->Scell_log;
+
+		if (us_idle < (p->qavg >> 1))
+			return p->qavg - us_idle;
+		else
+			return p->qavg >> 1;
+	}
+}
+
+static inline unsigned long red_calc_qavg_no_idle_time(struct red_parms *p,
+						       unsigned int backlog)
+{
+	/*
+	 * NOTE: p->qavg is fixed point number with point at Wlog.
+	 * The formula below is equvalent to floating point
+	 * version:
+	 *
+	 * 	qavg = qavg*(1-W) + backlog*W;
+	 *
+	 * --ANK (980924)
+	 */
+	return p->qavg + (backlog - (p->qavg >> p->Wlog));
+}
+
+static inline unsigned long red_calc_qavg(struct red_parms *p,
+					  unsigned int backlog)
+{
+	if (!red_is_idling(p))
+		return red_calc_qavg_no_idle_time(p, backlog);
+	else
+		return red_calc_qavg_from_idle_time(p);
+}
+
+static inline u32 red_random(struct red_parms *p)
+{
+	return net_random() & p->Rmask;
+}
+
+static inline int red_mark_probability(struct red_parms *p, unsigned long qavg)
+{
+	/* The formula used below causes questions.
+
+	   OK. qR is random number in the interval 0..Rmask
+	   i.e. 0..(2^Plog). If we used floating point
+	   arithmetics, it would be: (2^Plog)*rnd_num,
+	   where rnd_num is less 1.
+
+	   Taking into account, that qavg have fixed
+	   point at Wlog, and Plog is related to max_P by
+	   max_P = (qth_max-qth_min)/2^Plog; two lines
+	   below have the following floating point equivalent:
+
+	   max_P*(qavg - qth_min)/(qth_max-qth_min) < rnd/qcount
+
+	   Any questions? --ANK (980924)
+	 */
+	return !(((qavg - p->qth_min) >> p->Wlog) * p->qcount < p->qR);
+}
+
+enum {
+	RED_BELOW_MIN_THRESH,
+	RED_BETWEEN_TRESH,
+	RED_ABOVE_MAX_TRESH,
+};
+
+static inline int red_cmp_thresh(struct red_parms *p, unsigned long qavg)
+{
+	if (qavg < p->qth_min)
+		return RED_BELOW_MIN_THRESH;
+	else if (qavg >= p->qth_max)
+		return RED_ABOVE_MAX_TRESH;
+	else
+		return RED_BETWEEN_TRESH;
+}
+
+enum {
+	RED_DONT_MARK,
+	RED_PROB_MARK,
+	RED_HARD_MARK,
+};
+
+static inline int red_action(struct red_parms *p, unsigned long qavg)
+{
+	switch (red_cmp_thresh(p, qavg)) {
+		case RED_BELOW_MIN_THRESH:
+			p->qcount = -1;
+			return RED_DONT_MARK;
+
+		case RED_BETWEEN_TRESH:
+			if (++p->qcount) {
+				if (red_mark_probability(p, qavg)) {
+					p->qcount = 0;
+					p->qR = red_random(p);
+					return RED_PROB_MARK;
+				}
+			} else
+				p->qR = red_random(p);
+
+			return RED_DONT_MARK;
+
+		case RED_ABOVE_MAX_TRESH:
+			p->qcount = -1;
+			return RED_HARD_MARK;
+	}
+
+	BUG();
+	return RED_DONT_MARK;
+}
+
+#endif
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index d11f348..7f0ca79 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -387,15 +387,6 @@
 #define AC97_RATES_MIC_ADC	4
 #define AC97_RATES_SPDIF	5
 
-/* shared controllers */
-enum {
-	AC97_SHARED_TYPE_NONE,
-	AC97_SHARED_TYPE_ICH,
-	AC97_SHARED_TYPE_ATIIXP,
-	AC97_SHARED_TYPE_VIA,
-	AC97_SHARED_TYPES
-};
-
 /*
  *
  */
@@ -468,7 +459,6 @@
 	unsigned short used_slots[2][4]; /* actually used PCM slots */
 	unsigned short pcms_count; /* count of PCMs */
 	struct ac97_pcm *pcms;
-	unsigned int shared_type;	/* type of shared controller betwen audio and modem */
 	ac97_t *codec[4];
 	snd_info_entry_t *proc;
 };
diff --git a/include/sound/core.h b/include/sound/core.h
index 6d971a4..2be65ad 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -29,7 +29,6 @@
 #include <linux/pm.h>			/* pm_message_t */
 
 /* Typedef's */
-typedef struct timespec snd_timestamp_t;
 typedef struct sndrv_interval snd_interval_t;
 typedef enum sndrv_card_type snd_card_type;
 typedef struct sndrv_xferi snd_xferi_t;
@@ -256,6 +255,7 @@
 
 /* sound.c */
 
+extern int snd_major;
 extern int snd_ecards_limit;
 
 void snd_request_card(int card);
@@ -285,39 +285,6 @@
 
 /* memory.c */
 
-#ifdef CONFIG_SND_DEBUG_MEMORY
-void snd_memory_init(void);
-void snd_memory_done(void);
-int snd_memory_info_init(void);
-int snd_memory_info_done(void);
-void *snd_hidden_kmalloc(size_t size, gfp_t flags);
-void *snd_hidden_kzalloc(size_t size, gfp_t flags);
-void *snd_hidden_kcalloc(size_t n, size_t size, gfp_t flags);
-void snd_hidden_kfree(const void *obj);
-void *snd_hidden_vmalloc(unsigned long size);
-void snd_hidden_vfree(void *obj);
-char *snd_hidden_kstrdup(const char *s, gfp_t flags);
-#define kmalloc(size, flags) snd_hidden_kmalloc(size, flags)
-#define kzalloc(size, flags) snd_hidden_kzalloc(size, flags)
-#define kcalloc(n, size, flags) snd_hidden_kcalloc(n, size, flags)
-#define kfree(obj) snd_hidden_kfree(obj)
-#define vmalloc(size) snd_hidden_vmalloc(size)
-#define vfree(obj) snd_hidden_vfree(obj)
-#define kmalloc_nocheck(size, flags) snd_wrapper_kmalloc(size, flags)
-#define vmalloc_nocheck(size) snd_wrapper_vmalloc(size)
-#define kfree_nocheck(obj) snd_wrapper_kfree(obj)
-#define vfree_nocheck(obj) snd_wrapper_vfree(obj)
-#define kstrdup(s, flags)  snd_hidden_kstrdup(s, flags)
-#else
-#define snd_memory_init() /*NOP*/
-#define snd_memory_done() /*NOP*/
-#define snd_memory_info_init() /*NOP*/
-#define snd_memory_info_done() /*NOP*/
-#define kmalloc_nocheck(size, flags) kmalloc(size, flags)
-#define vmalloc_nocheck(size) vmalloc(size)
-#define kfree_nocheck(obj) kfree(obj)
-#define vfree_nocheck(obj) vfree(obj)
-#endif
 int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count);
 int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count);
 
@@ -373,8 +340,9 @@
 #endif
 
 /* misc.c */
+struct resource;
+void release_and_free_resource(struct resource *res);
 
-int snd_task_name(struct task_struct *task, char *name, size_t size);
 #ifdef CONFIG_SND_VERBOSE_PRINTK
 void snd_verbose_printk(const char *file, int line, const char *format, ...)
      __attribute__ ((format (printf, 3, 4)));
@@ -429,34 +397,24 @@
  * When CONFIG_SND_DEBUG is not set, the expression is executed but
  * not checked.
  */
-#define snd_assert(expr, args...) do {\
-	if (unlikely(!(expr))) {				\
-		snd_printk(KERN_ERR "BUG? (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\
-		args;\
-	}\
+#define snd_assert(expr, args...) do {					\
+	if (unlikely(!(expr))) {					\
+		snd_printk(KERN_ERR "BUG? (%s)\n", __ASTRING__(expr));	\
+		dump_stack();						\
+		args;							\
+	}								\
 } while (0)
-/**
- * snd_runtime_check - run-time assertion macro
- * @expr: expression
- * @args...: the action
- *
- * This macro checks the expression in run-time and invokes the commands
- * given in the rest arguments if the assertion is failed.
- * Unlike snd_assert(), the action commands are executed even if
- * CONFIG_SND_DEBUG is not set but without any error messages.
- */
-#define snd_runtime_check(expr, args...) do {\
-	if (unlikely(!(expr))) {				\
-		snd_printk(KERN_ERR "ERROR (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\
-		args;\
-	}\
+
+#define snd_BUG() do {				\
+	snd_printk(KERN_ERR "BUG?\n");		\
+	dump_stack();				\
 } while (0)
 
 #else /* !CONFIG_SND_DEBUG */
 
 #define snd_printd(fmt, args...)	/* nothing */
 #define snd_assert(expr, args...)	(void)(expr)
-#define snd_runtime_check(expr, args...) do { if (!(expr)) { args; } } while (0)
+#define snd_BUG()			/* nothing */
 
 #endif /* CONFIG_SND_DEBUG */
 
@@ -473,30 +431,6 @@
 #define snd_printdd(format, args...) /* nothing */
 #endif
 
-#define snd_BUG() snd_assert(0, )
-
-
-static inline void snd_timestamp_now(struct timespec *tstamp, int timespec)
-{
-	struct timeval val;
-	/* FIXME: use a linear time source */
-	do_gettimeofday(&val);
-	tstamp->tv_sec = val.tv_sec;
-	tstamp->tv_nsec = val.tv_usec;
-	if (timespec)
-		tstamp->tv_nsec *= 1000L;
-}
-
-static inline void snd_timestamp_zero(struct timespec *tstamp)
-{
-	tstamp->tv_sec = 0;
-	tstamp->tv_nsec = 0;
-}
-
-static inline int snd_timestamp_null(struct timespec *tstamp)
-{
-	return tstamp->tv_sec == 0 && tstamp->tv_nsec == 0;
-}
 
 #define SNDRV_OSS_VERSION         ((3<<16)|(8<<8)|(1<<4)|(0))	/* 3.8.1a */
 
diff --git a/include/sound/driver.h b/include/sound/driver.h
index 1ec2fae..3f0416a 100644
--- a/include/sound/driver.h
+++ b/include/sound/driver.h
@@ -44,21 +44,4 @@
 
 #include <linux/module.h>
 
-/*
- *  ==========================================================================
- */
-
-#ifdef CONFIG_SND_DEBUG_MEMORY
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-void *snd_wrapper_kmalloc(size_t, gfp_t);
-#undef kmalloc
-void snd_wrapper_kfree(const void *);
-#undef kfree
-void *snd_wrapper_vmalloc(size_t);
-#undef vmalloc
-void snd_wrapper_vfree(void *);
-#undef vfree
-#endif
-
 #endif /* __SOUND_DRIVER_H */
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 46e3c0b..8411c7e 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -48,7 +48,8 @@
 
 /* FIXME? - according to the OSS driver the EMU10K1 needs a 29 bit DMA mask */
 #define EMU10K1_DMA_MASK	0x7fffffffUL	/* 31bit */
-#define AUDIGY_DMA_MASK		0xffffffffUL	/* 32bit */
+#define AUDIGY_DMA_MASK		0x7fffffffUL	/* 31bit FIXME - 32 should work? */
+						/* See ALSA bug #1276 - rlrevell */
 
 #define TMEMSIZE        256*1024
 #define TMEMSIZEREG     4
diff --git a/include/sound/minors.h b/include/sound/minors.h
index b7b0d83..a17b5c9 100644
--- a/include/sound/minors.h
+++ b/include/sound/minors.h
@@ -27,8 +27,9 @@
 #define SNDRV_MINOR(card, dev)		(((card) << 5) | (dev))
 
 #define SNDRV_MINOR_CONTROL		0	/* 0 - 0 */
-#define SNDRV_MINOR_SEQUENCER		1
-#define SNDRV_MINOR_TIMER		(1+32)
+#define SNDRV_MINOR_GLOBAL		1	/* 1 */
+#define SNDRV_MINOR_SEQUENCER		(SNDRV_MINOR_GLOBAL + 0 * 32)
+#define SNDRV_MINOR_TIMER		(SNDRV_MINOR_GLOBAL + 1 * 32)
 #define SNDRV_MINOR_HWDEP		4	/* 4 - 7 */
 #define SNDRV_MINOR_HWDEPS		4
 #define SNDRV_MINOR_RAWMIDI		8	/* 8 - 15 */
@@ -39,12 +40,9 @@
 
 #define SNDRV_DEVICE_TYPE_CONTROL	SNDRV_MINOR_CONTROL
 #define SNDRV_DEVICE_TYPE_HWDEP		SNDRV_MINOR_HWDEP
-#define SNDRV_DEVICE_TYPE_MIXER		SNDRV_MINOR_MIXER
 #define SNDRV_DEVICE_TYPE_RAWMIDI	SNDRV_MINOR_RAWMIDI
 #define SNDRV_DEVICE_TYPE_PCM_PLAYBACK	SNDRV_MINOR_PCM_PLAYBACK
-#define SNDRV_DEVICE_TYPE_PCM_PLOOP	SNDRV_MINOR_PCM_PLOOP
 #define SNDRV_DEVICE_TYPE_PCM_CAPTURE	SNDRV_MINOR_PCM_CAPTURE
-#define SNDRV_DEVICE_TYPE_PCM_CLOOP	SNDRV_MINOR_PCM_CLOOP
 #define SNDRV_DEVICE_TYPE_SEQUENCER	SNDRV_MINOR_SEQUENCER
 #define SNDRV_DEVICE_TYPE_TIMER		SNDRV_MINOR_TIMER
 
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 2b23a59..acc4fa9 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -281,7 +281,7 @@
 struct _snd_pcm_runtime {
 	/* -- Status -- */
 	snd_pcm_substream_t *trigger_master;
-	snd_timestamp_t trigger_tstamp;	/* trigger timestamp */
+	struct timespec trigger_tstamp;	/* trigger timestamp */
 	int overrange;
 	snd_pcm_uframes_t avail_max;
 	snd_pcm_uframes_t hw_ptr_base;	/* Position at buffer restart */
@@ -306,7 +306,6 @@
 	unsigned int rate_den;
 
 	/* -- SW params -- */
-	int tstamp_timespec;		/* use timeval (0) or timespec (1) */
 	snd_pcm_tstamp_t tstamp_mode;	/* mmap timestamp is updated */
   	unsigned int period_step;
 	unsigned int sleep_min;		/* min ticks to sleep */
diff --git a/include/sound/timer.h b/include/sound/timer.h
index 1898511..b55f38a 100644
--- a/include/sound/timer.h
+++ b/include/sound/timer.h
@@ -88,6 +88,7 @@
 struct _snd_timer {
 	snd_timer_class_t tmr_class;
 	snd_card_t *card;
+	struct module *module;
 	int tmr_device;
 	int tmr_subdevice;
 	char id[64];
diff --git a/include/sound/version.h b/include/sound/version.h
index ee32af2..d1bd3b7 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
 /* include/version.h.  Generated by configure.  */
-#define CONFIG_SND_VERSION "1.0.10rc1"
-#define CONFIG_SND_DATE " (Mon Sep 12 08:13:09 2005 UTC)"
+#define CONFIG_SND_VERSION "1.0.10rc3"
+#define CONFIG_SND_DATE " (Mon Nov 07 13:30:21 2005 UTC)"
diff --git a/init/Kconfig b/init/Kconfig
index 3dcbd5b..ea097e0 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -501,3 +501,7 @@
 	help
 	  Need stop_machine() primitive.
 endmenu
+
+menu "Block layer"
+source "block/Kconfig"
+endmenu
diff --git a/ipc/shm.c b/ipc/shm.c
index b58c651..587d836 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -212,8 +212,16 @@
 		file = hugetlb_zero_setup(size);
 		shp->mlock_user = current->user;
 	} else {
+		int acctflag = VM_ACCOUNT;
+		/*
+		 * Do not allow no accounting for OVERCOMMIT_NEVER, even
+	 	 * if it's asked for.
+		 */
+		if  ((shmflg & SHM_NORESERVE) &&
+				sysctl_overcommit_memory != OVERCOMMIT_NEVER)
+			acctflag = 0;
 		sprintf (name, "SYSV%08x", key);
-		file = shmem_file_setup(name, size, VM_ACCOUNT);
+		file = shmem_file_setup(name, size, acctflag);
 	}
 	error = PTR_ERR(file);
 	if (IS_ERR(file))
diff --git a/ipc/util.c b/ipc/util.c
index 10e836d..23f1cec 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -410,7 +410,8 @@
 }
 
 /**
- *	ipc_schedule_free	- free ipc + rcu space
+ * ipc_schedule_free - free ipc + rcu space
+ * @head: RCU callback structure for queued work
  * 
  * Since RCU callback function is called in bh,
  * we need to defer the vfree to schedule_work
@@ -427,10 +428,10 @@
 }
 
 /**
- *	ipc_immediate_free	- free ipc + rcu space
+ * ipc_immediate_free - free ipc + rcu space
+ * @head: RCU callback structure that contains pointer to be freed
  *
- *	Free from the RCU callback context
- *
+ * Free from the RCU callback context
  */
 static void ipc_immediate_free(struct rcu_head *head)
 {
diff --git a/kernel/exit.c b/kernel/exit.c
index 537394b..452a1d1 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -28,6 +28,7 @@
 #include <linux/cpuset.h>
 #include <linux/syscalls.h>
 #include <linux/signal.h>
+#include <linux/cn_proc.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -863,6 +864,7 @@
 		module_put(tsk->binfmt->module);
 
 	tsk->exit_code = code;
+	proc_exit_connector(tsk);
 	exit_notify(tsk);
 #ifdef CONFIG_NUMA
 	mpol_free(tsk->mempolicy);
diff --git a/kernel/fork.c b/kernel/fork.c
index 8a06961..efac2c5 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -42,6 +42,7 @@
 #include <linux/profile.h>
 #include <linux/rmap.h>
 #include <linux/acct.h>
+#include <linux/cn_proc.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -1143,6 +1144,7 @@
 			__get_cpu_var(process_counts)++;
 	}
 
+	proc_fork_connector(p);
 	if (!current->signal->tty && p->signal->tty)
 		p->signal->tty = NULL;
 
diff --git a/kernel/futex.c b/kernel/futex.c
index 3b4d5ad..aca8d10 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -365,6 +365,11 @@
 		if (bh1 != bh2)
 			spin_unlock(&bh2->lock);
 
+		if (unlikely(op_ret != -EFAULT)) {
+			ret = op_ret;
+			goto out;
+		}
+
 		/* futex_atomic_op_inuser needs to both read and write
 		 * *(int __user *)uaddr2, but we can't modify it
 		 * non-atomically.  Therefore, if get_user below is not
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 1cfdb08..3bd7226 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -24,6 +24,7 @@
 
 /**
  *	synchronize_irq - wait for pending IRQ handlers (on other CPUs)
+ *	@irq: interrupt number to wait for
  *
  *	This function waits for any pending IRQ handlers for this interrupt
  *	to complete before returning. If you use this function while
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index ce4915d..5beda37 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -32,7 +32,6 @@
  *		<prasanna@in.ibm.com> added function-return probes.
  */
 #include <linux/kprobes.h>
-#include <linux/spinlock.h>
 #include <linux/hash.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -49,9 +48,9 @@
 static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
 static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
 
-unsigned int kprobe_cpu = NR_CPUS;
-static DEFINE_SPINLOCK(kprobe_lock);
-static struct kprobe *curr_kprobe;
+static DEFINE_SPINLOCK(kprobe_lock);	/* Protects kprobe_table */
+DEFINE_SPINLOCK(kretprobe_lock);	/* Protects kretprobe_inst_table */
+static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL;
 
 /*
  * kprobe->ainsn.insn points to the copy of the instruction to be
@@ -153,50 +152,31 @@
 	}
 }
 
-/* Locks kprobe: irqs must be disabled */
-void __kprobes lock_kprobes(void)
+/* We have preemption disabled.. so it is safe to use __ versions */
+static inline void set_kprobe_instance(struct kprobe *kp)
 {
-	unsigned long flags = 0;
-
-	/* Avoiding local interrupts to happen right after we take the kprobe_lock
-	 * and before we get a chance to update kprobe_cpu, this to prevent
-	 * deadlock when we have a kprobe on ISR routine and a kprobe on task
-	 * routine
-	 */
-	local_irq_save(flags);
-
-	spin_lock(&kprobe_lock);
-	kprobe_cpu = smp_processor_id();
-
- 	local_irq_restore(flags);
+	__get_cpu_var(kprobe_instance) = kp;
 }
 
-void __kprobes unlock_kprobes(void)
+static inline void reset_kprobe_instance(void)
 {
-	unsigned long flags = 0;
-
-	/* Avoiding local interrupts to happen right after we update
-	 * kprobe_cpu and before we get a a chance to release kprobe_lock,
-	 * this to prevent deadlock when we have a kprobe on ISR routine and
-	 * a kprobe on task routine
-	 */
-	local_irq_save(flags);
-
-	kprobe_cpu = NR_CPUS;
-	spin_unlock(&kprobe_lock);
-
- 	local_irq_restore(flags);
+	__get_cpu_var(kprobe_instance) = NULL;
 }
 
-/* You have to be holding the kprobe_lock */
+/*
+ * This routine is called either:
+ * 	- under the kprobe_lock spinlock - during kprobe_[un]register()
+ * 				OR
+ * 	- with preemption disabled - from arch/xxx/kernel/kprobes.c
+ */
 struct kprobe __kprobes *get_kprobe(void *addr)
 {
 	struct hlist_head *head;
 	struct hlist_node *node;
+	struct kprobe *p;
 
 	head = &kprobe_table[hash_ptr(addr, KPROBE_HASH_BITS)];
-	hlist_for_each(node, head) {
-		struct kprobe *p = hlist_entry(node, struct kprobe, hlist);
+	hlist_for_each_entry_rcu(p, node, head, hlist) {
 		if (p->addr == addr)
 			return p;
 	}
@@ -211,13 +191,13 @@
 {
 	struct kprobe *kp;
 
-	list_for_each_entry(kp, &p->list, list) {
+	list_for_each_entry_rcu(kp, &p->list, list) {
 		if (kp->pre_handler) {
-			curr_kprobe = kp;
+			set_kprobe_instance(kp);
 			if (kp->pre_handler(kp, regs))
 				return 1;
 		}
-		curr_kprobe = NULL;
+		reset_kprobe_instance();
 	}
 	return 0;
 }
@@ -227,11 +207,11 @@
 {
 	struct kprobe *kp;
 
-	list_for_each_entry(kp, &p->list, list) {
+	list_for_each_entry_rcu(kp, &p->list, list) {
 		if (kp->post_handler) {
-			curr_kprobe = kp;
+			set_kprobe_instance(kp);
 			kp->post_handler(kp, regs, flags);
-			curr_kprobe = NULL;
+			reset_kprobe_instance();
 		}
 	}
 	return;
@@ -240,12 +220,14 @@
 static int __kprobes aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
 					int trapnr)
 {
+	struct kprobe *cur = __get_cpu_var(kprobe_instance);
+
 	/*
 	 * if we faulted "during" the execution of a user specified
 	 * probe handler, invoke just that probe's fault handler
 	 */
-	if (curr_kprobe && curr_kprobe->fault_handler) {
-		if (curr_kprobe->fault_handler(curr_kprobe, regs, trapnr))
+	if (cur && cur->fault_handler) {
+		if (cur->fault_handler(cur, regs, trapnr))
 			return 1;
 	}
 	return 0;
@@ -253,17 +235,18 @@
 
 static int __kprobes aggr_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
-	struct kprobe *kp = curr_kprobe;
-	if (curr_kprobe && kp->break_handler) {
-		if (kp->break_handler(kp, regs)) {
-			curr_kprobe = NULL;
-			return 1;
-		}
+	struct kprobe *cur = __get_cpu_var(kprobe_instance);
+	int ret = 0;
+
+	if (cur && cur->break_handler) {
+		if (cur->break_handler(cur, regs))
+			ret = 1;
 	}
-	curr_kprobe = NULL;
-	return 0;
+	reset_kprobe_instance();
+	return ret;
 }
 
+/* Called with kretprobe_lock held */
 struct kretprobe_instance __kprobes *get_free_rp_inst(struct kretprobe *rp)
 {
 	struct hlist_node *node;
@@ -273,6 +256,7 @@
 	return NULL;
 }
 
+/* Called with kretprobe_lock held */
 static struct kretprobe_instance __kprobes *get_used_rp_inst(struct kretprobe
 							      *rp)
 {
@@ -283,6 +267,7 @@
 	return NULL;
 }
 
+/* Called with kretprobe_lock held */
 void __kprobes add_rp_inst(struct kretprobe_instance *ri)
 {
 	/*
@@ -301,6 +286,7 @@
 	hlist_add_head(&ri->uflist, &ri->rp->used_instances);
 }
 
+/* Called with kretprobe_lock held */
 void __kprobes recycle_rp_inst(struct kretprobe_instance *ri)
 {
 	/* remove rp inst off the rprobe_inst_table */
@@ -334,13 +320,13 @@
 	struct hlist_node *node, *tmp;
 	unsigned long flags = 0;
 
-	spin_lock_irqsave(&kprobe_lock, flags);
+	spin_lock_irqsave(&kretprobe_lock, flags);
         head = kretprobe_inst_table_head(current);
         hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
                 if (ri->task == tk)
                         recycle_rp_inst(ri);
         }
-	spin_unlock_irqrestore(&kprobe_lock, flags);
+	spin_unlock_irqrestore(&kretprobe_lock, flags);
 }
 
 /*
@@ -351,9 +337,12 @@
 					   struct pt_regs *regs)
 {
 	struct kretprobe *rp = container_of(p, struct kretprobe, kp);
+	unsigned long flags = 0;
 
 	/*TODO: consider to only swap the RA after the last pre_handler fired */
+	spin_lock_irqsave(&kretprobe_lock, flags);
 	arch_prepare_kretprobe(rp, regs);
+	spin_unlock_irqrestore(&kretprobe_lock, flags);
 	return 0;
 }
 
@@ -384,13 +373,13 @@
         struct kprobe *kp;
 
 	if (p->break_handler) {
-		list_for_each_entry(kp, &old_p->list, list) {
+		list_for_each_entry_rcu(kp, &old_p->list, list) {
 			if (kp->break_handler)
 				return -EEXIST;
 		}
-		list_add_tail(&p->list, &old_p->list);
+		list_add_tail_rcu(&p->list, &old_p->list);
 	} else
-		list_add(&p->list, &old_p->list);
+		list_add_rcu(&p->list, &old_p->list);
 	return 0;
 }
 
@@ -408,18 +397,18 @@
 	ap->break_handler = aggr_break_handler;
 
 	INIT_LIST_HEAD(&ap->list);
-	list_add(&p->list, &ap->list);
+	list_add_rcu(&p->list, &ap->list);
 
 	INIT_HLIST_NODE(&ap->hlist);
-	hlist_del(&p->hlist);
-	hlist_add_head(&ap->hlist,
+	hlist_del_rcu(&p->hlist);
+	hlist_add_head_rcu(&ap->hlist,
 		&kprobe_table[hash_ptr(ap->addr, KPROBE_HASH_BITS)]);
 }
 
 /*
  * This is the second or subsequent kprobe at the address - handle
  * the intricacies
- * TODO: Move kcalloc outside the spinlock
+ * TODO: Move kcalloc outside the spin_lock
  */
 static int __kprobes register_aggr_kprobe(struct kprobe *old_p,
 					  struct kprobe *p)
@@ -445,7 +434,7 @@
 static inline void cleanup_kprobe(struct kprobe *p, unsigned long flags)
 {
 	arch_disarm_kprobe(p);
-	hlist_del(&p->hlist);
+	hlist_del_rcu(&p->hlist);
 	spin_unlock_irqrestore(&kprobe_lock, flags);
 	arch_remove_kprobe(p);
 }
@@ -453,11 +442,10 @@
 static inline void cleanup_aggr_kprobe(struct kprobe *old_p,
 		struct kprobe *p, unsigned long flags)
 {
-	list_del(&p->list);
-	if (list_empty(&old_p->list)) {
+	list_del_rcu(&p->list);
+	if (list_empty(&old_p->list))
 		cleanup_kprobe(old_p, flags);
-		kfree(old_p);
-	} else
+	else
 		spin_unlock_irqrestore(&kprobe_lock, flags);
 }
 
@@ -480,9 +468,9 @@
 	if ((ret = arch_prepare_kprobe(p)) != 0)
 		goto rm_kprobe;
 
+	p->nmissed = 0;
 	spin_lock_irqsave(&kprobe_lock, flags);
 	old_p = get_kprobe(p->addr);
-	p->nmissed = 0;
 	if (old_p) {
 		ret = register_aggr_kprobe(old_p, p);
 		goto out;
@@ -490,7 +478,7 @@
 
 	arch_copy_kprobe(p);
 	INIT_HLIST_NODE(&p->hlist);
-	hlist_add_head(&p->hlist,
+	hlist_add_head_rcu(&p->hlist,
 		       &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
 
   	arch_arm_kprobe(p);
@@ -511,10 +499,16 @@
 	spin_lock_irqsave(&kprobe_lock, flags);
 	old_p = get_kprobe(p->addr);
 	if (old_p) {
+		/* cleanup_*_kprobe() does the spin_unlock_irqrestore */
 		if (old_p->pre_handler == aggr_pre_handler)
 			cleanup_aggr_kprobe(old_p, p, flags);
 		else
 			cleanup_kprobe(p, flags);
+
+		synchronize_sched();
+		if (old_p->pre_handler == aggr_pre_handler &&
+				list_empty(&old_p->list))
+			kfree(old_p);
 	} else
 		spin_unlock_irqrestore(&kprobe_lock, flags);
 }
@@ -591,13 +585,13 @@
 
 	unregister_kprobe(&rp->kp);
 	/* No race here */
-	spin_lock_irqsave(&kprobe_lock, flags);
+	spin_lock_irqsave(&kretprobe_lock, flags);
 	free_rp_inst(rp);
 	while ((ri = get_used_rp_inst(rp)) != NULL) {
 		ri->rp = NULL;
 		hlist_del(&ri->uflist);
 	}
-	spin_unlock_irqrestore(&kprobe_lock, flags);
+	spin_unlock_irqrestore(&kretprobe_lock, flags);
 }
 
 static int __init init_kprobes(void)
diff --git a/kernel/module.c b/kernel/module.c
index ff5c500..2ea929d 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -37,6 +37,7 @@
 #include <linux/stop_machine.h>
 #include <linux/device.h>
 #include <linux/string.h>
+#include <linux/sched.h>
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
 #include <asm/cacheflush.h>
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index 91a8942..84af54c 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -497,7 +497,7 @@
 		left = cputime_div(cputime_sub(expires.cpu, val.cpu),
 				   nthreads);
 		do {
-			if (!unlikely(t->flags & PF_EXITING)) {
+			if (likely(!(t->flags & PF_EXITING))) {
 				ticks = cputime_add(prof_ticks(t), left);
 				if (cputime_eq(t->it_prof_expires,
 					       cputime_zero) ||
@@ -512,7 +512,7 @@
 		left = cputime_div(cputime_sub(expires.cpu, val.cpu),
 				   nthreads);
 		do {
-			if (!unlikely(t->flags & PF_EXITING)) {
+			if (likely(!(t->flags & PF_EXITING))) {
 				ticks = cputime_add(virt_ticks(t), left);
 				if (cputime_eq(t->it_virt_expires,
 					       cputime_zero) ||
@@ -527,7 +527,7 @@
 		nsleft = expires.sched - val.sched;
 		do_div(nsleft, nthreads);
 		do {
-			if (!unlikely(t->flags & PF_EXITING)) {
+			if (likely(!(t->flags & PF_EXITING))) {
 				ns = t->sched_time + nsleft;
 				if (t->it_sched_expires == 0 ||
 				    t->it_sched_expires > ns) {
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 42a6287..723f517 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -168,9 +168,8 @@
 {
 	struct zone *zone;
 	unsigned long zone_pfn;
-	unsigned n;
+	unsigned int n = 0;
 
-	n = 0;
 	for_each_zone (zone) {
 		if (is_highmem(zone))
 			continue;
@@ -250,10 +249,10 @@
  *	of memory pages allocated with alloc_pagedir()
  */
 
-void create_pbe_list(struct pbe *pblist, unsigned nr_pages)
+void create_pbe_list(struct pbe *pblist, unsigned int nr_pages)
 {
 	struct pbe *pbpage, *p;
-	unsigned num = PBES_PER_PAGE;
+	unsigned int num = PBES_PER_PAGE;
 
 	for_each_pb_page (pbpage, pblist) {
 		if (num >= nr_pages)
@@ -293,9 +292,9 @@
  *	On each page we set up a list of struct_pbe elements.
  */
 
-struct pbe *alloc_pagedir(unsigned nr_pages)
+struct pbe *alloc_pagedir(unsigned int nr_pages)
 {
-	unsigned num;
+	unsigned int num;
 	struct pbe *pblist, *pbe;
 
 	if (!nr_pages)
@@ -329,7 +328,7 @@
 	for_each_zone(zone) {
 		for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
 			if (pfn_valid(zone_pfn + zone->zone_start_pfn)) {
-				struct page * page;
+				struct page *page;
 				page = pfn_to_page(zone_pfn + zone->zone_start_pfn);
 				if (PageNosave(page) && PageNosaveFree(page)) {
 					ClearPageNosave(page);
@@ -348,7 +347,7 @@
  *	free pages.
  */
 
-static int enough_free_mem(unsigned nr_pages)
+static int enough_free_mem(unsigned int nr_pages)
 {
 	pr_debug("swsusp: available memory: %u pages\n", nr_free_pages());
 	return nr_free_pages() > (nr_pages + PAGES_FOR_IO +
@@ -356,7 +355,7 @@
 }
 
 
-static struct pbe *swsusp_alloc(unsigned nr_pages)
+static struct pbe *swsusp_alloc(unsigned int nr_pages)
 {
 	struct pbe *pblist, *p;
 
@@ -380,7 +379,7 @@
 
 asmlinkage int swsusp_save(void)
 {
-	unsigned nr_pages;
+	unsigned int nr_pages;
 
 	pr_debug("swsusp: critical section: \n");
 	if (save_highmem()) {
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index 12db1d2..e1ab28b 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -85,18 +85,11 @@
 /* Suspend pagedir is allocated before final copy, therefore it
    must be freed after resume
 
-   Warning: this is evil. There are actually two pagedirs at time of
-   resume. One is "pagedir_save", which is empty frame allocated at
-   time of suspend, that must be freed. Second is "pagedir_nosave",
-   allocated at time of resume, that travels through memory not to
-   collide with anything.
-
    Warning: this is even more evil than it seems. Pagedirs this file
    talks about are completely different from page directories used by
    MMU hardware.
  */
 suspend_pagedir_t *pagedir_nosave __nosavedata = NULL;
-suspend_pagedir_t *pagedir_save;
 
 #define SWSUSP_SIG	"S1SUSPEND"
 
@@ -122,8 +115,8 @@
 static unsigned short swapfile_used[MAX_SWAPFILES];
 static unsigned short root_swap;
 
-static int write_page(unsigned long addr, swp_entry_t * loc);
-static int bio_read_page(pgoff_t page_off, void * page);
+static int write_page(unsigned long addr, swp_entry_t *loc);
+static int bio_read_page(pgoff_t page_off, void *page);
 
 static u8 key_iv[MAXKEY+MAXIV];
 
@@ -355,7 +348,7 @@
  *	This is a partial improvement, since we will at least return other
  *	errors, though we need to eventually fix the damn code.
  */
-static int write_page(unsigned long addr, swp_entry_t * loc)
+static int write_page(unsigned long addr, swp_entry_t *loc)
 {
 	swp_entry_t entry;
 	int error = 0;
@@ -383,9 +376,9 @@
 static void data_free(void)
 {
 	swp_entry_t entry;
-	struct pbe * p;
+	struct pbe *p;
 
-	for_each_pbe(p, pagedir_nosave) {
+	for_each_pbe (p, pagedir_nosave) {
 		entry = p->swap_address;
 		if (entry.val)
 			swap_free(entry);
@@ -492,8 +485,8 @@
 static int write_pagedir(void)
 {
 	int error = 0;
-	unsigned n = 0;
-	struct pbe * pbe;
+	unsigned int n = 0;
+	struct pbe *pbe;
 
 	printk( "Writing pagedir...");
 	for_each_pb_page (pbe, pagedir_nosave) {
@@ -543,7 +536,7 @@
  *	We should only consider resume_device.
  */
 
-int enough_swap(unsigned nr_pages)
+int enough_swap(unsigned int nr_pages)
 {
 	struct sysinfo i;
 
@@ -694,7 +687,7 @@
  *	restore from the loaded pages later.  We relocate them here.
  */
 
-static struct pbe * swsusp_pagedir_relocate(struct pbe *pblist)
+static struct pbe *swsusp_pagedir_relocate(struct pbe *pblist)
 {
 	struct zone *zone;
 	unsigned long zone_pfn;
@@ -770,7 +763,7 @@
 
 static atomic_t io_done = ATOMIC_INIT(0);
 
-static int end_io(struct bio * bio, unsigned int num, int err)
+static int end_io(struct bio *bio, unsigned int num, int err)
 {
 	if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
 		panic("I/O error reading memory image");
@@ -778,7 +771,7 @@
 	return 0;
 }
 
-static struct block_device * resume_bdev;
+static struct block_device *resume_bdev;
 
 /**
  *	submit - submit BIO request.
@@ -791,10 +784,10 @@
  *	Then submit it and wait.
  */
 
-static int submit(int rw, pgoff_t page_off, void * page)
+static int submit(int rw, pgoff_t page_off, void *page)
 {
 	int error = 0;
-	struct bio * bio;
+	struct bio *bio;
 
 	bio = bio_alloc(GFP_ATOMIC, 1);
 	if (!bio)
@@ -823,12 +816,12 @@
 	return error;
 }
 
-static int bio_read_page(pgoff_t page_off, void * page)
+static int bio_read_page(pgoff_t page_off, void *page)
 {
 	return submit(READ, page_off, page);
 }
 
-static int bio_write_page(pgoff_t page_off, void * page)
+static int bio_write_page(pgoff_t page_off, void *page)
 {
 	return submit(WRITE, page_off, page);
 }
@@ -838,7 +831,7 @@
  * I really don't think that it's foolproof but more than nothing..
  */
 
-static const char * sanity_check(void)
+static const char *sanity_check(void)
 {
 	dump_info();
 	if (swsusp_info.version_code != LINUX_VERSION_CODE)
@@ -864,7 +857,7 @@
 
 static int check_header(void)
 {
-	const char * reason = NULL;
+	const char *reason = NULL;
 	int error;
 
 	if ((error = bio_read_page(swp_offset(swsusp_header.swsusp_info), &swsusp_info)))
@@ -912,7 +905,7 @@
 
 static int data_read(struct pbe *pblist)
 {
-	struct pbe * p;
+	struct pbe *p;
 	int error = 0;
 	int i = 0;
 	int mod = swsusp_info.image_pages / 100;
@@ -950,7 +943,7 @@
 static int read_pagedir(struct pbe *pblist)
 {
 	struct pbe *pbpage, *p;
-	unsigned i = 0;
+	unsigned int i = 0;
 	int error;
 
 	if (!pblist)
diff --git a/kernel/printk.c b/kernel/printk.c
index 3cb9708..e9be027 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -806,7 +806,6 @@
 			c->unblank();
 	release_console_sem();
 }
-EXPORT_SYMBOL(console_unblank);
 
 /*
  * Return the console tty driver structure and its associated index
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 863eee8..5b8dd98 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -406,3 +406,85 @@
 
 	return ret;
 }
+
+#ifndef __ARCH_SYS_PTRACE
+static int ptrace_get_task_struct(long request, long pid,
+		struct task_struct **childp)
+{
+	struct task_struct *child;
+	int ret;
+
+	/*
+	 * Callers use child == NULL as an indication to exit early even
+	 * when the return value is 0, so make sure it is non-NULL here.
+	 */
+	*childp = NULL;
+
+	if (request == PTRACE_TRACEME) {
+		/*
+		 * Are we already being traced?
+		 */
+		if (current->ptrace & PT_PTRACED)
+			return -EPERM;
+		ret = security_ptrace(current->parent, current);
+		if (ret)
+			return -EPERM;
+		/*
+		 * Set the ptrace bit in the process ptrace flags.
+		 */
+		current->ptrace |= PT_PTRACED;
+		return 0;
+	}
+
+	/*
+	 * You may not mess with init
+	 */
+	if (pid == 1)
+		return -EPERM;
+
+	ret = -ESRCH;
+	read_lock(&tasklist_lock);
+	child = find_task_by_pid(pid);
+	if (child)
+		get_task_struct(child);
+	read_unlock(&tasklist_lock);
+	if (!child)
+		return -ESRCH;
+
+	*childp = child;
+	return 0;
+}
+
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+{
+	struct task_struct *child;
+	long ret;
+
+	/*
+	 * This lock_kernel fixes a subtle race with suid exec
+	 */
+	lock_kernel();
+	ret = ptrace_get_task_struct(request, pid, &child);
+	if (!child)
+		goto out;
+
+	if (request == PTRACE_ATTACH) {
+		ret = ptrace_attach(child);
+		goto out;
+	}
+
+	ret = ptrace_check_attach(child, request == PTRACE_KILL);
+	if (ret < 0)
+		goto out_put_task_struct;
+
+	ret = arch_ptrace(child, request, addr, data);
+	if (ret < 0)
+		goto out_put_task_struct;
+
+ out_put_task_struct:
+	put_task_struct(child);
+ out:
+	unlock_kernel();
+	return ret;
+}
+#endif /* __ARCH_SYS_PTRACE */
diff --git a/kernel/sched.c b/kernel/sched.c
index b4f4eb6..3ce2695 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -3563,8 +3563,6 @@
 	return cpu_curr(cpu) == cpu_rq(cpu)->idle;
 }
 
-EXPORT_SYMBOL_GPL(idle_cpu);
-
 /**
  * idle_task - return the idle task for a given cpu.
  * @cpu: the processor in question.
@@ -4680,7 +4678,8 @@
 #ifdef CONFIG_HOTPLUG_CPU
 	case CPU_UP_CANCELED:
 		/* Unbind it from offline cpu so it can run.  Fall thru. */
-		kthread_bind(cpu_rq(cpu)->migration_thread,smp_processor_id());
+		kthread_bind(cpu_rq(cpu)->migration_thread,
+			     any_online_cpu(cpu_online_map));
 		kthread_stop(cpu_rq(cpu)->migration_thread);
 		cpu_rq(cpu)->migration_thread = NULL;
 		break;
diff --git a/kernel/softirq.c b/kernel/softirq.c
index f766b2f..ad3295c 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -470,7 +470,8 @@
 #ifdef CONFIG_HOTPLUG_CPU
 	case CPU_UP_CANCELED:
 		/* Unbind so it can run.  Fall thru. */
-		kthread_bind(per_cpu(ksoftirqd, hotcpu), smp_processor_id());
+		kthread_bind(per_cpu(ksoftirqd, hotcpu),
+			     any_online_cpu(cpu_online_map));
 	case CPU_DEAD:
 		p = per_cpu(ksoftirqd, hotcpu);
 		per_cpu(ksoftirqd, hotcpu) = NULL;
diff --git a/kernel/softlockup.c b/kernel/softlockup.c
index 7597620..a2dcceb 100644
--- a/kernel/softlockup.c
+++ b/kernel/softlockup.c
@@ -123,7 +123,8 @@
 #ifdef CONFIG_HOTPLUG_CPU
 	case CPU_UP_CANCELED:
 		/* Unbind so it can run.  Fall thru. */
-		kthread_bind(per_cpu(watchdog_task, hotcpu), smp_processor_id());
+		kthread_bind(per_cpu(watchdog_task, hotcpu),
+			     any_online_cpu(cpu_online_map));
 	case CPU_DEAD:
 		p = per_cpu(watchdog_task, hotcpu);
 		per_cpu(watchdog_task, hotcpu) = NULL;
diff --git a/kernel/sys.c b/kernel/sys.c
index 2fa1ed1..c43b3e2 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -28,6 +28,7 @@
 #include <linux/suspend.h>
 #include <linux/tty.h>
 #include <linux/signal.h>
+#include <linux/cn_proc.h>
 
 #include <linux/compat.h>
 #include <linux/syscalls.h>
@@ -375,18 +376,21 @@
 }
 EXPORT_SYMBOL_GPL(emergency_restart);
 
-/**
- *	kernel_restart - reboot the system
- *
- *	Shutdown everything and perform a clean reboot.
- *	This is not safe to call in interrupt context.
- */
 void kernel_restart_prepare(char *cmd)
 {
 	notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd);
 	system_state = SYSTEM_RESTART;
 	device_shutdown();
 }
+
+/**
+ *	kernel_restart - reboot the system
+ *	@cmd: pointer to buffer containing command to execute for restart
+ *		or %NULL
+ *
+ *	Shutdown everything and perform a clean reboot.
+ *	This is not safe to call in interrupt context.
+ */
 void kernel_restart(char *cmd)
 {
 	kernel_restart_prepare(cmd);
@@ -623,6 +627,7 @@
 	current->egid = new_egid;
 	current->gid = new_rgid;
 	key_fsgid_changed(current);
+	proc_id_connector(current, PROC_EVENT_GID);
 	return 0;
 }
 
@@ -662,6 +667,7 @@
 		return -EPERM;
 
 	key_fsgid_changed(current);
+	proc_id_connector(current, PROC_EVENT_GID);
 	return 0;
 }
   
@@ -751,6 +757,7 @@
 	current->fsuid = current->euid;
 
 	key_fsuid_changed(current);
+	proc_id_connector(current, PROC_EVENT_UID);
 
 	return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_RE);
 }
@@ -798,6 +805,7 @@
 	current->suid = new_suid;
 
 	key_fsuid_changed(current);
+	proc_id_connector(current, PROC_EVENT_UID);
 
 	return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_ID);
 }
@@ -846,6 +854,7 @@
 		current->suid = suid;
 
 	key_fsuid_changed(current);
+	proc_id_connector(current, PROC_EVENT_UID);
 
 	return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_RES);
 }
@@ -898,6 +907,7 @@
 		current->sgid = sgid;
 
 	key_fsgid_changed(current);
+	proc_id_connector(current, PROC_EVENT_GID);
 	return 0;
 }
 
@@ -940,6 +950,7 @@
 	}
 
 	key_fsuid_changed(current);
+	proc_id_connector(current, PROC_EVENT_UID);
 
 	security_task_post_setuid(old_fsuid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS);
 
@@ -968,6 +979,7 @@
 		}
 		current->fsgid = gid;
 		key_fsgid_changed(current);
+		proc_id_connector(current, PROC_EVENT_GID);
 	}
 	return old_fsgid;
 }
@@ -1485,8 +1497,6 @@
 
 DECLARE_RWSEM(uts_sem);
 
-EXPORT_SYMBOL(uts_sem);
-
 asmlinkage long sys_newuname(struct new_utsname __user * name)
 {
 	int errno = 0;
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 8e56e24..c4f35f9 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -952,7 +952,7 @@
 		.data		= &aio_nr,
 		.maxlen		= sizeof(aio_nr),
 		.mode		= 0444,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler	= &proc_doulongvec_minmax,
 	},
 	{
 		.ctl_name	= FS_AIO_MAX_NR,
@@ -960,7 +960,7 @@
 		.data		= &aio_max_nr,
 		.maxlen		= sizeof(aio_max_nr),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler	= &proc_doulongvec_minmax,
 	},
 #ifdef CONFIG_INOTIFY
 	{
@@ -1997,6 +1997,7 @@
  * @filp: the file structure
  * @buffer: the user buffer
  * @lenp: the size of the user buffer
+ * @ppos: pointer to the file position
  *
  * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
  * values from/to the user buffer, treated as an ASCII string. 
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 7cee222..42df83d 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -524,7 +524,7 @@
 		list_for_each_entry(wq, &workqueues, list) {
 			/* Unbind so it can run. */
 			kthread_bind(per_cpu_ptr(wq->cpu_wq, hotcpu)->thread,
-				     smp_processor_id());
+				     any_online_cpu(cpu_online_map));
 			cleanup_workqueue_thread(wq, hotcpu);
 		}
 		break;
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index d1c057e7..88511c3 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -281,6 +281,47 @@
 }
 EXPORT_SYMBOL(radix_tree_insert);
 
+static inline void **__lookup_slot(struct radix_tree_root *root,
+				   unsigned long index)
+{
+	unsigned int height, shift;
+	struct radix_tree_node **slot;
+
+	height = root->height;
+	if (index > radix_tree_maxindex(height))
+		return NULL;
+
+	shift = (height-1) * RADIX_TREE_MAP_SHIFT;
+	slot = &root->rnode;
+
+	while (height > 0) {
+		if (*slot == NULL)
+			return NULL;
+
+		slot = (struct radix_tree_node **)
+			((*slot)->slots +
+				((index >> shift) & RADIX_TREE_MAP_MASK));
+		shift -= RADIX_TREE_MAP_SHIFT;
+		height--;
+	}
+
+	return (void **)slot;
+}
+
+/**
+ *	radix_tree_lookup_slot    -    lookup a slot in a radix tree
+ *	@root:		radix tree root
+ *	@index:		index key
+ *
+ *	Lookup the slot corresponding to the position @index in the radix tree
+ *	@root. This is useful for update-if-exists operations.
+ */
+void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index)
+{
+	return __lookup_slot(root, index);
+}
+EXPORT_SYMBOL(radix_tree_lookup_slot);
+
 /**
  *	radix_tree_lookup    -    perform lookup operation on a radix tree
  *	@root:		radix tree root
@@ -290,26 +331,10 @@
  */
 void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index)
 {
-	unsigned int height, shift;
-	struct radix_tree_node *slot;
+	void **slot;
 
-	height = root->height;
-	if (index > radix_tree_maxindex(height))
-		return NULL;
-
-	shift = (height-1) * RADIX_TREE_MAP_SHIFT;
-	slot = root->rnode;
-
-	while (height > 0) {
-		if (slot == NULL)
-			return NULL;
-
-		slot = slot->slots[(index >> shift) & RADIX_TREE_MAP_MASK];
-		shift -= RADIX_TREE_MAP_SHIFT;
-		height--;
-	}
-
-	return slot;
+	slot = __lookup_slot(root, index);
+	return slot != NULL ? *slot : NULL;
 }
 EXPORT_SYMBOL(radix_tree_lookup);
 
diff --git a/mm/Kconfig b/mm/Kconfig
index 1a4473fc..ae9ce6b 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -126,9 +126,11 @@
 # Default to 4 for wider testing, though 8 might be more appropriate.
 # ARM's adjust_pte (unused if VIPT) depends on mm-wide page_table_lock.
 # PA-RISC's debug spinlock_t is too large for the 32-bit struct page.
+# ARM26 and SPARC32 and PPC64 may use one page for multiple page tables.
 #
 config SPLIT_PTLOCK_CPUS
 	int
 	default "4096" if ARM && !CPU_CACHE_VIPT
 	default "4096" if PARISC && DEBUG_SPINLOCK && !64BIT
+	default "4096" if ARM26 || SPARC32 || PPC64
 	default "4"
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 9a56580..728e9bd 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -237,7 +237,6 @@
 {
 	return nr_huge_pages * (HPAGE_SIZE / PAGE_SIZE);
 }
-EXPORT_SYMBOL(hugetlb_total_pages);
 
 /*
  * We cannot handle pagefaults against hugetlb pages at all.  They cause
diff --git a/mm/mmap.c b/mm/mmap.c
index 320dda1..6c997b1 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -155,10 +155,6 @@
 	return -ENOMEM;
 }
 
-EXPORT_SYMBOL(sysctl_overcommit_memory);
-EXPORT_SYMBOL(sysctl_overcommit_ratio);
-EXPORT_SYMBOL(sysctl_max_map_count);
-EXPORT_SYMBOL(vm_committed_space);
 EXPORT_SYMBOL(__vm_enough_memory);
 
 /*
diff --git a/mm/nommu.c b/mm/nommu.c
index d1e076a..6deb6ab 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -44,10 +44,6 @@
 int heap_stack_gap = 0;
 
 EXPORT_SYMBOL(mem_map);
-EXPORT_SYMBOL(sysctl_max_map_count);
-EXPORT_SYMBOL(sysctl_overcommit_memory);
-EXPORT_SYMBOL(sysctl_overcommit_ratio);
-EXPORT_SYMBOL(vm_committed_space);
 EXPORT_SYMBOL(__vm_enough_memory);
 
 /* list of shareable VMAs */
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 0166ea15..74138c9 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -750,7 +750,6 @@
 	}
 	return TestClearPageDirty(page);
 }
-EXPORT_SYMBOL(clear_page_dirty_for_io);
 
 int test_clear_page_writeback(struct page *page)
 {
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 2dbdd98..ff81b5c 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -64,7 +64,6 @@
 int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1] = { 256, 32 };
 
 EXPORT_SYMBOL(totalram_pages);
-EXPORT_SYMBOL(nr_swap_pages);
 
 /*
  * Used by page_zone() to look up the address of the struct zone whose
diff --git a/mm/readahead.c b/mm/readahead.c
index d0b5003..72e7adb 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -254,7 +254,7 @@
  */
 static int
 __do_page_cache_readahead(struct address_space *mapping, struct file *filp,
-			unsigned long offset, unsigned long nr_to_read)
+			pgoff_t offset, unsigned long nr_to_read)
 {
 	struct inode *inode = mapping->host;
 	struct page *page;
@@ -274,7 +274,7 @@
 	 */
 	read_lock_irq(&mapping->tree_lock);
 	for (page_idx = 0; page_idx < nr_to_read; page_idx++) {
-		unsigned long page_offset = offset + page_idx;
+		pgoff_t page_offset = offset + page_idx;
 		
 		if (page_offset > end_index)
 			break;
@@ -311,7 +311,7 @@
  * memory at once.
  */
 int force_page_cache_readahead(struct address_space *mapping, struct file *filp,
-		unsigned long offset, unsigned long nr_to_read)
+		pgoff_t offset, unsigned long nr_to_read)
 {
 	int ret = 0;
 
@@ -368,7 +368,7 @@
  * request queues.
  */
 int do_page_cache_readahead(struct address_space *mapping, struct file *filp,
-			unsigned long offset, unsigned long nr_to_read)
+			pgoff_t offset, unsigned long nr_to_read)
 {
 	if (bdi_read_congested(mapping->backing_dev_info))
 		return -1;
@@ -385,7 +385,7 @@
  */
 static int
 blockable_page_cache_readahead(struct address_space *mapping, struct file *filp,
-			unsigned long offset, unsigned long nr_to_read,
+			pgoff_t offset, unsigned long nr_to_read,
 			struct file_ra_state *ra, int block)
 {
 	int actual;
@@ -430,14 +430,27 @@
 	return ret;
 }
 
-/*
- * page_cache_readahead is the main function.  If performs the adaptive
+/**
+ * page_cache_readahead - generic adaptive readahead
+ * @mapping: address_space which holds the pagecache and I/O vectors
+ * @ra: file_ra_state which holds the readahead state
+ * @filp: passed on to ->readpage() and ->readpages()
+ * @offset: start offset into @mapping, in PAGE_CACHE_SIZE units
+ * @req_size: hint: total size of the read which the caller is performing in
+ *            PAGE_CACHE_SIZE units
+ *
+ * page_cache_readahead() is the main function.  If performs the adaptive
  * readahead window size management and submits the readahead I/O.
+ *
+ * Note that @filp is purely used for passing on to the ->readpage[s]()
+ * handler: it may refer to a different file from @mapping (so we may not use
+ * @filp->f_mapping or @filp->f_dentry->d_inode here).
+ * Also, @ra may not be equal to &@filp->f_ra.
+ *
  */
 unsigned long
 page_cache_readahead(struct address_space *mapping, struct file_ra_state *ra,
-		     struct file *filp, unsigned long offset,
-		     unsigned long req_size)
+		     struct file *filp, pgoff_t offset, unsigned long req_size)
 {
 	unsigned long max, newsize;
 	int sequential;
diff --git a/mm/slab.c b/mm/slab.c
index 22bfb0b2..e291f5e 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -368,7 +368,7 @@
  * manages a cache.
  */
 	
-struct kmem_cache_s {
+struct kmem_cache {
 /* 1) per-cpu data, touched during every alloc/free */
 	struct array_cache	*array[NR_CPUS];
 	unsigned int		batchcount;
@@ -1502,6 +1502,7 @@
 {
 	size_t left_over, slab_size, ralign;
 	kmem_cache_t *cachep = NULL;
+	struct list_head *p;
 
 	/*
 	 * Sanity checks... these are all serious usage bugs.
@@ -1516,6 +1517,35 @@
 			BUG();
 		}
 
+	down(&cache_chain_sem);
+
+	list_for_each(p, &cache_chain) {
+		kmem_cache_t *pc = list_entry(p, kmem_cache_t, next);
+		mm_segment_t old_fs = get_fs();
+		char tmp;
+		int res;
+
+		/*
+		 * This happens when the module gets unloaded and doesn't
+		 * destroy its slab cache and no-one else reuses the vmalloc
+		 * area of the module.  Print a warning.
+		 */
+		set_fs(KERNEL_DS);
+		res = __get_user(tmp, pc->name);
+		set_fs(old_fs);
+		if (res) {
+			printk("SLAB: cache with size %d has lost its name\n",
+					pc->objsize);
+			continue;
+		}
+
+		if (!strcmp(pc->name,name)) {
+			printk("kmem_cache_create: duplicate cache %s\n", name);
+			dump_stack();
+			goto oops;
+		}
+	}
+
 #if DEBUG
 	WARN_ON(strchr(name, ' '));	/* It confuses parsers */
 	if ((flags & SLAB_DEBUG_INITIAL) && !ctor) {
@@ -1592,7 +1622,7 @@
 	/* Get cache's description obj. */
 	cachep = (kmem_cache_t *) kmem_cache_alloc(&cache_cache, SLAB_KERNEL);
 	if (!cachep)
-		goto opps;
+		goto oops;
 	memset(cachep, 0, sizeof(kmem_cache_t));
 
 #if DEBUG
@@ -1686,7 +1716,7 @@
 		printk("kmem_cache_create: couldn't create cache %s.\n", name);
 		kmem_cache_free(&cache_cache, cachep);
 		cachep = NULL;
-		goto opps;
+		goto oops;
 	}
 	slab_size = ALIGN(cachep->num*sizeof(kmem_bufctl_t)
 				+ sizeof(struct slab), align);
@@ -1781,43 +1811,14 @@
 		cachep->limit = BOOT_CPUCACHE_ENTRIES;
 	} 
 
-	/* Need the semaphore to access the chain. */
-	down(&cache_chain_sem);
-	{
-		struct list_head *p;
-		mm_segment_t old_fs;
-
-		old_fs = get_fs();
-		set_fs(KERNEL_DS);
-		list_for_each(p, &cache_chain) {
-			kmem_cache_t *pc = list_entry(p, kmem_cache_t, next);
-			char tmp;
-			/* This happens when the module gets unloaded and doesn't
-			   destroy its slab cache and noone else reuses the vmalloc
-			   area of the module. Print a warning. */
-			if (__get_user(tmp,pc->name)) { 
-				printk("SLAB: cache with size %d has lost its name\n", 
-					pc->objsize); 
-				continue; 
-			} 	
-			if (!strcmp(pc->name,name)) { 
-				printk("kmem_cache_create: duplicate cache %s\n",name); 
-				up(&cache_chain_sem); 
-				unlock_cpu_hotplug();
-				BUG(); 
-			}	
-		}
-		set_fs(old_fs);
-	}
-
 	/* cache setup completed, link it into the list */
 	list_add(&cachep->next, &cache_chain);
-	up(&cache_chain_sem);
 	unlock_cpu_hotplug();
-opps:
+oops:
 	if (!cachep && (flags & SLAB_PANIC))
 		panic("kmem_cache_create(): failed to create slab `%s'\n",
 			name);
+	up(&cache_chain_sem);
 	return cachep;
 }
 EXPORT_SYMBOL(kmem_cache_create);
@@ -3262,6 +3263,7 @@
 
 /**
  * cache_reap - Reclaim memory from caches.
+ * @unused: unused parameter
  *
  * Called from workqueue/eventd every few seconds.
  * Purpose:
@@ -3278,7 +3280,7 @@
 
 	if (down_trylock(&cache_chain_sem)) {
 		/* Give up. Setup the next iteration. */
-		schedule_delayed_work(&__get_cpu_var(reap_work), REAPTIMEOUT_CPUC + smp_processor_id());
+		schedule_delayed_work(&__get_cpu_var(reap_work), REAPTIMEOUT_CPUC);
 		return;
 	}
 
@@ -3347,7 +3349,7 @@
 	up(&cache_chain_sem);
 	drain_remote_pages();
 	/* Setup the next iteration */
-	schedule_delayed_work(&__get_cpu_var(reap_work), REAPTIMEOUT_CPUC + smp_processor_id());
+	schedule_delayed_work(&__get_cpu_var(reap_work), REAPTIMEOUT_CPUC);
 }
 
 #ifdef CONFIG_PROC_FS
diff --git a/mm/swap.c b/mm/swap.c
index 154ae13..d09cf7f 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -413,7 +413,6 @@
 	}
 	preempt_enable();
 }
-EXPORT_SYMBOL(vm_acct_memory);
 
 #ifdef CONFIG_HOTPLUG_CPU
 static void lru_drain_cache(unsigned int cpu)
diff --git a/mm/swap_state.c b/mm/swap_state.c
index dfd9a46..0df9a57 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -40,7 +40,6 @@
 	.i_mmap_nonlinear = LIST_HEAD_INIT(swapper_space.i_mmap_nonlinear),
 	.backing_dev_info = &swap_backing_dev_info,
 };
-EXPORT_SYMBOL(swapper_space);
 
 #define INC_CACHE_INFO(x)	do { swap_cache_info.x++; } while (0)
 
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 8970c0b..edafeac 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -36,8 +36,6 @@
 long total_swap_pages;
 static int swap_overflow;
 
-EXPORT_SYMBOL(total_swap_pages);
-
 static const char Bad_file[] = "Bad swap file entry ";
 static const char Unused_file[] = "Unused swap file entry ";
 static const char Bad_offset[] = "Bad swap offset entry ";
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 54a90e8..729eb3e 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -457,7 +457,7 @@
  *	@size:		allocation size
  *	@gfp_mask:	flags for the page level allocator
  *	@prot:		protection mask for the allocated pages
- *	@node		node to use for allocation or -1
+ *	@node:		node to use for allocation or -1
  *
  *	Allocate enough pages to cover @size from the page level
  *	allocator with @gfp_mask flags.  Map them into contiguous
@@ -507,7 +507,7 @@
  *	vmalloc_node  -  allocate memory on a specific node
  *
  *	@size:		allocation size
- *	@node;		numa node
+ *	@node:		numa node
  *
  *	Allocate enough pages to cover @size from the page level
  *	allocator and map them into contiguous kernel virtual space.
diff --git a/net/core/stream.c b/net/core/stream.c
index ac9edfd..15bfd03 100644
--- a/net/core/stream.c
+++ b/net/core/stream.c
@@ -52,8 +52,9 @@
 {
 	struct task_struct *tsk = current;
 	DEFINE_WAIT(wait);
+	int done;
 
-	while (1) {
+	do {
 		if (sk->sk_err)
 			return sock_error(sk);
 		if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV))
@@ -65,13 +66,12 @@
 
 		prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
 		sk->sk_write_pending++;
-		if (sk_wait_event(sk, timeo_p,
-				  !((1 << sk->sk_state) & 
-				    ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT))))
-			break;
+		done = sk_wait_event(sk, timeo_p,
+				     !((1 << sk->sk_state) & 
+				       ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)));
 		finish_wait(sk->sk_sleep, &wait);
 		sk->sk_write_pending--;
-	}
+	} while (!done);
 	return 0;
 }
 
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 6298cf5..4b9bc81 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -31,8 +31,6 @@
 	.lhash_lock	= RW_LOCK_UNLOCKED,
 	.lhash_users	= ATOMIC_INIT(0),
 	.lhash_wait = __WAIT_QUEUE_HEAD_INITIALIZER(dccp_hashinfo.lhash_wait),
-	.portalloc_lock	= SPIN_LOCK_UNLOCKED,
-	.port_rover	= 1024 - 1,
 };
 
 EXPORT_SYMBOL_GPL(dccp_hashinfo);
@@ -125,36 +123,15 @@
 	int ret;
 
  	if (snum == 0) {
- 		int rover;
  		int low = sysctl_local_port_range[0];
  		int high = sysctl_local_port_range[1];
  		int remaining = (high - low) + 1;
+ 		int rover = net_random() % (high - low) + low;
 		struct hlist_node *node;
  		struct inet_timewait_sock *tw = NULL;
 
  		local_bh_disable();
-
- 		/* TODO. Actually it is not so bad idea to remove
- 		 * dccp_hashinfo.portalloc_lock before next submission to
-		 * Linus.
- 		 * As soon as we touch this place at all it is time to think.
- 		 *
- 		 * Now it protects single _advisory_ variable
-		 * dccp_hashinfo.port_rover, hence it is mostly useless.
- 		 * Code will work nicely if we just delete it, but
- 		 * I am afraid in contented case it will work not better or
- 		 * even worse: another cpu just will hit the same bucket
- 		 * and spin there.
- 		 * So some cpu salt could remove both contention and
- 		 * memory pingpong. Any ideas how to do this in a nice way?
- 		 */
- 		spin_lock(&dccp_hashinfo.portalloc_lock);
- 		rover = dccp_hashinfo.port_rover;
-
  		do {
- 			rover++;
- 			if ((rover < low) || (rover > high))
- 				rover = low;
  			head = &dccp_hashinfo.bhash[inet_bhashfn(rover,
 						    dccp_hashinfo.bhash_size)];
  			spin_lock(&head->lock);
@@ -187,9 +164,9 @@
 
  		next_port:
  			spin_unlock(&head->lock);
+ 			if (++rover > high)
+ 				rover = low;
  		} while (--remaining > 0);
- 		dccp_hashinfo.port_rover = rover;
- 		spin_unlock(&dccp_hashinfo.portalloc_lock);
 
  		local_bh_enable();
 
@@ -197,9 +174,6 @@
 
 ok:
  		/* All locks still held and bhs disabled */
- 		dccp_hashinfo.port_rover = rover;
- 		spin_unlock(&dccp_hashinfo.portalloc_lock);
-
  		inet_bind_hash(sk, tb, rover);
 		if (sk_unhashed(sk)) {
  			inet_sk(sk)->sport = htons(rover);
diff --git a/net/ieee80211/ieee80211_crypt.c b/net/ieee80211/ieee80211_crypt.c
index f3b6aa3..20cc580 100644
--- a/net/ieee80211/ieee80211_crypt.c
+++ b/net/ieee80211/ieee80211_crypt.c
@@ -12,7 +12,6 @@
  */
 
 #include <linux/config.h>
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/ieee80211/ieee80211_crypt_ccmp.c
index 05a853c..4702217 100644
--- a/net/ieee80211/ieee80211_crypt_ccmp.c
+++ b/net/ieee80211/ieee80211_crypt_ccmp.c
@@ -10,7 +10,6 @@
  */
 
 #include <linux/config.h>
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index 2e34f29..e098832 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -10,7 +10,6 @@
  */
 
 #include <linux/config.h>
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index 7c08ed2..073aebd 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -10,7 +10,6 @@
  */
 
 #include <linux/config.h>
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
diff --git a/net/ieee80211/ieee80211_geo.c b/net/ieee80211/ieee80211_geo.c
index c4b54ef..610cc5c 100644
--- a/net/ieee80211/ieee80211_geo.c
+++ b/net/ieee80211/ieee80211_geo.c
@@ -38,7 +38,6 @@
 #include <linux/slab.h>
 #include <linux/tcp.h>
 #include <linux/types.h>
-#include <linux/version.h>
 #include <linux/wireless.h>
 #include <linux/etherdevice.h>
 #include <asm/uaccess.h>
diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c
index f66d792..321287b 100644
--- a/net/ieee80211/ieee80211_module.c
+++ b/net/ieee80211/ieee80211_module.c
@@ -45,7 +45,6 @@
 #include <linux/slab.h>
 #include <linux/tcp.h>
 #include <linux/types.h>
-#include <linux/version.h>
 #include <linux/wireless.h>
 #include <linux/etherdevice.h>
 #include <asm/uaccess.h>
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index ce694cf..6ad8821 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -28,7 +28,6 @@
 #include <linux/slab.h>
 #include <linux/tcp.h>
 #include <linux/types.h>
-#include <linux/version.h>
 #include <linux/wireless.h>
 #include <linux/etherdevice.h>
 #include <asm/uaccess.h>
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
index 95ccbad..445f206 100644
--- a/net/ieee80211/ieee80211_tx.c
+++ b/net/ieee80211/ieee80211_tx.c
@@ -38,7 +38,6 @@
 #include <linux/slab.h>
 #include <linux/tcp.h>
 #include <linux/types.h>
-#include <linux/version.h>
 #include <linux/wireless.h>
 #include <linux/etherdevice.h>
 #include <asm/uaccess.h>
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 94468a7..3fe021f 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -78,17 +78,9 @@
 		int low = sysctl_local_port_range[0];
 		int high = sysctl_local_port_range[1];
 		int remaining = (high - low) + 1;
-		int rover;
+		int rover = net_random() % (high - low) + low;
 
-		spin_lock(&hashinfo->portalloc_lock);
-		if (hashinfo->port_rover < low)
-			rover = low;
-		else
-			rover = hashinfo->port_rover;
 		do {
-			rover++;
-			if (rover > high)
-				rover = low;
 			head = &hashinfo->bhash[inet_bhashfn(rover, hashinfo->bhash_size)];
 			spin_lock(&head->lock);
 			inet_bind_bucket_for_each(tb, node, &head->chain)
@@ -97,9 +89,9 @@
 			break;
 		next:
 			spin_unlock(&head->lock);
+			if (++rover > high)
+				rover = low;
 		} while (--remaining > 0);
-		hashinfo->port_rover = rover;
-		spin_unlock(&hashinfo->portalloc_lock);
 
 		/* Exhausted local port range during search?  It is not
 		 * possible for us to be holding one of the bind hash
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
index 926a668..4108a5e 100644
--- a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
+++ b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
@@ -270,14 +270,10 @@
 	exp_orig->expectfn = pptp_expectfn;
 	exp_orig->flags = 0;
 
-	exp_orig->dir = IP_CT_DIR_ORIGINAL;
-
 	/* both expectations are identical apart from tuple */
 	memcpy(exp_reply, exp_orig, sizeof(*exp_reply));
 	memcpy(&exp_reply->tuple, &exp_tuples[1], sizeof(exp_reply->tuple));
 
-	exp_reply->dir = !exp_orig->dir;
-
 	if (ip_nat_pptp_hook_exp_gre)
 		ret = ip_nat_pptp_hook_exp_gre(exp_orig, exp_reply);
 	else {
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index 166e606..82a6504 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -815,7 +815,7 @@
 				  IPCTNL_MSG_CT_NEW, 1, ct);
 	ip_conntrack_put(ct);
 	if (err <= 0)
-		goto out;
+		goto free;
 
 	err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
 	if (err < 0)
@@ -824,9 +824,9 @@
 	DEBUGP("leaving\n");
 	return 0;
 
+free:
+	kfree_skb(skb2);
 out:
-	if (skb2)
-		kfree_skb(skb2);
 	return -1;
 }
 
@@ -1322,21 +1322,16 @@
 				      nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW,
 				      1, exp);
 	if (err <= 0)
-		goto out;
-
-	ip_conntrack_expect_put(exp);
-
-	err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
-	if (err < 0)
 		goto free;
 
-	return err;
+	ip_conntrack_expect_put(exp);
 
+	return netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
+
+free:
+	kfree_skb(skb2);
 out:
 	ip_conntrack_expect_put(exp);
-free:
-	if (skb2)
-		kfree_skb(skb2);
 	return err;
 }
 
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index c5e3abd..762f4d9 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -66,10 +66,8 @@
 	 * removed until we've grabbed the reference */
 	preempt_disable();
 	p = __ip_nat_proto_find(protonum);
-	if (p) {
-		if (!try_module_get(p->me))
-			p = &ip_nat_unknown_protocol;
-	}
+	if (!try_module_get(p->me))
+		p = &ip_nat_unknown_protocol;
 	preempt_enable();
 
 	return p;
diff --git a/net/ipv4/netfilter/ip_nat_helper_pptp.c b/net/ipv4/netfilter/ip_nat_helper_pptp.c
index 3cdd068..ee6ab74 100644
--- a/net/ipv4/netfilter/ip_nat_helper_pptp.c
+++ b/net/ipv4/netfilter/ip_nat_helper_pptp.c
@@ -216,6 +216,7 @@
 	expect_orig->saved_proto.gre.key = htons(nat_pptp_info->pac_call_id);
 	expect_orig->tuple.src.u.gre.key = htons(nat_pptp_info->pns_call_id);
 	expect_orig->tuple.dst.u.gre.key = htons(ct_pptp_info->pac_call_id);
+	expect_orig->dir = IP_CT_DIR_ORIGINAL;
 	inv_t.src.ip = reply_t->src.ip;
 	inv_t.dst.ip = reply_t->dst.ip;
 	inv_t.src.u.gre.key = htons(nat_pptp_info->pac_call_id);
@@ -233,6 +234,7 @@
 	expect_reply->saved_proto.gre.key = htons(nat_pptp_info->pns_call_id);
 	expect_reply->tuple.src.u.gre.key = htons(nat_pptp_info->pac_call_id);
 	expect_reply->tuple.dst.u.gre.key = htons(ct_pptp_info->pns_call_id);
+	expect_reply->dir = IP_CT_DIR_REPLY;
 	inv_t.src.ip = orig_t->src.ip;
 	inv_t.dst.ip = orig_t->dst.ip;
 	inv_t.src.u.gre.key = htons(nat_pptp_info->pns_call_id);
diff --git a/net/ipv4/netfilter/ip_nat_proto_gre.c b/net/ipv4/netfilter/ip_nat_proto_gre.c
index 7c12854..f7cad7c 100644
--- a/net/ipv4/netfilter/ip_nat_proto_gre.c
+++ b/net/ipv4/netfilter/ip_nat_proto_gre.c
@@ -139,8 +139,8 @@
 			break;
 		case GRE_VERSION_PPTP:
 			DEBUGP("call_id -> 0x%04x\n", 
-				ntohl(tuple->dst.u.gre.key));
-			pgreh->call_id = htons(ntohl(tuple->dst.u.gre.key));
+				ntohs(tuple->dst.u.gre.key));
+			pgreh->call_id = tuple->dst.u.gre.key;
 			break;
 		default:
 			DEBUGP("can't nat unknown GRE version\n");
diff --git a/net/ipv4/netfilter/ip_nat_proto_unknown.c b/net/ipv4/netfilter/ip_nat_proto_unknown.c
index 99bbef5..f0099a6 100644
--- a/net/ipv4/netfilter/ip_nat_proto_unknown.c
+++ b/net/ipv4/netfilter/ip_nat_proto_unknown.c
@@ -62,7 +62,7 @@
 
 struct ip_nat_protocol ip_nat_unknown_protocol = {
 	.name			= "unknown",
-	.me			= THIS_MODULE,
+	/* .me isn't set: getting a ref to this cannot fail. */
 	.manip_pkt		= unknown_manip_pkt,
 	.in_range		= unknown_in_range,
 	.unique_tuple		= unknown_unique_tuple,
diff --git a/net/ipv4/netfilter/ipt_CONNMARK.c b/net/ipv4/netfilter/ipt_CONNMARK.c
index 1346380..05d66ab 100644
--- a/net/ipv4/netfilter/ipt_CONNMARK.c
+++ b/net/ipv4/netfilter/ipt_CONNMARK.c
@@ -109,6 +109,7 @@
 
 static int __init init(void)
 {
+	need_ip_conntrack();
 	return ipt_register_target(&ipt_connmark_reg);
 }
 
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index f3f0013..72b7c22 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2112,7 +2112,6 @@
 		sysctl_tcp_max_orphans >>= (3 - order);
 		sysctl_max_syn_backlog = 128;
 	}
-	tcp_hashinfo.port_rover = sysctl_local_port_range[0] - 1;
 
 	sysctl_tcp_mem[0] =  768 << order;
 	sysctl_tcp_mem[1] = 1024 << order;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index c85819d..49d67cd 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -93,8 +93,6 @@
 	.lhash_lock	= RW_LOCK_UNLOCKED,
 	.lhash_users	= ATOMIC_INIT(0),
 	.lhash_wait	= __WAIT_QUEUE_HEAD_INITIALIZER(tcp_hashinfo.lhash_wait),
-	.portalloc_lock	= SPIN_LOCK_UNLOCKED,
-	.port_rover	= 1024 - 1,
 };
 
 static int tcp_v4_get_port(struct sock *sk, unsigned short snum)
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index d693cb9..d746d3b 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -114,16 +114,9 @@
 		int low = sysctl_local_port_range[0];
 		int high = sysctl_local_port_range[1];
 		int remaining = (high - low) + 1;
-		int rover;
+		int rover = net_random() % (high - low) + low;
 
-		spin_lock(&tcp_hashinfo.portalloc_lock);
-		if (tcp_hashinfo.port_rover < low)
-			rover = low;
-		else
-			rover = tcp_hashinfo.port_rover;
-		do {	rover++;
-			if (rover > high)
-				rover = low;
+		do {
 			head = &tcp_hashinfo.bhash[inet_bhashfn(rover, tcp_hashinfo.bhash_size)];
 			spin_lock(&head->lock);
 			inet_bind_bucket_for_each(tb, node, &head->chain)
@@ -132,9 +125,9 @@
 			break;
 		next:
 			spin_unlock(&head->lock);
+			if (++rover > high)
+				rover = low;
 		} while (--remaining > 0);
-		tcp_hashinfo.port_rover = rover;
-		spin_unlock(&tcp_hashinfo.portalloc_lock);
 
 		/* Exhausted local port range during search?  It is not
 		 * possible for us to be holding one of the bind hash
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index d10d552..d3a4f30 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -117,7 +117,7 @@
 
 	/* QUEUE == DROP if noone is waiting, to be safe. */
 	read_lock(&queue_handler_lock);
-	if (!queue_handler[pf]->outfn) {
+	if (!queue_handler[pf] || !queue_handler[pf]->outfn) {
 		read_unlock(&queue_handler_lock);
 		kfree_skb(*skb);
 		return 1;
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index efcd10f..d194676 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -146,11 +146,10 @@
 		goto out_unlock;
 	}
 
-	inst = kmalloc(sizeof(*inst), GFP_ATOMIC);
+	inst = kzalloc(sizeof(*inst), GFP_ATOMIC);
 	if (!inst)
 		goto out_unlock;
 
-	memset(inst, 0, sizeof(*inst));
 	INIT_HLIST_NODE(&inst->hlist);
 	inst->lock = SPIN_LOCK_UNLOCKED;
 	/* needs to be two, since we _put() after creation */
@@ -962,10 +961,9 @@
 	struct iter_state *is;
 	int ret;
 
-	is = kmalloc(sizeof(*is), GFP_KERNEL);
+	is = kzalloc(sizeof(*is), GFP_KERNEL);
 	if (!is)
 		return -ENOMEM;
-	memset(is, 0, sizeof(*is));
 	ret = seq_open(file, &nful_seq_ops);
 	if (ret < 0)
 		goto out_free;
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index eaa44c4..f065a6c 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -136,11 +136,10 @@
 		goto out_unlock;
 	}
 
-	inst = kmalloc(sizeof(*inst), GFP_ATOMIC);
+	inst = kzalloc(sizeof(*inst), GFP_ATOMIC);
 	if (!inst)
 		goto out_unlock;
 
-	memset(inst, 0, sizeof(*inst));
 	inst->queue_num = queue_num;
 	inst->peer_pid = pid;
 	inst->queue_maxlen = NFQNL_QMAX_DEFAULT;
@@ -1036,10 +1035,9 @@
 	struct iter_state *is;
 	int ret;
 
-	is = kmalloc(sizeof(*is), GFP_KERNEL);
+	is = kzalloc(sizeof(*is), GFP_KERNEL);
 	if (!is)
 		return -ENOMEM;
-	memset(is, 0, sizeof(*is));
 	ret = seq_open(file, &nfqnl_seq_ops);
 	if (ret < 0)
 		goto out_free;
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c
index 25c171c..29a2dd9 100644
--- a/net/sched/sch_gred.c
+++ b/net/sched/sch_gred.c
@@ -15,247 +15,281 @@
  *		         from Ren Liu
  *		       - More error checks
  *
- *
- *
- *  For all the glorious comments look at Alexey's sch_red.c
+ *  For all the glorious comments look at include/net/red.h
  */
 
 #include <linux/config.h>
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
 #include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
-#include <net/ip.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
-#include <net/sock.h>
 #include <net/pkt_sched.h>
+#include <net/red.h>
 
-#if 1 /* control */
-#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define DPRINTK(format,args...)
-#endif
-
-#if 0 /* data */
-#define D2PRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define D2PRINTK(format,args...)
-#endif
+#define GRED_DEF_PRIO (MAX_DPs / 2)
+#define GRED_VQ_MASK (MAX_DPs - 1)
 
 struct gred_sched_data;
 struct gred_sched;
 
 struct gred_sched_data
 {
-/* Parameters */
 	u32		limit;		/* HARD maximal queue length	*/
-	u32		qth_min;	/* Min average length threshold: A scaled */
-	u32		qth_max;	/* Max average length threshold: A scaled */
 	u32      	DP;		/* the drop pramaters */
-	char		Wlog;		/* log(W)		*/
-	char		Plog;		/* random number bits	*/
-	u32		Scell_max;
-	u32		Rmask;
 	u32		bytesin;	/* bytes seen on virtualQ so far*/
 	u32		packetsin;	/* packets seen on virtualQ so far*/
 	u32		backlog;	/* bytes on the virtualQ */
-	u32		forced;	/* packets dropped for exceeding limits */
-	u32		early;	/* packets dropped as a warning */
-	u32		other;	/* packets dropped by invoking drop() */
-	u32		pdrop;	/* packets dropped because we exceeded physical queue limits */
-	char		Scell_log;
-	u8		Stab[256];
-	u8              prio;        /* the prio of this vq */
+	u8		prio;		/* the prio of this vq */
 
-/* Variables */
-	unsigned long	qave;		/* Average queue length: A scaled */
-	int		qcount;		/* Packets since last random number generation */
-	u32		qR;		/* Cached random number */
+	struct red_parms parms;
+	struct red_stats stats;
+};
 
-	psched_time_t	qidlestart;	/* Start of idle period	*/
+enum {
+	GRED_WRED_MODE = 1,
+	GRED_RIO_MODE,
 };
 
 struct gred_sched
 {
 	struct gred_sched_data *tab[MAX_DPs];
-	u32 		DPs;   
-	u32 		def; 
-	u8 		initd; 
-	u8 		grio; 
-	u8 		eqp; 
+	unsigned long	flags;
+	u32		red_flags;
+	u32 		DPs;
+	u32 		def;
+	struct red_parms wred_set;
 };
 
-static int
-gred_enqueue(struct sk_buff *skb, struct Qdisc* sch)
+static inline int gred_wred_mode(struct gred_sched *table)
 {
-	psched_time_t now;
-	struct gred_sched_data *q=NULL;
-	struct gred_sched *t= qdisc_priv(sch);
-	unsigned long	qave=0;	
-	int i=0;
-
-	if (!t->initd && skb_queue_len(&sch->q) < (sch->dev->tx_queue_len ? : 1)) {
-		D2PRINTK("NO GRED Queues setup yet! Enqueued anyway\n");
-		goto do_enqueue;
-	}
-
-
-	if ( ((skb->tc_index&0xf) > (t->DPs -1)) || !(q=t->tab[skb->tc_index&0xf])) {
-		printk("GRED: setting to default (%d)\n ",t->def);
-		if (!(q=t->tab[t->def])) {
-			DPRINTK("GRED: setting to default FAILED! dropping!! "
-			    "(%d)\n ", t->def);
-			goto drop;
-		}
-		/* fix tc_index? --could be controvesial but needed for
-		   requeueing */
-		skb->tc_index=(skb->tc_index&0xfffffff0) | t->def;
-	}
-
-	D2PRINTK("gred_enqueue virtualQ 0x%x classid %x backlog %d "
-	    "general backlog %d\n",skb->tc_index&0xf,sch->handle,q->backlog,
-	    sch->qstats.backlog);
-	/* sum up all the qaves of prios <= to ours to get the new qave*/
-	if (!t->eqp && t->grio) {
-		for (i=0;i<t->DPs;i++) {
-			if ((!t->tab[i]) || (i==q->DP))	
-				continue; 
-				
-			if ((t->tab[i]->prio < q->prio) && (PSCHED_IS_PASTPERFECT(t->tab[i]->qidlestart)))
-				qave +=t->tab[i]->qave;
-		}
-			
-	}
-
-	q->packetsin++;
-	q->bytesin+=skb->len;
-
-	if (t->eqp && t->grio) {
-		qave=0;
-		q->qave=t->tab[t->def]->qave;
-		q->qidlestart=t->tab[t->def]->qidlestart;
-	}
-
-	if (!PSCHED_IS_PASTPERFECT(q->qidlestart)) {
-		long us_idle;
-		PSCHED_GET_TIME(now);
-		us_idle = PSCHED_TDIFF_SAFE(now, q->qidlestart, q->Scell_max);
-		PSCHED_SET_PASTPERFECT(q->qidlestart);
-
-		q->qave >>= q->Stab[(us_idle>>q->Scell_log)&0xFF];
-	} else {
-		if (t->eqp) {
-			q->qave += sch->qstats.backlog - (q->qave >> q->Wlog);
-		} else {
-			q->qave += q->backlog - (q->qave >> q->Wlog);
-		}
-
-	}
-	
-
-	if (t->eqp && t->grio) 
-		t->tab[t->def]->qave=q->qave;
-
-	if ((q->qave+qave) < q->qth_min) {
-		q->qcount = -1;
-enqueue:
-		if (q->backlog + skb->len <= q->limit) {
-			q->backlog += skb->len;
-do_enqueue:
-			__skb_queue_tail(&sch->q, skb);
-			sch->qstats.backlog += skb->len;
-			sch->bstats.bytes += skb->len;
-			sch->bstats.packets++;
-			return 0;
-		} else {
-			q->pdrop++;
-		}
-
-drop:
-		kfree_skb(skb);
-		sch->qstats.drops++;
-		return NET_XMIT_DROP;
-	}
-	if ((q->qave+qave) >= q->qth_max) {
-		q->qcount = -1;
-		sch->qstats.overlimits++;
-		q->forced++;
-		goto drop;
-	}
-	if (++q->qcount) {
-		if ((((qave+q->qave) - q->qth_min)>>q->Wlog)*q->qcount < q->qR)
-			goto enqueue;
-		q->qcount = 0;
-		q->qR = net_random()&q->Rmask;
-		sch->qstats.overlimits++;
-		q->early++;
-		goto drop;
-	}
-	q->qR = net_random()&q->Rmask;
-	goto enqueue;
+	return test_bit(GRED_WRED_MODE, &table->flags);
 }
 
-static int
-gred_requeue(struct sk_buff *skb, struct Qdisc* sch)
+static inline void gred_enable_wred_mode(struct gred_sched *table)
 {
-	struct gred_sched_data *q;
-	struct gred_sched *t= qdisc_priv(sch);
-	q= t->tab[(skb->tc_index&0xf)];
-/* error checking here -- probably unnecessary */
-	PSCHED_SET_PASTPERFECT(q->qidlestart);
+	__set_bit(GRED_WRED_MODE, &table->flags);
+}
 
-	__skb_queue_head(&sch->q, skb);
-	sch->qstats.backlog += skb->len;
-	sch->qstats.requeues++;
-	q->backlog += skb->len;
+static inline void gred_disable_wred_mode(struct gred_sched *table)
+{
+	__clear_bit(GRED_WRED_MODE, &table->flags);
+}
+
+static inline int gred_rio_mode(struct gred_sched *table)
+{
+	return test_bit(GRED_RIO_MODE, &table->flags);
+}
+
+static inline void gred_enable_rio_mode(struct gred_sched *table)
+{
+	__set_bit(GRED_RIO_MODE, &table->flags);
+}
+
+static inline void gred_disable_rio_mode(struct gred_sched *table)
+{
+	__clear_bit(GRED_RIO_MODE, &table->flags);
+}
+
+static inline int gred_wred_mode_check(struct Qdisc *sch)
+{
+	struct gred_sched *table = qdisc_priv(sch);
+	int i;
+
+	/* Really ugly O(n^2) but shouldn't be necessary too frequent. */
+	for (i = 0; i < table->DPs; i++) {
+		struct gred_sched_data *q = table->tab[i];
+		int n;
+
+		if (q == NULL)
+			continue;
+
+		for (n = 0; n < table->DPs; n++)
+			if (table->tab[n] && table->tab[n] != q &&
+			    table->tab[n]->prio == q->prio)
+				return 1;
+	}
+
 	return 0;
 }
 
-static struct sk_buff *
-gred_dequeue(struct Qdisc* sch)
+static inline unsigned int gred_backlog(struct gred_sched *table,
+					struct gred_sched_data *q,
+					struct Qdisc *sch)
+{
+	if (gred_wred_mode(table))
+		return sch->qstats.backlog;
+	else
+		return q->backlog;
+}
+
+static inline u16 tc_index_to_dp(struct sk_buff *skb)
+{
+	return skb->tc_index & GRED_VQ_MASK;
+}
+
+static inline void gred_load_wred_set(struct gred_sched *table,
+				      struct gred_sched_data *q)
+{
+	q->parms.qavg = table->wred_set.qavg;
+	q->parms.qidlestart = table->wred_set.qidlestart;
+}
+
+static inline void gred_store_wred_set(struct gred_sched *table,
+				       struct gred_sched_data *q)
+{
+	table->wred_set.qavg = q->parms.qavg;
+}
+
+static inline int gred_use_ecn(struct gred_sched *t)
+{
+	return t->red_flags & TC_RED_ECN;
+}
+
+static inline int gred_use_harddrop(struct gred_sched *t)
+{
+	return t->red_flags & TC_RED_HARDDROP;
+}
+
+static int gred_enqueue(struct sk_buff *skb, struct Qdisc* sch)
+{
+	struct gred_sched_data *q=NULL;
+	struct gred_sched *t= qdisc_priv(sch);
+	unsigned long qavg = 0;
+	u16 dp = tc_index_to_dp(skb);
+
+	if (dp >= t->DPs  || (q = t->tab[dp]) == NULL) {
+		dp = t->def;
+
+		if ((q = t->tab[dp]) == NULL) {
+			/* Pass through packets not assigned to a DP
+			 * if no default DP has been configured. This
+			 * allows for DP flows to be left untouched.
+			 */
+			if (skb_queue_len(&sch->q) < sch->dev->tx_queue_len)
+				return qdisc_enqueue_tail(skb, sch);
+			else
+				goto drop;
+		}
+
+		/* fix tc_index? --could be controvesial but needed for
+		   requeueing */
+		skb->tc_index = (skb->tc_index & ~GRED_VQ_MASK) | dp;
+	}
+
+	/* sum up all the qaves of prios <= to ours to get the new qave */
+	if (!gred_wred_mode(t) && gred_rio_mode(t)) {
+		int i;
+
+		for (i = 0; i < t->DPs; i++) {
+			if (t->tab[i] && t->tab[i]->prio < q->prio &&
+			    !red_is_idling(&t->tab[i]->parms))
+				qavg +=t->tab[i]->parms.qavg;
+		}
+
+	}
+
+	q->packetsin++;
+	q->bytesin += skb->len;
+
+	if (gred_wred_mode(t))
+		gred_load_wred_set(t, q);
+
+	q->parms.qavg = red_calc_qavg(&q->parms, gred_backlog(t, q, sch));
+
+	if (red_is_idling(&q->parms))
+		red_end_of_idle_period(&q->parms);
+
+	if (gred_wred_mode(t))
+		gred_store_wred_set(t, q);
+
+	switch (red_action(&q->parms, q->parms.qavg + qavg)) {
+		case RED_DONT_MARK:
+			break;
+
+		case RED_PROB_MARK:
+			sch->qstats.overlimits++;
+			if (!gred_use_ecn(t) || !INET_ECN_set_ce(skb)) {
+				q->stats.prob_drop++;
+				goto congestion_drop;
+			}
+
+			q->stats.prob_mark++;
+			break;
+
+		case RED_HARD_MARK:
+			sch->qstats.overlimits++;
+			if (gred_use_harddrop(t) || !gred_use_ecn(t) ||
+			    !INET_ECN_set_ce(skb)) {
+				q->stats.forced_drop++;
+				goto congestion_drop;
+			}
+			q->stats.forced_mark++;
+			break;
+	}
+
+	if (q->backlog + skb->len <= q->limit) {
+		q->backlog += skb->len;
+		return qdisc_enqueue_tail(skb, sch);
+	}
+
+	q->stats.pdrop++;
+drop:
+	return qdisc_drop(skb, sch);
+
+congestion_drop:
+	qdisc_drop(skb, sch);
+	return NET_XMIT_CN;
+}
+
+static int gred_requeue(struct sk_buff *skb, struct Qdisc* sch)
+{
+	struct gred_sched *t = qdisc_priv(sch);
+	struct gred_sched_data *q;
+	u16 dp = tc_index_to_dp(skb);
+
+	if (dp >= t->DPs || (q = t->tab[dp]) == NULL) {
+		if (net_ratelimit())
+			printk(KERN_WARNING "GRED: Unable to relocate VQ 0x%x "
+			       "for requeue, screwing up backlog.\n",
+			       tc_index_to_dp(skb));
+	} else {
+		if (red_is_idling(&q->parms))
+			red_end_of_idle_period(&q->parms);
+		q->backlog += skb->len;
+	}
+
+	return qdisc_requeue(skb, sch);
+}
+
+static struct sk_buff *gred_dequeue(struct Qdisc* sch)
 {
 	struct sk_buff *skb;
-	struct gred_sched_data *q;
-	struct gred_sched *t= qdisc_priv(sch);
+	struct gred_sched *t = qdisc_priv(sch);
 
-	skb = __skb_dequeue(&sch->q);
+	skb = qdisc_dequeue_head(sch);
+
 	if (skb) {
-		sch->qstats.backlog -= skb->len;
-		q= t->tab[(skb->tc_index&0xf)];
-		if (q) {
-			q->backlog -= skb->len;
-			if (!q->backlog && !t->eqp)
-				PSCHED_GET_TIME(q->qidlestart);
+		struct gred_sched_data *q;
+		u16 dp = tc_index_to_dp(skb);
+
+		if (dp >= t->DPs || (q = t->tab[dp]) == NULL) {
+			if (net_ratelimit())
+				printk(KERN_WARNING "GRED: Unable to relocate "
+				       "VQ 0x%x after dequeue, screwing up "
+				       "backlog.\n", tc_index_to_dp(skb));
 		} else {
-			D2PRINTK("gred_dequeue: skb has bad tcindex %x\n",skb->tc_index&0xf); 
+			q->backlog -= skb->len;
+
+			if (!q->backlog && !gred_wred_mode(t))
+				red_start_of_idle_period(&q->parms);
 		}
+
 		return skb;
 	}
 
-	if (t->eqp) {
-			q= t->tab[t->def];
-			if (!q)	
-				D2PRINTK("no default VQ set: Results will be "
-				       "screwed up\n");
-			else
-				PSCHED_GET_TIME(q->qidlestart);
-	}
+	if (gred_wred_mode(t) && !red_is_idling(&t->wred_set))
+		red_start_of_idle_period(&t->wred_set);
 
 	return NULL;
 }
@@ -263,36 +297,34 @@
 static unsigned int gred_drop(struct Qdisc* sch)
 {
 	struct sk_buff *skb;
+	struct gred_sched *t = qdisc_priv(sch);
 
-	struct gred_sched_data *q;
-	struct gred_sched *t= qdisc_priv(sch);
-
-	skb = __skb_dequeue_tail(&sch->q);
+	skb = qdisc_dequeue_tail(sch);
 	if (skb) {
 		unsigned int len = skb->len;
-		sch->qstats.backlog -= len;
-		sch->qstats.drops++;
-		q= t->tab[(skb->tc_index&0xf)];
-		if (q) {
-			q->backlog -= len;
-			q->other++;
-			if (!q->backlog && !t->eqp)
-				PSCHED_GET_TIME(q->qidlestart);
+		struct gred_sched_data *q;
+		u16 dp = tc_index_to_dp(skb);
+
+		if (dp >= t->DPs || (q = t->tab[dp]) == NULL) {
+			if (net_ratelimit())
+				printk(KERN_WARNING "GRED: Unable to relocate "
+				       "VQ 0x%x while dropping, screwing up "
+				       "backlog.\n", tc_index_to_dp(skb));
 		} else {
-			D2PRINTK("gred_dequeue: skb has bad tcindex %x\n",skb->tc_index&0xf); 
+			q->backlog -= len;
+			q->stats.other++;
+
+			if (!q->backlog && !gred_wred_mode(t))
+				red_start_of_idle_period(&q->parms);
 		}
 
-		kfree_skb(skb);
+		qdisc_drop(skb, sch);
 		return len;
 	}
 
-	q=t->tab[t->def];
-	if (!q) {
-		D2PRINTK("no default VQ set: Results might be screwed up\n");
-		return 0;
-	}
+	if (gred_wred_mode(t) && !red_is_idling(&t->wred_set))
+		red_start_of_idle_period(&t->wred_set);
 
-	PSCHED_GET_TIME(q->qidlestart);
 	return 0;
 
 }
@@ -300,293 +332,241 @@
 static void gred_reset(struct Qdisc* sch)
 {
 	int i;
-	struct gred_sched_data *q;
-	struct gred_sched *t= qdisc_priv(sch);
+	struct gred_sched *t = qdisc_priv(sch);
 
-	__skb_queue_purge(&sch->q);
+	qdisc_reset_queue(sch);
 
-	sch->qstats.backlog = 0;
+        for (i = 0; i < t->DPs; i++) {
+		struct gred_sched_data *q = t->tab[i];
 
-        for (i=0;i<t->DPs;i++) {
-	        q= t->tab[i];
-		if (!q)	
-			continue; 
-		PSCHED_SET_PASTPERFECT(q->qidlestart);
-		q->qave = 0;
-		q->qcount = -1;
+		if (!q)
+			continue;
+
+		red_restart(&q->parms);
 		q->backlog = 0;
-		q->other=0;
-		q->forced=0;
-		q->pdrop=0;
-		q->early=0;
 	}
 }
 
+static inline void gred_destroy_vq(struct gred_sched_data *q)
+{
+	kfree(q);
+}
+
+static inline int gred_change_table_def(struct Qdisc *sch, struct rtattr *dps)
+{
+	struct gred_sched *table = qdisc_priv(sch);
+	struct tc_gred_sopt *sopt;
+	int i;
+
+	if (dps == NULL || RTA_PAYLOAD(dps) < sizeof(*sopt))
+		return -EINVAL;
+
+	sopt = RTA_DATA(dps);
+
+	if (sopt->DPs > MAX_DPs || sopt->DPs == 0 || sopt->def_DP >= sopt->DPs)
+		return -EINVAL;
+
+	sch_tree_lock(sch);
+	table->DPs = sopt->DPs;
+	table->def = sopt->def_DP;
+	table->red_flags = sopt->flags;
+
+	/*
+	 * Every entry point to GRED is synchronized with the above code
+	 * and the DP is checked against DPs, i.e. shadowed VQs can no
+	 * longer be found so we can unlock right here.
+	 */
+	sch_tree_unlock(sch);
+
+	if (sopt->grio) {
+		gred_enable_rio_mode(table);
+		gred_disable_wred_mode(table);
+		if (gred_wred_mode_check(sch))
+			gred_enable_wred_mode(table);
+	} else {
+		gred_disable_rio_mode(table);
+		gred_disable_wred_mode(table);
+	}
+
+	for (i = table->DPs; i < MAX_DPs; i++) {
+		if (table->tab[i]) {
+			printk(KERN_WARNING "GRED: Warning: Destroying "
+			       "shadowed VQ 0x%x\n", i);
+			gred_destroy_vq(table->tab[i]);
+			table->tab[i] = NULL;
+  		}
+	}
+
+	return 0;
+}
+
+static inline int gred_change_vq(struct Qdisc *sch, int dp,
+				 struct tc_gred_qopt *ctl, int prio, u8 *stab)
+{
+	struct gred_sched *table = qdisc_priv(sch);
+	struct gred_sched_data *q;
+
+	if (table->tab[dp] == NULL) {
+		table->tab[dp] = kmalloc(sizeof(*q), GFP_KERNEL);
+		if (table->tab[dp] == NULL)
+			return -ENOMEM;
+		memset(table->tab[dp], 0, sizeof(*q));
+	}
+
+	q = table->tab[dp];
+	q->DP = dp;
+	q->prio = prio;
+	q->limit = ctl->limit;
+
+	if (q->backlog == 0)
+		red_end_of_idle_period(&q->parms);
+
+	red_set_parms(&q->parms,
+		      ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Plog,
+		      ctl->Scell_log, stab);
+
+	return 0;
+}
+
 static int gred_change(struct Qdisc *sch, struct rtattr *opt)
 {
 	struct gred_sched *table = qdisc_priv(sch);
-	struct gred_sched_data *q;
 	struct tc_gred_qopt *ctl;
-	struct tc_gred_sopt *sopt;
-	struct rtattr *tb[TCA_GRED_STAB];
-	struct rtattr *tb2[TCA_GRED_DPS];
-	int i;
+	struct rtattr *tb[TCA_GRED_MAX];
+	int err = -EINVAL, prio = GRED_DEF_PRIO;
+	u8 *stab;
 
-	if (opt == NULL || rtattr_parse_nested(tb, TCA_GRED_STAB, opt))
+	if (opt == NULL || rtattr_parse_nested(tb, TCA_GRED_MAX, opt))
 		return -EINVAL;
 
-	if (tb[TCA_GRED_PARMS-1] == 0 && tb[TCA_GRED_STAB-1] == 0) {
-		rtattr_parse_nested(tb2, TCA_GRED_DPS, opt);
+	if (tb[TCA_GRED_PARMS-1] == NULL && tb[TCA_GRED_STAB-1] == NULL)
+		return gred_change_table_def(sch, opt);
 
-	    if (tb2[TCA_GRED_DPS-1] == 0) 
-			return -EINVAL;
-
-		sopt = RTA_DATA(tb2[TCA_GRED_DPS-1]);
-		table->DPs=sopt->DPs;   
-		table->def=sopt->def_DP; 
-		table->grio=sopt->grio; 
-		table->initd=0;
-		/* probably need to clear all the table DP entries as well */
-		return 0;
-	    }
-
-
-	if (!table->DPs || tb[TCA_GRED_PARMS-1] == 0 || tb[TCA_GRED_STAB-1] == 0 ||
-		RTA_PAYLOAD(tb[TCA_GRED_PARMS-1]) < sizeof(*ctl) ||
-		RTA_PAYLOAD(tb[TCA_GRED_STAB-1]) < 256)
-			return -EINVAL;
+	if (tb[TCA_GRED_PARMS-1] == NULL ||
+	    RTA_PAYLOAD(tb[TCA_GRED_PARMS-1]) < sizeof(*ctl) ||
+	    tb[TCA_GRED_STAB-1] == NULL ||
+	    RTA_PAYLOAD(tb[TCA_GRED_STAB-1]) < 256)
+		return -EINVAL;
 
 	ctl = RTA_DATA(tb[TCA_GRED_PARMS-1]);
-	if (ctl->DP > MAX_DPs-1 ) {
-		/* misbehaving is punished! Put in the default drop probability */
-		DPRINTK("\nGRED: DP %u not in  the proper range fixed. New DP "
-			"set to default at %d\n",ctl->DP,table->def);
-		ctl->DP=table->def;
-	}
-	
-	if (table->tab[ctl->DP] == NULL) {
-		table->tab[ctl->DP]=kmalloc(sizeof(struct gred_sched_data),
-					    GFP_KERNEL);
-		if (NULL == table->tab[ctl->DP])
-			return -ENOMEM;
-		memset(table->tab[ctl->DP], 0, (sizeof(struct gred_sched_data)));
-	}
-	q= table->tab[ctl->DP]; 
+	stab = RTA_DATA(tb[TCA_GRED_STAB-1]);
 
-	if (table->grio) {
-		if (ctl->prio <=0) {
-			if (table->def && table->tab[table->def]) {
-				DPRINTK("\nGRED: DP %u does not have a prio"
-					"setting default to %d\n",ctl->DP,
-					table->tab[table->def]->prio);
-				q->prio=table->tab[table->def]->prio;
-			} else { 
-				DPRINTK("\nGRED: DP %u does not have a prio"
-					" setting default to 8\n",ctl->DP);
-				q->prio=8;
-			}
-		} else {
-			q->prio=ctl->prio;
-		}
-	} else {
-		q->prio=8;
+	if (ctl->DP >= table->DPs)
+		goto errout;
+
+	if (gred_rio_mode(table)) {
+		if (ctl->prio == 0) {
+			int def_prio = GRED_DEF_PRIO;
+
+			if (table->tab[table->def])
+				def_prio = table->tab[table->def]->prio;
+
+			printk(KERN_DEBUG "GRED: DP %u does not have a prio "
+			       "setting default to %d\n", ctl->DP, def_prio);
+
+			prio = def_prio;
+		} else
+			prio = ctl->prio;
 	}
 
+	sch_tree_lock(sch);
 
-	q->DP=ctl->DP;
-	q->Wlog = ctl->Wlog;
-	q->Plog = ctl->Plog;
-	q->limit = ctl->limit;
-	q->Scell_log = ctl->Scell_log;
-	q->Rmask = ctl->Plog < 32 ? ((1<<ctl->Plog) - 1) : ~0UL;
-	q->Scell_max = (255<<q->Scell_log);
-	q->qth_min = ctl->qth_min<<ctl->Wlog;
-	q->qth_max = ctl->qth_max<<ctl->Wlog;
-	q->qave=0;
-	q->backlog=0;
-	q->qcount = -1;
-	q->other=0;
-	q->forced=0;
-	q->pdrop=0;
-	q->early=0;
+	err = gred_change_vq(sch, ctl->DP, ctl, prio, stab);
+	if (err < 0)
+		goto errout_locked;
 
-	PSCHED_SET_PASTPERFECT(q->qidlestart);
-	memcpy(q->Stab, RTA_DATA(tb[TCA_GRED_STAB-1]), 256);
-
-	if ( table->initd && table->grio) {
-	/* this looks ugly but it's not in the fast path */
-		for (i=0;i<table->DPs;i++) {
-			if ((!table->tab[i]) || (i==q->DP) )    
-				continue; 
-			if (table->tab[i]->prio == q->prio ){
-				/* WRED mode detected */
-				table->eqp=1;
-				break;
-			}
-		}
+	if (gred_rio_mode(table)) {
+		gred_disable_wred_mode(table);
+		if (gred_wred_mode_check(sch))
+			gred_enable_wred_mode(table);
 	}
 
-	if (!table->initd) {
-		table->initd=1;
-		/* 
-        	the first entry also goes into the default until
-        	over-written 
-		*/
+	err = 0;
 
-		if (table->tab[table->def] == NULL) {
-			table->tab[table->def]=
-				kmalloc(sizeof(struct gred_sched_data), GFP_KERNEL);
-			if (NULL == table->tab[table->def])
-				return -ENOMEM;
-
-			memset(table->tab[table->def], 0,
-			       (sizeof(struct gred_sched_data)));
-		}
-		q= table->tab[table->def]; 
-		q->DP=table->def;
-		q->Wlog = ctl->Wlog;
-		q->Plog = ctl->Plog;
-		q->limit = ctl->limit;
-		q->Scell_log = ctl->Scell_log;
-		q->Rmask = ctl->Plog < 32 ? ((1<<ctl->Plog) - 1) : ~0UL;
-		q->Scell_max = (255<<q->Scell_log);
-		q->qth_min = ctl->qth_min<<ctl->Wlog;
-		q->qth_max = ctl->qth_max<<ctl->Wlog;
-
-		if (table->grio)
-			q->prio=table->tab[ctl->DP]->prio;
-		else
-			q->prio=8;
-
-		q->qcount = -1;
-		PSCHED_SET_PASTPERFECT(q->qidlestart);
-		memcpy(q->Stab, RTA_DATA(tb[TCA_GRED_STAB-1]), 256);
-	}
-	return 0;
-
+errout_locked:
+	sch_tree_unlock(sch);
+errout:
+	return err;
 }
 
 static int gred_init(struct Qdisc *sch, struct rtattr *opt)
 {
-	struct gred_sched *table = qdisc_priv(sch);
-	struct tc_gred_sopt *sopt;
-	struct rtattr *tb[TCA_GRED_STAB];
-	struct rtattr *tb2[TCA_GRED_DPS];
+	struct rtattr *tb[TCA_GRED_MAX];
 
-	if (opt == NULL || rtattr_parse_nested(tb, TCA_GRED_STAB, opt))
+	if (opt == NULL || rtattr_parse_nested(tb, TCA_GRED_MAX, opt))
 		return -EINVAL;
 
-	if (tb[TCA_GRED_PARMS-1] == 0 && tb[TCA_GRED_STAB-1] == 0) {
-		rtattr_parse_nested(tb2, TCA_GRED_DPS, opt);
+	if (tb[TCA_GRED_PARMS-1] || tb[TCA_GRED_STAB-1])
+		return -EINVAL;
 
-	    if (tb2[TCA_GRED_DPS-1] == 0) 
-			return -EINVAL;
-
-		sopt = RTA_DATA(tb2[TCA_GRED_DPS-1]);
-		table->DPs=sopt->DPs;   
-		table->def=sopt->def_DP; 
-		table->grio=sopt->grio; 
-		table->initd=0;
-		return 0;
-	}
-
-	DPRINTK("\n GRED_INIT error!\n");
-	return -EINVAL;
+	return gred_change_table_def(sch, tb[TCA_GRED_DPS-1]);
 }
 
 static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
-	unsigned long qave;
-	struct rtattr *rta;
-	struct tc_gred_qopt *opt = NULL ;
-	struct tc_gred_qopt *dst;
 	struct gred_sched *table = qdisc_priv(sch);
-	struct gred_sched_data *q;
+	struct rtattr *parms, *opts = NULL;
 	int i;
-	unsigned char	 *b = skb->tail;
+	struct tc_gred_sopt sopt = {
+		.DPs	= table->DPs,
+		.def_DP	= table->def,
+		.grio	= gred_rio_mode(table),
+		.flags	= table->red_flags,
+	};
 
-	rta = (struct rtattr*)b;
-	RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
+	opts = RTA_NEST(skb, TCA_OPTIONS);
+	RTA_PUT(skb, TCA_GRED_DPS, sizeof(sopt), &sopt);
+	parms = RTA_NEST(skb, TCA_GRED_PARMS);
 
-	opt=kmalloc(sizeof(struct tc_gred_qopt)*MAX_DPs, GFP_KERNEL);
+	for (i = 0; i < MAX_DPs; i++) {
+		struct gred_sched_data *q = table->tab[i];
+		struct tc_gred_qopt opt;
 
-	if (opt  == NULL) {
-		DPRINTK("gred_dump:failed to malloc for %Zd\n",
-		    sizeof(struct tc_gred_qopt)*MAX_DPs);
-		goto rtattr_failure;
-	}
-
-	memset(opt, 0, (sizeof(struct tc_gred_qopt))*table->DPs);
-
-	if (!table->initd) {
-		DPRINTK("NO GRED Queues setup!\n");
-	}
-
-	for (i=0;i<MAX_DPs;i++) {
-		dst= &opt[i]; 
-		q= table->tab[i]; 
+		memset(&opt, 0, sizeof(opt));
 
 		if (!q) {
 			/* hack -- fix at some point with proper message
 			   This is how we indicate to tc that there is no VQ
 			   at this DP */
 
-			dst->DP=MAX_DPs+i;
-			continue;
+			opt.DP = MAX_DPs + i;
+			goto append_opt;
 		}
 
-		dst->limit=q->limit;
-		dst->qth_min=q->qth_min>>q->Wlog;
-		dst->qth_max=q->qth_max>>q->Wlog;
-		dst->DP=q->DP;
-		dst->backlog=q->backlog;
-		if (q->qave) {
-			if (table->eqp && table->grio) {
-				q->qidlestart=table->tab[table->def]->qidlestart;
-				q->qave=table->tab[table->def]->qave;
-			}
-			if (!PSCHED_IS_PASTPERFECT(q->qidlestart)) {
-				long idle;
-				psched_time_t now;
-				PSCHED_GET_TIME(now);
-				idle = PSCHED_TDIFF_SAFE(now, q->qidlestart, q->Scell_max);
-				qave  = q->qave >> q->Stab[(idle>>q->Scell_log)&0xFF];
-				dst->qave = qave >> q->Wlog;
+		opt.limit	= q->limit;
+		opt.DP		= q->DP;
+		opt.backlog	= q->backlog;
+		opt.prio	= q->prio;
+		opt.qth_min	= q->parms.qth_min >> q->parms.Wlog;
+		opt.qth_max	= q->parms.qth_max >> q->parms.Wlog;
+		opt.Wlog	= q->parms.Wlog;
+		opt.Plog	= q->parms.Plog;
+		opt.Scell_log	= q->parms.Scell_log;
+		opt.other	= q->stats.other;
+		opt.early	= q->stats.prob_drop;
+		opt.forced	= q->stats.forced_drop;
+		opt.pdrop	= q->stats.pdrop;
+		opt.packets	= q->packetsin;
+		opt.bytesin	= q->bytesin;
 
-			} else {
-				dst->qave = q->qave >> q->Wlog;
-			}
-		} else {
-			dst->qave = 0;
+		if (gred_wred_mode(table)) {
+			q->parms.qidlestart =
+				table->tab[table->def]->parms.qidlestart;
+			q->parms.qavg = table->tab[table->def]->parms.qavg;
 		}
-		
 
-		dst->Wlog = q->Wlog;
-		dst->Plog = q->Plog;
-		dst->Scell_log = q->Scell_log;
-		dst->other = q->other;
-		dst->forced = q->forced;
-		dst->early = q->early;
-		dst->pdrop = q->pdrop;
-		dst->prio = q->prio;
-		dst->packets=q->packetsin;
-		dst->bytesin=q->bytesin;
+		opt.qave = red_calc_qavg(&q->parms, q->parms.qavg);
+
+append_opt:
+		RTA_APPEND(skb, sizeof(opt), &opt);
 	}
 
-	RTA_PUT(skb, TCA_GRED_PARMS, sizeof(struct tc_gred_qopt)*MAX_DPs, opt);
-	rta->rta_len = skb->tail - b;
+	RTA_NEST_END(skb, parms);
 
-	kfree(opt);
-	return skb->len;
+	return RTA_NEST_END(skb, opts);
 
 rtattr_failure:
-	if (opt)
-		kfree(opt);
-	DPRINTK("gred_dump: FAILURE!!!!\n");
-
-/* also free the opt struct here */
-	skb_trim(skb, b - skb->data);
-	return -1;
+	return RTA_NEST_CANCEL(skb, opts);
 }
 
 static void gred_destroy(struct Qdisc *sch)
@@ -594,15 +574,13 @@
 	struct gred_sched *table = qdisc_priv(sch);
 	int i;
 
-	for (i = 0;i < table->DPs; i++) {
+	for (i = 0; i < table->DPs; i++) {
 		if (table->tab[i])
-			kfree(table->tab[i]);
+			gred_destroy_vq(table->tab[i]);
 	}
 }
 
 static struct Qdisc_ops gred_qdisc_ops = {
-	.next		=	NULL,
-	.cl_ops		=	NULL,
 	.id		=	"gred",
 	.priv_size	=	sizeof(struct gred_sched),
 	.enqueue	=	gred_enqueue,
@@ -621,10 +599,13 @@
 {
 	return register_qdisc(&gred_qdisc_ops);
 }
-static void __exit gred_module_exit(void) 
+
+static void __exit gred_module_exit(void)
 {
 	unregister_qdisc(&gred_qdisc_ops);
 }
+
 module_init(gred_module_init)
 module_exit(gred_module_exit)
+
 MODULE_LICENSE("GPL");
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index bb9bf8d..cdc8d28 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -25,6 +25,8 @@
 
 #include <net/pkt_sched.h>
 
+#define VERSION "1.1"
+
 /*	Network Emulation Queuing algorithm.
 	====================================
 
@@ -185,10 +187,13 @@
 	    || q->counter < q->gap 	/* inside last reordering gap */
 	    || q->reorder < get_crandom(&q->reorder_cor)) {
 		psched_time_t now;
+		psched_tdiff_t delay;
+
+		delay = tabledist(q->latency, q->jitter,
+				  &q->delay_cor, q->delay_dist);
+
 		PSCHED_GET_TIME(now);
-		PSCHED_TADD2(now, tabledist(q->latency, q->jitter, 
-					    &q->delay_cor, q->delay_dist),
-			     cb->time_to_send);
+		PSCHED_TADD2(now, delay, cb->time_to_send);
 		++q->counter;
 		ret = q->qdisc->enqueue(skb, q->qdisc);
 	} else {
@@ -248,24 +253,31 @@
 		const struct netem_skb_cb *cb
 			= (const struct netem_skb_cb *)skb->cb;
 		psched_time_t now;
-		long delay;
 
 		/* if more time remaining? */
 		PSCHED_GET_TIME(now);
-		delay = PSCHED_US2JIFFIE(PSCHED_TDIFF(cb->time_to_send, now));
-		pr_debug("netem_run: skb=%p delay=%ld\n", skb, delay);
-		if (delay <= 0) {
+
+		if (PSCHED_TLESS(cb->time_to_send, now)) {
 			pr_debug("netem_dequeue: return skb=%p\n", skb);
 			sch->q.qlen--;
 			sch->flags &= ~TCQ_F_THROTTLED;
 			return skb;
+		} else {
+			psched_tdiff_t delay = PSCHED_TDIFF(cb->time_to_send, now);
+
+			if (q->qdisc->ops->requeue(skb, q->qdisc) != NET_XMIT_SUCCESS) {
+				sch->qstats.drops++;
+
+				/* After this qlen is confused */
+				printk(KERN_ERR "netem: queue discpline %s could not requeue\n",
+				       q->qdisc->ops->id);
+
+				sch->q.qlen--;
+			}
+
+			mod_timer(&q->timer, jiffies + PSCHED_US2JIFFIE(delay));
+			sch->flags |= TCQ_F_THROTTLED;
 		}
-
-		mod_timer(&q->timer, jiffies + delay);
-		sch->flags |= TCQ_F_THROTTLED;
-
-		if (q->qdisc->ops->requeue(skb, q->qdisc) != 0)
-			sch->qstats.drops++;
 	}
 
 	return NULL;
@@ -290,11 +302,16 @@
 	del_timer_sync(&q->timer);
 }
 
+/* Pass size change message down to embedded FIFO */
 static int set_fifo_limit(struct Qdisc *q, int limit)
 {
         struct rtattr *rta;
 	int ret = -ENOMEM;
 
+	/* Hack to avoid sending change message to non-FIFO */
+	if (strncmp(q->ops->id + 1, "fifo", 4) != 0)
+		return 0;
+
 	rta = kmalloc(RTA_LENGTH(sizeof(struct tc_fifo_qopt)), GFP_KERNEL);
 	if (rta) {
 		rta->rta_type = RTM_NEWQDISC;
@@ -426,6 +443,84 @@
 	return 0;
 }
 
+/*
+ * Special case version of FIFO queue for use by netem.
+ * It queues in order based on timestamps in skb's
+ */
+struct fifo_sched_data {
+	u32 limit;
+};
+
+static int tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch)
+{
+	struct fifo_sched_data *q = qdisc_priv(sch);
+	struct sk_buff_head *list = &sch->q;
+	const struct netem_skb_cb *ncb
+		= (const struct netem_skb_cb *)nskb->cb;
+	struct sk_buff *skb;
+
+	if (likely(skb_queue_len(list) < q->limit)) {
+		skb_queue_reverse_walk(list, skb) {
+			const struct netem_skb_cb *cb
+				= (const struct netem_skb_cb *)skb->cb;
+
+			if (PSCHED_TLESS(cb->time_to_send, ncb->time_to_send))
+				break;
+		}
+
+		__skb_queue_after(list, skb, nskb);
+
+		sch->qstats.backlog += nskb->len;
+		sch->bstats.bytes += nskb->len;
+		sch->bstats.packets++;
+
+		return NET_XMIT_SUCCESS;
+	}
+
+	return qdisc_drop(nskb, sch);
+}
+
+static int tfifo_init(struct Qdisc *sch, struct rtattr *opt)
+{
+	struct fifo_sched_data *q = qdisc_priv(sch);
+
+	if (opt) {
+		struct tc_fifo_qopt *ctl = RTA_DATA(opt);
+		if (RTA_PAYLOAD(opt) < sizeof(*ctl))
+			return -EINVAL;
+
+		q->limit = ctl->limit;
+	} else
+		q->limit = max_t(u32, sch->dev->tx_queue_len, 1);
+
+	return 0;
+}
+
+static int tfifo_dump(struct Qdisc *sch, struct sk_buff *skb)
+{
+	struct fifo_sched_data *q = qdisc_priv(sch);
+	struct tc_fifo_qopt opt = { .limit = q->limit };
+
+	RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+	return skb->len;
+
+rtattr_failure:
+	return -1;
+}
+
+static struct Qdisc_ops tfifo_qdisc_ops = {
+	.id		=	"tfifo",
+	.priv_size	=	sizeof(struct fifo_sched_data),
+	.enqueue	=	tfifo_enqueue,
+	.dequeue	=	qdisc_dequeue_head,
+	.requeue	=	qdisc_requeue,
+	.drop		=	qdisc_queue_drop,
+	.init		=	tfifo_init,
+	.reset		=	qdisc_reset_queue,
+	.change		=	tfifo_init,
+	.dump		=	tfifo_dump,
+};
+
 static int netem_init(struct Qdisc *sch, struct rtattr *opt)
 {
 	struct netem_sched_data *q = qdisc_priv(sch);
@@ -438,7 +533,7 @@
 	q->timer.function = netem_watchdog;
 	q->timer.data = (unsigned long) sch;
 
-	q->qdisc = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
+	q->qdisc = qdisc_create_dflt(sch->dev, &tfifo_qdisc_ops);
 	if (!q->qdisc) {
 		pr_debug("netem: qdisc create failed\n");
 		return -ENOMEM;
@@ -601,6 +696,7 @@
 
 static int __init netem_module_init(void)
 {
+	pr_info("netem: version " VERSION "\n");
 	return register_qdisc(&netem_qdisc_ops);
 }
 static void __exit netem_module_exit(void)
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index 7845d04..dccfa44 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -9,76 +9,23 @@
  * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
  *
  * Changes:
- * J Hadi Salim <hadi@nortel.com> 980914:	computation fixes
+ * J Hadi Salim 980914:	computation fixes
  * Alexey Makarenko <makar@phoenix.kharkov.ua> 990814: qave on idle link was calculated incorrectly.
- * J Hadi Salim <hadi@nortelnetworks.com> 980816:  ECN support	
+ * J Hadi Salim 980816:  ECN support
  */
 
 #include <linux/config.h>
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
 #include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
-#include <net/ip.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
-#include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <net/inet_ecn.h>
-#include <net/dsfield.h>
+#include <net/red.h>
 
 
-/*	Random Early Detection (RED) algorithm.
-	=======================================
-
-	Source: Sally Floyd and Van Jacobson, "Random Early Detection Gateways
-	for Congestion Avoidance", 1993, IEEE/ACM Transactions on Networking.
-
-	This file codes a "divisionless" version of RED algorithm
-	as written down in Fig.17 of the paper.
-
-Short description.
-------------------
-
-	When a new packet arrives we calculate the average queue length:
-
-	avg = (1-W)*avg + W*current_queue_len,
-
-	W is the filter time constant (chosen as 2^(-Wlog)), it controls
-	the inertia of the algorithm. To allow larger bursts, W should be
-	decreased.
-
-	if (avg > th_max) -> packet marked (dropped).
-	if (avg < th_min) -> packet passes.
-	if (th_min < avg < th_max) we calculate probability:
-
-	Pb = max_P * (avg - th_min)/(th_max-th_min)
-
-	and mark (drop) packet with this probability.
-	Pb changes from 0 (at avg==th_min) to max_P (avg==th_max).
-	max_P should be small (not 1), usually 0.01..0.02 is good value.
-
-	max_P is chosen as a number, so that max_P/(th_max-th_min)
-	is a negative power of two in order arithmetics to contain
-	only shifts.
-
-
-	Parameters, settable by user:
+/*	Parameters, settable by user:
 	-----------------------------
 
 	limit		- bytes (must be > qth_max + burst)
@@ -89,243 +36,93 @@
 	arbitrarily high (well, less than ram size)
 	Really, this limit will never be reached
 	if RED works correctly.
-
-	qth_min		- bytes (should be < qth_max/2)
-	qth_max		- bytes (should be at least 2*qth_min and less limit)
-	Wlog	       	- bits (<32) log(1/W).
-	Plog	       	- bits (<32)
-
-	Plog is related to max_P by formula:
-
-	max_P = (qth_max-qth_min)/2^Plog;
-
-	F.e. if qth_max=128K and qth_min=32K, then Plog=22
-	corresponds to max_P=0.02
-
-	Scell_log
-	Stab
-
-	Lookup table for log((1-W)^(t/t_ave).
-
-
-NOTES:
-
-Upper bound on W.
------------------
-
-	If you want to allow bursts of L packets of size S,
-	you should choose W:
-
-	L + 1 - th_min/S < (1-(1-W)^L)/W
-
-	th_min/S = 32         th_min/S = 4
-			                       
-	log(W)	L
-	-1	33
-	-2	35
-	-3	39
-	-4	46
-	-5	57
-	-6	75
-	-7	101
-	-8	135
-	-9	190
-	etc.
  */
 
 struct red_sched_data
 {
-/* Parameters */
-	u32		limit;		/* HARD maximal queue length	*/
-	u32		qth_min;	/* Min average length threshold: A scaled */
-	u32		qth_max;	/* Max average length threshold: A scaled */
-	u32		Rmask;
-	u32		Scell_max;
-	unsigned char	flags;
-	char		Wlog;		/* log(W)		*/
-	char		Plog;		/* random number bits	*/
-	char		Scell_log;
-	u8		Stab[256];
-
-/* Variables */
-	unsigned long	qave;		/* Average queue length: A scaled */
-	int		qcount;		/* Packets since last random number generation */
-	u32		qR;		/* Cached random number */
-
-	psched_time_t	qidlestart;	/* Start of idle period		*/
-	struct tc_red_xstats st;
+	u32			limit;		/* HARD maximal queue length */
+	unsigned char		flags;
+	struct red_parms	parms;
+	struct red_stats	stats;
 };
 
-static int red_ecn_mark(struct sk_buff *skb)
+static inline int red_use_ecn(struct red_sched_data *q)
 {
-	if (skb->nh.raw + 20 > skb->tail)
-		return 0;
-
-	switch (skb->protocol) {
-	case __constant_htons(ETH_P_IP):
-		if (INET_ECN_is_not_ect(skb->nh.iph->tos))
-			return 0;
-		IP_ECN_set_ce(skb->nh.iph);
-		return 1;
-	case __constant_htons(ETH_P_IPV6):
-		if (INET_ECN_is_not_ect(ipv6_get_dsfield(skb->nh.ipv6h)))
-			return 0;
-		IP6_ECN_set_ce(skb->nh.ipv6h);
-		return 1;
-	default:
-		return 0;
-	}
+	return q->flags & TC_RED_ECN;
 }
 
-static int
-red_enqueue(struct sk_buff *skb, struct Qdisc* sch)
+static inline int red_use_harddrop(struct red_sched_data *q)
+{
+	return q->flags & TC_RED_HARDDROP;
+}
+
+static int red_enqueue(struct sk_buff *skb, struct Qdisc* sch)
 {
 	struct red_sched_data *q = qdisc_priv(sch);
 
-	psched_time_t now;
+	q->parms.qavg = red_calc_qavg(&q->parms, sch->qstats.backlog);
 
-	if (!PSCHED_IS_PASTPERFECT(q->qidlestart)) {
-		long us_idle;
-		int  shift;
+	if (red_is_idling(&q->parms))
+		red_end_of_idle_period(&q->parms);
 
-		PSCHED_GET_TIME(now);
-		us_idle = PSCHED_TDIFF_SAFE(now, q->qidlestart, q->Scell_max);
-		PSCHED_SET_PASTPERFECT(q->qidlestart);
+	switch (red_action(&q->parms, q->parms.qavg)) {
+		case RED_DONT_MARK:
+			break;
 
-/*
-   The problem: ideally, average length queue recalcultion should
-   be done over constant clock intervals. This is too expensive, so that
-   the calculation is driven by outgoing packets.
-   When the queue is idle we have to model this clock by hand.
+		case RED_PROB_MARK:
+			sch->qstats.overlimits++;
+			if (!red_use_ecn(q) || !INET_ECN_set_ce(skb)) {
+				q->stats.prob_drop++;
+				goto congestion_drop;
+			}
 
-   SF+VJ proposed to "generate" m = idletime/(average_pkt_size/bandwidth)
-   dummy packets as a burst after idle time, i.e.
+			q->stats.prob_mark++;
+			break;
 
-          q->qave *= (1-W)^m
+		case RED_HARD_MARK:
+			sch->qstats.overlimits++;
+			if (red_use_harddrop(q) || !red_use_ecn(q) ||
+			    !INET_ECN_set_ce(skb)) {
+				q->stats.forced_drop++;
+				goto congestion_drop;
+			}
 
-   This is an apparently overcomplicated solution (f.e. we have to precompute
-   a table to make this calculation in reasonable time)
-   I believe that a simpler model may be used here,
-   but it is field for experiments.
-*/
-		shift = q->Stab[us_idle>>q->Scell_log];
-
-		if (shift) {
-			q->qave >>= shift;
-		} else {
-			/* Approximate initial part of exponent
-			   with linear function:
-			   (1-W)^m ~= 1-mW + ...
-
-			   Seems, it is the best solution to
-			   problem of too coarce exponent tabulation.
-			 */
-
-			us_idle = (q->qave * us_idle)>>q->Scell_log;
-			if (us_idle < q->qave/2)
-				q->qave -= us_idle;
-			else
-				q->qave >>= 1;
-		}
-	} else {
-		q->qave += sch->qstats.backlog - (q->qave >> q->Wlog);
-		/* NOTE:
-		   q->qave is fixed point number with point at Wlog.
-		   The formulae above is equvalent to floating point
-		   version:
-
-		   qave = qave*(1-W) + sch->qstats.backlog*W;
-		                                           --ANK (980924)
-		 */
+			q->stats.forced_mark++;
+			break;
 	}
 
-	if (q->qave < q->qth_min) {
-		q->qcount = -1;
-enqueue:
-		if (sch->qstats.backlog + skb->len <= q->limit) {
-			__skb_queue_tail(&sch->q, skb);
-			sch->qstats.backlog += skb->len;
-			sch->bstats.bytes += skb->len;
-			sch->bstats.packets++;
-			return NET_XMIT_SUCCESS;
-		} else {
-			q->st.pdrop++;
-		}
-		kfree_skb(skb);
-		sch->qstats.drops++;
-		return NET_XMIT_DROP;
-	}
-	if (q->qave >= q->qth_max) {
-		q->qcount = -1;
-		sch->qstats.overlimits++;
-mark:
-		if  (!(q->flags&TC_RED_ECN) || !red_ecn_mark(skb)) {
-			q->st.early++;
-			goto drop;
-		}
-		q->st.marked++;
-		goto enqueue;
-	}
+	if (sch->qstats.backlog + skb->len <= q->limit)
+		return qdisc_enqueue_tail(skb, sch);
 
-	if (++q->qcount) {
-		/* The formula used below causes questions.
+	q->stats.pdrop++;
+	return qdisc_drop(skb, sch);
 
-		   OK. qR is random number in the interval 0..Rmask
-		   i.e. 0..(2^Plog). If we used floating point
-		   arithmetics, it would be: (2^Plog)*rnd_num,
-		   where rnd_num is less 1.
-
-		   Taking into account, that qave have fixed
-		   point at Wlog, and Plog is related to max_P by
-		   max_P = (qth_max-qth_min)/2^Plog; two lines
-		   below have the following floating point equivalent:
-		   
-		   max_P*(qave - qth_min)/(qth_max-qth_min) < rnd/qcount
-
-		   Any questions? --ANK (980924)
-		 */
-		if (((q->qave - q->qth_min)>>q->Wlog)*q->qcount < q->qR)
-			goto enqueue;
-		q->qcount = 0;
-		q->qR = net_random()&q->Rmask;
-		sch->qstats.overlimits++;
-		goto mark;
-	}
-	q->qR = net_random()&q->Rmask;
-	goto enqueue;
-
-drop:
-	kfree_skb(skb);
-	sch->qstats.drops++;
+congestion_drop:
+	qdisc_drop(skb, sch);
 	return NET_XMIT_CN;
 }
 
-static int
-red_requeue(struct sk_buff *skb, struct Qdisc* sch)
+static int red_requeue(struct sk_buff *skb, struct Qdisc* sch)
 {
 	struct red_sched_data *q = qdisc_priv(sch);
 
-	PSCHED_SET_PASTPERFECT(q->qidlestart);
+	if (red_is_idling(&q->parms))
+		red_end_of_idle_period(&q->parms);
 
-	__skb_queue_head(&sch->q, skb);
-	sch->qstats.backlog += skb->len;
-	sch->qstats.requeues++;
-	return 0;
+	return qdisc_requeue(skb, sch);
 }
 
-static struct sk_buff *
-red_dequeue(struct Qdisc* sch)
+static struct sk_buff * red_dequeue(struct Qdisc* sch)
 {
 	struct sk_buff *skb;
 	struct red_sched_data *q = qdisc_priv(sch);
 
-	skb = __skb_dequeue(&sch->q);
-	if (skb) {
-		sch->qstats.backlog -= skb->len;
-		return skb;
-	}
-	PSCHED_GET_TIME(q->qidlestart);
-	return NULL;
+	skb = qdisc_dequeue_head(sch);
+
+	if (skb == NULL && !red_is_idling(&q->parms))
+		red_start_of_idle_period(&q->parms);
+
+	return skb;
 }
 
 static unsigned int red_drop(struct Qdisc* sch)
@@ -333,16 +130,17 @@
 	struct sk_buff *skb;
 	struct red_sched_data *q = qdisc_priv(sch);
 
-	skb = __skb_dequeue_tail(&sch->q);
+	skb = qdisc_dequeue_tail(sch);
 	if (skb) {
 		unsigned int len = skb->len;
-		sch->qstats.backlog -= len;
-		sch->qstats.drops++;
-		q->st.other++;
-		kfree_skb(skb);
+		q->stats.other++;
+		qdisc_drop(skb, sch);
 		return len;
 	}
-	PSCHED_GET_TIME(q->qidlestart);
+
+	if (!red_is_idling(&q->parms))
+		red_start_of_idle_period(&q->parms);
+
 	return 0;
 }
 
@@ -350,43 +148,38 @@
 {
 	struct red_sched_data *q = qdisc_priv(sch);
 
-	__skb_queue_purge(&sch->q);
-	sch->qstats.backlog = 0;
-	PSCHED_SET_PASTPERFECT(q->qidlestart);
-	q->qave = 0;
-	q->qcount = -1;
+	qdisc_reset_queue(sch);
+	red_restart(&q->parms);
 }
 
 static int red_change(struct Qdisc *sch, struct rtattr *opt)
 {
 	struct red_sched_data *q = qdisc_priv(sch);
-	struct rtattr *tb[TCA_RED_STAB];
+	struct rtattr *tb[TCA_RED_MAX];
 	struct tc_red_qopt *ctl;
 
-	if (opt == NULL ||
-	    rtattr_parse_nested(tb, TCA_RED_STAB, opt) ||
-	    tb[TCA_RED_PARMS-1] == 0 || tb[TCA_RED_STAB-1] == 0 ||
+	if (opt == NULL || rtattr_parse_nested(tb, TCA_RED_MAX, opt))
+		return -EINVAL;
+
+	if (tb[TCA_RED_PARMS-1] == NULL ||
 	    RTA_PAYLOAD(tb[TCA_RED_PARMS-1]) < sizeof(*ctl) ||
-	    RTA_PAYLOAD(tb[TCA_RED_STAB-1]) < 256)
+	    tb[TCA_RED_STAB-1] == NULL ||
+	    RTA_PAYLOAD(tb[TCA_RED_STAB-1]) < RED_STAB_SIZE)
 		return -EINVAL;
 
 	ctl = RTA_DATA(tb[TCA_RED_PARMS-1]);
 
 	sch_tree_lock(sch);
 	q->flags = ctl->flags;
-	q->Wlog = ctl->Wlog;
-	q->Plog = ctl->Plog;
-	q->Rmask = ctl->Plog < 32 ? ((1<<ctl->Plog) - 1) : ~0UL;
-	q->Scell_log = ctl->Scell_log;
-	q->Scell_max = (255<<q->Scell_log);
-	q->qth_min = ctl->qth_min<<ctl->Wlog;
-	q->qth_max = ctl->qth_max<<ctl->Wlog;
 	q->limit = ctl->limit;
-	memcpy(q->Stab, RTA_DATA(tb[TCA_RED_STAB-1]), 256);
 
-	q->qcount = -1;
+	red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog,
+				 ctl->Plog, ctl->Scell_log,
+				 RTA_DATA(tb[TCA_RED_STAB-1]));
+
 	if (skb_queue_empty(&sch->q))
-		PSCHED_SET_PASTPERFECT(q->qidlestart);
+		red_end_of_idle_period(&q->parms);
+
 	sch_tree_unlock(sch);
 	return 0;
 }
@@ -399,39 +192,39 @@
 static int red_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
 	struct red_sched_data *q = qdisc_priv(sch);
-	unsigned char	 *b = skb->tail;
-	struct rtattr *rta;
-	struct tc_red_qopt opt;
+	struct rtattr *opts = NULL;
+	struct tc_red_qopt opt = {
+		.limit		= q->limit,
+		.flags		= q->flags,
+		.qth_min	= q->parms.qth_min >> q->parms.Wlog,
+		.qth_max	= q->parms.qth_max >> q->parms.Wlog,
+		.Wlog		= q->parms.Wlog,
+		.Plog		= q->parms.Plog,
+		.Scell_log	= q->parms.Scell_log,
+	};
 
-	rta = (struct rtattr*)b;
-	RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
-	opt.limit = q->limit;
-	opt.qth_min = q->qth_min>>q->Wlog;
-	opt.qth_max = q->qth_max>>q->Wlog;
-	opt.Wlog = q->Wlog;
-	opt.Plog = q->Plog;
-	opt.Scell_log = q->Scell_log;
-	opt.flags = q->flags;
+	opts = RTA_NEST(skb, TCA_OPTIONS);
 	RTA_PUT(skb, TCA_RED_PARMS, sizeof(opt), &opt);
-	rta->rta_len = skb->tail - b;
-
-	return skb->len;
+	return RTA_NEST_END(skb, opts);
 
 rtattr_failure:
-	skb_trim(skb, b - skb->data);
-	return -1;
+	return RTA_NEST_CANCEL(skb, opts);
 }
 
 static int red_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
 {
 	struct red_sched_data *q = qdisc_priv(sch);
+	struct tc_red_xstats st = {
+		.early	= q->stats.prob_drop + q->stats.forced_drop,
+		.pdrop	= q->stats.pdrop,
+		.other	= q->stats.other,
+		.marked	= q->stats.prob_mark + q->stats.forced_mark,
+	};
 
-	return gnet_stats_copy_app(d, &q->st, sizeof(q->st));
+	return gnet_stats_copy_app(d, &st, sizeof(st));
 }
 
 static struct Qdisc_ops red_qdisc_ops = {
-	.next		=	NULL,
-	.cl_ops		=	NULL,
 	.id		=	"red",
 	.priv_size	=	sizeof(struct red_sched_data),
 	.enqueue	=	red_enqueue,
@@ -450,10 +243,13 @@
 {
 	return register_qdisc(&red_qdisc_ops);
 }
-static void __exit red_module_exit(void) 
+
+static void __exit red_module_exit(void)
 {
 	unregister_qdisc(&red_qdisc_ops);
 }
+
 module_init(red_module_init)
 module_exit(red_module_exit)
+
 MODULE_LICENSE("GPL");
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index e9bd912..5a220b2 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -313,6 +313,11 @@
 	rqstp->rq_proc = proc = ntohl(svc_getu32(argv));	/* procedure number */
 
 	progp = serv->sv_program;
+
+	for (progp = serv->sv_program; progp; progp = progp->pg_next)
+		if (prog == progp->pg_prog)
+			break;
+
 	/*
 	 * Decode auth data, and add verifier to reply buffer.
 	 * We do this before anything else in order to get a decent
@@ -320,7 +325,7 @@
 	 */
 	auth_res = svc_authenticate(rqstp, &auth_stat);
 	/* Also give the program a chance to reject this call: */
-	if (auth_res == SVC_OK) {
+	if (auth_res == SVC_OK && progp) {
 		auth_stat = rpc_autherr_badcred;
 		auth_res = progp->pg_authenticate(rqstp);
 	}
@@ -340,10 +345,7 @@
 	case SVC_COMPLETE:
 		goto sendit;
 	}
-		
-	for (progp = serv->sv_program; progp; progp = progp->pg_next)
-		if (prog == progp->pg_prog)
-			break;
+
 	if (progp == NULL)
 		goto err_bad_prog;
 
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 455aeab..c65c435 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -118,7 +118,7 @@
 
 # Needed for systems without gettext
 KBUILD_HAVE_NLS := $(shell \
-     if echo "\#include <libint.h>" | $(HOSTCC) $(HOSTCFLAGS) -E - > /dev/null 2>&1 ; \
+     if echo "\#include <libintl.h>" | $(HOSTCC) $(HOSTCFLAGS) -E - > /dev/null 2>&1 ; \
      then echo yes ; \
      else echo no ; fi)
 ifeq ($(KBUILD_HAVE_NLS),no)
diff --git a/security/keys/key.c b/security/keys/key.c
index ccde17a..01bcfec 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -115,8 +115,7 @@
  found:
 	atomic_inc(&user->usage);
 	spin_unlock(&key_user_lock);
-	if (candidate)
-		kfree(candidate);
+	kfree(candidate);
  out:
 	return user;
 
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index e1cc4dd..c7a0ab1 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -434,8 +434,8 @@
 		if (sp >= KEYRING_SEARCH_MAX_DEPTH)
 			continue;
 
-		if (!key_task_permission(make_key_ref(key, possessed),
-					 context, KEY_SEARCH) < 0)
+		if (key_task_permission(make_key_ref(key, possessed),
+					context, KEY_SEARCH) < 0)
 			continue;
 
 		/* stack the current position */
@@ -621,8 +621,8 @@
 			if (strcmp(keyring->description, name) != 0)
 				continue;
 
-			if (!key_permission(make_key_ref(keyring, 0),
-					    KEY_SEARCH) < 0)
+			if (key_permission(make_key_ref(keyring, 0),
+					   KEY_SEARCH) < 0)
 				continue;
 
 			/* found a potential candidate, but we still need to
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 2f5f539..0ac311d 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -632,22 +632,22 @@
 	cond_policydb_destroy(p);
 
 	for (tr = p->role_tr; tr; tr = tr->next) {
-		if (ltr) kfree(ltr);
+		kfree(ltr);
 		ltr = tr;
 	}
-	if (ltr) kfree(ltr);
+	kfree(ltr);
 
 	for (ra = p->role_allow; ra; ra = ra -> next) {
-		if (lra) kfree(lra);
+		kfree(lra);
 		lra = ra;
 	}
-	if (lra) kfree(lra);
+	kfree(lra);
 
 	for (rt = p->range_tr; rt; rt = rt -> next) {
-		if (lrt) kfree(lrt);
+		kfree(lrt);
 		lrt = rt;
 	}
-	if (lrt) kfree(lrt);
+	kfree(lrt);
 
 	if (p->type_attr_map) {
 		for (i = 0; i < p->p_types.nprim; i++)
diff --git a/sound/Kconfig b/sound/Kconfig
index b65ee47..d8f1140 100644
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -48,6 +48,14 @@
 
 	  For more information, see <http://www.alsa-project.org/>
 
+config SND_AC97_CODEC
+	tristate
+	select SND_PCM
+	select SND_AC97_BUS
+
+config SND_AC97_BUS
+	tristate
+
 source "sound/core/Kconfig"
 
 source "sound/drivers/Kconfig"
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index 48cf45c..8271883 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -127,12 +127,6 @@
 	help
 	  Say Y here to enable ALSA debug code.
 
-config SND_DEBUG_MEMORY
-	bool "Debug memory"
-	depends on SND_DEBUG
-	help
-	  Say Y here to enable debugging of memory allocations.
-
 config SND_DEBUG_DETECT
 	bool "Debug detection"
 	depends on SND_DEBUG
diff --git a/sound/core/Makefile b/sound/core/Makefile
index 969d755..5a01c76 100644
--- a/sound/core/Makefile
+++ b/sound/core/Makefile
@@ -3,8 +3,7 @@
 # Copyright (c) 1999,2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-snd-objs     := sound.o init.o memory.o info.o control.o misc.o \
-                device.o wrappers.o
+snd-objs     := sound.o init.o memory.o info.o control.o misc.o device.o
 ifeq ($(CONFIG_ISA_DMA_API),y)
 snd-objs     += isadma.o
 endif
diff --git a/sound/core/control.c b/sound/core/control.c
index 736edf3..212c46a 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -144,7 +144,7 @@
 	snd_ctl_file_t *ctl;
 	snd_kctl_event_t *ev;
 	
-	snd_runtime_check(card != NULL && id != NULL, return);
+	snd_assert(card != NULL && id != NULL, return);
 	read_lock(&card->ctl_files_rwlock);
 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
 	card->mixer_oss_change_count++;
@@ -193,8 +193,8 @@
 	snd_kcontrol_t *kctl;
 	unsigned int idx;
 	
-	snd_runtime_check(control != NULL, return NULL);
-	snd_runtime_check(control->count > 0, return NULL);
+	snd_assert(control != NULL, return NULL);
+	snd_assert(control->count > 0, return NULL);
 	kctl = kzalloc(sizeof(*kctl) + sizeof(snd_kcontrol_volatile_t) * control->count, GFP_KERNEL);
 	if (kctl == NULL)
 		return NULL;
@@ -220,7 +220,7 @@
 	snd_kcontrol_t kctl;
 	unsigned int access;
 	
-	snd_runtime_check(ncontrol != NULL, return NULL);
+	snd_assert(ncontrol != NULL, return NULL);
 	snd_assert(ncontrol->info != NULL, return NULL);
 	memset(&kctl, 0, sizeof(kctl));
 	kctl.id.iface = ncontrol->iface;
@@ -309,7 +309,7 @@
 	snd_ctl_elem_id_t id;
 	unsigned int idx;
 
-	snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL);
+	snd_assert(card != NULL && kcontrol != NULL, return -EINVAL);
 	snd_assert(kcontrol->info != NULL, return -EINVAL);
 	id = kcontrol->id;
 	down_write(&card->controls_rwsem);
@@ -355,7 +355,7 @@
 	snd_ctl_elem_id_t id;
 	unsigned int idx;
 
-	snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL);
+	snd_assert(card != NULL && kcontrol != NULL, return -EINVAL);
 	list_del(&kcontrol->list);
 	card->controls_count -= kcontrol->count;
 	id = kcontrol->id;
@@ -468,7 +468,7 @@
 	struct list_head *list;
 	snd_kcontrol_t *kctl;
 
-	snd_runtime_check(card != NULL && numid != 0, return NULL);
+	snd_assert(card != NULL && numid != 0, return NULL);
 	list_for_each(list, &card->controls) {
 		kctl = snd_kcontrol(list);
 		if (kctl->id.numid <= numid && kctl->id.numid + kctl->count > numid)
@@ -494,7 +494,7 @@
 	struct list_head *list;
 	snd_kcontrol_t *kctl;
 
-	snd_runtime_check(card != NULL && id != NULL, return NULL);
+	snd_assert(card != NULL && id != NULL, return NULL);
 	if (id->numid != 0)
 		return snd_ctl_find_numid(card, id->numid);
 	list_for_each(list, &card->controls) {
@@ -1215,7 +1215,7 @@
 	struct list_head *list;
 	snd_kctl_ioctl_t *p;
 
-	snd_runtime_check(fcn != NULL, return -EINVAL);
+	snd_assert(fcn != NULL, return -EINVAL);
 	down_write(&snd_ioctl_rwsem);
 	list_for_each(list, lists) {
 		p = list_entry(list, snd_kctl_ioctl_t, list);
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index 9383f12..e91cee3 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -81,20 +81,16 @@
 	int err;
 	wait_queue_t wait;
 
-	switch (major) {
-	case CONFIG_SND_MAJOR:
+	if (major == snd_major) {
 		cardnum = SNDRV_MINOR_CARD(iminor(inode));
 		device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_HWDEP;
-		break;
 #ifdef CONFIG_SND_OSSEMUL
-	case SOUND_MAJOR:
+	} else if (major == SOUND_MAJOR) {
 		cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode));
 		device = 0;
-		break;
 #endif
-	default:
+	} else
 		return -ENXIO;
-	}
 	cardnum %= SNDRV_CARDS;
 	device %= SNDRV_MINOR_HWDEPS;
 	hw = snd_hwdep_devices[(cardnum * SNDRV_MINOR_HWDEPS) + device];
diff --git a/sound/core/info.c b/sound/core/info.c
index 37024d6..39f9b97 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -566,7 +566,6 @@
 	}
 #endif
 	snd_info_version_init();
-	snd_memory_info_init();
 	snd_minor_info_init();
 	snd_minor_info_oss_init();
 	snd_card_info_init();
@@ -578,7 +577,6 @@
 	snd_card_info_done();
 	snd_minor_info_oss_done();
 	snd_minor_info_done();
-	snd_memory_info_done();
 	snd_info_version_done();
 	if (snd_proc_root) {
 #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
diff --git a/sound/core/init.c b/sound/core/init.c
index 41e2249..d9ee27a 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -420,7 +420,7 @@
 	int err;
 	snd_info_entry_t *entry;
 
-	snd_runtime_check(card != NULL, return -EINVAL);
+	snd_assert(card != NULL, return -EINVAL);
 	if ((err = snd_device_register_all(card)) < 0)
 		return err;
 	write_lock(&snd_card_rwlock);
@@ -524,7 +524,8 @@
 	snd_info_entry_t *entry;
 
 	entry = snd_info_create_module_entry(THIS_MODULE, "cards", NULL);
-	snd_runtime_check(entry != NULL, return -ENOMEM);
+	if (! entry)
+		return -ENOMEM;
 	entry->c.text.read_size = PAGE_SIZE;
 	entry->c.text.read = snd_card_info_read;
 	if (snd_info_register(entry) < 0) {
@@ -840,7 +841,7 @@
 	card = get_snd_generic_card(dev);
 	if (card->power_state == SNDRV_CTL_POWER_D0)
 		return 0;
-	if (card->pm_suspend)
+	if (card->pm_resume)
 		card->pm_resume(card);
 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
diff --git a/sound/core/memory.c b/sound/core/memory.c
index 7d8e2ee..862d62d 100644
--- a/sound/core/memory.c
+++ b/sound/core/memory.c
@@ -1,7 +1,7 @@
 /*
  *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
  * 
- *  Memory allocation helpers.
+ *  Misc memory accessors
  *
  *
  *   This program is free software; you can redistribute it and/or modify
@@ -20,221 +20,9 @@
  *
  */
 
-#include <sound/driver.h>
+#include <linux/config.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/pci.h>
-#include <sound/core.h>
-#include <sound/info.h>
-
-/*
- *  memory allocation helpers and debug routines
- */
-
-#ifdef CONFIG_SND_DEBUG_MEMORY
-
-struct snd_alloc_track {
-	unsigned long magic;
-	void *caller;
-	size_t size;
-	struct list_head list;
-	long data[0];
-};
-
-#define snd_alloc_track_entry(obj) (struct snd_alloc_track *)((char*)obj - (unsigned long)((struct snd_alloc_track *)0)->data)
-
-static long snd_alloc_kmalloc;
-static long snd_alloc_vmalloc;
-static LIST_HEAD(snd_alloc_kmalloc_list);
-static LIST_HEAD(snd_alloc_vmalloc_list);
-static DEFINE_SPINLOCK(snd_alloc_kmalloc_lock);
-static DEFINE_SPINLOCK(snd_alloc_vmalloc_lock);
-#define KMALLOC_MAGIC 0x87654321
-#define VMALLOC_MAGIC 0x87654320
-static snd_info_entry_t *snd_memory_info_entry;
-
-void __init snd_memory_init(void)
-{
-	snd_alloc_kmalloc = 0;
-	snd_alloc_vmalloc = 0;
-}
-
-void snd_memory_done(void)
-{
-	struct list_head *head;
-	struct snd_alloc_track *t;
-
-	if (snd_alloc_kmalloc > 0)
-		snd_printk(KERN_ERR "Not freed snd_alloc_kmalloc = %li\n", snd_alloc_kmalloc);
-	if (snd_alloc_vmalloc > 0)
-		snd_printk(KERN_ERR "Not freed snd_alloc_vmalloc = %li\n", snd_alloc_vmalloc);
-	list_for_each_prev(head, &snd_alloc_kmalloc_list) {
-		t = list_entry(head, struct snd_alloc_track, list);
-		if (t->magic != KMALLOC_MAGIC) {
-			snd_printk(KERN_ERR "Corrupted kmalloc\n");
-			break;
-		}
-		snd_printk(KERN_ERR "kmalloc(%ld) from %p not freed\n", (long) t->size, t->caller);
-	}
-	list_for_each_prev(head, &snd_alloc_vmalloc_list) {
-		t = list_entry(head, struct snd_alloc_track, list);
-		if (t->magic != VMALLOC_MAGIC) {
-			snd_printk(KERN_ERR "Corrupted vmalloc\n");
-			break;
-		}
-		snd_printk(KERN_ERR "vmalloc(%ld) from %p not freed\n", (long) t->size, t->caller);
-	}
-}
-
-static void *__snd_kmalloc(size_t size, gfp_t flags, void *caller)
-{
-	unsigned long cpu_flags;
-	struct snd_alloc_track *t;
-	void *ptr;
-	
-	ptr = snd_wrapper_kmalloc(size + sizeof(struct snd_alloc_track), flags);
-	if (ptr != NULL) {
-		t = (struct snd_alloc_track *)ptr;
-		t->magic = KMALLOC_MAGIC;
-		t->caller = caller;
-		spin_lock_irqsave(&snd_alloc_kmalloc_lock, cpu_flags);
-		list_add_tail(&t->list, &snd_alloc_kmalloc_list);
-		spin_unlock_irqrestore(&snd_alloc_kmalloc_lock, cpu_flags);
-		t->size = size;
-		snd_alloc_kmalloc += size;
-		ptr = t->data;
-	}
-	return ptr;
-}
-
-#define _snd_kmalloc(size, flags) __snd_kmalloc((size), (flags), __builtin_return_address(0));
-void *snd_hidden_kmalloc(size_t size, gfp_t flags)
-{
-	return _snd_kmalloc(size, flags);
-}
-
-void *snd_hidden_kzalloc(size_t size, gfp_t flags)
-{
-	void *ret = _snd_kmalloc(size, flags);
-	if (ret)
-		memset(ret, 0, size);
-	return ret;
-}
-EXPORT_SYMBOL(snd_hidden_kzalloc);
-
-void *snd_hidden_kcalloc(size_t n, size_t size, gfp_t flags)
-{
-	void *ret = NULL;
-	if (n != 0 && size > INT_MAX / n)
-		return ret;
-	return snd_hidden_kzalloc(n * size, flags);
-}
-
-void snd_hidden_kfree(const void *obj)
-{
-	unsigned long flags;
-	struct snd_alloc_track *t;
-	if (obj == NULL)
-		return;
-	t = snd_alloc_track_entry(obj);
-	if (t->magic != KMALLOC_MAGIC) {
-		snd_printk(KERN_WARNING "bad kfree (called from %p)\n", __builtin_return_address(0));
-		return;
-	}
-	spin_lock_irqsave(&snd_alloc_kmalloc_lock, flags);
-	list_del(&t->list);
-	spin_unlock_irqrestore(&snd_alloc_kmalloc_lock, flags);
-	t->magic = 0;
-	snd_alloc_kmalloc -= t->size;
-	obj = t;
-	snd_wrapper_kfree(obj);
-}
-
-void *snd_hidden_vmalloc(unsigned long size)
-{
-	void *ptr;
-	ptr = snd_wrapper_vmalloc(size + sizeof(struct snd_alloc_track));
-	if (ptr) {
-		struct snd_alloc_track *t = (struct snd_alloc_track *)ptr;
-		t->magic = VMALLOC_MAGIC;
-		t->caller = __builtin_return_address(0);
-		spin_lock(&snd_alloc_vmalloc_lock);
-		list_add_tail(&t->list, &snd_alloc_vmalloc_list);
-		spin_unlock(&snd_alloc_vmalloc_lock);
-		t->size = size;
-		snd_alloc_vmalloc += size;
-		ptr = t->data;
-	}
-	return ptr;
-}
-
-void snd_hidden_vfree(void *obj)
-{
-	struct snd_alloc_track *t;
-	if (obj == NULL)
-		return;
-	t = snd_alloc_track_entry(obj);
-	if (t->magic != VMALLOC_MAGIC) {
-		snd_printk(KERN_ERR "bad vfree (called from %p)\n", __builtin_return_address(0));
-		return;
-	}
-	spin_lock(&snd_alloc_vmalloc_lock);
-	list_del(&t->list);
-	spin_unlock(&snd_alloc_vmalloc_lock);
-	t->magic = 0;
-	snd_alloc_vmalloc -= t->size;
-	obj = t;
-	snd_wrapper_vfree(obj);
-}
-
-char *snd_hidden_kstrdup(const char *s, gfp_t flags)
-{
-	int len;
-	char *buf;
-
-	if (!s) return NULL;
-
-	len = strlen(s) + 1;
-	buf = _snd_kmalloc(len, flags);
-	if (buf)
-		memcpy(buf, s, len);
-	return buf;
-}
-
-static void snd_memory_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
-{
-	snd_iprintf(buffer, "kmalloc: %li bytes\n", snd_alloc_kmalloc);
-	snd_iprintf(buffer, "vmalloc: %li bytes\n", snd_alloc_vmalloc);
-}
-
-int __init snd_memory_info_init(void)
-{
-	snd_info_entry_t *entry;
-
-	entry = snd_info_create_module_entry(THIS_MODULE, "meminfo", NULL);
-	if (entry) {
-		entry->c.text.read_size = 256;
-		entry->c.text.read = snd_memory_info_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	snd_memory_info_entry = entry;
-	return 0;
-}
-
-int __exit snd_memory_info_done(void)
-{
-	if (snd_memory_info_entry)
-		snd_info_unregister(snd_memory_info_entry);
-	return 0;
-}
-
-#endif /* CONFIG_SND_DEBUG_MEMORY */
 
 /**
  * copy_to_user_fromio - copy data from mmio-space to user-space
diff --git a/sound/core/misc.c b/sound/core/misc.c
index 1a81fe4d..b53e563 100644
--- a/sound/core/misc.c
+++ b/sound/core/misc.c
@@ -23,17 +23,15 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/time.h>
+#include <linux/ioport.h>
 #include <sound/core.h>
 
-int snd_task_name(struct task_struct *task, char *name, size_t size)
+void release_and_free_resource(struct resource *res)
 {
-	unsigned int idx;
-
-	snd_assert(task != NULL && name != NULL && size >= 2, return -EINVAL);
-	for (idx = 0; idx < sizeof(task->comm) && idx + 1 < size; idx++)
-		name[idx] = task->comm[idx];
-	name[idx] = '\0';
-	return 0;
+	if (res) {
+		release_resource(res);
+		kfree(res);
+	}
 }
 
 #ifdef CONFIG_SND_VERBOSE_PRINTK
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 69e1059..214933c 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -521,9 +521,13 @@
 	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
 	if (uinfo == NULL || uctl == NULL)
 		goto __unalloc;
-	snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
-	snd_runtime_check(!kctl->get(kctl, uctl), goto __unalloc);
-	snd_runtime_check(uinfo->type != SNDRV_CTL_ELEM_TYPE_BOOLEAN || uinfo->value.integer.min != 0 || uinfo->value.integer.max != 1, goto __unalloc);
+	if (kctl->info(kctl, uinfo))
+		goto __unalloc;
+	if (kctl->get(kctl, uctl))
+		goto __unalloc;
+	if (uinfo->type == SNDRV_CTL_ELEM_TYPE_BOOLEAN &&
+	    uinfo->value.integer.min == 0 && uinfo->value.integer.max == 1)
+		goto __unalloc;
 	*left = snd_mixer_oss_conv1(uctl->value.integer.value[0], uinfo->value.integer.min, uinfo->value.integer.max, &pslot->volume[0]);
 	if (uinfo->count > 1)
 		*right = snd_mixer_oss_conv1(uctl->value.integer.value[1], uinfo->value.integer.min, uinfo->value.integer.max, &pslot->volume[1]);
@@ -555,8 +559,10 @@
 	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
 	if (uinfo == NULL || uctl == NULL)
 		goto __unalloc;
-	snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
-	snd_runtime_check(!kctl->get(kctl, uctl), goto __unalloc);
+	if (kctl->info(kctl, uinfo))
+		goto __unalloc;
+	if (kctl->get(kctl, uctl))
+		goto __unalloc;
 	if (!uctl->value.integer.value[0]) {
 		*left = 0;
 		if (uinfo->count == 1)
@@ -616,12 +622,16 @@
 	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
 	if (uinfo == NULL || uctl == NULL)
 		goto __unalloc;
-	snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
-	snd_runtime_check(uinfo->type != SNDRV_CTL_ELEM_TYPE_BOOLEAN || uinfo->value.integer.min != 0 || uinfo->value.integer.max != 1, goto __unalloc);
+	if (kctl->info(kctl, uinfo))
+		goto __unalloc;
+	if (uinfo->type == SNDRV_CTL_ELEM_TYPE_BOOLEAN &&
+	    uinfo->value.integer.min == 0 && uinfo->value.integer.max == 1)
+		goto __unalloc;
 	uctl->value.integer.value[0] = snd_mixer_oss_conv2(left, uinfo->value.integer.min, uinfo->value.integer.max);
 	if (uinfo->count > 1)
 		uctl->value.integer.value[1] = snd_mixer_oss_conv2(right, uinfo->value.integer.min, uinfo->value.integer.max);
-	snd_runtime_check((res = kctl->put(kctl, uctl)) >= 0, goto __unalloc);
+	if ((res = kctl->put(kctl, uctl)) < 0)
+		goto __unalloc;
 	if (res > 0)
 		snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
       __unalloc:
@@ -653,7 +663,8 @@
 	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
 	if (uinfo == NULL || uctl == NULL)
 		goto __unalloc;
-	snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
+	if (kctl->info(kctl, uinfo))
+		goto __unalloc;
 	if (uinfo->count > 1) {
 		uctl->value.integer.value[0] = left > 0 ? 1 : 0;
 		uctl->value.integer.value[route ? 3 : 1] = right > 0 ? 1 : 0;
@@ -664,7 +675,8 @@
 	} else {
 		uctl->value.integer.value[0] = (left > 0 || right > 0) ? 1 : 0;
 	}
-	snd_runtime_check((res = kctl->put(kctl, uctl)) >= 0, goto __unalloc);
+	if ((res = kctl->put(kctl, uctl)) < 0)
+		goto __unalloc;
 	if (res > 0)
 		snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
       __unalloc:
@@ -776,9 +788,14 @@
 	}
 	down_read(&card->controls_rwsem);
 	kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
-	snd_runtime_check(kctl != NULL, err = -ENOENT; goto __unlock);
-	snd_runtime_check(!(err = kctl->info(kctl, uinfo)), goto __unlock);
-	snd_runtime_check(!(err = kctl->get(kctl, uctl)), goto __unlock);
+	if (! kctl) {
+		err = -ENOENT;
+		goto __unlock;
+	}
+	if ((err = kctl->info(kctl, uinfo)) < 0)
+		goto __unlock;
+	if ((err = kctl->get(kctl, uctl)) < 0)
+		goto __unlock;
 	for (idx = 0; idx < 32; idx++) {
 		if (!(mixer->mask_recsrc & (1 << idx)))
 			continue;
@@ -821,8 +838,12 @@
 	}
 	down_read(&card->controls_rwsem);
 	kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
-	snd_runtime_check(kctl != NULL, err = -ENOENT; goto __unlock);
-	snd_runtime_check(!(err = kctl->info(kctl, uinfo)), goto __unlock);
+	if (! kctl) {
+		err = -ENOENT;
+		goto __unlock;
+	}
+	if ((err = kctl->info(kctl, uinfo)) < 0)
+		goto __unlock;
 	for (idx = 0; idx < 32; idx++) {
 		if (!(mixer->mask_recsrc & (1 << idx)))
 			continue;
@@ -836,10 +857,11 @@
 			break;
 		slot = NULL;
 	}
-	snd_runtime_check(slot != NULL, goto __unlock);
+	if (! slot)
+		goto __unlock;
 	for (idx = 0; idx < uinfo->count; idx++)
 		uctl->value.enumerated.item[idx] = slot->capture_item;
-	snd_runtime_check((err = kctl->put(kctl, uctl)) >= 0, );
+	err = kctl->put(kctl, uctl);
 	if (err > 0)
 		snd_ctl_notify(fmixer->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
 	err = 0;
@@ -1008,7 +1030,8 @@
 	up_read(&mixer->card->controls_rwsem);
 	if (slot.present != 0) {
 		pslot = (struct slot *)kmalloc(sizeof(slot), GFP_KERNEL);
-		snd_runtime_check(pslot != NULL, return -ENOMEM);
+		if (! pslot)
+			return -ENOMEM;
 		*pslot = slot;
 		pslot->signature = SNDRV_MIXER_OSS_SIGNATURE;
 		pslot->assigned = ptr;
@@ -1271,7 +1294,8 @@
 						   card, 0,
 						   &snd_mixer_oss_reg,
 						   name)) < 0) {
-			snd_printk("unable to register OSS mixer device %i:%i\n", card->number, 0);
+			snd_printk(KERN_ERR "unable to register OSS mixer device %i:%i\n",
+				   card->number, 0);
 			kfree(mixer);
 			return err;
 		}
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 842c28b..bcc9707 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1821,6 +1821,17 @@
 }
 
 
+static int snd_task_name(struct task_struct *task, char *name, size_t size)
+{
+	unsigned int idx;
+
+	snd_assert(task != NULL && name != NULL && size >= 2, return -EINVAL);
+	for (idx = 0; idx < sizeof(task->comm) && idx + 1 < size; idx++)
+		name[idx] = task->comm[idx];
+	name[idx] = '\0';
+	return 0;
+}
+
 static int snd_pcm_oss_open(struct inode *inode, struct file *file)
 {
 	int minor = iminor(inode);
@@ -2446,7 +2457,8 @@
 	if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_PCM,
 				    pcm->card, index, &snd_pcm_oss_reg,
 				    name) < 0) {
-		snd_printk("unable to register OSS PCM device %i:%i\n", pcm->card->number, pcm->device);
+		snd_printk(KERN_ERR "unable to register OSS PCM device %i:%i\n",
+			   pcm->card->number, pcm->device);
 	}
 }
 
@@ -2528,11 +2540,13 @@
 	/* check device map table */
 	for (i = 0; i < SNDRV_CARDS; i++) {
 		if (dsp_map[i] < 0 || dsp_map[i] >= SNDRV_PCM_DEVICES) {
-			snd_printk("invalid dsp_map[%d] = %d\n", i, dsp_map[i]);
+			snd_printk(KERN_ERR "invalid dsp_map[%d] = %d\n",
+				   i, dsp_map[i]);
 			dsp_map[i] = 0;
 		}
 		if (adsp_map[i] < 0 || adsp_map[i] >= SNDRV_PCM_DEVICES) {
-			snd_printk("invalid adsp_map[%d] = %d\n", i, adsp_map[i]);
+			snd_printk(KERN_ERR "invalid adsp_map[%d] = %d\n",
+				   i, adsp_map[i]);
 			adsp_map[i] = 1;
 		}
 	}
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 1be470e..184e74b 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -273,7 +273,8 @@
 	snd_pcm_info_t *info;
 	int err;
 
-	snd_runtime_check(substream, return);
+	if (! substream)
+		return;
 
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
 	if (! info) {
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 0503980..3dbf9bf 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -152,13 +152,12 @@
 	if (pos == SNDRV_PCM_POS_XRUN)
 		return pos; /* XRUN */
 	if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP)
-		snd_timestamp_now((snd_timestamp_t*)&runtime->status->tstamp, runtime->tstamp_timespec);
+		getnstimeofday((struct timespec *)&runtime->status->tstamp);
 #ifdef CONFIG_SND_DEBUG
 	if (pos >= runtime->buffer_size) {
 		snd_printk(KERN_ERR  "BUG: stream = %i, pos = 0x%lx, buffer size = 0x%lx, period size = 0x%lx\n", substream->stream, pos, runtime->buffer_size, runtime->period_size);
-	} else
+	}
 #endif
-	snd_runtime_check(pos < runtime->buffer_size, return 0);
 	pos -= pos % runtime->min_align;
 	return pos;
 }
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index e97b2d1..16e252f 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -565,9 +565,9 @@
 		if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP)
 			status->tstamp = runtime->status->tstamp;
 		else
-			snd_timestamp_now(&status->tstamp, runtime->tstamp_timespec);
+			getnstimeofday(&status->tstamp);
 	} else
-		snd_timestamp_now(&status->tstamp, runtime->tstamp_timespec);
+		getnstimeofday(&status->tstamp);
 	status->appl_ptr = runtime->control->appl_ptr;
 	status->hw_ptr = runtime->status->hw_ptr;
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -652,7 +652,7 @@
 	if (runtime->trigger_master == NULL)
 		return;
 	if (runtime->trigger_master == substream) {
-		snd_timestamp_now(&runtime->trigger_tstamp, runtime->tstamp_timespec);
+		getnstimeofday(&runtime->trigger_tstamp);
 	} else {
 		snd_pcm_trigger_tstamp(runtime->trigger_master);
 		runtime->trigger_tstamp = runtime->trigger_master->runtime->trigger_tstamp;
@@ -1522,7 +1522,6 @@
 
 
 /* WARNING: Don't forget to fput back the file */
-extern int snd_major;
 static struct file *snd_pcm_file_fd(int fd)
 {
 	struct file *file;
@@ -2053,7 +2052,8 @@
 	snd_pcm_file_t *pcm_file;
 	wait_queue_t wait;
 
-	snd_runtime_check(device >= SNDRV_MINOR_PCM_PLAYBACK && device < SNDRV_MINOR_DEVICES, return -ENXIO);
+	if (device < SNDRV_MINOR_PCM_PLAYBACK || device >= SNDRV_MINOR_DEVICES)
+		return -ENXIO;
 	pcm = snd_pcm_devices[(cardnum * SNDRV_PCM_DEVICES) + (device % SNDRV_MINOR_PCMS)];
 	if (pcm == NULL) {
 		err = -ENODEV;
@@ -2445,14 +2445,8 @@
 		return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0;
 	case SNDRV_PCM_IOCTL_INFO:
 		return snd_pcm_info_user(substream, arg);
-	case SNDRV_PCM_IOCTL_TSTAMP:
-	{
-		int xarg;
-		if (get_user(xarg, (int __user *)arg))
-			return -EFAULT;
-		substream->runtime->tstamp_timespec = xarg ? 1 : 0;
+	case SNDRV_PCM_IOCTL_TSTAMP: /* just for compatibility */
 		return 0;
-	}
 	case SNDRV_PCM_IOCTL_HW_REFINE:
 		return snd_pcm_hw_refine_user(substream, arg);
 	case SNDRV_PCM_IOCTL_HW_PARAMS:
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 7c20eaf..d033e61 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -378,24 +378,20 @@
 	struct list_head *list;
 	snd_ctl_file_t *kctl;
 
-	switch (maj) {
-	case CONFIG_SND_MAJOR:
+	if (maj == snd_major) {
 		cardnum = SNDRV_MINOR_CARD(iminor(inode));
 		cardnum %= SNDRV_CARDS;
 		device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_RAWMIDI;
 		device %= SNDRV_MINOR_RAWMIDIS;
-		break;
 #ifdef CONFIG_SND_OSSEMUL
-	case SOUND_MAJOR:
+	} else if (maj == SOUND_MAJOR) {
 		cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode));
 		cardnum %= SNDRV_CARDS;
 		device = SNDRV_MINOR_OSS_DEVICE(iminor(inode)) == SNDRV_MINOR_OSS_MIDI ?
 			midi_map[cardnum] : amidi_map[cardnum];
-		break;
 #endif
-	default:
+	} else
 		return -ENXIO;
-	}
 
 	rmidi = snd_rawmidi_devices[(cardnum * SNDRV_RAWMIDI_DEVICES) + device];
 	if (rmidi == NULL)
@@ -411,7 +407,7 @@
 	if (err < 0)
 		return -ENODEV;
 	fflags = snd_rawmidi_file_flags(file);
-	if ((file->f_flags & O_APPEND) || maj != CONFIG_SND_MAJOR) /* OSS emul? */
+	if ((file->f_flags & O_APPEND) || maj == SOUND_MAJOR) /* OSS emul? */
 		fflags |= SNDRV_RAWMIDI_LFLG_APPEND;
 	fflags |= SNDRV_RAWMIDI_LFLG_NOOPENLOCK;
 	rawmidi_file = kmalloc(sizeof(*rawmidi_file), GFP_KERNEL);
diff --git a/sound/core/rtctimer.c b/sound/core/rtctimer.c
index bd5d584..c3c1856 100644
--- a/sound/core/rtctimer.c
+++ b/sound/core/rtctimer.c
@@ -60,7 +60,6 @@
 
 static int rtctimer_freq = RTC_FREQ;		/* frequency */
 static snd_timer_t *rtctimer;
-static atomic_t rtc_inc = ATOMIC_INIT(0);
 static rtc_task_t rtc_task;
 
 
@@ -94,7 +93,6 @@
 	snd_assert(rtc != NULL, return -EINVAL);
 	rtc_control(rtc, RTC_IRQP_SET, rtctimer_freq);
 	rtc_control(rtc, RTC_PIE_ON, 0);
-	atomic_set(&rtc_inc, 0);
 	return 0;
 }
 
@@ -112,12 +110,7 @@
  */
 static void rtctimer_interrupt(void *private_data)
 {
-	int ticks;
-
-	atomic_inc(&rtc_inc);
-	ticks = atomic_read(&rtc_inc);
-	snd_timer_interrupt((snd_timer_t*)private_data, ticks);
-	atomic_sub(ticks, &rtc_inc);
+	snd_timer_interrupt(private_data, 1);
 }
 
 
@@ -126,17 +119,13 @@
  */
 static int __init rtctimer_init(void)
 {
-	int order, err;
+	int err;
 	snd_timer_t *timer;
 
-	if (rtctimer_freq < 2 || rtctimer_freq > 8192) {
-		snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n", rtctimer_freq);
-		return -EINVAL;
-	}
-	for (order = 1; rtctimer_freq > order; order <<= 1)
-		;
-	if (rtctimer_freq != order) {
-		snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n", rtctimer_freq);
+	if (rtctimer_freq < 2 || rtctimer_freq > 8192 ||
+	    (rtctimer_freq & (rtctimer_freq - 1)) != 0) {
+		snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n",
+			   rtctimer_freq);
 		return -EINVAL;
 	}
 
@@ -145,6 +134,7 @@
 	if (err < 0)
 		return err;
 
+	timer->module = THIS_MODULE;
 	strcpy(timer->name, "RTC timer");
 	timer->hw = rtc_hw;
 	timer->hw.resolution = NANO_SEC / rtctimer_freq;
diff --git a/sound/core/seq/seq_instr.c b/sound/core/seq/seq_instr.c
index 019d43a..1d525b1 100644
--- a/sound/core/seq/seq_instr.c
+++ b/sound/core/seq/seq_instr.c
@@ -109,8 +109,7 @@
 			spin_lock_irqsave(&list->lock, flags);
 			while (instr->use) {
 				spin_unlock_irqrestore(&list->lock, flags);
-				set_current_state(TASK_INTERRUPTIBLE);
-				schedule_timeout(1);
+				schedule_timeout_interruptible(1);
 				spin_lock_irqsave(&list->lock, flags);
 			}				
 			spin_unlock_irqrestore(&list->lock, flags);
@@ -199,10 +198,8 @@
 		while (flist) {
 			instr = flist;
 			flist = instr->next;
-			while (instr->use) {
-				set_current_state(TASK_INTERRUPTIBLE);
-				schedule_timeout(1);
-			}				
+			while (instr->use)
+				schedule_timeout_interruptible(1);
 			if (snd_seq_instr_free(instr, atomic)<0)
 				snd_printk(KERN_WARNING "instrument free problem\n");
 			instr = next;
@@ -554,8 +551,7 @@
 			instr->ops->notify(instr->ops->private_data, instr, SNDRV_SEQ_INSTR_NOTIFY_REMOVE);
 		while (instr->use) {
 			spin_unlock_irqrestore(&list->lock, flags);
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(1);
+			schedule_timeout_interruptible(1);
 			spin_lock_irqsave(&list->lock, flags);
 		}				
 		spin_unlock_irqrestore(&list->lock, flags);
diff --git a/sound/core/seq/seq_lock.c b/sound/core/seq/seq_lock.c
index b09cee0..a837a94 100644
--- a/sound/core/seq/seq_lock.c
+++ b/sound/core/seq/seq_lock.c
@@ -39,8 +39,7 @@
 			snd_printk(KERN_WARNING "seq_lock: timeout [%d left] in %s:%d\n", atomic_read(lockp), file, line);
 			break;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 		max_count--;
 	}
 }
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
index d4d7d32..8416bcf 100644
--- a/sound/core/seq/seq_memory.c
+++ b/sound/core/seq/seq_memory.c
@@ -423,8 +423,7 @@
 			snd_printk(KERN_WARNING "snd_seq_pool_done timeout: %d cells remain\n", atomic_read(&pool->counter));
 			break;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 		max_count--;
 	}
 	
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
index b4674ae..f89f40f 100644
--- a/sound/core/seq/seq_midi.c
+++ b/sound/core/seq/seq_midi.c
@@ -449,11 +449,9 @@
 	client->ports_per_device[device] = 0;
 	msynth = client->ports[device];
 	client->ports[device] = NULL;
-	snd_runtime_check(msynth != NULL || ports <= 0, goto __skip);
 	for (p = 0; p < ports; p++)
 		snd_seq_midisynth_delete(&msynth[p]);
 	kfree(msynth);
-      __skip:
 	client->num_ports--;
 	if (client->num_ports <= 0) {
 		snd_seq_delete_kernel_client(client->seq_client);
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
index b57a3c0..65b64a7 100644
--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -34,10 +34,15 @@
 extern int seq_default_timer_subdevice;
 extern int seq_default_timer_resolution;
 
+/* allowed sequencer timer frequencies, in Hz */
+#define MIN_FREQUENCY		10
+#define MAX_FREQUENCY		6250
+#define DEFAULT_FREQUENCY	1000
+
 #define SKEW_BASE	0x10000	/* 16bit shift */
 
 static void snd_seq_timer_set_tick_resolution(seq_timer_tick_t *tick,
-					      int tempo, int ppq, int nticks)
+					      int tempo, int ppq)
 {
 	if (tempo < 1000000)
 		tick->resolution = (tempo * 1000) / ppq;
@@ -51,7 +56,6 @@
 	}
 	if (tick->resolution <= 0)
 		tick->resolution = 1;
-	tick->resolution *= nticks;
 	snd_seq_timer_update_tick(tick, 0);
 }
 
@@ -100,7 +104,7 @@
 	/* setup defaults */
 	tmr->ppq = 96;		/* 96 PPQ */
 	tmr->tempo = 500000;	/* 120 BPM */
-	snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq, 1);
+	snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq);
 	tmr->running = 0;
 
 	tmr->type = SNDRV_SEQ_TIMER_ALSA;
@@ -183,7 +187,7 @@
 	spin_lock_irqsave(&tmr->lock, flags);
 	if ((unsigned int)tempo != tmr->tempo) {
 		tmr->tempo = tempo;
-		snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq, 1);
+		snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq);
 	}
 	spin_unlock_irqrestore(&tmr->lock, flags);
 	return 0;
@@ -207,7 +211,7 @@
 	}
 
 	tmr->ppq = ppq;
-	snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq, 1);
+	snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq);
 	spin_unlock_irqrestore(&tmr->lock, flags);
 	return 0;
 }
@@ -326,17 +330,26 @@
 static int initialize_timer(seq_timer_t *tmr)
 {
 	snd_timer_t *t;
+	unsigned long freq;
+
 	t = tmr->timeri->timer;
 	snd_assert(t, return -EINVAL);
 
+	freq = tmr->preferred_resolution;
+	if (!freq)
+		freq = DEFAULT_FREQUENCY;
+	else if (freq < MIN_FREQUENCY)
+		freq = MIN_FREQUENCY;
+	else if (freq > MAX_FREQUENCY)
+		freq = MAX_FREQUENCY;
+
 	tmr->ticks = 1;
-	if (tmr->preferred_resolution &&
-	    ! (t->hw.flags & SNDRV_TIMER_HW_SLAVE)) {
+	if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE)) {
 		unsigned long r = t->hw.resolution;
 		if (! r && t->hw.c_resolution)
 			r = t->hw.c_resolution(t);
 		if (r) {
-			tmr->ticks = (unsigned int)(1000000000uL / (r * tmr->preferred_resolution));
+			tmr->ticks = (unsigned int)(1000000000uL / (r * freq));
 			if (! tmr->ticks)
 				tmr->ticks = 1;
 		}
diff --git a/sound/core/sound.c b/sound/core/sound.c
index b57519a..1139dd8 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -130,7 +130,7 @@
 	struct file_operations *old_fops;
 	int err = 0;
 
-	if (dev != SNDRV_MINOR_SEQUENCER && dev != SNDRV_MINOR_TIMER) {
+	if (dev != SNDRV_MINOR_GLOBAL) {
 		if (snd_cards[card] == NULL) {
 #ifdef CONFIG_KMOD
 			snd_request_card(card);
@@ -287,7 +287,7 @@
 	for (card = 0; card < SNDRV_CARDS; card++) {
 		list_for_each(list, &snd_minors_hash[card]) {
 			mptr = list_entry(list, snd_minor_t, list);
-			if (SNDRV_MINOR_DEVICE(mptr->number) != SNDRV_MINOR_SEQUENCER) {
+			if (SNDRV_MINOR_DEVICE(mptr->number) != SNDRV_MINOR_GLOBAL) {
 				if ((device = mptr->device) >= 0)
 					snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", mptr->number, card, device, mptr->comment);
 				else
@@ -350,9 +350,7 @@
 		devfs_remove("snd");
 		return -EIO;
 	}
-	snd_memory_init();
 	if (snd_info_init() < 0) {
-		snd_memory_done();
 		unregister_chrdev(major, "alsa");
 		devfs_remove("snd");
 		return -ENOMEM;
@@ -381,7 +379,6 @@
 #endif
 	snd_info_minor_unregister();
 	snd_info_done();
-	snd_memory_done();
 	if (unregister_chrdev(major, "alsa") != 0)
 		snd_printk(KERN_ERR "unable to unregister major device number %d\n", major);
 	devfs_remove("snd");
@@ -403,14 +400,6 @@
 EXPORT_SYMBOL(snd_unregister_oss_device);
 #endif
   /* memory.c */
-#ifdef CONFIG_SND_DEBUG_MEMORY
-EXPORT_SYMBOL(snd_hidden_kmalloc);
-EXPORT_SYMBOL(snd_hidden_kcalloc);
-EXPORT_SYMBOL(snd_hidden_kfree);
-EXPORT_SYMBOL(snd_hidden_vmalloc);
-EXPORT_SYMBOL(snd_hidden_vfree);
-EXPORT_SYMBOL(snd_hidden_kstrdup);
-#endif
 EXPORT_SYMBOL(copy_to_user_fromio);
 EXPORT_SYMBOL(copy_from_user_toio);
   /* init.c */
@@ -487,17 +476,10 @@
 EXPORT_SYMBOL(snd_ctl_elem_read);
 EXPORT_SYMBOL(snd_ctl_elem_write);
   /* misc.c */
-EXPORT_SYMBOL(snd_task_name);
+EXPORT_SYMBOL(release_and_free_resource);
 #ifdef CONFIG_SND_VERBOSE_PRINTK
 EXPORT_SYMBOL(snd_verbose_printk);
 #endif
 #if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK)
 EXPORT_SYMBOL(snd_verbose_printd);
 #endif
-  /* wrappers */
-#ifdef CONFIG_SND_DEBUG_MEMORY
-EXPORT_SYMBOL(snd_wrapper_kmalloc);
-EXPORT_SYMBOL(snd_wrapper_kfree);
-EXPORT_SYMBOL(snd_wrapper_vmalloc);
-EXPORT_SYMBOL(snd_wrapper_vfree);
-#endif
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 22b1046..1b90a38 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -55,7 +55,7 @@
 
 typedef struct {
 	snd_timer_instance_t *timeri;
-	int tread;			/* enhanced read with timestamps and events */
+	int tread;		/* enhanced read with timestamps and events */
 	unsigned long ticks;
 	unsigned long overrun;
 	int qhead;
@@ -95,7 +95,8 @@
  * create a timer instance with the given owner string.
  * when timer is not NULL, increments the module counter
  */
-static snd_timer_instance_t *snd_timer_instance_new(char *owner, snd_timer_t *timer)
+static snd_timer_instance_t *snd_timer_instance_new(char *owner,
+						    snd_timer_t *timer)
 {
 	snd_timer_instance_t *timeri;
 	timeri = kzalloc(sizeof(*timeri), GFP_KERNEL);
@@ -113,7 +114,7 @@
 	INIT_LIST_HEAD(&timeri->slave_active_head);
 
 	timeri->timer = timer;
-	if (timer && timer->card && !try_module_get(timer->card->module)) {
+	if (timer && !try_module_get(timer->module)) {
 		kfree(timeri->owner);
 		kfree(timeri);
 		return NULL;
@@ -131,7 +132,7 @@
 	struct list_head *p;
 
 	list_for_each(p, &snd_timer_list) {
-		timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
+		timer = list_entry(p, snd_timer_t, device_list);
 
 		if (timer->tmr_class != tid->dev_class)
 			continue;
@@ -186,13 +187,14 @@
 
 	/* FIXME: it's really dumb to look up all entries.. */
 	list_for_each(p, &snd_timer_list) {
-		timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
+		timer = list_entry(p, snd_timer_t, device_list);
 		list_for_each(q, &timer->open_list_head) {
-			master = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, open_list);
+			master = list_entry(q, snd_timer_instance_t, open_list);
 			if (slave->slave_class == master->slave_class &&
 			    slave->slave_id == master->slave_id) {
 				list_del(&slave->open_list);
-				list_add_tail(&slave->open_list, &master->slave_list_head);
+				list_add_tail(&slave->open_list,
+					      &master->slave_list_head);
 				spin_lock_irq(&slave_active_lock);
 				slave->master = master;
 				slave->timer = master->timer;
@@ -216,7 +218,7 @@
 
 	/* check all pending slaves */
 	list_for_each_safe(p, n, &snd_timer_slave_list) {
-		slave = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list);
+		slave = list_entry(p, snd_timer_instance_t, open_list);
 		if (slave->slave_class == master->slave_class &&
 		    slave->slave_id == master->slave_id) {
 			list_del(p);
@@ -225,7 +227,8 @@
 			slave->master = master;
 			slave->timer = master->timer;
 			if (slave->flags & SNDRV_TIMER_IFLG_RUNNING)
-				list_add_tail(&slave->active_list, &master->slave_active_head);
+				list_add_tail(&slave->active_list,
+					      &master->slave_active_head);
 			spin_unlock_irq(&slave_active_lock);
 		}
 	}
@@ -241,7 +244,7 @@
 {
 	snd_timer_t *timer;
 	snd_timer_instance_t *timeri = NULL;
-	
+
 	if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) {
 		/* open a slave instance */
 		if (tid->dev_sclass <= SNDRV_TIMER_SCLASS_NONE ||
@@ -251,6 +254,10 @@
 		}
 		down(&register_mutex);
 		timeri = snd_timer_instance_new(owner, NULL);
+		if (!timeri) {
+			up(&register_mutex);
+			return -ENOMEM;
+		}
 		timeri->slave_class = tid->dev_sclass;
 		timeri->slave_id = tid->device;
 		timeri->flags |= SNDRV_TIMER_IFLG_SLAVE;
@@ -272,33 +279,36 @@
 		timer = snd_timer_find(tid);
 	}
 #endif
-	if (timer) {
-		if (!list_empty(&timer->open_list_head)) {
-			timeri = (snd_timer_instance_t *)list_entry(timer->open_list_head.next, snd_timer_instance_t, open_list);
-			if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) {
-				up(&register_mutex);
-				return -EBUSY;
-			}
-		}
-		timeri = snd_timer_instance_new(owner, timer);
-		if (timeri) {
-			timeri->slave_class = tid->dev_sclass;
-			timeri->slave_id = slave_id;
-			if (list_empty(&timer->open_list_head) && timer->hw.open)
-				timer->hw.open(timer);
-			list_add_tail(&timeri->open_list, &timer->open_list_head);
-			snd_timer_check_master(timeri);
-		}
-	} else {
+	if (!timer) {
 		up(&register_mutex);
 		return -ENODEV;
 	}
+	if (!list_empty(&timer->open_list_head)) {
+		timeri = list_entry(timer->open_list_head.next,
+				    snd_timer_instance_t, open_list);
+		if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) {
+			up(&register_mutex);
+			return -EBUSY;
+		}
+	}
+	timeri = snd_timer_instance_new(owner, timer);
+	if (!timeri) {
+		up(&register_mutex);
+		return -ENOMEM;
+	}
+	timeri->slave_class = tid->dev_sclass;
+	timeri->slave_id = slave_id;
+	if (list_empty(&timer->open_list_head) && timer->hw.open)
+		timer->hw.open(timer);
+	list_add_tail(&timeri->open_list, &timer->open_list_head);
+	snd_timer_check_master(timeri);
 	up(&register_mutex);
 	*ti = timeri;
 	return 0;
 }
 
-static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event);
+static int _snd_timer_stop(snd_timer_instance_t * timeri,
+			   int keep_flag, enum sndrv_timer_event event);
 
 /*
  * close a timer instance
@@ -338,11 +348,12 @@
 		spin_unlock_irq(&timer->lock);
 		down(&register_mutex);
 		list_del(&timeri->open_list);
-		if (timer && list_empty(&timer->open_list_head) && timer->hw.close)
+		if (timer && list_empty(&timer->open_list_head) &&
+		    timer->hw.close)
 			timer->hw.close(timer);
 		/* remove slave links */
 		list_for_each_safe(p, n, &timeri->slave_list_head) {
-			slave = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list);
+			slave = list_entry(p, snd_timer_instance_t, open_list);
 			spin_lock_irq(&slave_active_lock);
 			_snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION);
 			list_del(p);
@@ -357,8 +368,8 @@
 		timeri->private_free(timeri);
 	kfree(timeri->owner);
 	kfree(timeri);
-	if (timer && timer->card)
-		module_put(timer->card->module);
+	if (timer)
+		module_put(timer->module);
 	return 0;
 }
 
@@ -376,7 +387,8 @@
 	return 0;
 }
 
-static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event event)
+static void snd_timer_notify1(snd_timer_instance_t *ti,
+			      enum sndrv_timer_event event)
 {
 	snd_timer_t *timer;
 	unsigned long flags;
@@ -385,9 +397,11 @@
 	struct list_head *n;
 	struct timespec tstamp;
 
-	snd_timestamp_now(&tstamp, 1);
-	snd_assert(event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE, return);
-	if (event == SNDRV_TIMER_EVENT_START || event == SNDRV_TIMER_EVENT_CONTINUE)
+	getnstimeofday(&tstamp);
+	snd_assert(event >= SNDRV_TIMER_EVENT_START &&
+		   event <= SNDRV_TIMER_EVENT_PAUSE, return);
+	if (event == SNDRV_TIMER_EVENT_START ||
+	    event == SNDRV_TIMER_EVENT_CONTINUE)
 		resolution = snd_timer_resolution(ti);
 	if (ti->ccallback)
 		ti->ccallback(ti, SNDRV_TIMER_EVENT_START, &tstamp, resolution);
@@ -400,14 +414,15 @@
 		return;
 	spin_lock_irqsave(&timer->lock, flags);
 	list_for_each(n, &ti->slave_active_head) {
-		ts = (snd_timer_instance_t *)list_entry(n, snd_timer_instance_t, active_list);
+		ts = list_entry(n, snd_timer_instance_t, active_list);
 		if (ts->ccallback)
 			ts->ccallback(ti, event + 100, &tstamp, resolution);
 	}
 	spin_unlock_irqrestore(&timer->lock, flags);
 }
 
-static int snd_timer_start1(snd_timer_t *timer, snd_timer_instance_t *timeri, unsigned long sticks)
+static int snd_timer_start1(snd_timer_t *timer, snd_timer_instance_t *timeri,
+			    unsigned long sticks)
 {
 	list_del(&timeri->active_list);
 	list_add_tail(&timeri->active_list, &timer->active_list_head);
@@ -434,14 +449,15 @@
 	spin_lock_irqsave(&slave_active_lock, flags);
 	timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
 	if (timeri->master)
-		list_add_tail(&timeri->active_list, &timeri->master->slave_active_head);
+		list_add_tail(&timeri->active_list,
+			      &timeri->master->slave_active_head);
 	spin_unlock_irqrestore(&slave_active_lock, flags);
 	return 1; /* delayed start */
 }
 
 /*
  *  start the timer instance
- */ 
+ */
 int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks)
 {
 	snd_timer_t *timer;
@@ -467,7 +483,8 @@
 	return result;
 }
 
-static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event)
+static int _snd_timer_stop(snd_timer_instance_t * timeri,
+			   int keep_flag, enum sndrv_timer_event event)
 {
 	snd_timer_t *timer;
 	unsigned long flags;
@@ -501,7 +518,8 @@
 		}
 	}
 	if (!keep_flag)
-		timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING|SNDRV_TIMER_IFLG_START);
+		timeri->flags &=
+			~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START);
 	spin_unlock_irqrestore(&timer->lock, flags);
       __end:
 	if (event != SNDRV_TIMER_EVENT_RESOLUTION)
@@ -578,7 +596,7 @@
 	struct list_head *p;
 
 	list_for_each(p, &timer->active_list_head) {
-		ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list);
+		ti = list_entry(p, snd_timer_instance_t, active_list);
 		if (ti->flags & SNDRV_TIMER_IFLG_START) {
 			ti->flags &= ~SNDRV_TIMER_IFLG_START;
 			ti->flags |= SNDRV_TIMER_IFLG_RUNNING;
@@ -615,11 +633,11 @@
 	/* now process all callbacks */
 	while (!list_empty(&timer->sack_list_head)) {
 		p = timer->sack_list_head.next;		/* get first item */
-		ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, ack_list);
+		ti = list_entry(p, snd_timer_instance_t, ack_list);
 
 		/* remove from ack_list and make empty */
 		list_del_init(p);
-		
+
 		ticks = ti->pticks;
 		ti->pticks = 0;
 		resolution = ti->resolution;
@@ -644,7 +662,7 @@
 {
 	snd_timer_instance_t *ti, *ts;
 	unsigned long resolution, ticks;
-	struct list_head *p, *q, *n;
+	struct list_head *p, *q, *n, *ack_list_head;
 	int use_tasklet = 0;
 
 	if (timer == NULL)
@@ -659,11 +677,12 @@
 		resolution = timer->hw.resolution;
 
 	/* loop for all active instances
-	 * here we cannot use list_for_each because the active_list of a processed
-	 * instance is relinked to done_list_head before callback is called.
+	 * Here we cannot use list_for_each because the active_list of a
+	 * processed instance is relinked to done_list_head before the callback
+	 * is called.
 	 */
 	list_for_each_safe(p, n, &timer->active_list_head) {
-		ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list);
+		ti = list_entry(p, snd_timer_instance_t, active_list);
 		if (!(ti->flags & SNDRV_TIMER_IFLG_RUNNING))
 			continue;
 		ti->pticks += ticks_left;
@@ -681,26 +700,19 @@
 			if (--timer->running)
 				list_del(p);
 		}
-		if (list_empty(&ti->ack_list)) {
-			if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
-			    (ti->flags & SNDRV_TIMER_IFLG_FAST)) {
-				list_add_tail(&ti->ack_list, &timer->ack_list_head);
-			} else {
-				list_add_tail(&ti->ack_list, &timer->sack_list_head);
-			}
-		}
+		if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
+		    (ti->flags & SNDRV_TIMER_IFLG_FAST))
+			ack_list_head = &timer->ack_list_head;
+		else
+			ack_list_head = &timer->sack_list_head;
+		if (list_empty(&ti->ack_list))
+			list_add_tail(&ti->ack_list, ack_list_head);
 		list_for_each(q, &ti->slave_active_head) {
-			ts = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, active_list);
+			ts = list_entry(q, snd_timer_instance_t, active_list);
 			ts->pticks = ti->pticks;
 			ts->resolution = resolution;
-			if (list_empty(&ts->ack_list)) {
-				if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
-				    (ti->flags & SNDRV_TIMER_IFLG_FAST)) {
-					list_add_tail(&ts->ack_list, &timer->ack_list_head);
-				} else {
-					list_add_tail(&ts->ack_list, &timer->sack_list_head);
-				}
-			}
+			if (list_empty(&ts->ack_list))
+				list_add_tail(&ts->ack_list, ack_list_head);
 		}
 	}
 	if (timer->flags & SNDRV_TIMER_FLG_RESCHED)
@@ -723,11 +735,11 @@
 	/* now process all fast callbacks */
 	while (!list_empty(&timer->ack_list_head)) {
 		p = timer->ack_list_head.next;		/* get first item */
-		ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, ack_list);
-		
+		ti = list_entry(p, snd_timer_instance_t, ack_list);
+
 		/* remove from ack_list and make empty */
 		list_del_init(p);
-		
+
 		ticks = ti->pticks;
 		ti->pticks = 0;
 
@@ -751,7 +763,8 @@
 
  */
 
-int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, snd_timer_t ** rtimer)
+int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid,
+		  snd_timer_t **rtimer)
 {
 	snd_timer_t *timer;
 	int err;
@@ -779,9 +792,12 @@
 	INIT_LIST_HEAD(&timer->ack_list_head);
 	INIT_LIST_HEAD(&timer->sack_list_head);
 	spin_lock_init(&timer->lock);
-	tasklet_init(&timer->task_queue, snd_timer_tasklet, (unsigned long)timer);
+	tasklet_init(&timer->task_queue, snd_timer_tasklet,
+		     (unsigned long)timer);
 	if (card != NULL) {
-		if ((err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops)) < 0) {
+		timer->module = card->module;
+		err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops);
+		if (err < 0) {
 			snd_timer_free(timer);
 			return err;
 		}
@@ -811,14 +827,15 @@
 	snd_timer_t *timer1;
 	struct list_head *p;
 
-	snd_assert(timer != NULL && timer->hw.start != NULL && timer->hw.stop != NULL, return -ENXIO);
+	snd_assert(timer != NULL && timer->hw.start != NULL &&
+		   timer->hw.stop != NULL, return -ENXIO);
 	if (!(timer->hw.flags & SNDRV_TIMER_HW_SLAVE) &&
 	    !timer->hw.resolution && timer->hw.c_resolution == NULL)
 	    	return -EINVAL;
 
 	down(&register_mutex);
 	list_for_each(p, &snd_timer_list) {
-		timer1 = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
+		timer1 = list_entry(p, snd_timer_t, device_list);
 		if (timer1->tmr_class > timer->tmr_class)
 			break;
 		if (timer1->tmr_class < timer->tmr_class)
@@ -857,7 +874,7 @@
 		snd_printk(KERN_WARNING "timer 0x%lx is busy?\n", (long)timer);
 		list_for_each_safe(p, n, &timer->open_list_head) {
 			list_del_init(p);
-			ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list);
+			ti = list_entry(p, snd_timer_instance_t, open_list);
 			ti->timer = NULL;
 		}
 	}
@@ -872,15 +889,18 @@
 	return snd_timer_unregister(timer);
 }
 
-void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct timespec *tstamp)
+void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event,
+		      struct timespec *tstamp)
 {
 	unsigned long flags;
 	unsigned long resolution = 0;
 	snd_timer_instance_t *ti, *ts;
 	struct list_head *p, *n;
 
-	snd_runtime_check(timer->hw.flags & SNDRV_TIMER_HW_SLAVE, return);	
-	snd_assert(event >= SNDRV_TIMER_EVENT_MSTART && event <= SNDRV_TIMER_EVENT_MRESUME, return);
+	if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE))
+		return;
+	snd_assert(event >= SNDRV_TIMER_EVENT_MSTART &&
+		   event <= SNDRV_TIMER_EVENT_MRESUME, return);
 	spin_lock_irqsave(&timer->lock, flags);
 	if (event == SNDRV_TIMER_EVENT_MSTART ||
 	    event == SNDRV_TIMER_EVENT_MCONTINUE ||
@@ -891,11 +911,11 @@
 			resolution = timer->hw.resolution;
 	}
 	list_for_each(p, &timer->active_list_head) {
-		ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list);
+		ti = list_entry(p, snd_timer_instance_t, active_list);
 		if (ti->ccallback)
 			ti->ccallback(ti, event, tstamp, resolution);
 		list_for_each(n, &ti->slave_active_head) {
-			ts = (snd_timer_instance_t *)list_entry(n, snd_timer_instance_t, active_list);
+			ts = list_entry(n, snd_timer_instance_t, active_list);
 			if (ts->ccallback)
 				ts->ccallback(ts, event, tstamp, resolution);
 		}
@@ -909,7 +929,7 @@
 int snd_timer_global_new(char *id, int device, snd_timer_t **rtimer)
 {
 	snd_timer_id_t tid;
-	
+
 	tid.dev_class = SNDRV_TIMER_CLASS_GLOBAL;
 	tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
 	tid.card = -1;
@@ -937,7 +957,7 @@
 	return snd_timer_unregister(timer);
 }
 
-/* 
+/*
  *  System timer
  */
 
@@ -1013,7 +1033,8 @@
 	struct snd_timer_system_private *priv;
 	int err;
 
-	if ((err = snd_timer_global_new("system", SNDRV_TIMER_GLOBAL_SYSTEM, &timer)) < 0)
+	err = snd_timer_global_new("system", SNDRV_TIMER_GLOBAL_SYSTEM, &timer);
+	if (err < 0)
 		return err;
 	strcpy(timer->name, "system timer");
 	timer->hw = snd_timer_system;
@@ -1044,33 +1065,41 @@
 
 	down(&register_mutex);
 	list_for_each(p, &snd_timer_list) {
-		timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
+		timer = list_entry(p, snd_timer_t, device_list);
 		switch (timer->tmr_class) {
 		case SNDRV_TIMER_CLASS_GLOBAL:
 			snd_iprintf(buffer, "G%i: ", timer->tmr_device);
 			break;
 		case SNDRV_TIMER_CLASS_CARD:
-			snd_iprintf(buffer, "C%i-%i: ", timer->card->number, timer->tmr_device);
+			snd_iprintf(buffer, "C%i-%i: ",
+				    timer->card->number, timer->tmr_device);
 			break;
 		case SNDRV_TIMER_CLASS_PCM:
-			snd_iprintf(buffer, "P%i-%i-%i: ", timer->card->number, timer->tmr_device, timer->tmr_subdevice);
+			snd_iprintf(buffer, "P%i-%i-%i: ", timer->card->number,
+				    timer->tmr_device, timer->tmr_subdevice);
 			break;
 		default:
-			snd_iprintf(buffer, "?%i-%i-%i-%i: ", timer->tmr_class, timer->card ? timer->card->number : -1, timer->tmr_device, timer->tmr_subdevice);
+			snd_iprintf(buffer, "?%i-%i-%i-%i: ", timer->tmr_class,
+				    timer->card ? timer->card->number : -1,
+				    timer->tmr_device, timer->tmr_subdevice);
 		}
 		snd_iprintf(buffer, "%s :", timer->name);
 		if (timer->hw.resolution)
-			snd_iprintf(buffer, " %lu.%03luus (%lu ticks)", timer->hw.resolution / 1000, timer->hw.resolution % 1000, timer->hw.ticks);
+			snd_iprintf(buffer, " %lu.%03luus (%lu ticks)",
+				    timer->hw.resolution / 1000,
+				    timer->hw.resolution % 1000,
+				    timer->hw.ticks);
 		if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
 			snd_iprintf(buffer, " SLAVE");
 		snd_iprintf(buffer, "\n");
 		spin_lock_irqsave(&timer->lock, flags);
 		list_for_each(q, &timer->open_list_head) {
-			ti = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, open_list);
-			snd_iprintf(buffer, "  Client %s : %s : lost interrupts %li\n",
-					ti->owner ? ti->owner : "unknown",
-					ti->flags & (SNDRV_TIMER_IFLG_START|SNDRV_TIMER_IFLG_RUNNING) ? "running" : "stopped",
-					ti->lost);
+			ti = list_entry(q, snd_timer_instance_t, open_list);
+			snd_iprintf(buffer, "  Client %s : %s\n",
+				    ti->owner ? ti->owner : "unknown",
+				    ti->flags & (SNDRV_TIMER_IFLG_START |
+						 SNDRV_TIMER_IFLG_RUNNING)
+				    ? "running" : "stopped");
 		}
 		spin_unlock_irqrestore(&timer->lock, flags);
 	}
@@ -1088,7 +1117,7 @@
 	snd_timer_user_t *tu = timeri->callback_data;
 	snd_timer_read_t *r;
 	int prev;
-	
+
 	spin_lock(&tu->qlock);
 	if (tu->qused > 0) {
 		prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1;
@@ -1113,7 +1142,8 @@
 	wake_up(&tu->qchange_sleep);
 }
 
-static void snd_timer_user_append_to_tqueue(snd_timer_user_t *tu, snd_timer_tread_t *tread)
+static void snd_timer_user_append_to_tqueue(snd_timer_user_t *tu,
+					    snd_timer_tread_t *tread)
 {
 	if (tu->qused >= tu->queue_size) {
 		tu->overrun++;
@@ -1132,7 +1162,8 @@
 	snd_timer_user_t *tu = timeri->callback_data;
 	snd_timer_tread_t r1;
 
-	if (event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE)
+	if (event >= SNDRV_TIMER_EVENT_START &&
+	    event <= SNDRV_TIMER_EVENT_PAUSE)
 		tu->tstamp = *tstamp;
 	if ((tu->filter & (1 << event)) == 0 || !tu->tread)
 		return;
@@ -1155,15 +1186,17 @@
 	struct timespec tstamp;
 	int prev, append = 0;
 
-	snd_timestamp_zero(&tstamp);
+	memset(&tstamp, 0, sizeof(tstamp));
 	spin_lock(&tu->qlock);
-	if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION)|(1 << SNDRV_TIMER_EVENT_TICK))) == 0) {
+	if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION) |
+			   (1 << SNDRV_TIMER_EVENT_TICK))) == 0) {
 		spin_unlock(&tu->qlock);
 		return;
 	}
 	if (tu->last_resolution != resolution || ticks > 0)
-		snd_timestamp_now(&tstamp, 1);
-	if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && tu->last_resolution != resolution) {
+		getnstimeofday(&tstamp);
+	if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) &&
+	    tu->last_resolution != resolution) {
 		r1.event = SNDRV_TIMER_EVENT_RESOLUTION;
 		r1.tstamp = tstamp;
 		r1.val = resolution;
@@ -1201,7 +1234,7 @@
 static int snd_timer_user_open(struct inode *inode, struct file *file)
 {
 	snd_timer_user_t *tu;
-	
+
 	tu = kzalloc(sizeof(*tu), GFP_KERNEL);
 	if (tu == NULL)
 		return -ENOMEM;
@@ -1210,7 +1243,8 @@
 	init_MUTEX(&tu->tread_sem);
 	tu->ticks = 1;
 	tu->queue_size = 128;
-	tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL);
+	tu->queue = kmalloc(tu->queue_size * sizeof(snd_timer_read_t),
+			    GFP_KERNEL);
 	if (tu->queue == NULL) {
 		kfree(tu);
 		return -ENOMEM;
@@ -1259,7 +1293,7 @@
 	snd_timer_id_t id;
 	snd_timer_t *timer;
 	struct list_head *p;
-	
+
 	if (copy_from_user(&id, _tid, sizeof(id)))
 		return -EFAULT;
 	down(&register_mutex);
@@ -1267,7 +1301,8 @@
 		if (list_empty(&snd_timer_list))
 			snd_timer_user_zero_id(&id);
 		else {
-			timer = (snd_timer_t *)list_entry(snd_timer_list.next, snd_timer_t, device_list);
+			timer = list_entry(snd_timer_list.next,
+					   snd_timer_t, device_list);
 			snd_timer_user_copy_id(&id, timer);
 		}
 	} else {
@@ -1275,7 +1310,7 @@
 		case SNDRV_TIMER_CLASS_GLOBAL:
 			id.device = id.device < 0 ? 0 : id.device + 1;
 			list_for_each(p, &snd_timer_list) {
-				timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
+				timer = list_entry(p, snd_timer_t, device_list);
 				if (timer->tmr_class > SNDRV_TIMER_CLASS_GLOBAL) {
 					snd_timer_user_copy_id(&id, timer);
 					break;
@@ -1299,12 +1334,16 @@
 					if (id.device < 0) {
 						id.device = 0;
 					} else {
-						id.subdevice = id.subdevice < 0 ? 0 : id.subdevice + 1;
+						if (id.subdevice < 0) {
+							id.subdevice = 0;
+						} else {
+							id.subdevice++;
+						}
 					}
 				}
 			}
 			list_for_each(p, &snd_timer_list) {
-				timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
+				timer = list_entry(p, snd_timer_t, device_list);
 				if (timer->tmr_class > id.dev_class) {
 					snd_timer_user_copy_id(&id, timer);
 					break;
@@ -1343,9 +1382,10 @@
 	if (copy_to_user(_tid, &id, sizeof(*_tid)))
 		return -EFAULT;
 	return 0;
-} 
+}
 
-static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t __user *_ginfo)
+static int snd_timer_user_ginfo(struct file *file,
+				snd_timer_ginfo_t __user *_ginfo)
 {
 	snd_timer_ginfo_t *ginfo;
 	snd_timer_id_t tid;
@@ -1389,7 +1429,8 @@
 	return err;
 }
 
-static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t __user *_gparams)
+static int snd_timer_user_gparams(struct file *file,
+				  snd_timer_gparams_t __user *_gparams)
 {
 	snd_timer_gparams_t gparams;
 	snd_timer_t *t;
@@ -1399,23 +1440,26 @@
 		return -EFAULT;
 	down(&register_mutex);
 	t = snd_timer_find(&gparams.tid);
-	if (t != NULL) {
-		if (list_empty(&t->open_list_head)) {
-			if (t->hw.set_period)
-				err = t->hw.set_period(t, gparams.period_num, gparams.period_den);
-			else
-				err = -ENOSYS;
-		} else {
-			err = -EBUSY;
-		}
-	} else {
+	if (!t) {
 		err = -ENODEV;
+		goto _error;
 	}
+	if (!list_empty(&t->open_list_head)) {
+		err = -EBUSY;
+		goto _error;
+	}
+	if (!t->hw.set_period) {
+		err = -ENOSYS;
+		goto _error;
+	}
+	err = t->hw.set_period(t, gparams.period_num, gparams.period_den);
+_error:
 	up(&register_mutex);
 	return err;
 }
 
-static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user *_gstatus)
+static int snd_timer_user_gstatus(struct file *file,
+				  snd_timer_gstatus_t __user *_gstatus)
 {
 	snd_timer_gstatus_t gstatus;
 	snd_timer_id_t tid;
@@ -1435,7 +1479,8 @@
 		else
 			gstatus.resolution = t->hw.resolution;
 		if (t->hw.precise_resolution) {
-			t->hw.precise_resolution(t, &gstatus.resolution_num, &gstatus.resolution_den);
+			t->hw.precise_resolution(t, &gstatus.resolution_num,
+						 &gstatus.resolution_den);
 		} else {
 			gstatus.resolution_num = gstatus.resolution;
 			gstatus.resolution_den = 1000000000uL;
@@ -1449,13 +1494,14 @@
 	return err;
 }
 
-static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user *_tselect)
+static int snd_timer_user_tselect(struct file *file,
+				  snd_timer_select_t __user *_tselect)
 {
 	snd_timer_user_t *tu;
 	snd_timer_select_t tselect;
 	char str[32];
 	int err = 0;
-	
+
 	tu = file->private_data;
 	down(&tu->tread_sem);
 	if (tu->timeri) {
@@ -1469,7 +1515,8 @@
 	sprintf(str, "application %i", current->pid);
 	if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE)
 		tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION;
-	if ((err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid)) < 0)
+	err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid);
+	if (err < 0)
 		goto __err;
 
 	kfree(tu->queue);
@@ -1477,21 +1524,24 @@
 	kfree(tu->tqueue);
 	tu->tqueue = NULL;
 	if (tu->tread) {
-		tu->tqueue = (snd_timer_tread_t *)kmalloc(tu->queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL);
+		tu->tqueue = kmalloc(tu->queue_size * sizeof(snd_timer_tread_t),
+				     GFP_KERNEL);
 		if (tu->tqueue == NULL)
 			err = -ENOMEM;
 	} else {
-		tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL);
+		tu->queue = kmalloc(tu->queue_size * sizeof(snd_timer_read_t),
+				    GFP_KERNEL);
 		if (tu->queue == NULL)
 			err = -ENOMEM;
 	}
-	
+
       	if (err < 0) {
 		snd_timer_close(tu->timeri);
       		tu->timeri = NULL;
       	} else {
 		tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST;
-		tu->timeri->callback = tu->tread ? snd_timer_user_tinterrupt : snd_timer_user_interrupt;
+		tu->timeri->callback = tu->tread
+			? snd_timer_user_tinterrupt : snd_timer_user_interrupt;
 		tu->timeri->ccallback = snd_timer_user_ccallback;
 		tu->timeri->callback_data = (void *)tu;
 	}
@@ -1501,7 +1551,8 @@
 	return err;
 }
 
-static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info)
+static int snd_timer_user_info(struct file *file,
+			       snd_timer_info_t __user *_info)
 {
 	snd_timer_user_t *tu;
 	snd_timer_info_t *info;
@@ -1528,7 +1579,8 @@
 	return err;
 }
 
-static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_params)
+static int snd_timer_user_params(struct file *file,
+				 snd_timer_params_t __user *_params)
 {
 	snd_timer_user_t *tu;
 	snd_timer_params_t params;
@@ -1536,7 +1588,7 @@
 	snd_timer_read_t *tr;
 	snd_timer_tread_t *ttr;
 	int err;
-	
+
 	tu = file->private_data;
 	snd_assert(tu->timeri != NULL, return -ENXIO);
 	t = tu->timeri->timer;
@@ -1547,7 +1599,8 @@
 		err = -EINVAL;
 		goto _end;
 	}
-	if (params.queue_size > 0 && (params.queue_size < 32 || params.queue_size > 1024)) {
+	if (params.queue_size > 0 &&
+	    (params.queue_size < 32 || params.queue_size > 1024)) {
 		err = -EINVAL;
 		goto _end;
 	}
@@ -1580,16 +1633,19 @@
 	if (params.flags & SNDRV_TIMER_PSFLG_EARLY_EVENT)
 		tu->timeri->flags |= SNDRV_TIMER_IFLG_EARLY_EVENT;
 	spin_unlock_irq(&t->lock);
-	if (params.queue_size > 0 && (unsigned int)tu->queue_size != params.queue_size) {
+	if (params.queue_size > 0 &&
+	    (unsigned int)tu->queue_size != params.queue_size) {
 		if (tu->tread) {
-			ttr = (snd_timer_tread_t *)kmalloc(params.queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL);
+			ttr = kmalloc(params.queue_size * sizeof(*ttr),
+				      GFP_KERNEL);
 			if (ttr) {
 				kfree(tu->tqueue);
 				tu->queue_size = params.queue_size;
 				tu->tqueue = ttr;
 			}
 		} else {
-			tr = (snd_timer_read_t *)kmalloc(params.queue_size * sizeof(snd_timer_read_t), GFP_KERNEL);
+			tr = kmalloc(params.queue_size * sizeof(*tr),
+				     GFP_KERNEL);
 			if (tr) {
 				kfree(tu->queue);
 				tu->queue_size = params.queue_size;
@@ -1613,7 +1669,6 @@
 			tu->qused++;
 			tu->qtail++;
 		}
-		
 	}
 	tu->filter = params.filter;
 	tu->ticks = params.ticks;
@@ -1624,11 +1679,12 @@
 	return err;
 }
 
-static int snd_timer_user_status(struct file *file, snd_timer_status_t __user *_status)
+static int snd_timer_user_status(struct file *file,
+				 snd_timer_status_t __user *_status)
 {
 	snd_timer_user_t *tu;
 	snd_timer_status_t status;
-	
+
 	tu = file->private_data;
 	snd_assert(tu->timeri != NULL, return -ENXIO);
 	memset(&status, 0, sizeof(status));
@@ -1648,7 +1704,7 @@
 {
 	int err;
 	snd_timer_user_t *tu;
-		
+
 	tu = file->private_data;
 	snd_assert(tu->timeri != NULL, return -ENXIO);
 	snd_timer_stop(tu->timeri);
@@ -1661,7 +1717,7 @@
 {
 	int err;
 	snd_timer_user_t *tu;
-		
+
 	tu = file->private_data;
 	snd_assert(tu->timeri != NULL, return -ENXIO);
 	return (err = snd_timer_stop(tu->timeri)) < 0 ? err : 0;
@@ -1671,7 +1727,7 @@
 {
 	int err;
 	snd_timer_user_t *tu;
-		
+
 	tu = file->private_data;
 	snd_assert(tu->timeri != NULL, return -ENXIO);
 	tu->timeri->lost = 0;
@@ -1682,7 +1738,7 @@
 {
 	int err;
 	snd_timer_user_t *tu;
-		
+
 	tu = file->private_data;
 	snd_assert(tu->timeri != NULL, return -ENXIO);
 	return (err = snd_timer_pause(tu->timeri)) < 0 ? err : 0;
@@ -1695,12 +1751,13 @@
 	SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23),
 };
 
-static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
+				 unsigned long arg)
 {
 	snd_timer_user_t *tu;
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
-	
+
 	tu = file->private_data;
 	switch (cmd) {
 	case SNDRV_TIMER_IOCTL_PVERSION:
@@ -1710,7 +1767,7 @@
 	case SNDRV_TIMER_IOCTL_TREAD:
 	{
 		int xarg;
-		
+
 		down(&tu->tread_sem);
 		if (tu->timeri)	{	/* too late */
 			up(&tu->tread_sem);
@@ -1758,7 +1815,7 @@
 {
 	snd_timer_user_t *tu;
 	int err;
-	
+
 	tu = file->private_data;
 	err = fasync_helper(fd, file, on, &tu->fasync);
         if (err < 0)
@@ -1766,12 +1823,13 @@
 	return 0;
 }
 
-static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, size_t count, loff_t *offset)
+static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
+				   size_t count, loff_t *offset)
 {
 	snd_timer_user_t *tu;
 	long result = 0, unit;
 	int err = 0;
-	
+
 	tu = file->private_data;
 	unit = tu->tread ? sizeof(snd_timer_tread_t) : sizeof(snd_timer_read_t);
 	spin_lock_irq(&tu->qlock);
@@ -1805,12 +1863,14 @@
 			goto _error;
 
 		if (tu->tread) {
-			if (copy_to_user(buffer, &tu->tqueue[tu->qhead++], sizeof(snd_timer_tread_t))) {
+			if (copy_to_user(buffer, &tu->tqueue[tu->qhead++],
+					 sizeof(snd_timer_tread_t))) {
 				err = -EFAULT;
 				goto _error;
 			}
 		} else {
-			if (copy_to_user(buffer, &tu->queue[tu->qhead++], sizeof(snd_timer_read_t))) {
+			if (copy_to_user(buffer, &tu->queue[tu->qhead++],
+					 sizeof(snd_timer_read_t))) {
 				err = -EFAULT;
 				goto _error;
 			}
@@ -1837,7 +1897,7 @@
         tu = file->private_data;
 
         poll_wait(file, &tu->qchange_sleep, wait);
-	
+
 	mask = 0;
 	if (tu->qused)
 		mask |= POLLIN | POLLRDNORM;
@@ -1881,9 +1941,11 @@
 	snd_info_entry_t *entry;
 
 #ifdef SNDRV_OSS_INFO_DEV_TIMERS
-	snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1, "system timer");
+	snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1,
+			      "system timer");
 #endif
-	if ((entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL)) != NULL) {
+	entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL);
+	if (entry != NULL) {
 		entry->c.text.read_size = SNDRV_TIMER_DEVICES * 128;
 		entry->c.text.read = snd_timer_proc_read;
 		if (snd_info_register(entry) < 0) {
@@ -1893,10 +1955,12 @@
 	}
 	snd_timer_proc_entry = entry;
 	if ((err = snd_timer_register_system()) < 0)
-		snd_printk(KERN_ERR "unable to register system timer (%i)\n", err);
+		snd_printk(KERN_ERR "unable to register system timer (%i)\n",
+			   err);
 	if ((err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER,
 					NULL, 0, &snd_timer_reg, "timer"))<0)
-		snd_printk(KERN_ERR "unable to register timer device (%i)\n", err);
+		snd_printk(KERN_ERR "unable to register timer device (%i)\n",
+			   err);
 	return 0;
 }
 
@@ -1907,7 +1971,7 @@
 	snd_unregister_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0);
 	/* unregister the system timer */
 	list_for_each_safe(p, n, &snd_timer_list) {
-		snd_timer_t *timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
+		snd_timer_t *timer = list_entry(p, snd_timer_t, device_list);
 		snd_timer_unregister(timer);
 	}
 	if (snd_timer_proc_entry) {
diff --git a/sound/core/wrappers.c b/sound/core/wrappers.c
deleted file mode 100644
index 296b716..0000000
--- a/sound/core/wrappers.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *  Various wrappers
- *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
- *
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/vmalloc.h>
-#include <linux/fs.h>
-
-#ifdef CONFIG_SND_DEBUG_MEMORY
-void *snd_wrapper_kmalloc(size_t size, gfp_t flags)
-{
-	return kmalloc(size, flags);
-}
-
-void snd_wrapper_kfree(const void *obj)
-{
-	kfree(obj);
-}
-
-void *snd_wrapper_vmalloc(unsigned long size)
-{
-	return vmalloc(size);
-}
-
-void snd_wrapper_vfree(void *obj)
-{
-	vfree(obj);
-}
-#endif
-
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c
index fe3f921..bdeb2c0 100644
--- a/sound/drivers/mpu401/mpu401_uart.c
+++ b/sound/drivers/mpu401/mpu401_uart.c
@@ -423,10 +423,7 @@
 	mpu401_t *mpu = rmidi->private_data;
 	if (mpu->irq_flags && mpu->irq >= 0)
 		free_irq(mpu->irq, (void *) mpu);
-	if (mpu->res) {
-		release_resource(mpu->res);
-		kfree_nocheck(mpu->res);
-	}
+	release_and_free_resource(mpu->res);
 	kfree(mpu);
 }
 
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
index 3a25c89..e9d52c6 100644
--- a/sound/drivers/mtpav.c
+++ b/sound/drivers/mtpav.c
@@ -717,10 +717,7 @@
 	spin_unlock_irqrestore(&crd->spinlock, flags);
 	if (crd->irq >= 0)
 		free_irq(crd->irq, (void *)crd);
-	if (crd->res_port) {
-		release_resource(crd->res_port);
-		kfree_nocheck(crd->res_port);
-	}
+	release_and_free_resource(crd->res_port);
 	kfree(crd);
 }
 
diff --git a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c
index 1f84d78..0624650 100644
--- a/sound/drivers/opl3/opl3_lib.c
+++ b/sound/drivers/opl3/opl3_lib.c
@@ -325,14 +325,8 @@
 	snd_assert(opl3 != NULL, return -ENXIO);
 	if (opl3->private_free)
 		opl3->private_free(opl3);
-	if (opl3->res_l_port) {
-		release_resource(opl3->res_l_port);
-		kfree_nocheck(opl3->res_l_port);
-	}
-	if (opl3->res_r_port) {
-		release_resource(opl3->res_r_port);
-		kfree_nocheck(opl3->res_r_port);
-	}
+	release_and_free_resource(opl3->res_l_port);
+	release_and_free_resource(opl3->res_r_port);
 	kfree(opl3);
 	return 0;
 }
diff --git a/sound/drivers/opl4/opl4_lib.c b/sound/drivers/opl4/opl4_lib.c
index 380c2c7..4ae5dd8 100644
--- a/sound/drivers/opl4/opl4_lib.c
+++ b/sound/drivers/opl4/opl4_lib.c
@@ -169,14 +169,8 @@
 #ifdef CONFIG_PROC_FS
 	snd_opl4_free_proc(opl4);
 #endif
-	if (opl4->res_fm_port) {
-		release_resource(opl4->res_fm_port);
-		kfree_nocheck(opl4->res_fm_port);
-	}
-	if (opl4->res_pcm_port) {
-		release_resource(opl4->res_pcm_port);
-		kfree_nocheck(opl4->res_pcm_port);
-	}
+	release_and_free_resource(opl4->res_fm_port);
+	release_and_free_resource(opl4->res_pcm_port);
 	kfree(opl4);
 }
 
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index 416172e..1ed58df 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -749,10 +749,7 @@
 {
 	if (uart->irq >= 0)
 		free_irq(uart->irq, (void *)uart);
-	if (uart->res_base) {
-		release_resource(uart->res_base);
-		kfree_nocheck(uart->res_base);
-	}
+	release_and_free_resource(uart->res_base);
 	kfree(uart);
 	return 0;
 };
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
index c2312d9..2b46758 100644
--- a/sound/drivers/vx/vx_pcm.c
+++ b/sound/drivers/vx/vx_pcm.c
@@ -79,7 +79,7 @@
 		/* already allocated */
 		if (runtime->dma_bytes >= size)
 			return 0; /* already enough large */
-		vfree_nocheck(runtime->dma_area); /* bypass the memory wrapper */
+		vfree(runtime->dma_area);
 	}
 	runtime->dma_area = vmalloc_32(size);
 	if (! runtime->dma_area)
@@ -98,7 +98,7 @@
 {
 	snd_pcm_runtime_t *runtime = subs->runtime;
 	if (runtime->dma_area) {
-		vfree_nocheck(runtime->dma_area); /* bypass the memory wrapper */
+		vfree(runtime->dma_area);
 		runtime->dma_area = NULL;
 	}
 	return 0;
diff --git a/sound/i2c/cs8427.c b/sound/i2c/cs8427.c
index a21f7d5..1a05cfb 100644
--- a/sound/i2c/cs8427.c
+++ b/sound/i2c/cs8427.c
@@ -75,7 +75,7 @@
 	buf[0] = reg & 0x7f;
 	buf[1] = val;
 	if ((err = snd_i2c_sendbytes(device, buf, 2)) != 2) {
-		snd_printk("unable to send bytes 0x%02x:0x%02x to CS8427 (%i)\n", buf[0], buf[1], err);
+		snd_printk(KERN_ERR "unable to send bytes 0x%02x:0x%02x to CS8427 (%i)\n", buf[0], buf[1], err);
 		return err < 0 ? err : -EIO;
 	}
 	return 0;
@@ -87,11 +87,11 @@
 	unsigned char buf;
 
 	if ((err = snd_i2c_sendbytes(device, &reg, 1)) != 1) {
-		snd_printk("unable to send register 0x%x byte to CS8427\n", reg);
+		snd_printk(KERN_ERR "unable to send register 0x%x byte to CS8427\n", reg);
 		return err < 0 ? err : -EIO;
 	}
 	if ((err = snd_i2c_readbytes(device, &buf, 1)) != 1) {
-		snd_printk("unable to read register 0x%x byte from CS8427\n", reg);
+		snd_printk(KERN_ERR "unable to read register 0x%x byte from CS8427\n", reg);
 		return err < 0 ? err : -EIO;
 	}
 	return buf;
@@ -210,7 +210,7 @@
 	snd_i2c_lock(bus);
 	if ((err = snd_cs8427_reg_read(device, CS8427_REG_ID_AND_VER)) != CS8427_VER8427A) {
 		snd_i2c_unlock(bus);
-		snd_printk("unable to find CS8427 signature (expected 0x%x, read 0x%x), initialization is not completed\n", CS8427_VER8427A, err);
+		snd_printk(KERN_ERR "unable to find CS8427 signature (expected 0x%x, read 0x%x), initialization is not completed\n", CS8427_VER8427A, err);
 		return -EFAULT;
 	}
 	/* turn off run bit while making changes to configuration */
@@ -260,7 +260,7 @@
 	snd_i2c_sendbytes(device, buf, 1);
 	snd_i2c_readbytes(device, buf, 127);
 	for (xx = 0; xx < 127; xx++)
-		printk("reg[0x%x] = 0x%x\n", xx+1, buf[xx]);
+		printk(KERN_DEBUG "reg[0x%x] = 0x%x\n", xx+1, buf[xx]);
 	}
 #endif
 	
@@ -302,8 +302,7 @@
 		snd_i2c_unlock(cs8427->bus);
 		if (!(data & CS8427_UNLOCK))
 			break;
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	}
 	snd_i2c_lock(cs8427->bus);
 	chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~CS8427_RXDMASK;
@@ -354,12 +353,12 @@
 
 	snd_i2c_lock(device->bus);
 	if ((err = snd_i2c_sendbytes(device, &reg, 1)) != 1) {
-		snd_printk("unable to send register 0x%x byte to CS8427\n", reg);
+		snd_printk(KERN_ERR "unable to send register 0x%x byte to CS8427\n", reg);
 		snd_i2c_unlock(device->bus);
 		return err < 0 ? err : -EIO;
 	}
 	if ((err = snd_i2c_readbytes(device, ucontrol->value.bytes.data, 10)) != 10) {
-		snd_printk("unable to read Q-subcode bytes from CS8427\n");
+		snd_printk(KERN_ERR "unable to read Q-subcode bytes from CS8427\n");
 		snd_i2c_unlock(device->bus);
 		return err < 0 ? err : -EIO;
 	}
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c
index af5eadc..d351b3a 100644
--- a/sound/i2c/other/ak4114.c
+++ b/sound/i2c/other/ak4114.c
@@ -56,9 +56,9 @@
 {
 	int i;
 
-	printk("AK4114 REG DUMP:\n");
+	printk(KERN_DEBUG "AK4114 REG DUMP:\n");
 	for (i = 0; i < 0x20; i++)
-		printk("reg[%02x] = %02x (%02x)\n", i, reg_read(ak4114, i), i < sizeof(ak4114->regmap) ? ak4114->regmap[i] : 0);
+		printk(KERN_DEBUG "reg[%02x] = %02x (%02x)\n", i, reg_read(ak4114, i), i < sizeof(ak4114->regmap) ? ak4114->regmap[i] : 0);
 }
 #endif
 
@@ -552,7 +552,7 @@
 	if (!(flags & AK4114_CHECK_NO_RATE) && runtime && runtime->rate != res) {
 		snd_pcm_stream_lock_irqsave(ak4114->capture_substream, _flags);
 		if (snd_pcm_running(ak4114->capture_substream)) {
-			// printk("rate changed (%i <- %i)\n", runtime->rate, res);
+			// printk(KERN_DEBUG "rate changed (%i <- %i)\n", runtime->rate, res);
 			snd_pcm_stop(ak4114->capture_substream, SNDRV_PCM_STATE_DRAINING);
 			res = 1;
 		}
diff --git a/sound/i2c/other/ak4117.c b/sound/i2c/other/ak4117.c
index d51b51d..35b4584 100644
--- a/sound/i2c/other/ak4117.c
+++ b/sound/i2c/other/ak4117.c
@@ -54,9 +54,9 @@
 {
 	int i;
 
-	printk("AK4117 REG DUMP:\n");
+	printk(KERN_DEBUG "AK4117 REG DUMP:\n");
 	for (i = 0; i < 0x1b; i++)
-		printk("reg[%02x] = %02x (%02x)\n", i, reg_read(ak4117, i), i < sizeof(ak4117->regmap) ? ak4117->regmap[i] : 0);
+		printk(KERN_DEBUG "reg[%02x] = %02x (%02x)\n", i, reg_read(ak4117, i), i < sizeof(ak4117->regmap) ? ak4117->regmap[i] : 0);
 }
 #endif
 
@@ -477,7 +477,7 @@
 		goto __rate;
 	rcs0 = reg_read(ak4117, AK4117_REG_RCS0);
 	rcs2 = reg_read(ak4117, AK4117_REG_RCS2);
-	// printk("AK IRQ: rcs0 = 0x%x, rcs1 = 0x%x, rcs2 = 0x%x\n", rcs0, rcs1, rcs2);
+	// printk(KERN_DEBUG "AK IRQ: rcs0 = 0x%x, rcs1 = 0x%x, rcs2 = 0x%x\n", rcs0, rcs1, rcs2);
 	spin_lock_irqsave(&ak4117->lock, _flags);
 	if (rcs0 & AK4117_PAR)
 		ak4117->parity_errors++;
@@ -530,7 +530,7 @@
 	if (!(flags & AK4117_CHECK_NO_RATE) && runtime && runtime->rate != res) {
 		snd_pcm_stream_lock_irqsave(ak4117->substream, _flags);
 		if (snd_pcm_running(ak4117->substream)) {
-			// printk("rate changed (%i <- %i)\n", runtime->rate, res);
+			// printk(KERN_DEBUG "rate changed (%i <- %i)\n", runtime->rate, res);
 			snd_pcm_stop(ak4117->substream, SNDRV_PCM_STATE_DRAINING);
 			wake_up(&runtime->sleep);
 			res = 1;
diff --git a/sound/i2c/tea6330t.c b/sound/i2c/tea6330t.c
index fd65da6..4fdd1fb 100644
--- a/sound/i2c/tea6330t.c
+++ b/sound/i2c/tea6330t.c
@@ -58,7 +58,7 @@
 			     unsigned char addr, unsigned char value)
 {
 #if 0
-	printk("set - 0x%x/0x%x\n", addr, value);
+	printk(KERN_DEBUG "set - 0x%x/0x%x\n", addr, value);
 #endif
 	snd_i2c_write(tea->bus, TEA6330T_ADDR, addr, value, 1);
 }
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c
index 27a9dcf..7ae0239 100644
--- a/sound/isa/ad1816a/ad1816a_lib.c
+++ b/sound/isa/ad1816a/ad1816a_lib.c
@@ -542,10 +542,7 @@
 
 static int snd_ad1816a_free(ad1816a_t *chip)
 {
-	if (chip->res_port) {
-		release_resource(chip->res_port);
-		kfree_nocheck(chip->res_port);
-	}
+	release_and_free_resource(chip->res_port);
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *) chip);
 	if (chip->dma1 >= 0) {
diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c
index 303861c..891bacc 100644
--- a/sound/isa/ad1848/ad1848_lib.c
+++ b/sound/isa/ad1848/ad1848_lib.c
@@ -109,7 +109,7 @@
 		udelay(100);
 #ifdef CONFIG_SND_DEBUG
 	if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
-		snd_printk("auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
+		snd_printk(KERN_WARNING "auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
 #endif
 	outb(chip->mce_bit | reg, AD1848P(chip, REGSEL));
 	outb(chip->image[reg] = value, AD1848P(chip, REG));
@@ -139,7 +139,7 @@
 		udelay(100);
 #ifdef CONFIG_SND_DEBUG
 	if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
-		snd_printk("auto calibration time out - reg = 0x%x\n", reg);
+		snd_printk(KERN_WARNING "auto calibration time out - reg = 0x%x\n", reg);
 #endif
 	outb(chip->mce_bit | reg, AD1848P(chip, REGSEL));
 	mb();
@@ -185,13 +185,13 @@
 		udelay(100);
 #ifdef CONFIG_SND_DEBUG
 	if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
-		snd_printk("mce_up - auto calibration time out (0)\n");
+		snd_printk(KERN_WARNING "mce_up - auto calibration time out (0)\n");
 #endif
 	spin_lock_irqsave(&chip->reg_lock, flags);
 	chip->mce_bit |= AD1848_MCE;
 	timeout = inb(AD1848P(chip, REGSEL));
 	if (timeout == 0x80)
-		snd_printk("mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port);
+		snd_printk(KERN_WARNING "mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port);
 	if (!(timeout & AD1848_MCE))
 		outb(chip->mce_bit | (timeout & 0x1f), AD1848P(chip, REGSEL));
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
@@ -214,13 +214,13 @@
 #endif
 #ifdef CONFIG_SND_DEBUG
 	if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
-		snd_printk("mce_down [0x%lx] - auto calibration time out (0)\n", AD1848P(chip, REGSEL));
+		snd_printk(KERN_WARNING "mce_down [0x%lx] - auto calibration time out (0)\n", AD1848P(chip, REGSEL));
 #endif
 	chip->mce_bit &= ~AD1848_MCE;
 	timeout = inb(AD1848P(chip, REGSEL));
 	outb(chip->mce_bit | (timeout & 0x1f), AD1848P(chip, REGSEL));
 	if (timeout == 0x80)
-		snd_printk("mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port);
+		snd_printk(KERN_WARNING "mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port);
 	if ((timeout & AD1848_MCE) == 0) {
 		spin_unlock_irqrestore(&chip->reg_lock, flags);
 		return;
@@ -240,11 +240,10 @@
 	while (snd_ad1848_in(chip, AD1848_TEST_INIT) & AD1848_CALIB_IN_PROGRESS) {
 		spin_unlock_irqrestore(&chip->reg_lock, flags);
 		if (time <= 0) {
-			snd_printk("mce_down - auto calibration time out (2)\n");
+			snd_printk(KERN_ERR "mce_down - auto calibration time out (2)\n");
 			return;
 		}
-		set_current_state(TASK_INTERRUPTIBLE);
-		time = schedule_timeout(time);
+		time = schedule_timeout_interruptible(time);
 		spin_lock_irqsave(&chip->reg_lock, flags);
 	}
 #if 0
@@ -254,11 +253,10 @@
 	while (inb(AD1848P(chip, REGSEL)) & AD1848_INIT) {
 		spin_unlock_irqrestore(&chip->reg_lock, flags);
 		if (time <= 0) {
-			snd_printk("mce_down - auto calibration time out (3)\n");
+			snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n");
 			return;
 		}
-		set_current_state(TASK_INTERRUPTIBLE);
-		time = schedule_timeout(time);
+		time = schedule_timeout_interruptible(time);
 		spin_lock_irqsave(&chip->reg_lock, flags);
 	}
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
@@ -846,10 +844,7 @@
 
 static int snd_ad1848_free(ad1848_t *chip)
 {
-	if (chip->res_port) {
-		release_resource(chip->res_port);
-		kfree_nocheck(chip->res_port);
-	}
+	release_and_free_resource(chip->res_port);
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *) chip);
 	if (chip->dma >= 0) {
diff --git a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c
index 3231825..4af7690 100644
--- a/sound/isa/cs423x/cs4231_lib.c
+++ b/sound/isa/cs423x/cs4231_lib.c
@@ -1417,14 +1417,8 @@
 
 static int snd_cs4231_free(cs4231_t *chip)
 {
-	if (chip->res_port) {
-		release_resource(chip->res_port);
-		kfree_nocheck(chip->res_port);
-	}
-	if (chip->res_cport) {
-		release_resource(chip->res_cport);
-		kfree_nocheck(chip->res_cport);
-	}
+	release_and_free_resource(chip->res_port);
+	release_and_free_resource(chip->res_cport);
 	if (chip->irq >= 0) {
 		disable_irq(chip->irq);
 		if (!(chip->hwshare & CS4231_HWSHARE_IRQ))
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index d28315d..d60a55e 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -379,12 +379,8 @@
 {
 	struct snd_card_cs4236 *acard = (struct snd_card_cs4236 *)card->private_data;
 
-	if (acard) {
-		if (acard->res_sb_port) {
-			release_resource(acard->res_sb_port);
-			kfree_nocheck(acard->res_sb_port);
-		}
-	}
+	if (acard)
+		release_and_free_resource(acard->res_sb_port);
 }
 
 #ifdef CONFIG_PNP
diff --git a/sound/isa/cs423x/cs4236_lib.c b/sound/isa/cs423x/cs4236_lib.c
index 2128d4b..1adb88d 100644
--- a/sound/isa/cs423x/cs4236_lib.c
+++ b/sound/isa/cs423x/cs4236_lib.c
@@ -173,7 +173,10 @@
 	case 2117:	return 6;
 	case 2558:	return 7;
 	default:
-		snd_runtime_check(divisor >= 21 && divisor <= 192, return 192);
+		if (divisor < 21 || divisor > 192) {
+			snd_BUG();
+			return 192;
+		}
 		return divisor;
 	}
 }
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
index aac8987..2edc9c9 100644
--- a/sound/isa/es1688/es1688_lib.c
+++ b/sound/isa/es1688/es1688_lib.c
@@ -606,8 +606,7 @@
 {
 	if (chip->res_port) {
 		snd_es1688_init(chip, 0);
-		release_resource(chip->res_port);
-		kfree_nocheck(chip->res_port);
+		release_and_free_resource(chip->res_port);
 	}
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *) chip);
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index d0ea19f..970e2aa 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -173,7 +173,7 @@
                         outb(val, chip->port + 0x0C);
                         return 0;
                 }
-        snd_printk("dsp_command: timeout (0x%x)\n", val);
+	snd_printk(KERN_ERR "dsp_command: timeout (0x%x)\n", val);
         return -EINVAL;
 }
 
@@ -184,7 +184,8 @@
         for(i = MILLISECOND/10; i; i--)
                 if (inb(chip->port + 0x0C) & 0x40)
                         return inb(chip->port + 0x0A);
-        snd_printk("dsp_get_byte failed: 0x%lx = 0x%x!!!\n", chip->port + 0x0A, inb(chip->port + 0x0A));
+	snd_printk(KERN_ERR "dsp_get_byte failed: 0x%lx = 0x%x!!!\n",
+		   chip->port + 0x0A, inb(chip->port + 0x0A));
         return -ENODEV;
 }
 
@@ -204,7 +205,7 @@
  end:
         spin_unlock_irqrestore(&chip->reg_lock, flags);
 #ifdef REG_DEBUG
-	snd_printk("Reg %02x set to %02x\n", reg, data);
+	snd_printk(KERN_DEBUG "Reg %02x set to %02x\n", reg, data);
 #endif
 	return ret;
 }
@@ -223,7 +224,7 @@
 	data = snd_es18xx_dsp_get_byte(chip);
 	ret = data;
 #ifdef REG_DEBUG
-	snd_printk("Reg %02x now is %02x (%d)\n", reg, data, ret);
+	snd_printk(KERN_DEBUG "Reg %02x now is %02x (%d)\n", reg, data, ret);
 #endif
  end:
         spin_unlock_irqrestore(&chip->reg_lock, flags);
@@ -259,7 +260,8 @@
 		if (ret < 0)
 			goto end;
 #ifdef REG_DEBUG
-		snd_printk("Reg %02x was %02x, set to %02x (%d)\n", reg, old, new, ret);
+		snd_printk(KERN_DEBUG "Reg %02x was %02x, set to %02x (%d)\n",
+			   reg, old, new, ret);
 #endif
 	}
 	ret = oval;
@@ -277,7 +279,7 @@
         outb(data, chip->port + 0x05);
         spin_unlock_irqrestore(&chip->mixer_lock, flags);
 #ifdef REG_DEBUG
-	snd_printk("Mixer reg %02x set to %02x\n", reg, data);
+	snd_printk(KERN_DEBUG "Mixer reg %02x set to %02x\n", reg, data);
 #endif
 }
 
@@ -290,7 +292,7 @@
 	data = inb(chip->port + 0x05);
         spin_unlock_irqrestore(&chip->mixer_lock, flags);
 #ifdef REG_DEBUG
-	snd_printk("Mixer reg %02x now is %02x\n", reg, data);
+	snd_printk(KERN_DEBUG "Mixer reg %02x now is %02x\n", reg, data);
 #endif
         return data;
 }
@@ -309,7 +311,8 @@
 		new = (old & ~mask) | (val & mask);
 		outb(new, chip->port + 0x05);
 #ifdef REG_DEBUG
-		snd_printk("Mixer reg %02x was %02x, set to %02x\n", reg, old, new);
+		snd_printk(KERN_DEBUG "Mixer reg %02x was %02x, set to %02x\n",
+			   reg, old, new);
 #endif
 	}
         spin_unlock_irqrestore(&chip->mixer_lock, flags);
@@ -329,7 +332,8 @@
 	new = inb(chip->port + 0x05);
         spin_unlock_irqrestore(&chip->mixer_lock, flags);
 #ifdef REG_DEBUG
-	snd_printk("Mixer reg %02x was %02x, set to %02x, now is %02x\n", reg, old, expected, new);
+	snd_printk(KERN_DEBUG "Mixer reg %02x was %02x, set to %02x, now is %02x\n",
+		   reg, old, expected, new);
 #endif
 	return expected == new;
 }
@@ -1281,7 +1285,7 @@
 	outb(reg, chip->ctrl_port);
 	outb(data, chip->ctrl_port + 1);
 #ifdef REG_DEBUG
-	snd_printk("Config reg %02x set to %02x\n", reg, data);
+	snd_printk(KERN_DEBUG "Config reg %02x set to %02x\n", reg, data);
 #endif
 }
 
@@ -1346,7 +1350,7 @@
 			irqmask = 3;
 			break;
 		default:
-			snd_printk("invalid irq %d\n", chip->irq);
+			snd_printk(KERN_ERR "invalid irq %d\n", chip->irq);
 			return -ENODEV;
 		}
 		switch (chip->dma1) {
@@ -1360,7 +1364,7 @@
 			dma1mask = 3;
 			break;
 		default:
-			snd_printk("invalid dma1 %d\n", chip->dma1);
+			snd_printk(KERN_ERR "invalid dma1 %d\n", chip->dma1);
 			return -ENODEV;
 		}
 		switch (chip->dma2) {
@@ -1377,7 +1381,7 @@
 			dma2mask = 3;
 			break;
 		default:
-			snd_printk("invalid dma2 %d\n", chip->dma2);
+			snd_printk(KERN_ERR "invalid dma2 %d\n", chip->dma2);
 			return -ENODEV;
 		}
 
@@ -1440,7 +1444,7 @@
 
 	/* reset */
 	if (snd_es18xx_reset(chip) < 0) {
-                snd_printk("reset at 0x%lx failed!!!\n", chip->port);
+		snd_printk(KERN_ERR "reset at 0x%lx failed!!!\n", chip->port);
 		return -ENODEV;
 	}
 
@@ -1527,7 +1531,7 @@
 		chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME | ES18XX_HWV;
 		break;
 	default:
-                snd_printk("[0x%lx] unsupported chip ES%x\n",
+		snd_printk(KERN_ERR "[0x%lx] unsupported chip ES%x\n",
                            chip->port, chip->version);
                 return -ENODEV;
         }
@@ -1640,18 +1644,9 @@
 
 static int snd_es18xx_free(es18xx_t *chip)
 {
-	if (chip->res_port) {
-		release_resource(chip->res_port);
-		kfree_nocheck(chip->res_port);
-	}
-	if (chip->res_ctrl_port) {
-		release_resource(chip->res_ctrl_port);
-		kfree_nocheck(chip->res_ctrl_port);
-	}
-	if (chip->res_mpu_port) {
-		release_resource(chip->res_mpu_port);
-		kfree_nocheck(chip->res_mpu_port);
-	}
+	release_and_free_resource(chip->res_port);
+	release_and_free_resource(chip->res_ctrl_port);
+	release_and_free_resource(chip->res_mpu_port);
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *) chip);
 	if (chip->dma1 >= 0) {
diff --git a/sound/isa/gus/gus_dma.c b/sound/isa/gus/gus_dma.c
index de4b56d..ef1b2e9 100644
--- a/sound/isa/gus/gus_dma.c
+++ b/sound/isa/gus/gus_dma.c
@@ -199,7 +199,7 @@
 
 	block = kmalloc(sizeof(*block), atomic ? GFP_ATOMIC : GFP_KERNEL);
 	if (block == NULL) {
-		snd_printk("gf1: DMA transfer failure; not enough memory\n");
+		snd_printk(KERN_ERR "gf1: DMA transfer failure; not enough memory\n");
 		return -ENOMEM;
 	}
 	*block = *__block;
diff --git a/sound/isa/gus/gus_io.c b/sound/isa/gus/gus_io.c
index 23e1b5f1..8d5752b 100644
--- a/sound/isa/gus/gus_io.c
+++ b/sound/isa/gus/gus_io.c
@@ -343,7 +343,7 @@
 
 #ifdef CONFIG_SND_DEBUG
 	if (!gus->interwave)
-		snd_printk("snd_gf1_pokew - GF1!!!\n");
+		snd_printk(KERN_DEBUG "snd_gf1_pokew - GF1!!!\n");
 #endif
 	spin_lock_irqsave(&gus->reg_lock, flags);
 	outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
@@ -367,7 +367,7 @@
 
 #ifdef CONFIG_SND_DEBUG
 	if (!gus->interwave)
-		snd_printk("snd_gf1_peekw - GF1!!!\n");
+		snd_printk(KERN_DEBUG "snd_gf1_peekw - GF1!!!\n");
 #endif
 	spin_lock_irqsave(&gus->reg_lock, flags);
 	outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
@@ -393,7 +393,7 @@
 
 #ifdef CONFIG_SND_DEBUG
 	if (!gus->interwave)
-		snd_printk("snd_gf1_dram_setmem - GF1!!!\n");
+		snd_printk(KERN_DEBUG "snd_gf1_dram_setmem - GF1!!!\n");
 #endif
 	addr &= ~1;
 	count >>= 1;
@@ -449,30 +449,30 @@
 	int voice, ctrl;
 
 	voice = gus->gf1.active_voice;
-	printk(" -%i- GF1  voice ctrl, ramp ctrl  = 0x%x, 0x%x\n", voice, ctrl = snd_gf1_i_read8(gus, 0), snd_gf1_i_read8(gus, 0x0d));
-	printk(" -%i- GF1  frequency              = 0x%x\n", voice, snd_gf1_i_read16(gus, 1));
-	printk(" -%i- GF1  loop start, end        = 0x%x (0x%x), 0x%x (0x%x)\n", voice, snd_gf1_i_read_addr(gus, 2, ctrl & 4), snd_gf1_i_read_addr(gus, 2, (ctrl & 4) ^ 4), snd_gf1_i_read_addr(gus, 4, ctrl & 4), snd_gf1_i_read_addr(gus, 4, (ctrl & 4) ^ 4));
-	printk(" -%i- GF1  ramp start, end, rate  = 0x%x, 0x%x, 0x%x\n", voice, snd_gf1_i_read8(gus, 7), snd_gf1_i_read8(gus, 8), snd_gf1_i_read8(gus, 6));
-	printk(" -%i- GF1  volume                 = 0x%x\n", voice, snd_gf1_i_read16(gus, 9));
-	printk(" -%i- GF1  position               = 0x%x (0x%x)\n", voice, snd_gf1_i_read_addr(gus, 0x0a, ctrl & 4), snd_gf1_i_read_addr(gus, 0x0a, (ctrl & 4) ^ 4));
+	printk(KERN_INFO " -%i- GF1  voice ctrl, ramp ctrl  = 0x%x, 0x%x\n", voice, ctrl = snd_gf1_i_read8(gus, 0), snd_gf1_i_read8(gus, 0x0d));
+	printk(KERN_INFO " -%i- GF1  frequency              = 0x%x\n", voice, snd_gf1_i_read16(gus, 1));
+	printk(KERN_INFO " -%i- GF1  loop start, end        = 0x%x (0x%x), 0x%x (0x%x)\n", voice, snd_gf1_i_read_addr(gus, 2, ctrl & 4), snd_gf1_i_read_addr(gus, 2, (ctrl & 4) ^ 4), snd_gf1_i_read_addr(gus, 4, ctrl & 4), snd_gf1_i_read_addr(gus, 4, (ctrl & 4) ^ 4));
+	printk(KERN_INFO " -%i- GF1  ramp start, end, rate  = 0x%x, 0x%x, 0x%x\n", voice, snd_gf1_i_read8(gus, 7), snd_gf1_i_read8(gus, 8), snd_gf1_i_read8(gus, 6));
+	printk(KERN_INFO" -%i- GF1  volume                 = 0x%x\n", voice, snd_gf1_i_read16(gus, 9));
+	printk(KERN_INFO " -%i- GF1  position               = 0x%x (0x%x)\n", voice, snd_gf1_i_read_addr(gus, 0x0a, ctrl & 4), snd_gf1_i_read_addr(gus, 0x0a, (ctrl & 4) ^ 4));
 	if (gus->interwave && snd_gf1_i_read8(gus, 0x19) & 0x01) {	/* enhanced mode */
 		mode = snd_gf1_i_read8(gus, 0x15);
-		printk(" -%i- GFA1 mode                   = 0x%x\n", voice, mode);
+		printk(KERN_INFO " -%i- GFA1 mode                   = 0x%x\n", voice, mode);
 		if (mode & 0x01) {	/* Effect processor */
-			printk(" -%i- GFA1 effect address         = 0x%x\n", voice, snd_gf1_i_read_addr(gus, 0x11, ctrl & 4));
-			printk(" -%i- GFA1 effect volume          = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x16));
-			printk(" -%i- GFA1 effect volume final    = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x1d));
-			printk(" -%i- GFA1 effect acumulator      = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x14));
+			printk(KERN_INFO " -%i- GFA1 effect address         = 0x%x\n", voice, snd_gf1_i_read_addr(gus, 0x11, ctrl & 4));
+			printk(KERN_INFO " -%i- GFA1 effect volume          = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x16));
+			printk(KERN_INFO " -%i- GFA1 effect volume final    = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x1d));
+			printk(KERN_INFO " -%i- GFA1 effect acumulator      = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x14));
 		}
 		if (mode & 0x20) {
-			printk(" -%i- GFA1 left offset            = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x13), snd_gf1_i_read16(gus, 0x13) >> 4);
-			printk(" -%i- GFA1 left offset final      = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x1c), snd_gf1_i_read16(gus, 0x1c) >> 4);
-			printk(" -%i- GFA1 right offset           = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x0c), snd_gf1_i_read16(gus, 0x0c) >> 4);
-			printk(" -%i- GFA1 right offset final     = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x1b), snd_gf1_i_read16(gus, 0x1b) >> 4);
+			printk(KERN_INFO " -%i- GFA1 left offset            = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x13), snd_gf1_i_read16(gus, 0x13) >> 4);
+			printk(KERN_INFO " -%i- GFA1 left offset final      = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x1c), snd_gf1_i_read16(gus, 0x1c) >> 4);
+			printk(KERN_INFO " -%i- GFA1 right offset           = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x0c), snd_gf1_i_read16(gus, 0x0c) >> 4);
+			printk(KERN_INFO " -%i- GFA1 right offset final     = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x1b), snd_gf1_i_read16(gus, 0x1b) >> 4);
 		} else
-			printk(" -%i- GF1  pan                    = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c));
+			printk(KERN_INFO " -%i- GF1  pan                    = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c));
 	} else
-		printk(" -%i- GF1  pan                    = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c));
+		printk(KERN_INFO " -%i- GF1  pan                    = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c));
 }
 
 #if 0
@@ -481,45 +481,45 @@
 {
 	unsigned char global_mode = 0x00;
 
-	printk(" -G- GF1 active voices            = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_ACTIVE_VOICES));
+	printk(KERN_INFO " -G- GF1 active voices            = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_ACTIVE_VOICES));
 	if (gus->interwave) {
 		global_mode = snd_gf1_i_read8(gus, SNDRV_GF1_GB_GLOBAL_MODE);
-		printk(" -G- GF1 global mode              = 0x%x\n", global_mode);
+		printk(KERN_INFO " -G- GF1 global mode              = 0x%x\n", global_mode);
 	}
 	if (global_mode & 0x02)	/* LFO enabled? */
-		printk(" -G- GF1 LFO base                 = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_LFO_BASE));
-	printk(" -G- GF1 voices IRQ read          = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_VOICES_IRQ_READ));
-	printk(" -G- GF1 DRAM DMA control         = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL));
-	printk(" -G- GF1 DRAM DMA high/low        = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_HIGH), snd_gf1_i_read16(gus, SNDRV_GF1_GW_DRAM_DMA_LOW));
-	printk(" -G- GF1 DRAM IO high/low         = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_IO_HIGH), snd_gf1_i_read16(gus, SNDRV_GF1_GW_DRAM_IO_LOW));
+		printk(KERN_INFO " -G- GF1 LFO base                 = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_LFO_BASE));
+	printk(KERN_INFO " -G- GF1 voices IRQ read          = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_VOICES_IRQ_READ));
+	printk(KERN_INFO " -G- GF1 DRAM DMA control         = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL));
+	printk(KERN_INFO " -G- GF1 DRAM DMA high/low        = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_HIGH), snd_gf1_i_read16(gus, SNDRV_GF1_GW_DRAM_DMA_LOW));
+	printk(KERN_INFO " -G- GF1 DRAM IO high/low         = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_IO_HIGH), snd_gf1_i_read16(gus, SNDRV_GF1_GW_DRAM_IO_LOW));
 	if (!gus->interwave)
-		printk(" -G- GF1 record DMA control       = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL));
-	printk(" -G- GF1 DRAM IO 16               = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_DRAM_IO16));
+		printk(KERN_INFO " -G- GF1 record DMA control       = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL));
+	printk(KERN_INFO " -G- GF1 DRAM IO 16               = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_DRAM_IO16));
 	if (gus->gf1.enh_mode) {
-		printk(" -G- GFA1 memory config           = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG));
-		printk(" -G- GFA1 memory control          = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_MEMORY_CONTROL));
-		printk(" -G- GFA1 FIFO record base        = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_FIFO_RECORD_BASE_ADDR));
-		printk(" -G- GFA1 FIFO playback base      = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_FIFO_PLAY_BASE_ADDR));
-		printk(" -G- GFA1 interleave control      = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_INTERLEAVE));
+		printk(KERN_INFO " -G- GFA1 memory config           = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG));
+		printk(KERN_INFO " -G- GFA1 memory control          = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_MEMORY_CONTROL));
+		printk(KERN_INFO " -G- GFA1 FIFO record base        = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_FIFO_RECORD_BASE_ADDR));
+		printk(KERN_INFO " -G- GFA1 FIFO playback base      = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_FIFO_PLAY_BASE_ADDR));
+		printk(KERN_INFO " -G- GFA1 interleave control      = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_INTERLEAVE));
 	}
 }
 
 void snd_gf1_print_setup_registers(snd_gus_card_t * gus)
 {
-	printk(" -S- mix control                  = 0x%x\n", inb(GUSP(gus, MIXCNTRLREG)));
-	printk(" -S- IRQ status                   = 0x%x\n", inb(GUSP(gus, IRQSTAT)));
-	printk(" -S- timer control                = 0x%x\n", inb(GUSP(gus, TIMERCNTRL)));
-	printk(" -S- timer data                   = 0x%x\n", inb(GUSP(gus, TIMERDATA)));
-	printk(" -S- status read                  = 0x%x\n", inb(GUSP(gus, REGCNTRLS)));
-	printk(" -S- Sound Blaster control        = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL));
-	printk(" -S- AdLib timer 1/2              = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_ADLIB_TIMER_1), snd_gf1_i_look8(gus, SNDRV_GF1_GB_ADLIB_TIMER_2));
-	printk(" -S- reset                        = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET));
+	printk(KERN_INFO " -S- mix control                  = 0x%x\n", inb(GUSP(gus, MIXCNTRLREG)));
+	printk(KERN_INFO " -S- IRQ status                   = 0x%x\n", inb(GUSP(gus, IRQSTAT)));
+	printk(KERN_INFO " -S- timer control                = 0x%x\n", inb(GUSP(gus, TIMERCNTRL)));
+	printk(KERN_INFO " -S- timer data                   = 0x%x\n", inb(GUSP(gus, TIMERDATA)));
+	printk(KERN_INFO " -S- status read                  = 0x%x\n", inb(GUSP(gus, REGCNTRLS)));
+	printk(KERN_INFO " -S- Sound Blaster control        = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL));
+	printk(KERN_INFO " -S- AdLib timer 1/2              = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_ADLIB_TIMER_1), snd_gf1_i_look8(gus, SNDRV_GF1_GB_ADLIB_TIMER_2));
+	printk(KERN_INFO " -S- reset                        = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET));
 	if (gus->interwave) {
-		printk(" -S- compatibility                = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_COMPATIBILITY));
-		printk(" -S- decode control               = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DECODE_CONTROL));
-		printk(" -S- version number               = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER));
-		printk(" -S- MPU-401 emul. control A/B    = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_MPU401_CONTROL_A), snd_gf1_i_look8(gus, SNDRV_GF1_GB_MPU401_CONTROL_B));
-		printk(" -S- emulation IRQ                = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_EMULATION_IRQ));
+		printk(KERN_INFO " -S- compatibility                = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_COMPATIBILITY));
+		printk(KERN_INFO " -S- decode control               = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DECODE_CONTROL));
+		printk(KERN_INFO " -S- version number               = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER));
+		printk(KERN_INFO " -S- MPU-401 emul. control A/B    = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_MPU401_CONTROL_A), snd_gf1_i_look8(gus, SNDRV_GF1_GB_MPU401_CONTROL_B));
+		printk(KERN_INFO " -S- emulation IRQ                = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_EMULATION_IRQ));
 	}
 }
 
diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c
index 8f2872f..4f57ff4 100644
--- a/sound/isa/gus/gus_main.c
+++ b/sound/isa/gus/gus_main.c
@@ -113,14 +113,8 @@
 	snd_gf1_stop(gus);
 	snd_gus_init_dma_irq(gus, 0);
       __hw_end:
-	if (gus->gf1.res_port1) {
-		release_resource(gus->gf1.res_port1);
-		kfree_nocheck(gus->gf1.res_port1);
-	}
-	if (gus->gf1.res_port2) {
-		release_resource(gus->gf1.res_port2);
-		kfree_nocheck(gus->gf1.res_port2);
-	}
+	release_and_free_resource(gus->gf1.res_port1);
+	release_and_free_resource(gus->gf1.res_port2);
 	if (gus->gf1.irq >= 0)
 		free_irq(gus->gf1.irq, (void *) gus);
 	if (gus->gf1.dma1 >= 0) {
@@ -252,7 +246,7 @@
 	snd_gf1_poke(gus, 0L, 0xaa);
 	snd_gf1_poke(gus, 1L, 0x55);
 	if (snd_gf1_peek(gus, 0L) != 0xaa || snd_gf1_peek(gus, 1L) != 0x55) {
-		snd_printk("plain GF1 card at 0x%lx without onboard DRAM?\n", gus->gf1.port);
+		snd_printk(KERN_ERR "plain GF1 card at 0x%lx without onboard DRAM?\n", gus->gf1.port);
 		return -ENOMEM;
 	}
 	for (idx = 1, d = 0xab; idx < 4; idx++, d++) {
@@ -305,20 +299,17 @@
 	dma2 = gus->gf1.dma2;
 	dma2 = dma2 < 0 ? -dma2 : dma2;
 	dma2 = dmas[dma2 & 7];
-#if 0
-	printk("dma1 = %i, dma2 = %i\n", gus->gf1.dma1, gus->gf1.dma2);
-#endif
 	dma1 |= gus->equal_dma ? 0x40 : (dma2 << 3);
 
 	if ((dma1 & 7) == 0 || (dma2 & 7) == 0) {
-		snd_printk("Error! DMA isn't defined.\n");
+		snd_printk(KERN_ERR "Error! DMA isn't defined.\n");
 		return -EINVAL;
 	}
 	irq = gus->gf1.irq;
 	irq = irq < 0 ? -irq : irq;
 	irq = irqs[irq & 0x0f];
 	if (irq == 0) {
-		snd_printk("Error! IRQ isn't defined.\n");
+		snd_printk(KERN_ERR "Error! IRQ isn't defined.\n");
 		return -EINVAL;
 	}
 	irq |= 0x40;
@@ -406,8 +397,8 @@
 				strcpy(card->longname, "Gravis UltraSound Extreme");
 				gus->ess_flag = 1;
 			} else {
-				snd_printk("unknown GF1 revision number at 0x%lx - 0x%x (0x%x)\n", gus->gf1.port, rev, val);
-				snd_printk("  please - report to <perex@suse.cz>\n");
+				snd_printk(KERN_ERR "unknown GF1 revision number at 0x%lx - 0x%x (0x%x)\n", gus->gf1.port, rev, val);
+				snd_printk(KERN_ERR "  please - report to <perex@suse.cz>\n");
 			}
 		}
 	}
@@ -431,7 +422,7 @@
 
 	if (!gus->interwave) {
 		if ((err = snd_gus_check_version(gus)) < 0) {
-			snd_printk("version check failed\n");
+			snd_printk(KERN_ERR "version check failed\n");
 			return err;
 		}
 		if ((err = snd_gus_detect_memory(gus)) < 0)
diff --git a/sound/isa/gus/gus_mem.c b/sound/isa/gus/gus_mem.c
index 5eb766d..2e23f2a 100644
--- a/sound/isa/gus/gus_mem.c
+++ b/sound/isa/gus/gus_mem.c
@@ -198,7 +198,7 @@
 		if (nblock != NULL) {
 			if (size != (int)nblock->size) {
 				/* TODO: remove in the future */
-				snd_printk("snd_gf1_mem_alloc - share: sizes differ\n");
+				snd_printk(KERN_ERR "snd_gf1_mem_alloc - share: sizes differ\n");
 				goto __std;
 			}
 			nblock->share++;
diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c
index beb0136..1cc89fb 100644
--- a/sound/isa/gus/gus_pcm.c
+++ b/sound/isa/gus/gus_pcm.c
@@ -333,8 +333,7 @@
 			}
 		}
 		if (count > 0 && !in_interrupt()) {
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(1);
+			schedule_timeout_interruptible(1);
 			if (signal_pending(current))
 				return -EAGAIN;
 		}
@@ -698,7 +697,7 @@
 	gus_pcm_private_t *pcmp = runtime->private_data;
 	
 	if (!wait_event_timeout(pcmp->sleep, (atomic_read(&pcmp->dma_count) <= 0), 2*HZ))
-		snd_printk("gf1 pcm - serious DMA problem\n");
+		snd_printk(KERN_ERR "gf1 pcm - serious DMA problem\n");
 
 	snd_gf1_dma_done(gus);	
 	return 0;
diff --git a/sound/isa/gus/gus_reset.c b/sound/isa/gus/gus_reset.c
index ef687ab..9071096 100644
--- a/sound/isa/gus/gus_reset.c
+++ b/sound/isa/gus/gus_reset.c
@@ -134,7 +134,7 @@
 	spin_lock_irqsave(&gus->reg_lock, flags);
 	snd_gf1_select_voice(gus, voice);
 #if 0
-	printk(" -%i- smart stop voice - volume = 0x%x\n", voice, snd_gf1_i_read16(gus, SNDRV_GF1_VW_VOLUME));
+	printk(KERN_DEBUG " -%i- smart stop voice - volume = 0x%x\n", voice, snd_gf1_i_read16(gus, SNDRV_GF1_VW_VOLUME));
 #endif
 	snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_ADDRESS_CONTROL);
 	snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
@@ -148,7 +148,7 @@
 	spin_lock_irqsave(&gus->reg_lock, flags);
 	snd_gf1_select_voice(gus, voice);
 #if 0
-	printk(" -%i- stop voice - volume = 0x%x\n", voice, snd_gf1_i_read16(gus, SNDRV_GF1_VW_VOLUME));
+	printk(KERN_DEBUG " -%i- stop voice - volume = 0x%x\n", voice, snd_gf1_i_read16(gus, SNDRV_GF1_VW_VOLUME));
 #endif
 	snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_ADDRESS_CONTROL);
 	snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
diff --git a/sound/isa/gus/gus_simple.c b/sound/isa/gus/gus_simple.c
index c122e7b..dfed85b 100644
--- a/sound/isa/gus/gus_simple.c
+++ b/sound/isa/gus/gus_simple.c
@@ -136,7 +136,7 @@
 		snd_gf1_select_voice(gus, voice->number);
 		snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
 		snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, voice->gf1_volume);
-		printk("gf1_volume = 0x%x\n", voice->gf1_volume);
+		/* printk("gf1_volume = 0x%x\n", voice->gf1_volume); */
 		spin_unlock_irqrestore(&gus->reg_lock, flags);
 		return;
 	}
diff --git a/sound/isa/gus/gus_uart.c b/sound/isa/gus/gus_uart.c
index 1bc2da8..fbc95e9 100644
--- a/sound/isa/gus/gus_uart.c
+++ b/sound/isa/gus/gus_uart.c
@@ -104,7 +104,7 @@
 	gus->midi_substream_output = substream;
 	spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
 #if 0
-	snd_printk("write init - cmd = 0x%x, stat = 0x%x\n", gus->gf1.uart_cmd, snd_gf1_uart_stat(gus));
+	snd_printk(KERN_DEBUG "write init - cmd = 0x%x, stat = 0x%x\n", gus->gf1.uart_cmd, snd_gf1_uart_stat(gus));
 #endif
 	return 0;
 }
@@ -126,7 +126,7 @@
 		for (i = 0; i < 1000 && (snd_gf1_uart_stat(gus) & 0x01); i++)
 			snd_gf1_uart_get(gus);	/* clean Rx */
 		if (i >= 1000)
-			snd_printk("gus midi uart init read - cleanup error\n");
+			snd_printk(KERN_ERR "gus midi uart init read - cleanup error\n");
 	}
 	spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
 #if 0
diff --git a/sound/isa/gus/gus_volume.c b/sound/isa/gus/gus_volume.c
index 3d36f6c..b3382fe 100644
--- a/sound/isa/gus/gus_volume.c
+++ b/sound/isa/gus/gus_volume.c
@@ -119,7 +119,7 @@
 		freq16 = 50;
 	if (freq16 & 0xf8000000) {
 		freq16 = ~0xf8000000;
-		snd_printk("snd_gf1_translate_freq: overflow - freq = 0x%x\n", freq16);
+		snd_printk(KERN_ERR "snd_gf1_translate_freq: overflow - freq = 0x%x\n", freq16);
 	}
 	return ((freq16 << 9) + (gus->gf1.playback_freq >> 1)) / gus->gf1.playback_freq;
 }
@@ -203,14 +203,14 @@
 	fc = (freq << 10) / rate;
 	if (fc > 97391L) {
 		fc = 97391;
-		snd_printk("patch: (1) fc frequency overflow - %u\n", fc);
+		snd_printk(KERN_ERR "patch: (1) fc frequency overflow - %u\n", fc);
 	}
 	fc = (fc * 44100UL) / mix_rate;
 	while (scale--)
 		fc <<= 1;
 	if (fc > 65535L) {
 		fc = 65535;
-		snd_printk("patch: (2) fc frequency overflow - %u\n", fc);
+		snd_printk(KERN_ERR "patch: (2) fc frequency overflow - %u\n", fc);
 	}
 	return (unsigned short) fc;
 }
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 358cba9..f703a9f 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -437,7 +437,7 @@
 		for (i = 0; i < 8; ++i)
 			iwave[i] = snd_gf1_peek(gus, bank_pos + i);
 #ifdef CONFIG_SND_DEBUG_ROM
-		printk("ROM at 0x%06x = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", bank_pos,
+		printk(KERN_DEBUG "ROM at 0x%06x = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", bank_pos,
 		       iwave[0], iwave[1], iwave[2], iwave[3],
 		       iwave[4], iwave[5], iwave[6], iwave[7]);
 #endif
@@ -447,7 +447,7 @@
 		for (i = 0; i < sizeof(struct rom_hdr); i++)
 			csum += snd_gf1_peek(gus, bank_pos + i);
 #ifdef CONFIG_SND_DEBUG_ROM
-		printk("ROM checksum = 0x%x (computed)\n", csum);
+		printk(KERN_DEBUG "ROM checksum = 0x%x (computed)\n", csum);
 #endif
 		if (csum != 0)
 			continue;	/* not valid rom */
@@ -638,10 +638,7 @@
 	if (iwcard == NULL)
 		return;
 #ifdef SNDRV_STB
-	if (iwcard->i2c_res) {
-		release_resource(iwcard->i2c_res);
-		kfree_nocheck(iwcard->i2c_res);
-	}
+	release_and_free_resource(iwcard->i2c_res);
 #endif
 	if (iwcard->irq >= 0)
 		free_irq(iwcard->irq, (void *)iwcard);
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 4ba268f..47cabda 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -656,10 +656,7 @@
 {
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *)chip);
-	if (chip->res_port) {
-		release_resource(chip->res_port);
-		kfree_nocheck(chip->res_port);
-	}
+	release_and_free_resource(chip->res_port);
 	kfree(chip);
 	return 0;
 }
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index 73573cb..b94339f 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -299,10 +299,8 @@
 static long snd_legacy_find_free_ioport(long *port_table, long size)
 {
 	while (*port_table != -1) {
-		struct resource *res;
-		if ((res = request_region(*port_table, size, "ALSA test")) != NULL) {
-			release_resource(res);
-			kfree_nocheck(res);
+		if (request_region(*port_table, size, "ALSA test")) {
+			release_region(*port_table, size);
 			return *port_table;
 		}
 		port_table++;
@@ -1227,10 +1225,7 @@
 
 static int snd_opti93x_free(opti93x_t *chip)
 {
-	if (chip->res_port) {
-		release_resource(chip->res_port);
-		kfree_nocheck(chip->res_port);
-	}
+	release_and_free_resource(chip->res_port);
 	if (chip->dma1 >= 0) {
 		disable_dma(chip->dma1);
 		free_dma(chip->dma1);
@@ -1656,8 +1651,7 @@
 			if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)))
 				return 1;
 
-		release_resource(chip->res_mc_base);
-		kfree_nocheck(chip->res_mc_base);
+		release_and_free_resource(chip->res_mc_base);
 		chip->res_mc_base = NULL;
 
 	}
@@ -1683,8 +1677,7 @@
 		if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value)
 			return 1;
 
-		release_resource(chip->res_mc_base);
-		kfree_nocheck(chip->res_mc_base);
+		release_and_free_resource(chip->res_mc_base);
 		chip->res_mc_base = NULL;
 	}
 #endif	/* OPTi93X */
@@ -1886,12 +1879,8 @@
 {
 	opti9xx_t *chip = (opti9xx_t *)card->private_data;
         
-	if (chip) {
-		if (chip->res_mc_base) {
-			release_resource(chip->res_mc_base);
-			kfree_nocheck(chip->res_mc_base);
-		}
-	}
+	if (chip)
+		release_and_free_resource(chip->res_mc_base);
 }
 
 static int snd_card_opti9xx_probe(struct pnp_card_link *pcard,
diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c
index 5375705..b09c657 100644
--- a/sound/isa/sb/emu8000.c
+++ b/sound/isa/sb/emu8000.c
@@ -135,8 +135,7 @@
 snd_emu8000_read_wait(emu8000_t *emu)
 {
 	while ((EMU8000_SMALR_READ(emu) & 0x80000000) != 0) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_interruptible(1);
 		if (signal_pending(current))
 			break;
 	}
@@ -148,8 +147,7 @@
 snd_emu8000_write_wait(emu8000_t *emu)
 {
 	while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_interruptible(1);
 		if (signal_pending(current))
 			break;
 	}
@@ -437,8 +435,7 @@
 	for (i = 0; i < 10000; i++) {
 		if ((EMU8000_SMALW_READ(emu) & 0x80000000) == 0)
 			break;
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_interruptible(1);
 		if (signal_pending(current))
 			break;
 	}
@@ -1054,18 +1051,9 @@
  */
 static int snd_emu8000_free(emu8000_t *hw)
 {
-	if (hw->res_port1) {
-		release_resource(hw->res_port1);
-		kfree_nocheck(hw->res_port1);
-	}
-	if (hw->res_port2) {
-		release_resource(hw->res_port2);
-		kfree_nocheck(hw->res_port2);
-	}
-	if (hw->res_port3) {
-		release_resource(hw->res_port3);
-		kfree_nocheck(hw->res_port3);
-	}
+	release_and_free_resource(hw->res_port1);
+	release_and_free_resource(hw->res_port2);
+	release_and_free_resource(hw->res_port3);
 	kfree(hw);
 	return 0;
 }
diff --git a/sound/isa/sb/emu8000_patch.c b/sound/isa/sb/emu8000_patch.c
index 26e6930..2fea67e 100644
--- a/sound/isa/sb/emu8000_patch.c
+++ b/sound/isa/sb/emu8000_patch.c
@@ -109,8 +109,7 @@
 snd_emu8000_write_wait(emu8000_t *emu)
 {
 	while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_interruptible(1);
 		if (signal_pending(current))
 			break;
 	}
diff --git a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c
index 0209790..b323bee 100644
--- a/sound/isa/sb/emu8000_pcm.c
+++ b/sound/isa/sb/emu8000_pcm.c
@@ -117,8 +117,7 @@
 {
 	while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
 		if (can_schedule) {
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(1);
+			schedule_timeout_interruptible(1);
 			if (signal_pending(current))
 				break;
 		}
diff --git a/sound/isa/sb/emu8000_synth.c b/sound/isa/sb/emu8000_synth.c
index 1f63aa5..f68e2174 100644
--- a/sound/isa/sb/emu8000_synth.c
+++ b/sound/isa/sb/emu8000_synth.c
@@ -56,7 +56,7 @@
 	emu->num_ports = hw->seq_ports;
 
 	if (hw->memhdr) {
-		snd_printk("memhdr is already initialized!?\n");
+		snd_printk(KERN_ERR "memhdr is already initialized!?\n");
 		snd_util_memhdr_free(hw->memhdr);
 	}
 	hw->memhdr = snd_util_memhdr_new(hw->mem_size);
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index 7888783..c2fa451 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -345,10 +345,7 @@
         
 	if (acard == NULL)
 		return;
-	if (acard->fm_res) {
-		release_resource(acard->fm_res);
-		kfree_nocheck(acard->fm_res);
-	}
+	release_and_free_resource(acard->fm_res);
 }
 
 #ifdef CONFIG_PNP
diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c
index a99e642..556b95e 100644
--- a/sound/isa/sb/sb16_main.c
+++ b/sound/isa/sb/sb16_main.c
@@ -747,7 +747,7 @@
 	unsigned char realirq, realdma, realmpureg;
 	/* note: mpu register should be present only on SB16 Vibra soundcards */
 
-	// printk("codec->irq=%i, codec->dma8=%i, codec->dma16=%i\n", chip->irq, chip->dma8, chip->dma16);
+	// printk(KERN_DEBUG "codec->irq=%i, codec->dma8=%i, codec->dma16=%i\n", chip->irq, chip->dma8, chip->dma16);
 	spin_lock_irqsave(&chip->mixer_lock, flags);
 	mpureg = snd_sbmixer_read(chip, SB_DSP4_MPUSETUP) & ~0x06;
 	spin_unlock_irqrestore(&chip->mixer_lock, flags);
@@ -821,9 +821,9 @@
 
 	spin_unlock_irqrestore(&chip->mixer_lock, flags);
 	if ((~realirq) & irqreg || (~realdma) & dmareg) {
-		snd_printk("SB16 [0x%lx]: unable to set DMA & IRQ (PnP device?)\n", chip->port);
-		snd_printk("SB16 [0x%lx]: wanted: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, realirq, realdma, realmpureg);
-		snd_printk("SB16 [0x%lx]:    got: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, irqreg, dmareg, mpureg);
+		snd_printk(KERN_ERR "SB16 [0x%lx]: unable to set DMA & IRQ (PnP device?)\n", chip->port);
+		snd_printk(KERN_ERR "SB16 [0x%lx]: wanted: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, realirq, realdma, realmpureg);
+		snd_printk(KERN_ERR "SB16 [0x%lx]:    got: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, irqreg, dmareg, mpureg);
 		return -ENODEV;
 	}
 	return 0;
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
index c41ac25..0bc0a3a 100644
--- a/sound/isa/sb/sb8.c
+++ b/sound/isa/sb/sb8.c
@@ -78,10 +78,7 @@
 
 	if (acard == NULL)
 		return;
-	if (acard->fm_res) {
-		release_resource(acard->fm_res);
-		kfree_nocheck(acard->fm_res);
-	}
+	release_and_free_resource(acard->fm_res);
 }
 
 static int __init snd_sb8_probe(int dev)
diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c
index 87c9b1b..5ddc6e4 100644
--- a/sound/isa/sb/sb8_main.c
+++ b/sound/isa/sb/sb8_main.c
@@ -334,9 +334,6 @@
 	snd_pcm_substream_t *substream;
 	snd_pcm_runtime_t *runtime;
 
-#if 0
-	snd_printk("sb8: interrupt\n");
-#endif
 	snd_sb_ack_8bit(chip);
 	switch (chip->mode) {
 	case SB_MODE_PLAYBACK_8:	/* ok.. playback is active */
diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c
index f0f205a..603e923 100644
--- a/sound/isa/sb/sb_common.c
+++ b/sound/isa/sb/sb_common.c
@@ -45,7 +45,7 @@
 {
 	int i;
 #ifdef IO_DEBUG
-	snd_printk("command 0x%x\n", val);
+	snd_printk(KERN_DEBUG "command 0x%x\n", val);
 #endif
 	for (i = BUSY_LOOPS; i; i--)
 		if ((inb(SBP(chip, STATUS)) & 0x80) == 0) {
@@ -64,7 +64,7 @@
 		if (inb(SBP(chip, DATA_AVAIL)) & 0x80) {
 			val = inb(SBP(chip, READ));
 #ifdef IO_DEBUG
-			snd_printk("get_byte 0x%x\n", val);
+			snd_printk(KERN_DEBUG "get_byte 0x%x\n", val);
 #endif
 			return val;
 		}
@@ -154,7 +154,7 @@
 			str = "16";
 			break;
 		default:
-			snd_printk("SB [0x%lx]: unknown DSP chip version %i.%i\n",
+			snd_printk(KERN_INFO "SB [0x%lx]: unknown DSP chip version %i.%i\n",
 				   chip->port, major, minor);
 			return -ENODEV;
 		}
@@ -178,10 +178,8 @@
 
 static int snd_sbdsp_free(sb_t *chip)
 {
-	if (chip->res_port) {
-		release_resource(chip->res_port);
-		kfree_nocheck(chip->res_port);
-	}
+	if (chip->res_port)
+		release_and_free_resource(chip->res_port);
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *) chip);
 #ifdef CONFIG_ISA
diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c
index ff4b599..5a926a4 100644
--- a/sound/isa/sb/sb_mixer.c
+++ b/sound/isa/sb/sb_mixer.c
@@ -36,7 +36,7 @@
 	outb(data, SBP(chip, MIXER_DATA));
 	udelay(10);
 #ifdef IO_DEBUG
-	snd_printk("mixer_write 0x%x 0x%x\n", reg, data);
+	snd_printk(KERN_DEBUG "mixer_write 0x%x 0x%x\n", reg, data);
 #endif
 }
 
@@ -49,7 +49,7 @@
 	result = inb(SBP(chip, MIXER_DATA));
 	udelay(10);
 #ifdef IO_DEBUG
-	snd_printk("mixer_read 0x%x 0x%x\n", reg, result);
+	snd_printk(KERN_DEBUG "mixer_read 0x%x 0x%x\n", reg, result);
 #endif
 	return result;
 }
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index 9f6b58c..1158806 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -338,25 +338,11 @@
 static void soundscape_free(snd_card_t * c)
 {
 	register struct soundscape *sscape = get_card_soundscape(c);
-	release_resource(sscape->io_res);
-	kfree_nocheck(sscape->io_res);
+	release_and_free_resource(sscape->io_res);
 	free_dma(sscape->chip->dma1);
 }
 
 /*
- * Put this process into an idle wait-state for a certain number
- * of "jiffies". The process can almost certainly be rescheduled
- * while we're waiting, and so we must NOT be holding any spinlocks
- * when we call this function. If we are then we risk DEADLOCK in
- * SMP (Ha!) or pre-emptible kernels.
- */
-static inline void sleep(long jiffs, int state)
-{
-	set_current_state(state);
-	schedule_timeout(jiffs);
-}
-
-/*
  * Tell the SoundScape to begin a DMA tranfer using the given channel.
  * All locking issues are left to the caller.
  */
@@ -393,7 +379,7 @@
 		unsigned long flags;
 		unsigned char x;
 
-		sleep(1, TASK_INTERRUPTIBLE);
+		schedule_timeout_interruptible(1);
 
 		spin_lock_irqsave(&s->lock, flags);
 		x = inb(HOST_DATA_IO(s->io_base));
@@ -420,7 +406,7 @@
 		unsigned long flags;
 		unsigned char x;
 
-		sleep(1, TASK_INTERRUPTIBLE);
+		schedule_timeout_interruptible(1);
 
 		spin_lock_irqsave(&s->lock, flags);
 		x = inb(HOST_DATA_IO(s->io_base));
@@ -1288,8 +1274,7 @@
 	free_dma(params->dma1);
 
 	_release_region:
-	release_resource(io_res);
-	kfree_nocheck(io_res);
+	release_and_free_resource(io_res);
 
 	return err;
 }
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index 0a572e0..1818f10 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -379,10 +379,7 @@
 	snd_wavefront_card_t *acard = (snd_wavefront_card_t *)card->private_data;
 	
 	if (acard) {
-		if (acard->wavefront.res_base != NULL) {
-			release_resource(acard->wavefront.res_base);
-			kfree_nocheck(acard->wavefront.res_base);
-		}
+		release_and_free_resource(acard->wavefront.res_base);
 		if (acard->wavefront.irq > 0)
 			free_irq(acard->wavefront.irq, (void *)acard);
 	}
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
index 0c3c951..abd79b7 100644
--- a/sound/isa/wavefront/wavefront_synth.c
+++ b/sound/isa/wavefront/wavefront_synth.c
@@ -275,8 +275,7 @@
 wavefront_sleep (int limit)
 
 {
-	set_current_state(TASK_INTERRUPTIBLE);
-	schedule_timeout(limit);
+	schedule_timeout_interruptible(limit);
 
 	return signal_pending(current);
 }
@@ -1788,8 +1787,7 @@
 	outb (val,port);
 	spin_unlock_irq(&dev->irq_lock);
 	while (1) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		if ((timeout = schedule_timeout(timeout)) == 0)
+		if ((timeout = schedule_timeout_interruptible(timeout)) == 0)
 			return;
 		if (dev->irq_ok)
 			return;
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c
index 3f9684f..d08a42b 100644
--- a/sound/mips/au1x00.c
+++ b/sound/mips/au1x00.c
@@ -57,8 +57,6 @@
 MODULE_DEVICES("{{AMD,Au1000 AC'97}}");
 #endif
 
-#define chip_t au1000_t
-
 #define PLAYBACK 0
 #define CAPTURE 1
 #define AC97_SLOT_3 0x01
@@ -474,7 +472,7 @@
 	u32 volatile cmd;
 	u16 volatile data;
 	int             i;
-	spin_lock(au1000->ac97_lock);
+	spin_lock(&au1000->ac97_lock);
 /* would rather use the interupt than this polling but it works and I can't
 get the interupt driven case to work efficiently */
 	for (i = 0; i < 0x5000; i++)
@@ -497,7 +495,7 @@
 	}
 
 	data = au1000->ac97_ioport->cmd & 0xffff;
-	spin_unlock(au1000->ac97_lock);
+	spin_unlock(&au1000->ac97_lock);
 
 	return data;
 
@@ -509,7 +507,7 @@
 {
 	u32 cmd;
 	int i;
-	spin_lock(au1000->ac97_lock);
+	spin_lock(&au1000->ac97_lock);
 /* would rather use the interupt than this polling but it works and I can't
 get the interupt driven case to work efficiently */
 	for (i = 0; i < 0x5000; i++)
@@ -522,7 +520,7 @@
 	cmd &= ~AC97C_READ;
 	cmd |= ((u32) val << AC97C_WD_BIT);
 	au1000->ac97_ioport->cmd = cmd;
-	spin_unlock(au1000->ac97_lock);
+	spin_unlock(&au1000->ac97_lock);
 }
 static void
 snd_au1000_ac97_free(ac97_t *ac97)
@@ -606,8 +604,7 @@
 		/* put internal AC97 block into reset */
 		au1000->ac97_ioport->cntrl = AC97C_RS;
 		au1000->ac97_ioport = NULL;
-		release_resource(au1000->ac97_res_port);
-		kfree_nocheck(au1000->ac97_res_port);
+		release_and_free_resource(au1000->ac97_res_port);
 	}
 
 	if (au1000->stream[PLAYBACK]->dma >= 0)
diff --git a/sound/oss/sequencer_syms.c b/sound/oss/sequencer_syms.c
index 45edfd7..5d00879 100644
--- a/sound/oss/sequencer_syms.c
+++ b/sound/oss/sequencer_syms.c
@@ -19,7 +19,6 @@
 EXPORT_SYMBOL(sound_timer_init);
 EXPORT_SYMBOL(sound_timer_interrupt);
 EXPORT_SYMBOL(sound_timer_syncinterval);
-EXPORT_SYMBOL(reprogram_timer);
 
 /* Tuning */
 
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index a5d593c..0fb16cf 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -1,13 +1,5 @@
 # ALSA PCI drivers
 
-config SND_AC97_CODEC
-	tristate
-	select SND_PCM
-	select SND_AC97_BUS
-
-config SND_AC97_BUS
-	tristate
-
 menu "PCI devices"
 	depends on SND!=n && PCI
 
@@ -192,6 +184,7 @@
 	tristate "SB Audigy LS / Live 24bit"
 	depends on SND
 	select SND_AC97_CODEC
+	select SND_RAWMIDI
 	help
 	  Say Y here to include support for the Sound Blaster Audigy LS
 	  and Live 24bit.
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index 41fc290..9bde76c 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -220,12 +220,6 @@
   /*  31 */ "Reserved 31"
 };
 
-/*
- * Shared AC97 controllers (ICH, ATIIXP...)
- */
-static DECLARE_MUTEX(shared_codec_mutex);
-static ac97_t *shared_codec[AC97_SHARED_TYPES][4];
-
 
 /*
  *  I/O routines
@@ -996,14 +990,8 @@
 {
 	if (ac97) {
 		snd_ac97_proc_done(ac97);
-		if (ac97->bus) {
+		if (ac97->bus)
 			ac97->bus->codec[ac97->num] = NULL;
-			if (ac97->bus->shared_type) {
-				down(&shared_codec_mutex);
-				shared_codec[ac97->bus->shared_type-1][ac97->num] = NULL;
-				up(&shared_codec_mutex);
-			}
-		}
 		if (ac97->private_free)
 			ac97->private_free(ac97);
 		kfree(ac97);
@@ -1139,7 +1127,6 @@
 {
 	snd_kcontrol_new_t template;
 	memcpy(&template, _template, sizeof(template));
-	snd_runtime_check(!template.index, return NULL);
 	template.index = ac97->num;
 	return snd_ctl_new1(&template, ac97);
 }
@@ -1758,8 +1745,7 @@
 			if ((snd_ac97_read(ac97, AC97_REC_GAIN) & 0x7fff) == 0x0a05)
 				return 0;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	} while (time_after_eq(end_time, jiffies));
 	return -ENODEV;
 }
@@ -1889,21 +1875,6 @@
 	snd_assert(bus != NULL && template != NULL, return -EINVAL);
 	snd_assert(template->num < 4 && bus->codec[template->num] == NULL, return -EINVAL);
 
-	snd_assert(bus->shared_type <= AC97_SHARED_TYPES, return -EINVAL);
-	if (bus->shared_type) {
-		/* already shared? */
-		down(&shared_codec_mutex);
-		ac97 = shared_codec[bus->shared_type-1][template->num];
-		if (ac97) {
-			if ((ac97_is_audio(ac97) && (template->scaps & AC97_SCAP_SKIP_AUDIO)) ||
-			    (ac97_is_modem(ac97) && (template->scaps & AC97_SCAP_SKIP_MODEM))) {
-				up(&shared_codec_mutex);
-				return -EACCES; /* skip this */
-			}
-		}
-		up(&shared_codec_mutex);
-	}
-
 	card = bus->card;
 	ac97 = kzalloc(sizeof(*ac97), GFP_KERNEL);
 	if (ac97 == NULL)
@@ -2020,8 +1991,7 @@
 		do {
 			if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0f) == 0x0f)
 				goto __ready_ok;
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
+			schedule_timeout_uninterruptible(1);
 		} while (time_after_eq(end_time, jiffies));
 		snd_printk(KERN_WARNING "AC'97 %d analog subsections not ready\n", ac97->num);
 	}
@@ -2053,8 +2023,7 @@
 		do {
 			if ((snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS) & tmp) == tmp)
 				goto __ready_ok;
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
+			schedule_timeout_uninterruptible(1);
 		} while (time_after_eq(end_time, jiffies));
 		snd_printk(KERN_WARNING "MC'97 %d converters and GPIO not ready (0x%x)\n", ac97->num, snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS));
 	}
@@ -2077,6 +2046,8 @@
 		snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, AC97_GP_DRSS_MASK, AC97_GP_DRSS_78);
 		if ((snd_ac97_read(ac97, AC97_GENERAL_PURPOSE) & AC97_GP_DRSS_MASK) == AC97_GP_DRSS_78)
 			ac97->flags |= AC97_DOUBLE_RATE;
+		/* restore to slots 10/11 to avoid the confliction with surrounds */
+		snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, AC97_GP_DRSS_MASK, 0);
 	}
 	if (ac97->ext_id & AC97_EI_VRA) {	/* VRA support */
 		snd_ac97_determine_rates(ac97, AC97_PCM_FRONT_DAC_RATE, 0, &ac97->rates[AC97_RATES_FRONT_DAC]);
@@ -2153,7 +2124,7 @@
 		}
 	}
 	/* make sure the proper powerdown bits are cleared */
-	if (ac97->scaps) {
+	if (ac97->scaps && ac97_is_audio(ac97)) {
 		reg = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
 		if (ac97->scaps & AC97_SCAP_SURROUND_DAC) 
 			reg &= ~AC97_EA_PRJ;
@@ -2167,13 +2138,6 @@
 		return err;
 	}
 	*rac97 = ac97;
-
-	if (bus->shared_type) {
-		down(&shared_codec_mutex);
-		shared_codec[bus->shared_type-1][ac97->num] = ac97;
-		up(&shared_codec_mutex);
-	}
-
 	return 0;
 }
 
@@ -2295,8 +2259,7 @@
 		do {
 			if (snd_ac97_read(ac97, AC97_MASTER) == 0x8101)
 				break;
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
+			schedule_timeout_uninterruptible(1);
 		} while (time_after_eq(end_time, jiffies));
 		/* FIXME: extra delay */
 		ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000);
@@ -2308,8 +2271,7 @@
 			unsigned short val = snd_ac97_read(ac97, AC97_EXTENDED_MID);
 			if (val != 0xffff && (val & 1) != 0)
 				break;
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
+			schedule_timeout_uninterruptible(1);
 		} while (time_after_eq(end_time, jiffies));
 	}
 __reset_ready:
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 0238cc6..de1c72a 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -163,14 +163,24 @@
 		.private_value = 1, \
 	}
 
+static inline int is_surround_on(ac97_t *ac97)
+{
+	return ac97->channel_mode >= 1;
+}
+
+static inline int is_clfe_on(ac97_t *ac97)
+{
+	return ac97->channel_mode >= 2;
+}
+
 static inline int is_shared_linein(ac97_t *ac97)
 {
-	return ! ac97->indep_surround && ac97->channel_mode >= 1;
+	return ! ac97->indep_surround && is_surround_on(ac97);
 }
 
 static inline int is_shared_micin(ac97_t *ac97)
 {
-	return ! ac97->indep_surround && ac97->channel_mode >= 2;
+	return ! ac97->indep_surround && is_clfe_on(ac97);
 }
 
 
@@ -1450,7 +1460,8 @@
 	codecs[1] = patch_ad1881_unchained(ac97, 1, (1<<14));
 	codecs[2] = patch_ad1881_unchained(ac97, 2, (1<<13));
 
-	snd_runtime_check(codecs[0] | codecs[1] | codecs[2], goto __end);
+	if (! (codecs[0] || codecs[1] || codecs[2]))
+		goto __end;
 
 	for (idx = 0; idx < 3; idx++)
 		if (ac97->spec.ad18xx.unchained[idx])
@@ -1753,12 +1764,13 @@
 
 static void ad1888_update_jacks(ac97_t *ac97)
 {
+	unsigned short val = 0;
+	if (! is_shared_linein(ac97))
+		val |= (1 << 12);
+	if (! is_shared_micin(ac97))
+		val |= (1 << 11);
 	/* shared Line-In */
-	snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 12,
-			     is_shared_linein(ac97) ? 0 : 1 << 12);
-	/* shared Mic */
-	snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 11,
-			     is_shared_micin(ac97) ? 0 : 1 << 11);
+	snd_ac97_update_bits(ac97, AC97_AD_MISC, (1 << 11) | (1 << 12), val);
 }
 
 static const snd_kcontrol_new_t snd_ac97_ad1888_controls[] = {
@@ -1852,12 +1864,7 @@
 
 static void ad1985_update_jacks(ac97_t *ac97)
 {
-	/* shared Line-In */
-	snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 12,
-			     is_shared_linein(ac97) ? 0 : 1 << 12);
-	/* shared Mic */
-	snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 11,
-			     is_shared_micin(ac97) ? 0 : 1 << 11);
+	ad1888_update_jacks(ac97);
 	snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 1 << 9,
 			     is_shared_micin(ac97) ? 0 : 1 << 9);
 }
@@ -2442,21 +2449,37 @@
 
 static void cm9761_update_jacks(ac97_t *ac97)
 {
-	unsigned short surr_vals[2][2] = {
-		{ 0x0008, 0x0400 }, /* off, on */
-		{ 0x0000, 0x0408 }, /* off, on (9761-82 rev.B) */
+	/* FIXME: check the bits for each model
+	 *        model 83 is confirmed to work
+	 */
+	static unsigned short surr_on[3][2] = {
+		{ 0x0008, 0x0000 }, /* 9761-78 & 82 */
+		{ 0x0000, 0x0008 }, /* 9761-82 rev.B */
+		{ 0x0000, 0x0008 }, /* 9761-83 */
 	};
-	unsigned short clfe_vals[2][2] = {
-		{ 0x2000, 0x1880 }, /* off, on */
-		{ 0x1000, 0x2880 }, /* off, on (9761-82 rev.B) */
+	static unsigned short clfe_on[3][2] = {
+		{ 0x0000, 0x1000 }, /* 9761-78 & 82 */
+		{ 0x1000, 0x0000 }, /* 9761-82 rev.B */
+		{ 0x0000, 0x1000 }, /* 9761-83 */
 	};
+	static unsigned short surr_shared[3][2] = {
+		{ 0x0000, 0x0400 }, /* 9761-78 & 82 */
+		{ 0x0000, 0x0400 }, /* 9761-82 rev.B */
+		{ 0x0000, 0x0400 }, /* 9761-83 */
+	};
+	static unsigned short clfe_shared[3][2] = {
+		{ 0x2000, 0x0880 }, /* 9761-78 & 82 */
+		{ 0x0000, 0x2880 }, /* 9761-82 rev.B */
+		{ 0x2000, 0x0800 }, /* 9761-83 */
+	};
+	unsigned short val = 0;
 
-	/* shared Line-In */
-	snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x0408,
-			     surr_vals[ac97->spec.dev_flags][is_shared_linein(ac97)]);
-	/* shared Mic */
-	snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3880,
-			     clfe_vals[ac97->spec.dev_flags][is_shared_micin(ac97)]);
+	val |= surr_on[ac97->spec.dev_flags][is_surround_on(ac97)];
+	val |= clfe_on[ac97->spec.dev_flags][is_clfe_on(ac97)];
+	val |= surr_shared[ac97->spec.dev_flags][is_shared_linein(ac97)];
+	val |= clfe_shared[ac97->spec.dev_flags][is_shared_micin(ac97)];
+
+	snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3c88, val);
 }
 
 static const snd_kcontrol_new_t snd_ac97_cm9761_controls[] = {
@@ -2551,7 +2574,7 @@
 	snd_ac97_write_cache(ac97, AC97_MASTER, 0x8808);
 	snd_ac97_write_cache(ac97, AC97_PCM, 0x8808);
 
-	ac97->spec.dev_flags = 0; /* 1 = model 82 revision B */
+	ac97->spec.dev_flags = 0; /* 1 = model 82 revision B, 2 = model 83 */
 	if (ac97->id == AC97_ID_CM9761_82) {
 		unsigned short tmp;
 		/* check page 1, reg 0x60 */
@@ -2560,7 +2583,8 @@
 		tmp = snd_ac97_read(ac97, 0x60);
 		ac97->spec.dev_flags = tmp & 1; /* revision B? */
 		snd_ac97_write_cache(ac97, AC97_INT_PAGING, val);
-	}
+	} else if (ac97->id == AC97_ID_CM9761_83)
+		ac97->spec.dev_flags = 2;
 
 	ac97->build_ops = &patch_cm9761_ops;
 
diff --git a/sound/pci/ac97/ac97_pcm.c b/sound/pci/ac97/ac97_pcm.c
index dd289b9..ded1316 100644
--- a/sound/pci/ac97/ac97_pcm.c
+++ b/sound/pci/ac97/ac97_pcm.c
@@ -303,6 +303,15 @@
 				     AC97_EA_DRA, dbl ? AC97_EA_DRA : 0);
 	snd_ac97_update(ac97, reg, tmp & 0xffff);
 	snd_ac97_read(ac97, reg);
+	if ((ac97->ext_id & AC97_EI_DRA) && reg == AC97_PCM_FRONT_DAC_RATE) {
+		/* Intel controllers require double rate data to be put in
+		 * slots 7+8
+		 */
+		snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE,
+				     AC97_GP_DRSS_MASK,
+				     dbl ? AC97_GP_DRSS_78 : 0);
+		snd_ac97_read(ac97, AC97_GENERAL_PURPOSE);
+	}
 	return 0;
 }
 
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index d7d99a2..e72ccd1 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -50,7 +50,7 @@
 #include "ad1889.h"
 #include "ac97/ac97_id.h"
 
-#define	AD1889_DRVVER	"$Revision: 1.3 $"
+#define	AD1889_DRVVER	"$Revision: 1.4 $"
 
 MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>, Thibaut Varene <t-bone@parisc-linux.org>");
 MODULE_DESCRIPTION("Analog Devices AD1889 ALSA sound driver");
@@ -982,8 +982,7 @@
 	return 0;
 
 free_and_ret:
-	if (chip)
-		kfree(chip);
+	kfree(chip);
 	pci_disable_device(pci);
 
 	return err;
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index f35b558..4e76c4a 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -45,23 +45,25 @@
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{ALI,M5451,pci},{ALI,M5451}}");
 
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 32};
-static int spdif[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
+static int index = SNDRV_DEFAULT_IDX1;	/* Index */
+static char *id = SNDRV_DEFAULT_STR1;	/* ID for this card */
+static int pcm_channels = 32;
+static int spdif = 0;
 
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for ALI M5451 PCI Audio.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
 MODULE_PARM_DESC(id, "ID string for ALI M5451 PCI Audio.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable ALI 5451 PCI Audio.");
-module_param_array(pcm_channels, int, NULL, 0444);
+module_param(pcm_channels, int, 0444);
 MODULE_PARM_DESC(pcm_channels, "PCM Channels");
-module_param_array(spdif, bool, NULL, 0444);
+module_param(spdif, bool, 0444);
 MODULE_PARM_DESC(spdif, "Support SPDIF I/O");
 
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
+
 /*
  *  Debug part definitions
  */
@@ -396,10 +398,8 @@
 		res = snd_ali_5451_peek(codec,port);
 		if (! (res & 0x8000))
 			return 0;
-		if (sched) {
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
-		}
+		if (sched)
+			schedule_timeout_uninterruptible(1);
 	} while (time_after_eq(end_time, jiffies));
 	snd_ali_5451_poke(codec, port, res & ~0x8000);
 	snd_printdd("ali_codec_ready: codec is not ready.\n ");
@@ -419,12 +419,10 @@
 		dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER);
 		if (dwChk2 != dwChk1)
 			return 0;
-		if (sched) {
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
-		}
+		if (sched)
+			schedule_timeout_uninterruptible(1);
 	} while (time_after_eq(end_time, jiffies));
-	snd_printk("ali_stimer_read: stimer is not ready.\n");
+	snd_printk(KERN_ERR "ali_stimer_read: stimer is not ready.\n");
 	return -EIO;
 }
 
@@ -436,7 +434,7 @@
 	unsigned int port = 0;
 
 	if (reg >= 0x80) {
-		snd_printk("ali_codec_poke: reg(%xh) invalid.\n", reg);
+		snd_printk(KERN_ERR "ali_codec_poke: reg(%xh) invalid.\n", reg);
 		return;
 	}
 
@@ -465,7 +463,7 @@
 	unsigned int port = 0;
 
 	if (reg >= 0x80) {
-		snd_printk("ali_codec_peek: reg(%xh) invalid.\n", reg);
+		snd_printk(KERN_ERR "ali_codec_peek: reg(%xh) invalid.\n", reg);
 		return ~0;
 	}
 
@@ -669,7 +667,7 @@
 	unsigned int idx =  channel & 0x1f;
 
 	if (codec->synth.chcnt >= ALI_CHANNELS){
-		snd_printk("ali_alloc_pcm_channel: no free channels.\n");
+		snd_printk(KERN_ERR "ali_alloc_pcm_channel: no free channels.\n");
 		return -1;
 	}
 
@@ -700,7 +698,7 @@
 		if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) {
 			return result;
 		} else {
-			snd_printk("ali_find_free_channel: record channel is busy now.\n");
+			snd_printk(KERN_ERR "ali_find_free_channel: record channel is busy now.\n");
 			return -1;
 		}
 	}
@@ -712,7 +710,7 @@
 		if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) {
 			return result;
 		} else {
-			snd_printk("ali_find_free_channel: S/PDIF out channel is in busy now.\n");
+			snd_printk(KERN_ERR "ali_find_free_channel: S/PDIF out channel is in busy now.\n");
 		}
 	}
 
@@ -720,7 +718,7 @@
 		if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0)
 			return result;
 	}
-	snd_printk("ali_find_free_channel: no free channels.\n");
+	snd_printk(KERN_ERR "ali_find_free_channel: no free channels.\n");
 	return -1;
 }
 
@@ -734,7 +732,7 @@
 		return;
 
 	if (!(codec->synth.chmap & (1 << idx))) {
-		snd_printk("ali_free_channel_pcm: channel %d is not in use.\n",channel);
+		snd_printk(KERN_ERR "ali_free_channel_pcm: channel %d is not in use.\n",channel);
 		return;
 	} else {
 		codec->synth.chmap &= ~(1 << idx);
@@ -796,7 +794,7 @@
 	}
 
 	if (count > 50000) {
-		snd_printk("ali_detect_spdif_rate: timeout!\n");
+		snd_printk(KERN_ERR "ali_detect_spdif_rate: timeout!\n");
 		return;
 	}
 
@@ -809,7 +807,7 @@
 	}
 
 	if (count > 50000) {
-		snd_printk("ali_detect_spdif_rate: timeout!\n");
+		snd_printk(KERN_ERR "ali_detect_spdif_rate: timeout!\n");
 		return;
 	}
 
@@ -1077,7 +1075,7 @@
 		idx = channel > 0 ? snd_ali_alloc_pcm_channel(codec, channel) :
 			snd_ali_find_free_channel(codec,rec);
 		if(idx < 0) {
-			snd_printk("ali_alloc_voice: err.\n");
+			snd_printk(KERN_ERR "ali_alloc_voice: err.\n");
 			spin_unlock_irqrestore(&codec->voice_alloc, flags);
 			return NULL;
 		}
@@ -1479,13 +1477,13 @@
 		}
 		rate = snd_ali_get_spdif_in_rate(codec);
 		if (rate == 0) {
-			snd_printk("ali_capture_preapre: spdif rate detect err!\n");
+			snd_printk(KERN_WARNING "ali_capture_preapre: spdif rate detect err!\n");
 			rate = 48000;
 		}
 		bValue = inb(ALI_REG(codec,ALI_SPDIF_CTRL));
 		if (bValue & 0x10) {
 			outb(bValue,ALI_REG(codec,ALI_SPDIF_CTRL));
-			printk("clear SPDIF parity error flag.\n");
+			printk(KERN_WARNING "clear SPDIF parity error flag.\n");
 		}
 
 		if (rate != 48000)
@@ -1795,6 +1793,7 @@
 	unsigned int capture_num;
 	snd_pcm_ops_t *playback_ops;
 	snd_pcm_ops_t *capture_ops;
+	unsigned short class;
 };
 
 
@@ -1813,12 +1812,11 @@
 	err = snd_pcm_new(codec->card, desc->name, device,
 			  desc->playback_num, desc->capture_num, &pcm);
 	if (err < 0) {
-		snd_printk("snd_ali_pcm: err called snd_pcm_new.\n");
+		snd_printk(KERN_ERR "snd_ali_pcm: err called snd_pcm_new.\n");
 		return err;
 	}
 	pcm->private_data = codec;
 	pcm->private_free = snd_ali_pcm_free;
-	pcm->info_flags = 0;
 	if (desc->playback_ops)
 		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, desc->playback_ops);
 	if (desc->capture_ops)
@@ -1828,6 +1826,7 @@
 					      snd_dma_pci_data(codec->pci), 64*1024, 128*1024);
 
 	pcm->info_flags = 0;
+	pcm->dev_class = desc->class;
 	pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
 	strcpy(pcm->name, desc->name);
 	codec->pcm[0] = pcm;
@@ -1836,7 +1835,7 @@
 
 static struct ali_pcm_description ali_pcms[] = {
 	{ "ALI 5451", ALI_CHANNELS, 1, &snd_ali_playback_ops, &snd_ali_capture_ops },
-	{ "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops }
+	{ "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops, SNDRV_PCM_CLASS_MODEM }
 };
 
 static int __devinit snd_ali_build_pcms(ali_t *codec)
@@ -1991,7 +1990,7 @@
 	for ( i = 0 ; i < codec->num_of_codecs ; i++) {
 		ac97.num = i;
 		if ((err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i])) < 0) {
-			snd_printk("ali mixer %d creating error.\n", i);
+			snd_printk(KERN_ERR "ali mixer %d creating error.\n", i);
 			if(i == 0)
 				return err;
 			codec->num_of_codecs = 1;
@@ -2125,7 +2124,7 @@
 	snd_ali_printk("chip initializing ... \n");
 
 	if (snd_ali_reset_5451(codec)) {
-		snd_printk("ali_chip_init: reset 5451 error.\n");
+		snd_printk(KERN_ERR "ali_chip_init: reset 5451 error.\n");
 		return -1;
 	}
 
@@ -2200,7 +2199,7 @@
 	codec->port = pci_resource_start(codec->pci, 0);
 
 	if (request_irq(codec->pci->irq, snd_ali_card_interrupt, SA_INTERRUPT|SA_SHIRQ, "ALI 5451", (void *)codec)) {
-		snd_printk("Unable to request irq.\n");
+		snd_printk(KERN_ERR "Unable to request irq.\n");
 		return -EBUSY;
 	}
 	codec->irq = codec->pci->irq;
@@ -2240,7 +2239,7 @@
 	/* check, if we can restrict PCI DMA transfers to 31 bits */
 	if (pci_set_dma_mask(pci, 0x7fffffff) < 0 ||
 	    pci_set_consistent_dma_mask(pci, 0x7fffffff) < 0) {
-		snd_printk("architecture does not support 31bit PCI busmaster DMA\n");
+		snd_printk(KERN_ERR "architecture does not support 31bit PCI busmaster DMA\n");
 		pci_disable_device(pci);
 		return -ENXIO;
 	}
@@ -2329,7 +2328,7 @@
 	}
 
 	if ((err = snd_ali_chip_init(codec)) < 0) {
-		snd_printk("ali create: chip init error.\n");
+		snd_printk(KERN_ERR "ali create: chip init error.\n");
 		return err;
 	}
 
@@ -2352,25 +2351,17 @@
 static int __devinit snd_ali_probe(struct pci_dev *pci,
 				   const struct pci_device_id *pci_id)
 {
-	static int dev;
 	snd_card_t *card;
 	ali_t *codec;
 	int err;
 
 	snd_ali_printk("probe ...\n");
 
-        if (dev >= SNDRV_CARDS)
-                return -ENODEV;
-	if (!enable[dev]) {
-		dev++;
-		return -ENOENT;
-	}
-
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	card = snd_card_new(index, id, THIS_MODULE, 0);
 	if (card == NULL)
 		return -ENOMEM;
 
-	if ((err = snd_ali_create(card, pci, pcm_channels[dev], spdif[dev], &codec)) < 0) {
+	if ((err = snd_ali_create(card, pci, pcm_channels, spdif, &codec)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
@@ -2401,7 +2392,6 @@
 		return err;
 	}
 	pci_set_drvdata(pci, card);
-	dev++;
 	return 0;
 }
 
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 196ec1c..7c61561f 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -594,8 +594,7 @@
 	acard->gameport = gp = gameport_allocate_port();
 	if (!gp) {
 		printk(KERN_ERR "als4000: cannot allocate memory for gameport\n");
-		release_resource(r);
-		kfree_nocheck(r);
+		release_and_free_resource(r);
 		return -ENOMEM;
 	}
 
@@ -622,8 +621,7 @@
 		acard->gameport = NULL;
 
 		snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0); /* disable joystick */
-		release_resource(r);
-		kfree_nocheck(r);
+		release_and_free_resource(r);
 	}
 }
 #else
@@ -669,7 +667,7 @@
 	/* check, if we can restrict PCI DMA transfers to 24 bits */
 	if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
 	    pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
-		snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
+		snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
 		pci_disable_device(pci);
 		return -ENXIO;
 	}
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 241eacf..f5dad92 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -39,26 +39,27 @@
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250/300/400}}");
 
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
-static char *ac97_quirk[SNDRV_CARDS];
-static int spdif_aclink[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
+static int index = SNDRV_DEFAULT_IDX1;	/* Index 0-MAX */
+static char *id = SNDRV_DEFAULT_STR1;	/* ID for this card */
+static int ac97_clock = 48000;
+static char *ac97_quirk;
+static int spdif_aclink = 1;
 
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for ATI IXP controller.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
 MODULE_PARM_DESC(id, "ID string for ATI IXP controller.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable audio part of ATI IXP controller.");
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
-module_param_array(ac97_quirk, charp, NULL, 0444);
+module_param(ac97_quirk, charp, 0444);
 MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
-module_param_array(spdif_aclink, bool, NULL, 0444);
+module_param(spdif_aclink, bool, 0444);
 MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link.");
 
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
 
 /*
  */
@@ -329,8 +330,7 @@
 
 /* delay for one tick */
 #define do_delay() do { \
-	set_current_state(TASK_UNINTERRUPTIBLE); \
-	schedule_timeout(1); \
+	schedule_timeout_uninterruptible(1); \
 } while (0)
 
 
@@ -1372,7 +1372,6 @@
 	if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
 		return err;
 	pbus->clock = clock;
-	pbus->shared_type = AC97_SHARED_TYPE_ATIIXP;	/* shared with modem driver */
 	chip->ac97_bus = pbus;
 
 	codec_count = 0;
@@ -1579,26 +1578,18 @@
 static int __devinit snd_atiixp_probe(struct pci_dev *pci,
 				     const struct pci_device_id *pci_id)
 {
-	static int dev;
 	snd_card_t *card;
 	atiixp_t *chip;
 	unsigned char revision;
 	int err;
 
-	if (dev >= SNDRV_CARDS)
-		return -ENODEV;
-	if (!enable[dev]) {
-		dev++;
-		return -ENOENT;
-	}
-
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	card = snd_card_new(index, id, THIS_MODULE, 0);
 	if (card == NULL)
 		return -ENOMEM;
 
 	pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
 
-	strcpy(card->driver, spdif_aclink[dev] ? "ATIIXP" : "ATIIXP-SPDMA");
+	strcpy(card->driver, spdif_aclink ? "ATIIXP" : "ATIIXP-SPDMA");
 	strcpy(card->shortname, "ATI IXP");
 	if ((err = snd_atiixp_create(card, pci, &chip)) < 0)
 		goto __error;
@@ -1606,9 +1597,9 @@
 	if ((err = snd_atiixp_aclink_reset(chip)) < 0)
 		goto __error;
 
-	chip->spdif_over_aclink = spdif_aclink[dev];
+	chip->spdif_over_aclink = spdif_aclink;
 
-	if ((err = snd_atiixp_mixer_new(chip, ac97_clock[dev], ac97_quirk[dev])) < 0)
+	if ((err = snd_atiixp_mixer_new(chip, ac97_clock, ac97_quirk)) < 0)
 		goto __error;
 
 	if ((err = snd_atiixp_pcm_new(chip)) < 0)
@@ -1629,7 +1620,6 @@
 		goto __error;
 
 	pci_set_drvdata(pci, card);
-	dev++;
 	return 0;
 
  __error:
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index c1a239a..0cf2020 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -39,20 +39,21 @@
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250}}");
 
-static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
+static int index = -2; /* Exclude the first card */
+static char *id = SNDRV_DEFAULT_STR1;	/* ID for this card */
+static int ac97_clock = 48000;
 
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for ATI IXP controller.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
 MODULE_PARM_DESC(id, "ID string for ATI IXP controller.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable audio part of ATI IXP controller.");
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
 
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
 
 /*
  */
@@ -306,8 +307,7 @@
 
 /* delay for one tick */
 #define do_delay() do { \
-	set_current_state(TASK_UNINTERRUPTIBLE); \
-	schedule_timeout(1); \
+	schedule_timeout_uninterruptible(1); \
 } while (0)
 
 
@@ -989,6 +989,7 @@
 		return err;
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_playback_ops);
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_atiixp_capture_ops);
+	pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
 	pcm->private_data = chip;
 	strcpy(pcm->name, "ATI IXP MC97");
 	chip->pcmdevs[ATI_PCMDEV_ANALOG] = pcm;
@@ -1067,7 +1068,6 @@
 	if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
 		return err;
 	pbus->clock = clock;
-	pbus->shared_type = AC97_SHARED_TYPE_ATIIXP;	/* shared with audio driver */
 	chip->ac97_bus = pbus;
 
 	codec_count = 0;
@@ -1256,20 +1256,12 @@
 static int __devinit snd_atiixp_probe(struct pci_dev *pci,
 				      const struct pci_device_id *pci_id)
 {
-	static int dev;
 	snd_card_t *card;
 	atiixp_t *chip;
 	unsigned char revision;
 	int err;
 
-	if (dev >= SNDRV_CARDS)
-		return -ENODEV;
-	if (!enable[dev]) {
-		dev++;
-		return -ENOENT;
-	}
-
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	card = snd_card_new(index, id, THIS_MODULE, 0);
 	if (card == NULL)
 		return -ENOMEM;
 
@@ -1283,7 +1275,7 @@
 	if ((err = snd_atiixp_aclink_reset(chip)) < 0)
 		goto __error;
 
-	if ((err = snd_atiixp_mixer_new(chip, ac97_clock[dev])) < 0)
+	if ((err = snd_atiixp_mixer_new(chip, ac97_clock)) < 0)
 		goto __error;
 
 	if ((err = snd_atiixp_pcm_new(chip)) < 0)
@@ -1302,7 +1294,6 @@
 		goto __error;
 
 	pci_set_drvdata(pci, card);
-	dev++;
 	return 0;
 
  __error:
diff --git a/sound/pci/au88x0/au8810.h b/sound/pci/au88x0/au8810.h
index 3837d2b..5d69c31 100644
--- a/sound/pci/au88x0/au8810.h
+++ b/sound/pci/au88x0/au8810.h
@@ -178,11 +178,6 @@
 #define		EN_SPDIF	0x000c0000
 
 #define VORTEX_CODEC_CHN 	0x29080
-#define VORTEX_CODEC_WRITE	0x00800000
-#define VORTEX_CODEC_ADDSHIFT 	16
-#define VORTEX_CODEC_ADDMASK	0x7f0000	/* 0x000f0000 */
-#define VORTEX_CODEC_DATSHIFT	0
-#define VORTEX_CODEC_DATMASK	0xffff
 #define VORTEX_CODEC_IO		0x29188
 
 /* SPDIF */
diff --git a/sound/pci/au88x0/au8820.h b/sound/pci/au88x0/au8820.h
index be8022e..abbe85e 100644
--- a/sound/pci/au88x0/au8820.h
+++ b/sound/pci/au88x0/au8820.h
@@ -162,11 +162,6 @@
 #define		EN_SPORT	0x00030000
 #define		EN_SPDIF	0x000c0000
 #define VORTEX_CODEC_CHN 0x11880
-#define VORTEX_CODEC_WRITE 0x00800000
-#define VORTEX_CODEC_ADDSHIFT 16
-#define VORTEX_CODEC_ADDMASK 0x7f0000	/* 0x000f0000 */
-#define VORTEX_CODEC_DATSHIFT 0
-#define VORTEX_CODEC_DATMASK 0xffff
 #define VORTEX_CODEC_IO 0x11988
 
 #define VORTEX_SPDIF_FLAGS		0x1005c	/* FIXME */
diff --git a/sound/pci/au88x0/au8830.h b/sound/pci/au88x0/au8830.h
index aa77826..04ece1b 100644
--- a/sound/pci/au88x0/au8830.h
+++ b/sound/pci/au88x0/au8830.h
@@ -194,11 +194,6 @@
 
 #define VORTEX_CODEC_CTRL 0x29184
 #define VORTEX_CODEC_IO 0x29188
-#define 	VORTEX_CODEC_WRITE 0x00800000
-#define 	VORTEX_CODEC_ADDSHIFT 16
-#define 	VORTEX_CODEC_ADDMASK 0x7f0000	/* 0x000f0000 */
-#define 	VORTEX_CODEC_DATSHIFT 0
-#define 	VORTEX_CODEC_DATMASK 0xffff
 
 #define VORTEX_CODEC_SPORTCTRL 0x2918c
 
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index 04b695d..6af3b13 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -303,7 +303,7 @@
 	if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_VORTEX_SYNTH,
 			       sizeof(snd_vortex_synth_arg_t), &wave) < 0
 	    || wave == NULL) {
-		snd_printk("Can't initialize Aureal wavetable synth\n");
+		snd_printk(KERN_ERR "Can't initialize Aureal wavetable synth\n");
 	} else {
 		snd_vortex_synth_arg_t *arg;
 
diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h
index ee1ede1..b1197cf 100644
--- a/sound/pci/au88x0/au88x0.h
+++ b/sound/pci/au88x0/au88x0.h
@@ -79,6 +79,14 @@
 #define VORTEX_RESOURCE_A3D	0x00000004
 #define VORTEX_RESOURCE_LAST	0x00000005
 
+/* codec io: VORTEX_CODEC_IO bits */
+#define VORTEX_CODEC_ID_SHIFT	24
+#define VORTEX_CODEC_WRITE	0x00800000
+#define VORTEX_CODEC_ADDSHIFT 	16
+#define VORTEX_CODEC_ADDMASK	0x7f0000
+#define VORTEX_CODEC_DATSHIFT	0
+#define VORTEX_CODEC_DATMASK	0xffff
+
 /* Check for SDAC bit in "Extended audio ID" AC97 register */
 //#define VORTEX_IS_QUAD(x) (((x)->codec == NULL) ?  0 : ((x)->codec->ext_id&0x80))
 #define VORTEX_IS_QUAD(x) ((x)->isquad)
diff --git a/sound/pci/au88x0/au88x0_a3d.c b/sound/pci/au88x0/au88x0_a3d.c
index 9ea2ba7..d5755db 100644
--- a/sound/pci/au88x0/au88x0_a3d.c
+++ b/sound/pci/au88x0/au88x0_a3d.c
@@ -488,7 +488,7 @@
 	int i, var, var2;
 
 	if ((a->vortex) == NULL) {
-		printk("vortex: ZeroStateA3D: ERROR: a->vortex is NULL\n");
+		printk(KERN_ERR "vortex: ZeroStateA3D: ERROR: a->vortex is NULL\n");
 		return;
 	}
 
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index f0eda4b..5905188 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -2033,7 +2033,7 @@
 			}
 		}
 	}
-	printk("vortex: FATAL: ResManager: resource type %d exhausted.\n", restype);
+	printk(KERN_ERR "vortex: FATAL: ResManager: resource type %d exhausted.\n", restype);
 	return -ENOMEM;
 }
 
@@ -2165,7 +2165,7 @@
 				memset(stream->resources, 0,
 				       sizeof(unsigned char) *
 				       VORTEX_RESOURCE_LAST);
-				printk("vortex: out of A3D sources. Sorry\n");
+				printk(KERN_ERR "vortex: out of A3D sources. Sorry\n");
 				return -EBUSY;
 			}
 			/* (De)Initialize A3D hardware source. */
@@ -2532,7 +2532,8 @@
 	hwwrite(card->mmio, VORTEX_CODEC_IO,
 		((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) |
 		((data << VORTEX_CODEC_DATSHIFT) & VORTEX_CODEC_DATMASK) |
-		VORTEX_CODEC_WRITE);
+		VORTEX_CODEC_WRITE |
+		(codec->num << VORTEX_CODEC_ID_SHIFT) );
 
 	/* Flush Caches. */
 	hwread(card->mmio, VORTEX_CODEC_IO);
@@ -2554,7 +2555,8 @@
 		}
 	}
 	/* set up read address */
-	read_addr = ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK);
+	read_addr = ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) |
+		(codec->num << VORTEX_CODEC_ID_SHIFT) ;
 	hwwrite(card->mmio, VORTEX_CODEC_IO, read_addr);
 
 	/* wait for address */
diff --git a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c
index 53b47a4..9d933cc 100644
--- a/sound/pci/au88x0/au88x0_eq.c
+++ b/sound/pci/au88x0/au88x0_eq.c
@@ -854,7 +854,7 @@
 
 	vortex_Eqlzr_GetAllPeaks(vortex, peaks, &count);
 	if (count != 20) {
-		printk("vortex: peak count error 20 != %d \n", count);
+		printk(KERN_ERR "vortex: peak count error 20 != %d \n", count);
 		return -1;
 	}
 	for (i = 0; i < 20; i++)
diff --git a/sound/pci/au88x0/au88x0_synth.c b/sound/pci/au88x0/au88x0_synth.c
index 400417d..65f375b 100644
--- a/sound/pci/au88x0/au88x0_synth.c
+++ b/sound/pci/au88x0/au88x0_synth.c
@@ -90,7 +90,7 @@
 	hwwrite(vortex->mmio, WT_PARM(wt, 2), 0);
 
 	temp = hwread(vortex->mmio, WT_PARM(wt, 3));
-	printk("vortex: WT PARM3: %x\n", temp);
+	printk(KERN_DEBUG "vortex: WT PARM3: %x\n", temp);
 	//hwwrite(vortex->mmio, WT_PARM(wt, 3), temp);
 
 	hwwrite(vortex->mmio, WT_DELAY(wt, 0), 0);
@@ -98,7 +98,7 @@
 	hwwrite(vortex->mmio, WT_DELAY(wt, 2), 0);
 	hwwrite(vortex->mmio, WT_DELAY(wt, 3), 0);
 
-	printk("vortex: WT GMODE: %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
+	printk(KERN_DEBUG "vortex: WT GMODE: %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
 
 	hwwrite(vortex->mmio, WT_PARM(wt, 2), 0xffffffff);
 	hwwrite(vortex->mmio, WT_PARM(wt, 3), 0xcff1c810);
@@ -106,7 +106,7 @@
 	voice->parm0 = voice->parm1 = 0xcfb23e2f;
 	hwwrite(vortex->mmio, WT_PARM(wt, 0), voice->parm0);
 	hwwrite(vortex->mmio, WT_PARM(wt, 1), voice->parm1);
-	printk("vortex: WT GMODE 2 : %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
+	printk(KERN_DEBUG "vortex: WT GMODE 2 : %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
 	return 0;
 }
 
@@ -203,7 +203,7 @@
 		}
 	} else {
 		if (wt >= NR_WT) {
-			printk("vortex: WT SetReg: voice out of range\n");
+			printk(KERN_ERR "vortex: WT SetReg: voice out of range\n");
 			return 0;
 		}
 	}
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index d5261bd..da99b1b 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1,6 +1,6 @@
 /*
  *  azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
- *  Copyright (C) 2002 by Andreas Mohr <hw7oshyuv3001@sneakemail.com>
+ *  Copyright (C) 2002, 2005 by Andreas Mohr <andi AT lisas.de>
  *
  *  Framework borrowed from Bart Hartgers's als4000.c.
  *  Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801),
@@ -46,7 +46,7 @@
  *  - MPU401 (+ legacy address support) FIXME: how to enable legacy addr??
  *  - game port (legacy address support)
  *  - built-in General DirectX timer having a 20 bits counter
- *    with 1us resolution (FIXME: where is it?)
+ *    with 1us resolution (see below!)
  *  - I2S serial port for external DAC
  *  - supports 33MHz PCI spec 2.1, PCI power management 1.0, compliant with ACPI
  *  - supports hardware volume control
@@ -55,13 +55,23 @@
  *    required for Microsoft's logo compliance (FIXME: where?)
  *  - PCI168 AP(W) card: power amplifier with 4 Watts/channel at 4 Ohms
  *
+ *  Note that this driver now is actually *better* than the Windows driver,
+ *  since it additionally supports the card's 1MHz DirectX timer - just try
+ *  the following snd-seq module parameters etc.:
+ *  - options snd-seq seq_default_timer_class=2 seq_default_timer_sclass=0
+ *    seq_default_timer_card=0 seq_client_load=1 seq_default_timer_device=0
+ *    seq_default_timer_subdevice=0 seq_default_timer_resolution=1000000
+ *  - "timidity -iAv -B2,8 -Os -EFreverb=0"
+ *  - "pmidi -p 128:0 jazz.mid"
+ *
  *  Certain PCI versions of this card are susceptible to DMA traffic underruns
  *  in some systems (resulting in sound crackling/clicking/popping),
  *  probably because they don't have a DMA FIFO buffer or so.
  *  Overview (PCI ID/PCI subID/PCI rev.):
  *  - no DMA crackling on SiS735: 0x50DC/0x1801/16
  *  - unknown performance: 0x50DC/0x1801/10
- *  
+ *    (well, it's not bad on an Athlon 1800 with now very optimized IRQ handler)
+ *
  *  Crackling happens with VIA chipsets or, in my case, an SiS735, which is
  *  supposed to be very fast and supposed to get rid of crackling much
  *  better than a VIA, yet ironically I still get crackling, like many other
@@ -76,18 +86,13 @@
  *  - Disable ACPI/power management/"Auto Detect RAM/PCI Clk" in BIOS
  * 
  * BUGS
- *  - when Ctrl-C'ing mpg321, the playback loops a bit
- *    (premature DMA playback reset?)
- *  - full-duplex sometimes breaks (IRQ management issues?).
- *    Once even a spontaneous REBOOT happened!!!
+ *  - full-duplex might *still* be problematic, not fully tested recently
  * 
  * TODO
  *  - test MPU401 MIDI playback etc.
- *  - power management (CONFIG_PM). See e.g. intel8x0 or cs4281.
+ *  - power management. See e.g. intel8x0 or cs4281.
  *    This would be nice since the chip runs a bit hot, and it's *required*
- *    anyway for proper ACPI power management. In other words: rest
- *    assured that I *will* implement this very soon; as soon as Linux 2.5.x
- *    has power management that's bugfree enough to work properly on my desktop.
+ *    anyway for proper ACPI power management.
  *  - figure out what all unknown port bits are responsible for
  */
 
@@ -108,7 +113,7 @@
 #include <sound/initval.h>
 #include "azt3328.h"
 
-MODULE_AUTHOR("Andreas Mohr <hw7oshyuv3001@sneakemail.com>");
+MODULE_AUTHOR("Andreas Mohr <andi AT lisas.de>");
 MODULE_DESCRIPTION("Aztech AZF3328 (PCI168)");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
@@ -122,6 +127,7 @@
 #define DEBUG_MIXER	0
 #define DEBUG_PLAY_REC	0
 #define DEBUG_IO	0
+#define DEBUG_TIMER	0
 #define MIXER_TESTING	0
 
 #if DEBUG_MISC
@@ -132,8 +138,8 @@
 
 #if DEBUG_CALLS
 #define snd_azf3328_dbgcalls(format, args...) printk(format, ##args)
-#define snd_azf3328_dbgcallenter() printk(KERN_ERR "entering %s\n", __FUNCTION__)
-#define snd_azf3328_dbgcallleave() printk(KERN_ERR "leaving %s\n", __FUNCTION__)
+#define snd_azf3328_dbgcallenter() printk(KERN_ERR "--> %s\n", __FUNCTION__)
+#define snd_azf3328_dbgcallleave() printk(KERN_ERR "<-- %s\n", __FUNCTION__)
 #else
 #define snd_azf3328_dbgcalls(format, args...)
 #define snd_azf3328_dbgcallenter()
@@ -152,13 +158,12 @@
 #define snd_azf3328_dbgplay(format, args...)
 #endif		
 
-#if DEBUG_IO
-#define snd_azf3328_dbgio(chip, where) \
-	    printk(KERN_ERR "%s: IDX_IO_PLAY_FLAGS %04x, IDX_IO_PLAY_IRQMASK %04x, IDX_IO_IRQSTATUS %04x\n", where, inw(chip->codec_port+IDX_IO_PLAY_FLAGS), inw(chip->codec_port+IDX_IO_PLAY_IRQMASK), inw(chip->codec_port+IDX_IO_IRQSTATUS))
+#if DEBUG_MISC
+#define snd_azf3328_dbgtimer(format, args...) printk(KERN_ERR format, ##args)
 #else
-#define snd_azf3328_dbgio(chip, where)
-#endif
-	    
+#define snd_azf3328_dbgtimer(format, args...)
+#endif		
+
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for AZF3328 soundcard.");
@@ -177,35 +182,40 @@
 MODULE_PARM_DESC(joystick, "Enable joystick for AZF3328 soundcard.");
 #endif
 
-typedef struct _snd_azf3328 azf3328_t;
+static int seqtimer_scaling = 128;
+module_param(seqtimer_scaling, int, 0444);
+MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128.");
 
-struct _snd_azf3328 {
-	int irq;
-
+typedef struct _snd_azf3328 {
+	/* often-used fields towards beginning, then grouped */
 	unsigned long codec_port;
 	unsigned long io2_port;
 	unsigned long mpu_port;
 	unsigned long synth_port;
 	unsigned long mixer_port;
 
-#ifdef SUPPORT_JOYSTICK
-	struct gameport *gameport;
-#endif
+	spinlock_t reg_lock;
 
-	struct pci_dev *pci;
-	snd_card_t *card;
-
+	snd_timer_t *timer;
+	
 	snd_pcm_t *pcm;
-	snd_rawmidi_t *rmidi;
 	snd_pcm_substream_t *playback_substream;
 	snd_pcm_substream_t *capture_substream;
 	unsigned int is_playing;
 	unsigned int is_recording;
 
-	spinlock_t reg_lock;
-};
+	snd_card_t *card;
+	snd_rawmidi_t *rmidi;
 
-static struct pci_device_id snd_azf3328_ids[] = {
+#ifdef SUPPORT_JOYSTICK
+	struct gameport *gameport;
+#endif
+
+	struct pci_dev *pci;
+	int irq;
+} azf3328_t;
+
+static const struct pci_device_id snd_azf3328_ids[] = {
 	{ 0x122D, 0x50DC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },   /* PCI168/3328 */
 	{ 0x122D, 0x80DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },   /* 3328 */
 	{ 0, }
@@ -213,57 +223,90 @@
 
 MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
 
-static inline void snd_azf3328_io2_write(azf3328_t *chip, int reg, unsigned char value)
+static inline void
+snd_azf3328_codec_outb(const azf3328_t *chip, int reg, u8 value)
+{
+	outb(value, chip->codec_port + reg);
+}
+
+static inline u8
+snd_azf3328_codec_inb(const azf3328_t *chip, int reg)
+{
+	return inb(chip->codec_port + reg);
+}
+
+static inline void
+snd_azf3328_codec_outw(const azf3328_t *chip, int reg, u16 value)
+{
+	outw(value, chip->codec_port + reg);
+}
+
+static inline u16
+snd_azf3328_codec_inw(const azf3328_t *chip, int reg)
+{
+	return inw(chip->codec_port + reg);
+}
+
+static inline void
+snd_azf3328_codec_outl(const azf3328_t *chip, int reg, u32 value)
+{
+	outl(value, chip->codec_port + reg);
+}
+
+static inline void
+snd_azf3328_io2_outb(const azf3328_t *chip, int reg, u8 value)
 {
 	outb(value, chip->io2_port + reg);
 }
 
-static inline unsigned char snd_azf3328_io2_read(azf3328_t *chip, int reg)
+static inline u8
+snd_azf3328_io2_inb(const azf3328_t *chip, int reg)
 {
 	return inb(chip->io2_port + reg);
 }
 
-static void snd_azf3328_mixer_write(azf3328_t *chip, int reg, unsigned long value, int type)
+static inline void
+snd_azf3328_mixer_outw(const azf3328_t *chip, int reg, u16 value)
 {
-	switch(type) {
-	case WORD_VALUE:
-		outw(value, chip->mixer_port + reg);
-		break;
-	case DWORD_VALUE:
-		outl(value, chip->mixer_port + reg);
-		break;
-	case BYTE_VALUE:
-		outb(value, chip->mixer_port + reg);
-		break;
-	}
+	outw(value, chip->mixer_port + reg);
 }
 
-static void snd_azf3328_mixer_set_mute(azf3328_t *chip, int reg, int do_mute)
+static inline u16
+snd_azf3328_mixer_inw(const azf3328_t *chip, int reg)
 {
+	return inw(chip->mixer_port + reg);
+}
+
+static void
+snd_azf3328_mixer_set_mute(const azf3328_t *chip, int reg, int do_mute)
+{
+	unsigned long portbase = chip->mixer_port + reg + 1;
 	unsigned char oldval;
 
 	/* the mute bit is on the *second* (i.e. right) register of a
 	 * left/right channel setting */
-	oldval = inb(chip->mixer_port + reg + 1);
+	oldval = inb(portbase);
 	if (do_mute)
 		oldval |= 0x80;
 	else
 		oldval &= ~0x80;
-	outb(oldval, chip->mixer_port + reg + 1);
+	outb(oldval, portbase);
 }
 
-static void snd_azf3328_mixer_write_volume_gradually(azf3328_t *chip, int reg, unsigned char dst_vol_left, unsigned char dst_vol_right, int chan_sel, int delay)
+static void
+snd_azf3328_mixer_write_volume_gradually(const azf3328_t *chip, int reg, unsigned char dst_vol_left, unsigned char dst_vol_right, int chan_sel, int delay)
 {
+	unsigned long portbase = chip->mixer_port + reg;
 	unsigned char curr_vol_left = 0, curr_vol_right = 0;
 	int left_done = 0, right_done = 0;
 	
 	snd_azf3328_dbgcallenter();
 	if (chan_sel & SET_CHAN_LEFT)
-		curr_vol_left  = inb(chip->mixer_port + reg + 1);
+		curr_vol_left  = inb(portbase + 1);
 	else
 		left_done = 1;
 	if (chan_sel & SET_CHAN_RIGHT)
-		curr_vol_right = inb(chip->mixer_port + reg + 0);
+		curr_vol_right = inb(portbase + 0);
 	else
 		right_done = 1;
 	
@@ -284,7 +327,7 @@
 				curr_vol_left++;
 			else
 			    left_done = 1;
-			outb(curr_vol_left, chip->mixer_port + reg + 1);
+			outb(curr_vol_left, portbase + 1);
 		}
 		if (!right_done)
 		{
@@ -298,7 +341,7 @@
 			/* during volume change, the right channel is crackling
 			 * somewhat more than the left channel, unfortunately.
 			 * This seems to be a hardware issue. */
-			outb(curr_vol_right, chip->mixer_port + reg + 0);
+			outb(curr_vol_right, portbase + 0);
 		}
 		if (delay)
 			mdelay(delay);
@@ -320,7 +363,11 @@
 } azf3328_mixer_reg_t;
 
 #define COMPOSE_MIXER_REG(reg,lchan_shift,rchan_shift,mask,invert,stereo,enum_c) \
- ((reg) | (lchan_shift << 8) | (rchan_shift << 12) | (mask << 16) | (invert << 24) | (stereo << 25) | (enum_c << 26))
+ ((reg) | (lchan_shift << 8) | (rchan_shift << 12) | \
+  (mask << 16) | \
+  (invert << 24) | \
+  (stereo << 25) | \
+  (enum_c << 26))
 
 static void snd_azf3328_mixer_reg_decode(azf3328_mixer_reg_t *r, unsigned long val)
 {
@@ -372,13 +419,15 @@
   .private_value = COMPOSE_MIXER_REG(reg, shift, 0, 0, 0, 0, enum_c), \
 }
 
-static int snd_azf3328_info_mixer(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int
+snd_azf3328_info_mixer(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
 {
 	azf3328_mixer_reg_t reg;
 
 	snd_azf3328_dbgcallenter();
 	snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
-	uinfo->type = reg.mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->type = reg.mask == 1 ?
+		SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = reg.stereo + 1;
 	uinfo->value.integer.min = 0;
 	uinfo->value.integer.max = reg.mask;
@@ -386,7 +435,8 @@
 	return 0;
 }
 
-static int snd_azf3328_get_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int
+snd_azf3328_get_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	azf3328_t *chip = snd_kcontrol_chip(kcontrol);
 	azf3328_mixer_reg_t reg;
@@ -395,7 +445,7 @@
 	snd_azf3328_dbgcallenter();
 	snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
 
-	oreg = inw(chip->mixer_port + reg.reg);
+	oreg = snd_azf3328_mixer_inw(chip, reg.reg);
 	val = (oreg >> reg.lchan_shift) & reg.mask;
 	if (reg.invert)
 		val = reg.mask - val;
@@ -406,12 +456,17 @@
 			val = reg.mask - val;
 		ucontrol->value.integer.value[1] = val;
 	}
-	snd_azf3328_dbgmixer("get: %02x is %04x -> vol %02lx|%02lx (shift %02d|%02d, mask %02x, inv. %d, stereo %d)\n", reg.reg, oreg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1], reg.lchan_shift, reg.rchan_shift, reg.mask, reg.invert, reg.stereo);
+	snd_azf3328_dbgmixer("get: %02x is %04x -> vol %02lx|%02lx "
+			     "(shift %02d|%02d, mask %02x, inv. %d, stereo %d)\n",
+		reg.reg, oreg,
+		ucontrol->value.integer.value[0], ucontrol->value.integer.value[1],
+		reg.lchan_shift, reg.rchan_shift, reg.mask, reg.invert, reg.stereo);
 	snd_azf3328_dbgcallleave();
 	return 0;
 }
 
-static int snd_azf3328_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int
+snd_azf3328_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	azf3328_t *chip = snd_kcontrol_chip(kcontrol);
 	azf3328_mixer_reg_t reg;
@@ -419,7 +474,7 @@
 
 	snd_azf3328_dbgcallenter();
 	snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
-	oreg = inw(chip->mixer_port + reg.reg);
+	oreg = snd_azf3328_mixer_inw(chip, reg.reg);
 	val = ucontrol->value.integer.value[0] & reg.mask;
 	if (reg.invert)
 		val = reg.mask - val;
@@ -433,24 +488,37 @@
 		nreg |= (val << reg.rchan_shift);
 	}
 	if (reg.mask >= 0x07) /* it's a volume control, so better take care */
-		snd_azf3328_mixer_write_volume_gradually(chip, reg.reg, nreg >> 8, nreg & 0xff, SET_CHAN_LEFT|SET_CHAN_RIGHT, 0); /* just set both channels, doesn't matter */
+		snd_azf3328_mixer_write_volume_gradually(
+			chip, reg.reg, nreg >> 8, nreg & 0xff,
+			/* just set both channels, doesn't matter */
+			SET_CHAN_LEFT|SET_CHAN_RIGHT,
+			0);
 	else
-        	outw(nreg, chip->mixer_port + reg.reg);
+        	snd_azf3328_mixer_outw(chip, reg.reg, nreg);
 
-	snd_azf3328_dbgmixer("put: %02x to %02lx|%02lx, oreg %04x; shift %02d|%02d -> nreg %04x; after: %04x\n", reg.reg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1], oreg, reg.lchan_shift, reg.rchan_shift, nreg, inw(chip->mixer_port + reg.reg));
+	snd_azf3328_dbgmixer("put: %02x to %02lx|%02lx, "
+			     "oreg %04x; shift %02d|%02d -> nreg %04x; after: %04x\n",
+		reg.reg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1],
+		oreg, reg.lchan_shift, reg.rchan_shift,
+		nreg, snd_azf3328_mixer_inw(chip, reg.reg));
 	snd_azf3328_dbgcallleave();
 	return (nreg != oreg);
 }
 
-static int snd_azf3328_info_mixer_enum(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int
+snd_azf3328_info_mixer_enum(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
-	azf3328_mixer_reg_t reg;
-	static char *texts1[2] = { "ModemOut1", "ModemOut2" };
-	static char *texts2[2] = { "MonoSelectSource1", "MonoSelectSource2" };
-        static char *texts3[8] = {
-                "Mic", "CD", "Video", "Aux", "Line",
-                "Mix", "Mix Mono", "Phone"
+	static const char * const texts1[] = {
+		"ModemOut1", "ModemOut2"
+	};
+	static const char * const texts2[] = {
+		"MonoSelectSource1", "MonoSelectSource2"
+	};
+	static const char * const texts3[] = {
+                "Mic", "CD", "Video", "Aux",
+		"Line", "Mix", "Mix Mono", "Phone"
         };
+	azf3328_mixer_reg_t reg;
 
 	snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -471,14 +539,15 @@
         return 0;
 }
 
-static int snd_azf3328_get_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int
+snd_azf3328_get_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-	azf3328_mixer_reg_t reg;
         azf3328_t *chip = snd_kcontrol_chip(kcontrol);
+	azf3328_mixer_reg_t reg;
         unsigned short val;
         
 	snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
-	val = inw(chip->mixer_port + reg.reg);
+	val = snd_azf3328_mixer_inw(chip, reg.reg);
 	if (reg.reg == IDX_MIXER_REC_SELECT)
 	{
         	ucontrol->value.enumerated.item[0] = (val >> 8) & (reg.enum_c - 1);
@@ -486,18 +555,22 @@
 	}
 	else
         	ucontrol->value.enumerated.item[0] = (val >> reg.lchan_shift) & (reg.enum_c - 1);
-	snd_azf3328_dbgmixer("get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n", reg.reg, val, ucontrol->value.enumerated.item[0], ucontrol->value.enumerated.item[1], reg.lchan_shift, reg.enum_c);
+
+	snd_azf3328_dbgmixer("get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n",
+		reg.reg, val, ucontrol->value.enumerated.item[0], ucontrol->value.enumerated.item[1],
+		reg.lchan_shift, reg.enum_c);
         return 0;
 }
 
-static int snd_azf3328_put_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int
+snd_azf3328_put_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-	azf3328_mixer_reg_t reg;
         azf3328_t *chip = snd_kcontrol_chip(kcontrol);
+	azf3328_mixer_reg_t reg;
 	unsigned int oreg, nreg, val;
         
 	snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
-	oreg = inw(chip->mixer_port + reg.reg);
+	oreg = snd_azf3328_mixer_inw(chip, reg.reg);
 	val = oreg;
 	if (reg.reg == IDX_MIXER_REC_SELECT)
 	{
@@ -514,19 +587,19 @@
 		val &= ~((reg.enum_c - 1) << reg.lchan_shift);
         	val |= (ucontrol->value.enumerated.item[0] << reg.lchan_shift);
 	}
-	outw(val, chip->mixer_port + reg.reg);
+	snd_azf3328_mixer_outw(chip, reg.reg, val);
 	nreg = val;
 
 	snd_azf3328_dbgmixer("put_enum: %02x to %04x, oreg %04x\n", reg.reg, val, oreg);
 	return (nreg != oreg);
 }
 
-static snd_kcontrol_new_t snd_azf3328_mixer_controls[] __devinitdata = {
+static const snd_kcontrol_new_t snd_azf3328_mixer_controls[] __devinitdata = {
 	AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1),
 	AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1),
 	AZF3328_MIXER_SWITCH("Wave Playback Switch", IDX_MIXER_WAVEOUT, 15, 1),
 	AZF3328_MIXER_VOL_STEREO("Wave Playback Volume", IDX_MIXER_WAVEOUT, 0x1f, 1),
-	AZF3328_MIXER_SWITCH("Wave Playback 3D Bypass", IDX_MIXER_ADVCTL2, 7, 1),
+	AZF3328_MIXER_SWITCH("Wave 3D Bypass Playback Switch", IDX_MIXER_ADVCTL2, 7, 1),
 	AZF3328_MIXER_SWITCH("FM Playback Switch", IDX_MIXER_FMSYNTH, 15, 1),
 	AZF3328_MIXER_VOL_STEREO("FM Playback Volume", IDX_MIXER_FMSYNTH, 0x1f, 1),
 	AZF3328_MIXER_SWITCH("CD Playback Switch", IDX_MIXER_CDAUDIO, 15, 1),
@@ -539,8 +612,8 @@
 	AZF3328_MIXER_SWITCH("Mic Boost (+20dB)", IDX_MIXER_MIC, 6, 0),
 	AZF3328_MIXER_SWITCH("Line Playback Switch", IDX_MIXER_LINEIN, 15, 1),
 	AZF3328_MIXER_VOL_STEREO("Line Playback Volume", IDX_MIXER_LINEIN, 0x1f, 1),
-	AZF3328_MIXER_SWITCH("PCBeep Playback Switch", IDX_MIXER_PCBEEP, 15, 1),
-	AZF3328_MIXER_VOL_SPECIAL("PCBeep Playback Volume", IDX_MIXER_PCBEEP, 0x0f, 1, 1),
+	AZF3328_MIXER_SWITCH("PC Speaker Playback Switch", IDX_MIXER_PCBEEP, 15, 1),
+	AZF3328_MIXER_VOL_SPECIAL("PC Speaker Playback Volume", IDX_MIXER_PCBEEP, 0x0f, 1, 1),
 	AZF3328_MIXER_SWITCH("Video Playback Switch", IDX_MIXER_VIDEO, 15, 1),
 	AZF3328_MIXER_VOL_STEREO("Video Playback Volume", IDX_MIXER_VIDEO, 0x1f, 1),
 	AZF3328_MIXER_SWITCH("Aux Playback Switch", IDX_MIXER_AUX, 15, 1),
@@ -553,8 +626,8 @@
 	AZF3328_MIXER_ENUM("Mono Select Source", IDX_MIXER_ADVCTL2, 2, 9),
 	AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0),
 	AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0),
-	AZF3328_MIXER_SWITCH("3D Control - Toggle", IDX_MIXER_ADVCTL2, 13, 0),
-	AZF3328_MIXER_VOL_SPECIAL("3D Control - Volume", IDX_MIXER_ADVCTL1, 0x07, 1, 0), /* "3D Width" */
+	AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0),
+	AZF3328_MIXER_VOL_SPECIAL("3D Control - Wide", IDX_MIXER_ADVCTL1, 0x07, 1, 0), /* "3D Width" */
 	AZF3328_MIXER_VOL_SPECIAL("3D Control - Space", IDX_MIXER_ADVCTL1, 0x03, 8, 0), /* "Hifi 3D" */
 #if MIXER_TESTING
 	AZF3328_MIXER_SWITCH("0", IDX_MIXER_ADVCTL2, 0, 0),
@@ -576,9 +649,7 @@
 #endif
 };
 
-#define AZF3328_INIT_VALUES (sizeof(snd_azf3328_init_values)/sizeof(unsigned int)/2)
-
-static unsigned int snd_azf3328_init_values[][2] = {
+static const u16 __devinitdata snd_azf3328_init_values[][2] = {
         { IDX_MIXER_PLAY_MASTER,	MIXER_MUTE_MASK|0x1f1f },
         { IDX_MIXER_MODEMOUT,		MIXER_MUTE_MASK|0x1f1f },
 	{ IDX_MIXER_BASSTREBLE,		0x0000 },
@@ -594,10 +665,11 @@
         { IDX_MIXER_REC_VOLUME,		MIXER_MUTE_MASK|0x0707 },
 };
 
-static int __devinit snd_azf3328_mixer_new(azf3328_t *chip)
+static int __devinit
+snd_azf3328_mixer_new(azf3328_t *chip)
 {
 	snd_card_t *card;
-	snd_kcontrol_new_t *sw;
+	const snd_kcontrol_new_t *sw;
 	unsigned int idx;
 	int err;
 
@@ -607,11 +679,13 @@
 	card = chip->card;
 
 	/* mixer reset */
-	snd_azf3328_mixer_write(chip, IDX_MIXER_RESET, 0x0, WORD_VALUE);
+	snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
 
 	/* mute and zero volume channels */
-	for (idx = 0; idx < AZF3328_INIT_VALUES; idx++) {
-		snd_azf3328_mixer_write(chip, snd_azf3328_init_values[idx][0], snd_azf3328_init_values[idx][1], WORD_VALUE);
+	for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_init_values); idx++) {
+		snd_azf3328_mixer_outw(chip,
+			snd_azf3328_init_values[idx][0],
+			snd_azf3328_init_values[idx][1]);
 	}
 	
 	/* add mixer controls */
@@ -627,7 +701,8 @@
 	return 0;
 }
 
-static int snd_azf3328_hw_params(snd_pcm_substream_t * substream,
+static int
+snd_azf3328_hw_params(snd_pcm_substream_t * substream,
 				 snd_pcm_hw_params_t * hw_params)
 {
 	int res;
@@ -637,7 +712,8 @@
 	return res;
 }
 
-static int snd_azf3328_hw_free(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_hw_free(snd_pcm_substream_t * substream)
 {
 	snd_azf3328_dbgcallenter();
 	snd_pcm_lib_free_pages(substream);
@@ -645,43 +721,48 @@
 	return 0;
 }
 
-static void snd_azf3328_setfmt(azf3328_t *chip,
+static void
+snd_azf3328_setfmt(azf3328_t *chip,
 			       unsigned int reg,
 			       unsigned int bitrate,
 			       unsigned int format_width,
 			       unsigned int channels
 )
 {
-	unsigned int val = 0xff00;
+	u16 val = 0xff00;
 	unsigned long flags;
 
 	snd_azf3328_dbgcallenter();
 	switch (bitrate) {
-	case  5512: val |= 0x0d; break; /* the AZF3328 names it "5510" for some strange reason */
-	case  6620: val |= 0x0b; break;
-	case  8000: val |= 0x00; break;
-	case  9600: val |= 0x08; break;
-	case 11025: val |= 0x01; break;
-	case 16000: val |= 0x02; break;
-	case 22050: val |= 0x03; break;
-	case 32000: val |= 0x04; break;
-	case 44100: val |= 0x05; break;
-	case 48000: val |= 0x06; break;
-	case 64000: val |= 0x07; break;
+	case  4000: val |= SOUNDFORMAT_FREQ_SUSPECTED_4000; break;
+	case  4800: val |= SOUNDFORMAT_FREQ_SUSPECTED_4800; break;
+	case  5512: val |= SOUNDFORMAT_FREQ_5510; break; /* the AZF3328 names it "5510" for some strange reason */
+	case  6620: val |= SOUNDFORMAT_FREQ_6620; break;
+	case  8000: val |= SOUNDFORMAT_FREQ_8000; break;
+	case  9600: val |= SOUNDFORMAT_FREQ_9600; break;
+	case 11025: val |= SOUNDFORMAT_FREQ_11025; break;
+	case 13240: val |= SOUNDFORMAT_FREQ_SUSPECTED_13240; break;
+	case 16000: val |= SOUNDFORMAT_FREQ_16000; break;
+	case 22050: val |= SOUNDFORMAT_FREQ_22050; break;
+	case 32000: val |= SOUNDFORMAT_FREQ_32000; break;
+	case 44100: val |= SOUNDFORMAT_FREQ_44100; break;
+	case 48000: val |= SOUNDFORMAT_FREQ_48000; break;
+	case 66200: val |= SOUNDFORMAT_FREQ_SUSPECTED_66200; break;
 	default:
-		snd_printk("unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
-		val |= 0x05; /* 44100 */
+		snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
+		val |= SOUNDFORMAT_FREQ_44100;
 		break;
 	}
-	/* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) */
-	/* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) */
-	/* val = 0xff0a; 47m30.599s (4764,891Hz; -> 4800Hz???) */
-	/* val = 0xff0c; 57m0.510s (4010,263Hz; -> 4000Hz???) */
+	/* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */
+	/* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */
+	/* val = 0xff0a; 47m30.599s (4764,891Hz; -> 4800Hz???) yup, 4803Hz */
+	/* val = 0xff0c; 57m0.510s (4010,263Hz; -> 4000Hz???) yup, 4003Hz */
 	/* val = 0xff05; 5m11.556s (... -> 44100Hz) */
 	/* val = 0xff03; 10m21.529s (21872,463Hz; -> 22050Hz???) */
 	/* val = 0xff0f; 20m41.883s (10937,993Hz; -> 11025Hz???) */
 	/* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */
 	/* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */
+
 	if (channels == 2)
 		val |= SOUNDFORMAT_FLAG_2CHANNELS;
 
@@ -691,7 +772,7 @@
 	spin_lock_irqsave(&chip->reg_lock, flags);
 	
 	/* set bitrate/format */
-	outw(val, chip->codec_port+reg);
+	snd_azf3328_codec_outw(chip, reg, val);
 	
 	/* changing the bitrate/format settings switches off the
 	 * audio output with an annoying click in case of 8/16bit format change
@@ -701,47 +782,67 @@
 	 * FIXME: does this have some side effects for full-duplex
 	 * or other dramatic side effects? */
 	if (reg == IDX_IO_PLAY_SOUNDFORMAT) /* only do it for playback */
-		outw(inw(chip->codec_port + IDX_IO_PLAY_FLAGS)|DMA_PLAY_SOMETHING1|DMA_PLAY_SOMETHING2|SOMETHING_ALMOST_ALWAYS_SET|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_PLAY_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
+			snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) |
+			DMA_PLAY_SOMETHING1 |
+			DMA_PLAY_SOMETHING2 |
+			SOMETHING_ALMOST_ALWAYS_SET |
+			DMA_EPILOGUE_SOMETHING |
+			DMA_SOMETHING_ELSE
+		);
 
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 	snd_azf3328_dbgcallleave();
 }
 
-static void snd_azf3328_setdmaa(azf3328_t *chip,
+static void
+snd_azf3328_setdmaa(azf3328_t *chip,
 				long unsigned int addr,
                                 unsigned int count,
                                 unsigned int size,
 				int do_recording)
 {
-	long unsigned int addr1;
-	long unsigned int addr2;
-	unsigned int count1;
-	unsigned int count2;
-	unsigned long flags;
-	int reg_offs = do_recording ? 0x20 : 0x00;
+	unsigned long flags, portbase;
+	unsigned int is_running;
 
 	snd_azf3328_dbgcallenter();
-	/* AZF3328 uses a two buffer pointer DMA playback approach */
-	if (!chip->is_playing)
+	if (do_recording)
 	{
-		addr1 = addr;
-		addr2 = addr+(size/2);
-		count1 = (size/2)-1;
-		count2 = (size/2)-1;
-#if DEBUG_PLAY_REC
-		snd_azf3328_dbgplay("setting dma: buf1 %08lx[%d], buf2 %08lx[%d]\n", addr1, count1, addr2, count2);
-#endif
+		/* access capture registers, i.e. skip playback reg section */
+		portbase = chip->codec_port + 0x20;
+		is_running = chip->is_recording;
+	}
+	else
+	{
+		/* access the playback register section */
+		portbase = chip->codec_port + 0x00;
+		is_running = chip->is_playing;
+	}
+
+	/* AZF3328 uses a two buffer pointer DMA playback approach */
+	if (!is_running)
+	{
+		unsigned long addr_area2;
+		unsigned long count_areas, count_tmp; /* width 32bit -- overflow!! */
+		count_areas = size/2;
+		addr_area2 = addr+count_areas;
+		count_areas--; /* max. index */
+		snd_azf3328_dbgplay("set DMA: buf1 %08lx[%lu], buf2 %08lx[%lu]\n", addr, count_areas, addr_area2, count_areas);
+
+		/* build combined I/O buffer length word */
+		count_tmp = count_areas;
+		count_areas |= (count_tmp << 16);
 		spin_lock_irqsave(&chip->reg_lock, flags);
-		outl(addr1, chip->codec_port+reg_offs+IDX_IO_PLAY_DMA_START_1);
-		outl(addr2, chip->codec_port+reg_offs+IDX_IO_PLAY_DMA_START_2);
-		outw(count1, chip->codec_port+reg_offs+IDX_IO_PLAY_DMA_LEN_1);
-		outw(count2, chip->codec_port+reg_offs+IDX_IO_PLAY_DMA_LEN_2);
+		outl(addr, portbase + IDX_IO_PLAY_DMA_START_1);
+		outl(addr_area2, portbase + IDX_IO_PLAY_DMA_START_2);
+		outl(count_areas, portbase + IDX_IO_PLAY_DMA_LEN_1);
 		spin_unlock_irqrestore(&chip->reg_lock, flags);
 	}
 	snd_azf3328_dbgcallleave();
 }
 
-static int snd_azf3328_playback_prepare(snd_pcm_substream_t *substream)
+static int
+snd_azf3328_playback_prepare(snd_pcm_substream_t *substream)
 {
 #if 0
 	azf3328_t *chip = snd_pcm_substream_chip(substream);
@@ -752,14 +853,18 @@
 
 	snd_azf3328_dbgcallenter();
 #if 0
-	snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels);
+	snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT,
+		runtime->rate,
+		snd_pcm_format_width(runtime->format),
+		runtime->channels);
 	snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, 0);
 #endif
 	snd_azf3328_dbgcallleave();
 	return 0;
 }
 
-static int snd_azf3328_capture_prepare(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_capture_prepare(snd_pcm_substream_t * substream)
 {
 #if 0
 	azf3328_t *chip = snd_pcm_substream_chip(substream);
@@ -770,14 +875,18 @@
 
 	snd_azf3328_dbgcallenter();
 #if 0
-	snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels);
+	snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
+		runtime->rate,
+		snd_pcm_format_width(runtime->format),
+		runtime->channels);
 	snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, 1);
 #endif
 	snd_azf3328_dbgcallleave();
 	return 0;
 }
 
-static int snd_azf3328_playback_trigger(snd_pcm_substream_t * substream, int cmd)
+static int
+snd_azf3328_playback_trigger(snd_pcm_substream_t * substream, int cmd)
 {
 	azf3328_t *chip = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -785,79 +894,98 @@
 	unsigned int status1;
 
 	snd_azf3328_dbgcalls("snd_azf3328_playback_trigger cmd %d\n", cmd);
+
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
-
-		snd_azf3328_dbgio(chip, "trigger1");
+		snd_azf3328_dbgplay("START PLAYBACK\n");
 
 		/* mute WaveOut */
 		snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
 
-		snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels);
+		snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT,
+			runtime->rate,
+			snd_pcm_format_width(runtime->format),
+			runtime->channels);
 
 		spin_lock(&chip->reg_lock);
 		/* stop playback */
-		status1 = inw(chip->codec_port+IDX_IO_PLAY_FLAGS);
+		status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS);
 		status1 &= ~DMA_RESUME;
-		outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
 	    
 		/* FIXME: clear interrupts or what??? */
-		outw(0xffff, chip->codec_port+IDX_IO_PLAY_IRQMASK);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_IRQTYPE, 0xffff);
 		spin_unlock(&chip->reg_lock);
 
-		snd_azf3328_setdmaa(chip, runtime->dma_addr, snd_pcm_lib_period_bytes(substream), snd_pcm_lib_buffer_bytes(substream), 0);
+		snd_azf3328_setdmaa(chip, runtime->dma_addr,
+			snd_pcm_lib_period_bytes(substream),
+			snd_pcm_lib_buffer_bytes(substream),
+			0);
 
 		spin_lock(&chip->reg_lock);
 #ifdef WIN9X
 		/* FIXME: enable playback/recording??? */
 		status1 |= DMA_PLAY_SOMETHING1 | DMA_PLAY_SOMETHING2;
-		outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
 
 		/* start playback again */
 		/* FIXME: what is this value (0x0010)??? */
 		status1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
-		outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
 #else /* NT4 */
-		outw(0x00, chip->codec_port+IDX_IO_PLAY_FLAGS);
-		outw(DMA_PLAY_SOMETHING1, chip->codec_port+IDX_IO_PLAY_FLAGS);
-		outw(DMA_PLAY_SOMETHING1|DMA_PLAY_SOMETHING2, chip->codec_port+IDX_IO_PLAY_FLAGS);
-		outw(DMA_RESUME|SOMETHING_ALMOST_ALWAYS_SET|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port+IDX_IO_PLAY_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
+			0x0000);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
+			DMA_PLAY_SOMETHING1);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
+			DMA_PLAY_SOMETHING1 |
+			DMA_PLAY_SOMETHING2);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
+			DMA_RESUME |
+			SOMETHING_ALMOST_ALWAYS_SET |
+			DMA_EPILOGUE_SOMETHING |
+			DMA_SOMETHING_ELSE);
 #endif
 		spin_unlock(&chip->reg_lock);
 
 		/* now unmute WaveOut */
 		snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
 
-		snd_azf3328_dbgio(chip, "trigger2");
 		chip->is_playing = 1;
+		snd_azf3328_dbgplay("STARTED PLAYBACK\n");
 		break;
-        case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_STOP:
+		snd_azf3328_dbgplay("STOP PLAYBACK\n");
+
 		/* mute WaveOut */
 		snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
 
 		spin_lock(&chip->reg_lock);
 		/* stop playback */
-		status1 = inw(chip->codec_port+IDX_IO_PLAY_FLAGS);
+		status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS);
 
 		status1 &= ~DMA_RESUME;
-		outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
 
+		/* hmm, is this really required? we're resetting the same bit
+		 * immediately thereafter... */
 		status1 |= DMA_PLAY_SOMETHING1;
-		outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
 
 		status1 &= ~DMA_PLAY_SOMETHING1;
-		outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
 		spin_unlock(&chip->reg_lock);
 	    
 		/* now unmute WaveOut */
 		snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
 		chip->is_playing = 0;
+		snd_azf3328_dbgplay("STOPPED PLAYBACK\n");
 		break;
         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		snd_printk("FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
+		snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
                 break;
         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		snd_printk("FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
+		snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
                 break;
         default:
                 return -EINVAL;
@@ -869,7 +997,8 @@
 
 /* this is just analogous to playback; I'm not quite sure whether recording
  * should actually be triggered like that */
-static int snd_azf3328_capture_trigger(snd_pcm_substream_t * substream, int cmd)
+static int
+snd_azf3328_capture_trigger(snd_pcm_substream_t * substream, int cmd)
 {
 	azf3328_t *chip = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -877,68 +1006,86 @@
 	unsigned int status1;
 
 	snd_azf3328_dbgcalls("snd_azf3328_capture_trigger cmd %d\n", cmd);
+
         switch (cmd) {
         case SNDRV_PCM_TRIGGER_START:
 
-		snd_azf3328_dbgio(chip, "trigger1");
+		snd_azf3328_dbgplay("START CAPTURE\n");
 
-		snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels);
+		snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
+			runtime->rate,
+			snd_pcm_format_width(runtime->format),
+			runtime->channels);
 
 		spin_lock(&chip->reg_lock);
 		/* stop recording */
-		status1 = inw(chip->codec_port+IDX_IO_REC_FLAGS);
+		status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS);
 		status1 &= ~DMA_RESUME;
-		outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
 	    
 		/* FIXME: clear interrupts or what??? */
-		outw(0xffff, chip->codec_port+IDX_IO_REC_IRQMASK);
+		snd_azf3328_codec_outw(chip, IDX_IO_REC_IRQTYPE, 0xffff);
 		spin_unlock(&chip->reg_lock);
 
-		snd_azf3328_setdmaa(chip, runtime->dma_addr, snd_pcm_lib_period_bytes(substream), snd_pcm_lib_buffer_bytes(substream), 1);
+		snd_azf3328_setdmaa(chip, runtime->dma_addr,
+			snd_pcm_lib_period_bytes(substream),
+			snd_pcm_lib_buffer_bytes(substream),
+			1);
 
 		spin_lock(&chip->reg_lock);
 #ifdef WIN9X
 		/* FIXME: enable playback/recording??? */
 		status1 |= DMA_PLAY_SOMETHING1 | DMA_PLAY_SOMETHING2;
-		outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
 
-		/* start playback again */
+		/* start capture again */
 		/* FIXME: what is this value (0x0010)??? */
 		status1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
-		outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
 #else
-		outw(0x00, chip->codec_port+IDX_IO_REC_FLAGS);
-		outw(DMA_PLAY_SOMETHING1, chip->codec_port+IDX_IO_REC_FLAGS);
-		outw(DMA_PLAY_SOMETHING1|DMA_PLAY_SOMETHING2, chip->codec_port+IDX_IO_REC_FLAGS);
-		outw(DMA_RESUME|SOMETHING_ALMOST_ALWAYS_SET|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port+IDX_IO_REC_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
+			0x0000);
+		snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
+			DMA_PLAY_SOMETHING1);
+		snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
+			DMA_PLAY_SOMETHING1 |
+			DMA_PLAY_SOMETHING2);
+		snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
+			DMA_RESUME |
+			SOMETHING_ALMOST_ALWAYS_SET |
+			DMA_EPILOGUE_SOMETHING |
+			DMA_SOMETHING_ELSE);
 #endif
 		spin_unlock(&chip->reg_lock);
 
-		snd_azf3328_dbgio(chip, "trigger2");
-		chip->is_playing = 1;
+		chip->is_recording = 1;
+		snd_azf3328_dbgplay("STARTED CAPTURE\n");
 		break;
         case SNDRV_PCM_TRIGGER_STOP:
+		snd_azf3328_dbgplay("STOP CAPTURE\n");
+
 		spin_lock(&chip->reg_lock);
 		/* stop recording */
-		status1 = inw(chip->codec_port+IDX_IO_REC_FLAGS);
+		status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS);
 
 		status1 &= ~DMA_RESUME;
-		outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
 
 		status1 |= DMA_PLAY_SOMETHING1;
-		outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
 
 		status1 &= ~DMA_PLAY_SOMETHING1;
-		outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
 		spin_unlock(&chip->reg_lock);
 	    
-		chip->is_playing = 0;
+		chip->is_recording = 0;
+		snd_azf3328_dbgplay("STOPPED CAPTURE\n");
 		break;
         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		snd_printk("FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
+		snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
                 break;
         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		snd_printk("FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
+		snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
                 break;
         default:
                 return -EINVAL;
@@ -948,11 +1095,11 @@
 	return result;
 }
 
-static snd_pcm_uframes_t snd_azf3328_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t
+snd_azf3328_playback_pointer(snd_pcm_substream_t * substream)
 {
 	azf3328_t *chip = snd_pcm_substream_chip(substream);
-	unsigned long bufptr, playptr;
-	unsigned long result;
+	unsigned long bufptr, result;
 	snd_pcm_uframes_t frmres;
 
 #ifdef QUERY_HARDWARE
@@ -960,19 +1107,20 @@
 #else
 	bufptr = substream->runtime->dma_addr;
 #endif
-	playptr = inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS);
+	result = inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS);
 
-	result = playptr - bufptr;
-	frmres = bytes_to_frames( substream->runtime, result );
-	snd_azf3328_dbgplay("result %lx, playptr %lx (base %x), frames %ld\n", result, playptr, substream->runtime->dma_addr, frmres);
+	/* calculate offset */
+	result -= bufptr;
+	frmres = bytes_to_frames( substream->runtime, result);
+	snd_azf3328_dbgplay("PLAY @ 0x%8lx, frames %8ld\n", result, frmres);
 	return frmres;
 }
 
-static snd_pcm_uframes_t snd_azf3328_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t
+snd_azf3328_capture_pointer(snd_pcm_substream_t * substream)
 {
 	azf3328_t *chip = snd_pcm_substream_chip(substream);
-	unsigned long bufptr, recptr;
-	unsigned long result;
+	unsigned long bufptr, result;
 	snd_pcm_uframes_t frmres;
 
 #ifdef QUERY_HARDWARE
@@ -980,96 +1128,116 @@
 #else
 	bufptr = substream->runtime->dma_addr;
 #endif
-	recptr = inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS);
+	result = inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS);
 
-	result = recptr - bufptr;
-	frmres = bytes_to_frames( substream->runtime, result );
-	snd_azf3328_dbgplay("result %lx, rec ptr %lx (base %x), frames %ld\n", result, recptr, substream->runtime->dma_addr, frmres);
+	/* calculate offset */
+	result -= bufptr;
+	frmres = bytes_to_frames( substream->runtime, result);
+	snd_azf3328_dbgplay("REC  @ 0x%8lx, frames %8ld\n", result, frmres);
 	return frmres;
 }
 
-static irqreturn_t snd_azf3328_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t
+snd_azf3328_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	azf3328_t *chip = dev_id;
-	unsigned int status, which;
-	static unsigned long count;
+	u8 status, which;
+	static unsigned long irq_count;
 
-	status  = inw(chip->codec_port+IDX_IO_IRQSTATUS);
+	status = snd_azf3328_codec_inb(chip, IDX_IO_IRQSTATUS);
 
         /* fast path out, to ease interrupt sharing */
-	if (!(status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_MPU401|IRQ_SOMEIRQ)))
+	if (!(status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_MPU401|IRQ_TIMER)))
 		return IRQ_NONE; /* must be interrupt for another device */
 
-	snd_azf3328_dbgplay("Interrupt %ld!\nIDX_IO_PLAY_FLAGS %04x, IDX_IO_PLAY_IRQMASK %04x, IDX_IO_IRQSTATUS %04x\n", count, inw(chip->codec_port+IDX_IO_PLAY_FLAGS), inw(chip->codec_port+IDX_IO_PLAY_IRQMASK), inw(chip->codec_port+IDX_IO_IRQSTATUS));
+	snd_azf3328_dbgplay("Interrupt %ld!\nIDX_IO_PLAY_FLAGS %04x, IDX_IO_PLAY_IRQTYPE %04x, IDX_IO_IRQSTATUS %04x\n",
+		irq_count,
+		snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS),
+		snd_azf3328_codec_inw(chip, IDX_IO_PLAY_IRQTYPE),
+		status);
 		
+	if (status & IRQ_TIMER)
+	{
+		/* snd_azf3328_dbgplay("timer %ld\n", inl(chip->codec_port+IDX_IO_TIMER_VALUE) & TIMER_VALUE_MASK); */
+		if (chip->timer)
+			snd_timer_interrupt(chip->timer, chip->timer->sticks);
+		/* ACK timer */
+                spin_lock(&chip->reg_lock);
+		snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x07);
+		spin_unlock(&chip->reg_lock);
+		snd_azf3328_dbgplay("azt3328: timer IRQ\n");
+	}
 	if (status & IRQ_PLAYBACK)
 	{
 		spin_lock(&chip->reg_lock);
-		which = inw(chip->codec_port+IDX_IO_PLAY_IRQMASK);
-		if (which & IRQ_FINISHED_PLAYBUF_1)
-			/* ack IRQ */
-			outw(which | IRQ_FINISHED_PLAYBUF_1, chip->codec_port+IDX_IO_PLAY_IRQMASK);
-		if (which & IRQ_FINISHED_PLAYBUF_2)
-			/* ack IRQ */
-			outw(which | IRQ_FINISHED_PLAYBUF_2, chip->codec_port+IDX_IO_PLAY_IRQMASK);
-		if (which & IRQ_PLAY_SOMETHING)
-		{
-			snd_azf3328_dbgplay("azt3328: unknown play IRQ type occurred, please report!\n");
-		}
+		which = snd_azf3328_codec_inb(chip, IDX_IO_PLAY_IRQTYPE);
+		/* ack all IRQ types immediately */
+		snd_azf3328_codec_outb(chip, IDX_IO_PLAY_IRQTYPE, which);
+               	spin_unlock(&chip->reg_lock);
+
 		if (chip->pcm && chip->playback_substream)
 		{
-			snd_azf3328_dbgplay("which %x, playptr %lx\n", which, inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS));
 			snd_pcm_period_elapsed(chip->playback_substream);
-			snd_azf3328_dbgplay("period done, playptr %lx.\n", inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS));
+			snd_azf3328_dbgplay("PLAY period done (#%x), @ %x\n",
+				which,
+				inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS));
 		}
 		else
 			snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n");
-               	spin_unlock(&chip->reg_lock);
+		if (which & IRQ_PLAY_SOMETHING)
+			snd_azf3328_dbgplay("azt3328: unknown play IRQ type occurred, please report!\n");
 	}
 	if (status & IRQ_RECORDING)
 	{
                 spin_lock(&chip->reg_lock);
-		which = inw(chip->codec_port+IDX_IO_REC_IRQMASK);
-		if (which & IRQ_FINISHED_RECBUF_1)
-			/* ack interrupt */
-			outw(which | IRQ_FINISHED_RECBUF_1, chip->codec_port+IDX_IO_REC_IRQMASK);
-		if (which & IRQ_FINISHED_RECBUF_2)
-			/* ack interrupt */
-			outw(which | IRQ_FINISHED_RECBUF_2, chip->codec_port+IDX_IO_REC_IRQMASK);
-		if (which & IRQ_REC_SOMETHING)
-		{
-			snd_azf3328_dbgplay("azt3328: unknown rec IRQ type occurred, please report!\n");
-		}
+		which = snd_azf3328_codec_inb(chip, IDX_IO_REC_IRQTYPE);
+		/* ack all IRQ types immediately */
+		snd_azf3328_codec_outb(chip, IDX_IO_REC_IRQTYPE, which);
+		spin_unlock(&chip->reg_lock);
+
 		if (chip->pcm && chip->capture_substream)
 		{
-			snd_azf3328_dbgplay("which %x, recptr %lx\n", which, inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS));
-			spin_unlock(&chip->reg_lock);
 			snd_pcm_period_elapsed(chip->capture_substream);
-			spin_lock(&chip->reg_lock);
-			snd_azf3328_dbgplay("period done, recptr %lx.\n", inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS));
+			snd_azf3328_dbgplay("REC  period done (#%x), @ %x\n",
+				which,
+				inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS));
 		}
-               	spin_unlock(&chip->reg_lock);
+		else
+			snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n");
+		if (which & IRQ_REC_SOMETHING)
+			snd_azf3328_dbgplay("azt3328: unknown rec IRQ type occurred, please report!\n");
 	}
+	/* MPU401 has less critical IRQ requirements
+	 * than timer and playback/recording, right? */
 	if (status & IRQ_MPU401)
+	{
 		snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
-	if (status & IRQ_SOMEIRQ)
-		snd_azf3328_dbgplay("azt3328: unknown IRQ type occurred, please report!\n");
-	count++;
+
+		/* hmm, do we have to ack the IRQ here somehow?
+		 * If so, then I don't know how... */
+		snd_azf3328_dbgplay("azt3328: MPU401 IRQ\n");
+	}
+	irq_count++;
 	return IRQ_HANDLED;
 }
 
 /*****************************************************************/
 
-static snd_pcm_hardware_t snd_azf3328_playback =
+static const snd_pcm_hardware_t snd_azf3328_playback =
 {
 	/* FIXME!! Correct? */
-	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_MMAP_VALID),
-	.formats =		SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
-				SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE,
-	.rates =		SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_KNOT,
-	.rate_min =		5512,
-	.rate_max =		64000,
+	.info =			SNDRV_PCM_INFO_MMAP |
+				SNDRV_PCM_INFO_INTERLEAVED |
+				SNDRV_PCM_INFO_MMAP_VALID,
+	.formats =		SNDRV_PCM_FMTBIT_S8 |
+				SNDRV_PCM_FMTBIT_U8 |
+				SNDRV_PCM_FMTBIT_S16_LE |
+				SNDRV_PCM_FMTBIT_U16_LE,
+	.rates =		SNDRV_PCM_RATE_5512 |
+				SNDRV_PCM_RATE_8000_48000 |
+				SNDRV_PCM_RATE_KNOT,
+	.rate_min =		4000,
+	.rate_max =		66200,
 	.channels_min =		1,
 	.channels_max =		2,
 	.buffer_bytes_max =	65536,
@@ -1083,16 +1251,21 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_azf3328_capture =
+static const snd_pcm_hardware_t snd_azf3328_capture =
 {
 	/* FIXME */
-	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_MMAP_VALID),
-	.formats =		SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
-				SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE,
-	.rates =		SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_KNOT,
-	.rate_min =		5512,
-	.rate_max =		64000,
+	.info =			SNDRV_PCM_INFO_MMAP |
+				SNDRV_PCM_INFO_INTERLEAVED |
+				SNDRV_PCM_INFO_MMAP_VALID,
+	.formats =		SNDRV_PCM_FMTBIT_S8 |
+				SNDRV_PCM_FMTBIT_U8 |
+				SNDRV_PCM_FMTBIT_S16_LE |
+				SNDRV_PCM_FMTBIT_U16_LE,
+	.rates =		SNDRV_PCM_RATE_5512 |
+				SNDRV_PCM_RATE_8000_48000 |
+				SNDRV_PCM_RATE_KNOT,
+	.rate_min =		4000,
+	.rate_max =		66200,
 	.channels_min =		1,
 	.channels_max =		2,
 	.buffer_bytes_max =	65536,
@@ -1105,8 +1278,8 @@
 
 
 static unsigned int snd_azf3328_fixed_rates[] = {
-	5512, 6620, 8000, 9600, 11025, 16000, 22050, 32000, 44100, 48000, 64000
-};
+	4000, 4800, 5512, 6620, 8000, 9600, 11025, 13240, 16000, 22050, 32000,
+	44100, 48000, 66200 };
 static snd_pcm_hw_constraint_list_t snd_azf3328_hw_constraints_rates = {
 	.count = ARRAY_SIZE(snd_azf3328_fixed_rates), 
 	.list = snd_azf3328_fixed_rates,
@@ -1115,7 +1288,8 @@
 
 /*****************************************************************/
 
-static int snd_azf3328_playback_open(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_playback_open(snd_pcm_substream_t * substream)
 {
 	azf3328_t *chip = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -1129,7 +1303,8 @@
 	return 0;
 }
 
-static int snd_azf3328_capture_open(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_capture_open(snd_pcm_substream_t * substream)
 {
 	azf3328_t *chip = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -1143,7 +1318,8 @@
 	return 0;
 }
 
-static int snd_azf3328_playback_close(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_playback_close(snd_pcm_substream_t * substream)
 {
 	azf3328_t *chip = snd_pcm_substream_chip(substream);
 
@@ -1154,7 +1330,8 @@
 	return 0;
 }
 
-static int snd_azf3328_capture_close(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_capture_close(snd_pcm_substream_t * substream)
 {
 	azf3328_t *chip = snd_pcm_substream_chip(substream);
 
@@ -1188,14 +1365,16 @@
 	.pointer =	snd_azf3328_capture_pointer
 };
 
-static void snd_azf3328_pcm_free(snd_pcm_t *pcm)
+static void
+snd_azf3328_pcm_free(snd_pcm_t *pcm)
 {
 	azf3328_t *chip = pcm->private_data;
 	chip->pcm = NULL;
 	snd_pcm_lib_preallocate_free_for_all(pcm);
 }
 
-static int __devinit snd_azf3328_pcm(azf3328_t *chip, int device)
+static int __devinit
+snd_azf3328_pcm(azf3328_t *chip, int device)
 {
 	snd_pcm_t *pcm;
 	int err;
@@ -1222,7 +1401,8 @@
 /******************************************************************/
 
 #ifdef SUPPORT_JOYSTICK
-static int __devinit snd_azf3328_config_joystick(azf3328_t *chip, int dev)
+static int __devinit
+snd_azf3328_config_joystick(azf3328_t *chip, int dev)
 {
 	struct gameport *gp;
 	struct resource *r;
@@ -1238,8 +1418,7 @@
 	chip->gameport = gp = gameport_allocate_port();
 	if (!gp) {
 		printk(KERN_ERR "azt3328: cannot allocate memory for gameport\n");
-		release_resource(r);
-		kfree_nocheck(r);
+		release_and_free_resource(r);
 		return -ENOMEM;
 	}
 
@@ -1249,15 +1428,16 @@
 	gp->io = 0x200;
 	gameport_set_port_data(gp, r);
 
-	snd_azf3328_io2_write(chip, IDX_IO2_LEGACY_ADDR,
-			      snd_azf3328_io2_read(chip, IDX_IO2_LEGACY_ADDR) | LEGACY_JOY);
+	snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR,
+			      snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) | LEGACY_JOY);
 
 	gameport_register_port(chip->gameport);
 
 	return 0;
 }
 
-static void snd_azf3328_free_joystick(azf3328_t *chip)
+static void
+snd_azf3328_free_joystick(azf3328_t *chip)
 {
 	if (chip->gameport) {
 		struct resource *r = gameport_get_port_data(chip->gameport);
@@ -1265,33 +1445,36 @@
 		gameport_unregister_port(chip->gameport);
 		chip->gameport = NULL;
 		/* disable gameport */
-		snd_azf3328_io2_write(chip, IDX_IO2_LEGACY_ADDR,
-				      snd_azf3328_io2_read(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
-		release_resource(r);
-		kfree_nocheck(r);
+		snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR,
+				      snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
+		release_and_free_resource(r);
 	}
 }
 #else
-static inline int snd_azf3328_config_joystick(azf3328_t *chip, int dev) { return -ENOSYS; }
-static inline void snd_azf3328_free_joystick(azf3328_t *chip) { }
+static inline int
+snd_azf3328_config_joystick(azf3328_t *chip, int dev) { return -ENOSYS; }
+static inline void
+snd_azf3328_free_joystick(azf3328_t *chip) { }
 #endif
 
 /******************************************************************/
 
-static int snd_azf3328_free(azf3328_t *chip)
+static int
+snd_azf3328_free(azf3328_t *chip)
 {
         if (chip->irq < 0)
                 goto __end_hw;
 
 	/* reset (close) mixer */
 	snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1); /* first mute master volume */
-	snd_azf3328_mixer_write(chip, IDX_MIXER_RESET, 0x0, WORD_VALUE);
+	snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
 
-        /* interrupt setup - mask everything */
-	/* FIXME */
+        /* interrupt setup - mask everything (FIXME!) */
+	/* well, at least we know how to disable the timer IRQ */
+	snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x00);
 
         synchronize_irq(chip->irq);
-      __end_hw:
+__end_hw:
 	snd_azf3328_free_joystick(chip);
         if (chip->irq >= 0)
 		free_irq(chip->irq, (void *)chip);
@@ -1302,15 +1485,129 @@
         return 0;
 }
 
-static int snd_azf3328_dev_free(snd_device_t *device)
+static int
+snd_azf3328_dev_free(snd_device_t *device)
 {
 	azf3328_t *chip = device->device_data;
 	return snd_azf3328_free(chip);
 }
 
+/******************************************************************/
+
+/*** NOTE: the physical timer resolution actually is 1024000 ticks per second,
+ *** but announcing those attributes to user-space would make programs
+ *** configure the timer to a 1 tick value, resulting in an absolutely fatal
+ *** timer IRQ storm.
+ *** Thus I chose to announce a down-scaled virtual timer to the outside and
+ *** calculate real timer countdown values internally.
+ *** (the scale factor can be set via module parameter "seqtimer_scaling").
+ ***/
+
+static int
+snd_azf3328_timer_start(snd_timer_t *timer)
+{
+	azf3328_t *chip;
+	unsigned long flags;
+	unsigned int delay;
+
+	snd_azf3328_dbgcallenter();
+	chip = snd_timer_chip(timer);
+	delay = ((timer->sticks * seqtimer_scaling) - 1) & TIMER_VALUE_MASK;
+	if (delay < 49)
+	{
+		/* uhoh, that's not good, since user-space won't know about
+		 * this timing tweak
+		 * (we need to do it to avoid a lockup, though) */
+
+		snd_azf3328_dbgtimer("delay was too low (%d)!\n", delay);
+		delay = 49; /* minimum time is 49 ticks */
+	}
+	snd_azf3328_dbgtimer("setting timer countdown value %d, add COUNTDOWN|IRQ\n", delay);
+	delay |= TIMER_ENABLE_COUNTDOWN | TIMER_ENABLE_IRQ;
+	spin_lock_irqsave(&chip->reg_lock, flags);
+	snd_azf3328_codec_outl(chip, IDX_IO_TIMER_VALUE, delay);
+	spin_unlock_irqrestore(&chip->reg_lock, flags);
+	snd_azf3328_dbgcallleave();
+	return 0;
+}
+
+static int
+snd_azf3328_timer_stop(snd_timer_t *timer)
+{
+	azf3328_t *chip;
+	unsigned long flags;
+
+	snd_azf3328_dbgcallenter();
+	chip = snd_timer_chip(timer);
+	spin_lock_irqsave(&chip->reg_lock, flags);
+	/* disable timer countdown and interrupt */
+	/* FIXME: should we write TIMER_ACK_IRQ here? */
+	snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0);
+	spin_unlock_irqrestore(&chip->reg_lock, flags);
+	snd_azf3328_dbgcallleave();
+	return 0;
+}
+
+
+static int
+snd_azf3328_timer_precise_resolution(snd_timer_t *timer,
+					       unsigned long *num, unsigned long *den)
+{
+	snd_azf3328_dbgcallenter();
+	*num = 1;
+	*den = 1024000 / seqtimer_scaling;
+	snd_azf3328_dbgcallleave();
+	return 0;
+}
+
+static struct _snd_timer_hardware snd_azf3328_timer_hw = {
+	.flags = SNDRV_TIMER_HW_AUTO,
+	.resolution = 977, /* 1000000/1024000 = 0.9765625us */
+	.ticks = 1024000, /* max tick count, defined by the value register; actually it's not 1024000, but 1048576, but we don't care */
+	.start = snd_azf3328_timer_start,
+	.stop = snd_azf3328_timer_stop,
+	.precise_resolution = snd_azf3328_timer_precise_resolution,
+};
+
+static int __devinit
+snd_azf3328_timer(azf3328_t *chip, int device)
+{
+	snd_timer_t *timer = NULL;
+	snd_timer_id_t tid;
+	int err;
+
+	snd_azf3328_dbgcallenter();
+	tid.dev_class = SNDRV_TIMER_CLASS_CARD;
+	tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
+	tid.card = chip->card->number;
+	tid.device = device;
+	tid.subdevice = 0;
+
+	snd_azf3328_timer_hw.resolution *= seqtimer_scaling;
+	snd_azf3328_timer_hw.ticks /= seqtimer_scaling;
+	if ((err = snd_timer_new(chip->card, "AZF3328", &tid, &timer)) < 0) {
+		goto out;
+	}
+
+	strcpy(timer->name, "AZF3328 timer");
+	timer->private_data = chip;
+	timer->hw = snd_azf3328_timer_hw;
+
+	chip->timer = timer;
+
+	err = 0;
+
+out:
+	snd_azf3328_dbgcallleave();
+	return err;
+}
+
+/******************************************************************/
+
 #if 0
 /* check whether a bit can be modified */
-static void snd_azf3328_test_bit(unsigned int reg, int bit)
+static void
+snd_azf3328_test_bit(unsigned int reg, int bit)
 {
 	unsigned char val, valoff, valon;
 
@@ -1328,7 +1625,26 @@
 }
 #endif
 
-static int __devinit snd_azf3328_create(snd_card_t * card,
+static void
+snd_azf3328_debug_show_ports(const azf3328_t *chip)
+{
+#if DEBUG_MISC
+	u16 tmp;
+
+	snd_azf3328_dbgmisc("codec_port 0x%lx, io2_port 0x%lx, mpu_port 0x%lx, synth_port 0x%lx, mixer_port 0x%lx, irq %d\n", chip->codec_port, chip->io2_port, chip->mpu_port, chip->synth_port, chip->mixer_port, chip->irq);
+
+	snd_azf3328_dbgmisc("io2 %02x %02x %02x %02x %02x %02x\n", snd_azf3328_io2_inb(chip, 0), snd_azf3328_io2_inb(chip, 1), snd_azf3328_io2_inb(chip, 2), snd_azf3328_io2_inb(chip, 3), snd_azf3328_io2_inb(chip, 4), snd_azf3328_io2_inb(chip, 5));
+
+	for (tmp=0; tmp <= 0x01; tmp += 1)
+		snd_azf3328_dbgmisc("0x%02x: opl 0x%04x, mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, mpu330 0x%04x\n", tmp, inb(0x388 + tmp), inb(0x300 + tmp), inb(0x310 + tmp), inb(0x320 + tmp), inb(0x330 + tmp));
+
+	for (tmp = 0; tmp <= 0x6E; tmp += 2)
+		snd_azf3328_dbgmisc("0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inb(chip, tmp));
+#endif
+}
+
+static int __devinit
+snd_azf3328_create(snd_card_t * card,
                                          struct pci_dev *pci,
                                          unsigned long device_type,
                                          azf3328_t ** rchip)
@@ -1347,8 +1663,8 @@
 
 	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL) {
-		pci_disable_device(pci);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto out_err;
 	}
 	spin_lock_init(&chip->reg_lock);
 	chip->card = card;
@@ -1358,47 +1674,39 @@
 	/* check if we can restrict PCI DMA transfers to 24 bits */
 	if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
 	    pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
-		snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
-		pci_disable_device(pci);
-		return -ENXIO;
+		snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
+		err = -ENXIO;
+		goto out_err;
 	}
 
 	if ((err = pci_request_regions(pci, "Aztech AZF3328")) < 0) {
-		kfree(chip);
-		pci_disable_device(pci);
-		return err;
+		goto out_err;
 	}
 
 	chip->codec_port = pci_resource_start(pci, 0);
-	chip->io2_port = pci_resource_start(pci, 1);
-	chip->mpu_port = pci_resource_start(pci, 2);
+	chip->io2_port   = pci_resource_start(pci, 1);
+	chip->mpu_port   = pci_resource_start(pci, 2);
 	chip->synth_port = pci_resource_start(pci, 3);
 	chip->mixer_port = pci_resource_start(pci, 4);
 
 	if (request_irq(pci->irq, snd_azf3328_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
-		snd_azf3328_free(chip);
-		return -EBUSY;
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
+		err = -EBUSY;
+		goto out_err;
 	}
 	chip->irq = pci->irq;
 	pci_set_master(pci);
 	synchronize_irq(chip->irq);
 
-	snd_azf3328_dbgmisc("codec_port 0x%lx, io2_port 0x%lx, mpu_port 0x%lx, synth_port 0x%lx, mixer_port 0x%lx, irq %d\n", chip->codec_port, chip->io2_port, chip->mpu_port, chip->synth_port, chip->mixer_port, chip->irq);
-
-	snd_azf3328_dbgmisc("io2 %02x %02x %02x %02x %02x %02x\n", snd_azf3328_io2_read(chip, 0), snd_azf3328_io2_read(chip, 1), snd_azf3328_io2_read(chip, 2), snd_azf3328_io2_read(chip, 3), snd_azf3328_io2_read(chip, 4), snd_azf3328_io2_read(chip, 5));
-
-	for (tmp=0; tmp <= 0x01; tmp += 1)
-		snd_azf3328_dbgmisc("0x%02x: opl 0x%04x, mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, mpu330 0x%04x\n", tmp, inb(0x388 + tmp), inb(0x300 + tmp), inb(0x310 + tmp), inb(0x320 + tmp), inb(0x330 + tmp));
-
+	snd_azf3328_debug_show_ports(chip);
+	
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
-		snd_azf3328_free(chip);
-		return err;
+		goto out_err;
 	}
 
 	/* create mixer interface & switches */
 	if ((err = snd_azf3328_mixer_new(chip)) < 0)
-		return err;
+		goto out_err;
 
 #if 0
 	/* set very low bitrate to reduce noise and power consumption? */
@@ -1406,22 +1714,34 @@
 #endif
 
 	/* standard chip init stuff */
-	spin_lock_irq(&chip->reg_lock);
-	outb(DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_PLAY_FLAGS);
-	outb(DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_SOMETHING_FLAGS);
-	outb(DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_REC_FLAGS);
-	outb(0x0, chip->codec_port + IDX_IO_IRQ63H);
+	/* default IRQ init value */
+	tmp = DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE;
 
+	spin_lock_irq(&chip->reg_lock);
+	snd_azf3328_codec_outb(chip, IDX_IO_PLAY_FLAGS, tmp);
+	snd_azf3328_codec_outb(chip, IDX_IO_REC_FLAGS, tmp);
+	snd_azf3328_codec_outb(chip, IDX_IO_SOMETHING_FLAGS, tmp);
+	snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x00); /* disable timer */
 	spin_unlock_irq(&chip->reg_lock);
 
 	snd_card_set_dev(card, &pci->dev);
 
 	*rchip = chip;
-	return 0;
+
+	err = 0;
+	goto out;
+
+out_err:
+	if (chip)
+		snd_azf3328_free(chip);
+	pci_disable_device(pci);
+
+out:
+	return err;
 }
 
-static int __devinit snd_azf3328_probe(struct pci_dev *pci,
-					  const struct pci_device_id *pci_id)
+static int __devinit
+snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 {
 	static int dev;
 	snd_card_t *card;
@@ -1445,63 +1765,70 @@
 	strcpy(card->shortname, "Aztech AZF3328 (PCI168)");
 
         if ((err = snd_azf3328_create(card, pci, pci_id->driver_data, &chip)) < 0) {
-		snd_card_free(card);
-		return err;
+		goto out_err;
 	}
 
 	if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_MPU401,
 				        chip->mpu_port, 1, pci->irq, 0,
 				        &chip->rmidi)) < 0) {
-		snd_printk("azf3328: no MPU-401 device at 0x%lx?\n", chip->mpu_port);
-		snd_card_free(card);
-		return err;
+		snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n", chip->mpu_port);
+		goto out_err;
+	}
+
+	if ((err = snd_azf3328_timer(chip, 0)) < 0) {
+		goto out_err;
 	}
 
 	if ((err = snd_azf3328_pcm(chip, 0)) < 0) {
-		snd_card_free(card);
-		return err;
+		goto out_err;
 	}
 
 	if (snd_opl3_create(card, chip->synth_port, chip->synth_port+2,
 			    OPL3_HW_AUTO, 1, &opl3) < 0) {
-		snd_printk("azf3328: no OPL3 device at 0x%lx-0x%lx?\n",
+		snd_printk(KERN_ERR "azf3328: no OPL3 device at 0x%lx-0x%lx?\n",
 			   chip->synth_port, chip->synth_port+2 );
 	} else {
 		if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
-			snd_card_free(card);
-			return err;
+			goto out_err;
 		}
 	}
 
-	snd_azf3328_dbgio(chip, "create");
-
 	sprintf(card->longname, "%s at 0x%lx, irq %i",
 		card->shortname, chip->codec_port, chip->irq);
 
 	if ((err = snd_card_register(card)) < 0) {
-		snd_card_free(card);
-		return err;
+		goto out_err;
 	}
 
 #ifdef MODULE
 	printk(
-"azt3328: Experimental driver for Aztech AZF3328-based soundcards such as PCI168.\n"
-"azt3328: ZERO support from Aztech: you might think hard about future purchase.\n"
-"azt3328: Feel free to contact hw7oshyuv3001@sneakemail.com for bug reports etc.!\n");
+"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168\n"
+"azt3328: (hardware was completely undocumented - ZERO support from Aztech).\n"
+"azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n"
+"azt3328: User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n",
+	1024000 / seqtimer_scaling, seqtimer_scaling);
 #endif
 
 	if (snd_azf3328_config_joystick(chip, dev) < 0)
-		snd_azf3328_io2_write(chip, IDX_IO2_LEGACY_ADDR,
-			      snd_azf3328_io2_read(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
+		snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR,
+			      snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
 
 	pci_set_drvdata(pci, card);
 	dev++;
 
+	err = 0;
+	goto out;
+	
+out_err:
+	snd_card_free(card);
+	
+out:
 	snd_azf3328_dbgcallleave();
-	return 0;
+	return err;
 }
 
-static void __devexit snd_azf3328_remove(struct pci_dev *pci)
+static void __devexit
+snd_azf3328_remove(struct pci_dev *pci)
 {
 	snd_azf3328_dbgcallenter();
 	snd_card_free(pci_get_drvdata(pci));
@@ -1517,7 +1844,8 @@
 	.remove = __devexit_p(snd_azf3328_remove),
 };
 
-static int __init alsa_card_azf3328_init(void)
+static int __init
+alsa_card_azf3328_init(void)
 {
 	int err;
 	snd_azf3328_dbgcallenter();
@@ -1526,7 +1854,8 @@
 	return err;
 }
 
-static void __exit alsa_card_azf3328_exit(void)
+static void __exit
+alsa_card_azf3328_exit(void)
 {
 	snd_azf3328_dbgcallenter();
 	pci_unregister_driver(&driver);
diff --git a/sound/pci/azt3328.h b/sound/pci/azt3328.h
index 7e0e791..f489bda 100644
--- a/sound/pci/azt3328.h
+++ b/sound/pci/azt3328.h
@@ -1,19 +1,17 @@
-#ifndef __SOUND_AZF3328_H
-#define __SOUND_AZF3328_H
+#ifndef __SOUND_AZT3328_H
+#define __SOUND_AZT3328_H
 
-/* type argument to use for the I/O functions */
-#define WORD_VALUE      0x1000
-#define DWORD_VALUE     0x2000
-#define BYTE_VALUE      0x4000
+/* "PU" == "power-up value", as tested on PCI168 PCI rev. 10 */
 
 /*** main I/O area port indices ***/
 /* (only 0x70 of 0x80 bytes saved/restored by Windows driver) */
-/* the driver initialisation suggests a layout of 3 main areas:
- * from 0x00 (playback), from 0x20 (recording) and from 0x40 (maybe DirectX
- * timer ???). and probably another area from 0x60 to 0x6f
- * (IRQ management, power management etc. ???). */
-/* playback area */
-#define IDX_IO_PLAY_FLAGS       0x00
+/* the driver initialisation suggests a layout of 4 main areas:
+ * from 0x00 (playback), from 0x20 (recording) and from 0x40 (maybe MPU401??).
+ * And another area from 0x60 to 0x6f (DirectX timer, IRQ management,
+ * power management etc.???). */
+
+/** playback area **/
+#define IDX_IO_PLAY_FLAGS       0x00 /* PU:0x0000 */
      /* able to reactivate output after output muting due to 8/16bit
       * output change, just like 0x0002.
       * 0x0001 is the only bit that's able to start the DMA counter */
@@ -29,7 +27,7 @@
   #define DMA_EPILOGUE_SOMETHING	0x0010
   #define DMA_SOMETHING_ELSE		0x0020 /* ??? */
   #define SOMETHING_UNMODIFIABLE	0xffc0 /* unused ? not modifiable */
-#define IDX_IO_PLAY_IRQMASK     0x02
+#define IDX_IO_PLAY_IRQTYPE     0x02 /* PU:0x0001 */
   /* write back to flags in case flags are set, in order to ACK IRQ in handler
    * (bit 1 of port 0x64 indicates interrupt for one of these three types)
    * sometimes in this case it just writes 0xffff to globally ACK all IRQs
@@ -41,36 +39,39 @@
   #define IRQMASK_SOME_STATUS_1		0x0008 /* \ related bits */
   #define IRQMASK_SOME_STATUS_2		0x0010 /* / (checked together in loop) */
   #define IRQMASK_UNMODIFIABLE		0xffe0 /* unused ? not modifiable */
-#define IDX_IO_PLAY_DMA_START_1 0x04 /* start address of 1st DMA play area */
-#define IDX_IO_PLAY_DMA_START_2 0x08 /* start address of 2nd DMA play area */
-#define IDX_IO_PLAY_DMA_LEN_1   0x0c /* length of 1st DMA play area */
-#define IDX_IO_PLAY_DMA_LEN_2   0x0e /* length of 2nd DMA play area */
-#define IDX_IO_PLAY_DMA_CURRPOS 0x10 /* current DMA position  */
-#define IDX_IO_PLAY_DMA_CURROFS	0x14 /* offset within current DMA play area */
-#define IDX_IO_PLAY_SOUNDFORMAT 0x16
+#define IDX_IO_PLAY_DMA_START_1 0x04 /* start address of 1st DMA play area, PU:0x00000000 */
+#define IDX_IO_PLAY_DMA_START_2 0x08 /* start address of 2nd DMA play area, PU:0x00000000 */
+#define IDX_IO_PLAY_DMA_LEN_1   0x0c /* length of 1st DMA play area, PU:0x0000 */
+#define IDX_IO_PLAY_DMA_LEN_2   0x0e /* length of 2nd DMA play area, PU:0x0000 */
+#define IDX_IO_PLAY_DMA_CURRPOS 0x10 /* current DMA position, PU:0x00000000 */
+#define IDX_IO_PLAY_DMA_CURROFS	0x14 /* offset within current DMA play area, PU:0x0000 */
+#define IDX_IO_PLAY_SOUNDFORMAT 0x16 /* PU:0x0010 */
   /* all unspecified bits can't be modified */
   #define SOUNDFORMAT_FREQUENCY_MASK	0x000f
+  #define SOUNDFORMAT_XTAL1		0x00
+  #define SOUNDFORMAT_XTAL2		0x01
     /* all _SUSPECTED_ values are not used by Windows drivers, so we don't
      * have any hard facts, only rough measurements */
-    #define SOUNDFORMAT_FREQ_SUSPECTED_4000	0x0c
-    #define SOUNDFORMAT_FREQ_SUSPECTED_4800	0x0a
-    #define SOUNDFORMAT_FREQ_5510		0x0d
-    #define SOUNDFORMAT_FREQ_6620		0x0b
-    #define SOUNDFORMAT_FREQ_8000		0x00 /* also 0x0e ? */
-    #define SOUNDFORMAT_FREQ_9600		0x08
-    #define SOUNDFORMAT_FREQ_SUSPECTED_12000	0x09
-    #define SOUNDFORMAT_FREQ_11025		0x01 /* also 0x0f ? */
-    #define SOUNDFORMAT_FREQ_16000		0x02
-    #define SOUNDFORMAT_FREQ_22050		0x03
-    #define SOUNDFORMAT_FREQ_32000		0x04
-    #define SOUNDFORMAT_FREQ_44100		0x05
-    #define SOUNDFORMAT_FREQ_48000		0x06
-    #define SOUNDFORMAT_FREQ_SUSPECTED_64000	0x07
+    #define SOUNDFORMAT_FREQ_SUSPECTED_4000	0x0c | SOUNDFORMAT_XTAL1
+    #define SOUNDFORMAT_FREQ_SUSPECTED_4800	0x0a | SOUNDFORMAT_XTAL1
+    #define SOUNDFORMAT_FREQ_5510		0x0c | SOUNDFORMAT_XTAL2
+    #define SOUNDFORMAT_FREQ_6620		0x0a | SOUNDFORMAT_XTAL2
+    #define SOUNDFORMAT_FREQ_8000		0x00 | SOUNDFORMAT_XTAL1 /* also 0x0e | SOUNDFORMAT_XTAL1? */
+    #define SOUNDFORMAT_FREQ_9600		0x08 | SOUNDFORMAT_XTAL1
+    #define SOUNDFORMAT_FREQ_11025		0x00 | SOUNDFORMAT_XTAL2 /* also 0x0e | SOUNDFORMAT_XTAL2? */
+    #define SOUNDFORMAT_FREQ_SUSPECTED_13240	0x08 | SOUNDFORMAT_XTAL2 /* seems to be 6620 *2 */
+    #define SOUNDFORMAT_FREQ_16000		0x02 | SOUNDFORMAT_XTAL1
+    #define SOUNDFORMAT_FREQ_22050		0x02 | SOUNDFORMAT_XTAL2
+    #define SOUNDFORMAT_FREQ_32000		0x04 | SOUNDFORMAT_XTAL1
+    #define SOUNDFORMAT_FREQ_44100		0x04 | SOUNDFORMAT_XTAL2
+    #define SOUNDFORMAT_FREQ_48000		0x06 | SOUNDFORMAT_XTAL1
+    #define SOUNDFORMAT_FREQ_SUSPECTED_66200	0x06 | SOUNDFORMAT_XTAL2 /* 66200 (13240 * 5); 64000 may have been nicer :-\ */
   #define SOUNDFORMAT_FLAG_16BIT	0x0010
   #define SOUNDFORMAT_FLAG_2CHANNELS	0x0020
-/* recording area (see also: playback bit flag definitions) */
-#define IDX_IO_REC_FLAGS	0x20 /* ?? */
-#define IDX_IO_REC_IRQMASK	0x22 /* ?? */
+
+/** recording area (see also: playback bit flag definitions) **/
+#define IDX_IO_REC_FLAGS	0x20 /* ??, PU:0x0000 */
+#define IDX_IO_REC_IRQTYPE	0x22 /* ??, PU:0x0000 */
   #define IRQ_REC_SOMETHING		0x0001 /* something & ACK */
   #define IRQ_FINISHED_RECBUF_1		0x0002 /* 1st dmabuf finished & ACK */
   #define IRQ_FINISHED_RECBUF_2		0x0004 /* 2nd dmabuf finished & ACK */
@@ -78,39 +79,47 @@
    * but OTOH they are most likely at port 0x22 instead */
   #define IRQMASK_SOME_STATUS_1		0x0008 /* \ related bits */
   #define IRQMASK_SOME_STATUS_2		0x0010 /* / (checked together in loop) */
-#define IDX_IO_REC_DMA_START_1  0x24
-#define IDX_IO_REC_DMA_START_2  0x28
-#define IDX_IO_REC_DMA_LEN_1    0x2c
-#define IDX_IO_REC_DMA_LEN_2    0x2e
-#define IDX_IO_REC_DMA_CURRPOS  0x30
-#define IDX_IO_REC_DMA_CURROFS  0x34
-#define IDX_IO_REC_SOUNDFORMAT  0x36
-/* some third area ? (after playback and recording) */
-#define IDX_IO_SOMETHING_FLAGS	0x40 /* gets set to 0x34 just like port 0x0 and 0x20 on card init */
+#define IDX_IO_REC_DMA_START_1  0x24 /* PU:0x00000000 */
+#define IDX_IO_REC_DMA_START_2  0x28 /* PU:0x00000000 */
+#define IDX_IO_REC_DMA_LEN_1    0x2c /* PU:0x0000 */
+#define IDX_IO_REC_DMA_LEN_2    0x2e /* PU:0x0000 */
+#define IDX_IO_REC_DMA_CURRPOS  0x30 /* PU:0x00000000 */
+#define IDX_IO_REC_DMA_CURROFS  0x34 /* PU:0x00000000 */
+#define IDX_IO_REC_SOUNDFORMAT  0x36 /* PU:0x0000 */
+
+/** hmm, what is this I/O area for? MPU401?? (after playback, recording, ???, timer) **/
+#define IDX_IO_SOMETHING_FLAGS	0x40 /* gets set to 0x34 just like port 0x0 and 0x20 on card init, PU:0x0000 */
 /* general */
-#define IDX_IO_60H		0x60 /* writing 0xffff returns 0xffff */
-#define IDX_IO_62H		0x62 /* writing to WORD 0x0062 can hang the box ! --> responsible for IRQ management as a whole ?? */
-#define IDX_IO_IRQ63H		0x63 /* FIXME !! */
-  #define IO_IRQ63H_SOMETHING		0x04 /* being set in IRQ handler in case port 0x00 had 0x0020 set upon IRQ handler */
+#define IDX_IO_42H		0x42 /* PU:0x0001 */
+
+/** DirectX timer, main interrupt area (FIXME: and something else?) **/ 
+#define IDX_IO_TIMER_VALUE	0x60 /* found this timer area by pure luck :-) */
+  #define TIMER_VALUE_MASK		0x000fffffUL /* timer countdown value; triggers IRQ when timer is finished */
+  #define TIMER_ENABLE_COUNTDOWN	0x01000000UL /* activate the timer countdown */
+  #define TIMER_ENABLE_IRQ		0x02000000UL /* trigger timer IRQ on zero transition */
+  #define TIMER_ACK_IRQ			0x04000000UL /* being set in IRQ handler in case port 0x00 (hmm, not port 0x64!?!?) had 0x0020 set upon IRQ handler */
 #define IDX_IO_IRQSTATUS        0x64
   #define IRQ_PLAYBACK			0x0001
   #define IRQ_RECORDING			0x0002
   #define IRQ_MPU401			0x0010
-  #define IRQ_SOMEIRQ			0x0020 /* ???? */
-  #define IRQ_WHO_KNOWS_UNUSED		0x00e0 /* probably unused */
+  #define IRQ_TIMER			0x0020 /* DirectX timer */
+  #define IRQ_UNKNOWN1			0x0040 /* probably unused */
+  #define IRQ_UNKNOWN2			0x0080 /* probably unused */
 #define IDX_IO_66H		0x66    /* writing 0xffff returns 0x0000 */
-#define IDX_IO_SOME_VALUE	0x68	/* this is always set to 0x3ff, and writable; maybe some buffer limit, but I couldn't find out more */
-#define IDX_IO_6AH		0x6A	/* this WORD can be set to have bits 0x0028 activated; actually inhibits PCM playback !!! maybe power management ?? */
-#define IDX_IO_6CH		0x6C	/* this WORD can have all its bits activated ? */
+#define IDX_IO_SOME_VALUE	0x68	/* this is set to e.g. 0x3ff or 0x300, and writable; maybe some buffer limit, but I couldn't find out more, PU:0x00ff */
+#define IDX_IO_6AH		0x6A	/* this WORD can be set to have bits 0x0028 activated; actually inhibits PCM playback!!! maybe power management?? */
+#define IDX_IO_6CH		0x6C
 #define IDX_IO_6EH		0x6E	/* writing 0xffff returns 0x83fe */
 /* further I/O indices not saved/restored, so probably not used */
 
+
 /*** I/O 2 area port indices ***/
 /* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */ 
 #define IDX_IO2_LEGACY_ADDR	0x04
-  #define LEGACY_SOMETHING		0x01 /* OPL3 ?? */
+  #define LEGACY_SOMETHING		0x01 /* OPL3?? */
   #define LEGACY_JOY			0x08
 
+
 /*** mixer I/O area port indices ***/
 /* (only 0x22 of 0x40 bytes saved/restored by Windows driver)
  * generally spoken: AC97 register index = AZF3328 mixer reg index + 2
@@ -148,18 +157,18 @@
   /* unlisted bits are unmodifiable */
   #define MIXER_ADVCTL1_3DWIDTH_MASK	0x000e
   #define MIXER_ADVCTL1_HIFI3D_MASK	0x0300
-#define IDX_MIXER_ADVCTL2       0x20 /* resembles AC97_GENERAL_PURPOSE reg ! */
+#define IDX_MIXER_ADVCTL2       0x20 /* resembles AC97_GENERAL_PURPOSE reg! */
   /* unlisted bits are unmodifiable */
-  #define MIXER_ADVCTL2_BIT7		0x0080 /* WaveOut 3D Bypass ? mutes WaveOut at LineOut */
-  #define MIXER_ADVCTL2_BIT8		0x0100 /* is this Modem Out Select ? */
-  #define MIXER_ADVCTL2_BIT9		0x0200 /* Mono Select Source ? */
-  #define MIXER_ADVCTL2_BIT13		0x2000 /* 3D enable ? */
+  #define MIXER_ADVCTL2_BIT7		0x0080 /* WaveOut 3D Bypass? mutes WaveOut at LineOut */
+  #define MIXER_ADVCTL2_BIT8		0x0100 /* is this Modem Out Select? */
+  #define MIXER_ADVCTL2_BIT9		0x0200 /* Mono Select Source? */
+  #define MIXER_ADVCTL2_BIT13		0x2000 /* 3D enable? */
   #define MIXER_ADVCTL2_BIT15		0x8000 /* unknown */
   
-#define IDX_MIXER_SOMETHING30H	0x30 /* used, but unknown ??? */
+#define IDX_MIXER_SOMETHING30H	0x30 /* used, but unknown??? */
 
 /* driver internal flags */
 #define SET_CHAN_LEFT	1
 #define SET_CHAN_RIGHT	2
 
-#endif /* __SOUND_AZF3328_H  */
+#endif /* __SOUND_AZT3328_H  */
diff --git a/sound/pci/ca0106/Makefile b/sound/pci/ca0106/Makefile
index 89c6cee..dcbae7b 100644
--- a/sound/pci/ca0106/Makefile
+++ b/sound/pci/ca0106/Makefile
@@ -1,3 +1,3 @@
-snd-ca0106-objs := ca0106_main.o ca0106_proc.o ca0106_mixer.o
+snd-ca0106-objs := ca0106_main.o ca0106_proc.o ca0106_mixer.o ca_midi.o
 
 obj-$(CONFIG_SND_CA0106) += snd-ca0106.o
diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
index da09cab..9a4b640 100644
--- a/sound/pci/ca0106/ca0106.h
+++ b/sound/pci/ca0106/ca0106.h
@@ -399,10 +399,24 @@
 #define PLAYBACK_VOLUME2        0x6a            /* Playback Analog volume per channel. Does not effect AC3 output */
 						/* Similar to register 0x66, except that the destination is the I2S mixer instead of the SPDIF mixer. I.E. Outputs to the Analog outputs instead of SPDIF. */
 #define UNKNOWN6b               0x6b            /* Unknown. Readonly. Default 00400000 00400000 00400000 00400000 */
-#define UART_A_DATA		0x6c            /* Uart, used in setting sample rates, bits per sample etc. */
-#define UART_A_CMD		0x6d            /* Uart, used in setting sample rates, bits per sample etc. */
-#define UART_B_DATA		0x6e            /* Uart, Unknown. */
-#define UART_B_CMD		0x6f            /* Uart, Unknown. */
+#define MIDI_UART_A_DATA		0x6c            /* Midi Uart A Data */
+#define MIDI_UART_A_CMD		0x6d            /* Midi Uart A Command/Status */
+#define MIDI_UART_B_DATA		0x6e            /* Midi Uart B Data (currently unused) */
+#define MIDI_UART_B_CMD		0x6f            /* Midi Uart B Command/Status (currently unused) */
+
+/* unique channel identifier for midi->channel */
+
+#define CA0106_MIDI_CHAN_A		0x1
+#define CA0106_MIDI_CHAN_B		0x2
+
+/* from mpu401 */
+
+#define CA0106_MIDI_INPUT_AVAIL 	0x80
+#define CA0106_MIDI_OUTPUT_READY	0x40
+#define CA0106_MPU401_RESET		0xff
+#define CA0106_MPU401_ENTER_UART	0x3f
+#define CA0106_MPU401_ACK		0xfe
+
 #define SAMPLE_RATE_TRACKER_STATUS 0x70         /* Readonly. Default 00108000 00108000 00500000 00500000 */
 						/* Estimated sample rate [19:0] Relative to 48kHz. 0x8000 =  1.0
 						 * Rate Locked [20]
@@ -538,6 +552,8 @@
 #define CONTROL_CENTER_LFE_CHANNEL 1
 #define CONTROL_UNKNOWN_CHANNEL 2
 
+#include "ca_midi.h"
+
 typedef struct snd_ca0106_channel ca0106_channel_t;
 typedef struct snd_ca0106 ca0106_t;
 typedef struct snd_ca0106_pcm ca0106_pcm_t;
@@ -592,6 +608,9 @@
 	int capture_mic_line_in;
 
 	struct snd_dma_buffer buffer;
+
+	ca_midi_t midi;
+	ca_midi_t midi2;
 };
 
 int __devinit snd_ca0106_mixer(ca0106_t *emu);
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index ba07960..ee58d16 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -281,7 +281,7 @@
 	int retry;
 	if ((reg > 0x7f) || (value > 0x1ff))
 	{
-                snd_printk("i2c_write: invalid values.\n");
+		snd_printk(KERN_ERR "i2c_write: invalid values.\n");
 		return -EINVAL;
 	}
 
@@ -319,7 +319,7 @@
 
 	if(retry==10)
 	{
-                snd_printk("Writing to ADC failed!\n");
+		snd_printk(KERN_ERR "Writing to ADC failed!\n");
 		return -EINVAL;
 	}
     
@@ -338,6 +338,18 @@
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
+static void snd_ca0106_intr_disable(ca0106_t *emu, unsigned int intrenb)
+{
+	unsigned long flags;
+	unsigned int enable;
+  
+	spin_lock_irqsave(&emu->emu_lock, flags);
+	enable = inl(emu->port + INTE) & ~intrenb;
+	outl(enable, emu->port + INTE);
+	spin_unlock_irqrestore(&emu->emu_lock, flags);
+}
+
+
 static void snd_ca0106_pcm_free_substream(snd_pcm_runtime_t *runtime)
 {
 	kfree(runtime->private_data);
@@ -421,7 +433,7 @@
 
 	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
 	if (epcm == NULL) {
-                snd_printk("open_capture_channel: failed epcm alloc\n");
+		snd_printk(KERN_ERR "open_capture_channel: failed epcm alloc\n");
 		return -ENOMEM;
         }
 	epcm->emu = chip;
@@ -969,10 +981,8 @@
 #endif
 
 	// release the i/o port
-	if (chip->res_port) {
-		release_resource(chip->res_port);
-		kfree_nocheck(chip->res_port);
-	}
+	release_and_free_resource(chip->res_port);
+
 	// release the irq
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *)chip);
@@ -1042,6 +1052,15 @@
 
         snd_ca0106_ptr_write(chip, EXTENDED_INT, 0, stat76);
 	spin_lock(&chip->emu_lock);
+
+	if (chip->midi.dev_id &&
+	  (status & (chip->midi.ipr_tx|chip->midi.ipr_rx))) {
+		if (chip->midi.interrupt)
+			chip->midi.interrupt(&chip->midi, status);
+		else
+			chip->midi.interrupt_disable(&chip->midi, chip->midi.tx_enable | chip->midi.rx_enable);
+	}
+
 	// acknowledge the interrupt if necessary
 	outl(status, chip->port+IPR);
 
@@ -1311,6 +1330,88 @@
 	return 0;
 }
 
+
+static void ca0106_midi_interrupt_enable(ca_midi_t *midi, int intr)
+{
+	snd_ca0106_intr_enable((ca0106_t *)(midi->dev_id), intr);
+}
+
+static void ca0106_midi_interrupt_disable(ca_midi_t *midi, int intr)
+{
+	snd_ca0106_intr_disable((ca0106_t *)(midi->dev_id), intr);
+}
+
+static unsigned char ca0106_midi_read(ca_midi_t *midi, int idx)
+{
+	return (unsigned char)snd_ca0106_ptr_read((ca0106_t *)(midi->dev_id), midi->port + idx, 0);
+}
+
+static void ca0106_midi_write(ca_midi_t *midi, int data, int idx)
+{
+	snd_ca0106_ptr_write((ca0106_t *)(midi->dev_id), midi->port + idx, 0, data);
+}
+
+static snd_card_t *ca0106_dev_id_card(void *dev_id)
+{
+	return ((ca0106_t *)dev_id)->card;
+}
+
+static int ca0106_dev_id_port(void *dev_id)
+{
+	return ((ca0106_t *)dev_id)->port;
+}
+
+static int __devinit snd_ca0106_midi(ca0106_t *chip, unsigned int channel)
+{
+	ca_midi_t *midi;
+	char *name;
+	int err;
+
+        if(channel==CA0106_MIDI_CHAN_B) {
+		name = "CA0106 MPU-401 (UART) B";
+		midi =  &chip->midi2;
+		midi->tx_enable = INTE_MIDI_TX_B;
+		midi->rx_enable = INTE_MIDI_RX_B;
+		midi->ipr_tx = IPR_MIDI_TX_B;
+		midi->ipr_rx = IPR_MIDI_RX_B;
+		midi->port = MIDI_UART_B_DATA;
+	} else {
+		name = "CA0106 MPU-401 (UART)";
+		midi =  &chip->midi;
+		midi->tx_enable = INTE_MIDI_TX_A;
+		midi->rx_enable = INTE_MIDI_TX_B;
+		midi->ipr_tx = IPR_MIDI_TX_A;
+		midi->ipr_rx = IPR_MIDI_RX_A;
+		midi->port = MIDI_UART_A_DATA;
+	}
+
+	midi->reset = CA0106_MPU401_RESET;
+	midi->enter_uart = CA0106_MPU401_ENTER_UART;
+	midi->ack = CA0106_MPU401_ACK;
+
+	midi->input_avail = CA0106_MIDI_INPUT_AVAIL;
+	midi->output_ready = CA0106_MIDI_OUTPUT_READY;
+
+	midi->channel = channel;
+
+	midi->interrupt_enable = ca0106_midi_interrupt_enable;
+	midi->interrupt_disable = ca0106_midi_interrupt_disable;
+
+	midi->read = ca0106_midi_read;
+	midi->write = ca0106_midi_write;
+
+	midi->get_dev_id_card = ca0106_dev_id_card;
+	midi->get_dev_id_port = ca0106_dev_id_port;
+
+	midi->dev_id = chip;
+	
+	if ((err = ca_midi_init(chip, midi, 0, name)) < 0)
+		return err;
+
+	return 0;
+}
+
+
 static int __devinit snd_ca0106_probe(struct pci_dev *pci,
 					const struct pci_device_id *pci_id)
 {
@@ -1362,6 +1463,14 @@
 		return err;
 	}
 
+	snd_printdd("ca0106: probe for MIDI channel A ...");
+	if ((err = snd_ca0106_midi(chip,CA0106_MIDI_CHAN_A)) < 0) {
+		snd_card_free(card);
+		snd_printdd(" failed, err=0x%x\n",err);
+		return err;
+	}
+	snd_printdd(" done.\n");
+
 	snd_ca0106_proc_init(chip);
 
 	if ((err = snd_card_register(card)) < 0) {
diff --git a/sound/pci/ca0106/ca_midi.c b/sound/pci/ca0106/ca_midi.c
new file mode 100644
index 0000000..2e08b27
--- /dev/null
+++ b/sound/pci/ca0106/ca_midi.c
@@ -0,0 +1,306 @@
+/* 
+ *  Copyright 10/16/2005 Tilman Kranz <tilde@tk-sls.de>
+ *  Creative Audio MIDI, for the CA0106 Driver
+ *  Version: 0.0.1
+ *
+ *  Changelog:
+ *    Implementation is based on mpu401 and emu10k1x and
+ *    tested with ca0106.
+ *    mpu401: Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ *    emu10k1x: Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ *
+ */
+
+#include <linux/spinlock.h>
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/rawmidi.h>
+
+#include "ca_midi.h"
+
+#define ca_midi_write_data(midi, data)	midi->write(midi, data, 0)
+#define ca_midi_write_cmd(midi, data)	midi->write(midi, data, 1)
+#define ca_midi_read_data(midi)		midi->read(midi, 0)
+#define ca_midi_read_stat(midi)		midi->read(midi, 1)
+#define ca_midi_input_avail(midi)	(!(ca_midi_read_stat(midi) & midi->input_avail))
+#define ca_midi_output_ready(midi)	(!(ca_midi_read_stat(midi) & midi->output_ready))
+
+static void ca_midi_clear_rx(ca_midi_t *midi)
+{
+	int timeout = 100000;
+	for (; timeout > 0 && ca_midi_input_avail(midi); timeout--)
+		ca_midi_read_data(midi);
+#ifdef CONFIG_SND_DEBUG
+	if (timeout <= 0)
+		snd_printk(KERN_ERR "ca_midi_clear_rx: timeout (status = 0x%x)\n", ca_midi_read_stat(midi));
+#endif
+}
+
+static void ca_midi_interrupt(ca_midi_t *midi, unsigned int status) {
+	unsigned char byte;
+
+	if (midi->rmidi == NULL) {
+		midi->interrupt_disable(midi,midi->tx_enable | midi->rx_enable);
+		return;
+	}
+
+	spin_lock(&midi->input_lock);
+	if ((status & midi->ipr_rx) && ca_midi_input_avail(midi)) {
+		if (!(midi->midi_mode & CA_MIDI_MODE_INPUT)) {
+			ca_midi_clear_rx(midi);
+		} else {
+			byte = ca_midi_read_data(midi);
+			if(midi->substream_input)
+				snd_rawmidi_receive(midi->substream_input, &byte, 1);
+
+
+		}
+	}
+	spin_unlock(&midi->input_lock);
+
+	spin_lock(&midi->output_lock);
+	if ((status & midi->ipr_tx) && ca_midi_output_ready(midi)) {
+		if (midi->substream_output &&
+		    snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
+			ca_midi_write_data(midi, byte);
+		} else {
+			midi->interrupt_disable(midi,midi->tx_enable);
+		}
+	}
+	spin_unlock(&midi->output_lock);
+
+}
+
+static void ca_midi_cmd(ca_midi_t *midi, unsigned char cmd, int ack)
+{
+	unsigned long flags;
+	int timeout, ok;
+
+	spin_lock_irqsave(&midi->input_lock, flags);
+	ca_midi_write_data(midi, 0x00);
+	/* ca_midi_clear_rx(midi); */
+
+	ca_midi_write_cmd(midi, cmd);
+	if (ack) {
+		ok = 0;
+		timeout = 10000;
+		while (!ok && timeout-- > 0) {
+			if (ca_midi_input_avail(midi)) {
+				if (ca_midi_read_data(midi) == midi->ack)
+					ok = 1;
+			}
+		}
+		if (!ok && ca_midi_read_data(midi) == midi->ack)
+			ok = 1;
+	} else {
+		ok = 1;
+	}
+	spin_unlock_irqrestore(&midi->input_lock, flags);
+	if (!ok)
+		snd_printk(KERN_ERR "ca_midi_cmd: 0x%x failed at 0x%x (status = 0x%x, data = 0x%x)!!!\n",
+			   cmd,
+			   midi->get_dev_id_port(midi->dev_id),
+			   ca_midi_read_stat(midi),
+			   ca_midi_read_data(midi));
+}
+
+static int ca_midi_input_open(snd_rawmidi_substream_t * substream)
+{
+	ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+	unsigned long flags;
+	
+	snd_assert(midi->dev_id, return -ENXIO);
+	spin_lock_irqsave(&midi->open_lock, flags);
+	midi->midi_mode |= CA_MIDI_MODE_INPUT;
+	midi->substream_input = substream;
+	if (!(midi->midi_mode & CA_MIDI_MODE_OUTPUT)) {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+		ca_midi_cmd(midi, midi->reset, 1);
+		ca_midi_cmd(midi, midi->enter_uart, 1);
+	} else {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+	}
+	return 0;
+}
+
+static int ca_midi_output_open(snd_rawmidi_substream_t * substream)
+{
+	ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+	unsigned long flags;
+
+	snd_assert(midi->dev_id, return -ENXIO);
+	spin_lock_irqsave(&midi->open_lock, flags);
+	midi->midi_mode |= CA_MIDI_MODE_OUTPUT;
+	midi->substream_output = substream;
+	if (!(midi->midi_mode & CA_MIDI_MODE_INPUT)) {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+		ca_midi_cmd(midi, midi->reset, 1);
+		ca_midi_cmd(midi, midi->enter_uart, 1);
+	} else {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+	}
+	return 0;
+}
+
+static int ca_midi_input_close(snd_rawmidi_substream_t * substream)
+{
+	ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+	unsigned long flags;
+
+	snd_assert(midi->dev_id, return -ENXIO);
+	spin_lock_irqsave(&midi->open_lock, flags);
+	midi->interrupt_disable(midi,midi->rx_enable);
+	midi->midi_mode &= ~CA_MIDI_MODE_INPUT;
+	midi->substream_input = NULL;
+	if (!(midi->midi_mode & CA_MIDI_MODE_OUTPUT)) {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+		ca_midi_cmd(midi, midi->reset, 0);
+	} else {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+	}
+	return 0;
+}
+
+static int ca_midi_output_close(snd_rawmidi_substream_t * substream)
+{
+	ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+	unsigned long flags;
+	snd_assert(midi->dev_id, return -ENXIO);
+	
+	spin_lock_irqsave(&midi->open_lock, flags);
+
+	midi->interrupt_disable(midi,midi->tx_enable);
+	midi->midi_mode &= ~CA_MIDI_MODE_OUTPUT;
+	midi->substream_output = NULL;
+	
+	if (!(midi->midi_mode & CA_MIDI_MODE_INPUT)) {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+		ca_midi_cmd(midi, midi->reset, 0);
+	} else {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+	}
+	return 0;
+}
+
+static void ca_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
+{
+	ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+	snd_assert(midi->dev_id, return);
+
+	if (up) {
+		midi->interrupt_enable(midi,midi->rx_enable);
+	} else {
+		midi->interrupt_disable(midi, midi->rx_enable);
+	}
+}
+
+static void ca_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
+{
+	ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+	unsigned long flags;
+
+	snd_assert(midi->dev_id, return);
+
+	if (up) {
+		int max = 4;
+		unsigned char byte;
+
+		spin_lock_irqsave(&midi->output_lock, flags);
+	
+		/* try to send some amount of bytes here before interrupts */
+		while (max > 0) {
+			if (ca_midi_output_ready(midi)) {
+				if (!(midi->midi_mode & CA_MIDI_MODE_OUTPUT) ||
+				    snd_rawmidi_transmit(substream, &byte, 1) != 1) {
+					/* no more data */
+					spin_unlock_irqrestore(&midi->output_lock, flags);
+					return;
+				}
+				ca_midi_write_data(midi, byte);
+				max--;
+			} else {
+				break;
+			}
+		}
+
+		spin_unlock_irqrestore(&midi->output_lock, flags);
+		midi->interrupt_enable(midi,midi->tx_enable);
+
+	} else {
+		midi->interrupt_disable(midi,midi->tx_enable);
+	}
+}
+
+static snd_rawmidi_ops_t ca_midi_output =
+{
+	.open =		ca_midi_output_open,
+	.close =	ca_midi_output_close,
+	.trigger =	ca_midi_output_trigger,
+};
+
+static snd_rawmidi_ops_t ca_midi_input =
+{
+	.open =		ca_midi_input_open,
+	.close =	ca_midi_input_close,
+	.trigger =	ca_midi_input_trigger,
+};
+
+static void ca_midi_free(ca_midi_t *midi) {
+	midi->interrupt = NULL;
+	midi->interrupt_enable = NULL;
+	midi->interrupt_disable = NULL;
+	midi->read = NULL;
+	midi->write = NULL;
+	midi->get_dev_id_card = NULL;
+	midi->get_dev_id_port = NULL;
+	midi->rmidi = NULL;
+}
+
+static void ca_rmidi_free(snd_rawmidi_t *rmidi)
+{
+	ca_midi_free((ca_midi_t *)rmidi->private_data);
+}
+
+int __devinit ca_midi_init(void *dev_id, ca_midi_t *midi, int device, char *name)
+{
+	snd_rawmidi_t *rmidi;
+	int err;
+
+	if ((err = snd_rawmidi_new(midi->get_dev_id_card(midi->dev_id), name, device, 1, 1, &rmidi)) < 0)
+		return err;
+
+	midi->dev_id = dev_id;
+	midi->interrupt = ca_midi_interrupt;
+
+	spin_lock_init(&midi->open_lock);
+	spin_lock_init(&midi->input_lock);
+	spin_lock_init(&midi->output_lock);
+
+	strcpy(rmidi->name, name);
+	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &ca_midi_output);
+	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &ca_midi_input);
+	rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
+	                     SNDRV_RAWMIDI_INFO_INPUT |
+	                     SNDRV_RAWMIDI_INFO_DUPLEX;
+	rmidi->private_data = midi;
+	rmidi->private_free = ca_rmidi_free;
+	
+	midi->rmidi = rmidi;
+	return 0;
+}
+
diff --git a/sound/pci/ca0106/ca_midi.h b/sound/pci/ca0106/ca_midi.h
new file mode 100644
index 0000000..b452cec
--- /dev/null
+++ b/sound/pci/ca0106/ca_midi.h
@@ -0,0 +1,69 @@
+/* 
+ *  Copyright 10/16/2005 Tilman Kranz <tilde@tk-sls.de>
+ *  Creative Audio MIDI, for the CA0106 Driver
+ *  Version: 0.0.1
+ *
+ *  Changelog:
+ *    See ca_midi.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.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#include<linux/spinlock.h>
+#include<sound/rawmidi.h>
+#include<sound/mpu401.h>
+
+#define CA_MIDI_MODE_INPUT	MPU401_MODE_INPUT
+#define CA_MIDI_MODE_OUTPUT	MPU401_MODE_OUTPUT
+
+typedef struct ca_midi ca_midi_t;
+struct ca_midi {
+
+	snd_rawmidi_t *rmidi;
+	snd_rawmidi_substream_t *substream_input;
+	snd_rawmidi_substream_t *substream_output;
+
+	void *dev_id;
+
+	spinlock_t input_lock;
+	spinlock_t output_lock;
+	spinlock_t open_lock;
+
+	unsigned int channel;
+
+	unsigned int midi_mode;
+	int port;
+	int tx_enable, rx_enable;
+	int ipr_tx, ipr_rx;            
+	
+	int input_avail, output_ready;
+	int ack, reset, enter_uart;
+
+	void (*interrupt)(ca_midi_t *midi, unsigned int status);
+	void (*interrupt_enable)(ca_midi_t *midi, int intr);
+	void (*interrupt_disable)(ca_midi_t *midi, int intr);
+
+	unsigned char (*read)(ca_midi_t *midi, int idx);
+	void (*write)(ca_midi_t *midi, int data, int idx);
+
+	/* get info from dev_id */
+	snd_card_t *(*get_dev_id_card)(void *dev_id);
+	int (*get_dev_id_port)(void *dev_id);
+};
+
+int __devinit ca_midi_init(void *card, ca_midi_t *midi, int device, char *name);
+
+
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 1eb3315..57e8e43 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -446,9 +446,6 @@
 	snd_kcontrol_t *mixer_res_ctl[CM_SAVED_MIXERS];
 	int mixer_res_status[CM_SAVED_MIXERS];
 
-	opl3_t *opl3;
-	snd_hwdep_t *opl3hwdep;
-
 	cmipci_pcm_t channel[2];	/* ch0 - DAC, ch1 - ADC or 2nd DAC */
 
 	/* external MIDI */
@@ -2686,8 +2683,7 @@
 	cm->gameport = gp = gameport_allocate_port();
 	if (!gp) {
 		printk(KERN_ERR "cmipci: cannot allocate memory for gameport\n");
-		release_resource(r);
-		kfree_nocheck(r);
+		release_and_free_resource(r);
 		return -ENOMEM;
 	}
 	gameport_set_name(gp, "C-Media Gameport");
@@ -2712,8 +2708,7 @@
 		cm->gameport = NULL;
 
 		snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN);
-		release_resource(r);
-		kfree_nocheck(r);
+		release_and_free_resource(r);
 	}
 }
 #else
@@ -2753,6 +2748,51 @@
 	return snd_cmipci_free(cm);
 }
 
+static int __devinit snd_cmipci_create_fm(cmipci_t *cm, long fm_port)
+{
+	long iosynth;
+	unsigned int val;
+	opl3_t *opl3;
+	int err;
+
+	/* first try FM regs in PCI port range */
+	iosynth = cm->iobase + CM_REG_FM_PCI;
+	err = snd_opl3_create(cm->card, iosynth, iosynth + 2,
+			      OPL3_HW_OPL3, 1, &opl3);
+	if (err < 0) {
+		/* then try legacy ports */
+		val = snd_cmipci_read(cm, CM_REG_LEGACY_CTRL) & ~CM_FMSEL_MASK;
+		iosynth = fm_port;
+		switch (iosynth) {
+		case 0x3E8: val |= CM_FMSEL_3E8; break;
+		case 0x3E0: val |= CM_FMSEL_3E0; break;
+		case 0x3C8: val |= CM_FMSEL_3C8; break;
+		case 0x388: val |= CM_FMSEL_388; break;
+		default:
+			    return 0;
+		}
+		snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val);
+		/* enable FM */
+		snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
+
+		if (snd_opl3_create(cm->card, iosynth, iosynth + 2,
+				    OPL3_HW_OPL3, 0, &opl3) < 0) {
+			printk(KERN_ERR "cmipci: no OPL device at %#lx, "
+			       "skipping...\n", iosynth);
+			/* disable FM */
+			snd_cmipci_write(cm, CM_REG_LEGACY_CTRL,
+					 val & ~CM_FMSEL_MASK);
+			snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
+			return 0;
+		}
+	}
+	if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
+		printk(KERN_ERR "cmipci: cannot create OPL3 hwdep\n");
+		return err;
+	}
+	return 0;
+}
+
 static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci,
 				       int dev, cmipci_t **rcmipci)
 {
@@ -2762,8 +2802,8 @@
 		.dev_free =	snd_cmipci_dev_free,
 	};
 	unsigned int val = 0;
-	long iomidi = mpu_port[dev];
-	long iosynth = fm_port[dev];
+	long iomidi;
+	int integrated_midi;
 	int pcm_index, pcm_spdif_index;
 	static struct pci_device_id intel_82437vx[] = {
 		{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX) },
@@ -2799,7 +2839,7 @@
 	cm->iobase = pci_resource_start(pci, 0);
 
 	if (request_irq(pci->irq, snd_cmipci_interrupt, SA_INTERRUPT|SA_SHIRQ, card->driver, (void *)cm)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_cmipci_free(cm);
 		return -EBUSY;
 	}
@@ -2867,52 +2907,28 @@
 		return err;
 	}
 
-	/* set MPU address */
-	switch (iomidi) {
-	case 0x320: val = CM_VMPU_320; break;
-	case 0x310: val = CM_VMPU_310; break;
-	case 0x300: val = CM_VMPU_300; break;
-	case 0x330: val = CM_VMPU_330; break;
-	default:
-		iomidi = 0; break;
-	}
-	if (iomidi > 0) {
-		snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val);
-		/* enable UART */
-		snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_UART_EN);
-	}
-
-	/* set FM address */
-	val = snd_cmipci_read(cm, CM_REG_LEGACY_CTRL) & ~CM_FMSEL_MASK;
-	switch (iosynth) {
-	case 0x3E8: val |= CM_FMSEL_3E8; break;
-	case 0x3E0: val |= CM_FMSEL_3E0; break;
-	case 0x3C8: val |= CM_FMSEL_3C8; break;
-	case 0x388: val |= CM_FMSEL_388; break;
-	default:
-		iosynth = 0; break;
-	}
-	if (iosynth > 0) {
-		snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val);
-		/* enable FM */
-		snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
-
-		if (snd_opl3_create(card, iosynth, iosynth + 2,
-				    OPL3_HW_OPL3, 0, &cm->opl3) < 0) {
-			printk(KERN_ERR "cmipci: no OPL device at 0x%lx, skipping...\n", iosynth);
-			iosynth = 0;
-		} else {
-			if ((err = snd_opl3_hwdep_new(cm->opl3, 0, 1, &cm->opl3hwdep)) < 0) {
-				printk(KERN_ERR "cmipci: cannot create OPL3 hwdep\n");
-				return err;
-			}
+	integrated_midi = snd_cmipci_read_b(cm, CM_REG_MPU_PCI) != 0xff;
+	if (integrated_midi)
+		iomidi = cm->iobase + CM_REG_MPU_PCI;
+	else {
+		iomidi = mpu_port[dev];
+		switch (iomidi) {
+		case 0x320: val = CM_VMPU_320; break;
+		case 0x310: val = CM_VMPU_310; break;
+		case 0x300: val = CM_VMPU_300; break;
+		case 0x330: val = CM_VMPU_330; break;
+		default:
+			    iomidi = 0; break;
+		}
+		if (iomidi > 0) {
+			snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val);
+			/* enable UART */
+			snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_UART_EN);
 		}
 	}
-	if (! iosynth) {
-		/* disable FM */
-		snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val & ~CM_FMSEL_MASK);
-		snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
-	}
+
+	if ((err = snd_cmipci_create_fm(cm, fm_port[dev])) < 0)
+		return err;
 
 	/* reset mixer */
 	snd_cmipci_mixer_write(cm, 0, 0);
@@ -2941,7 +2957,7 @@
 
 	if (iomidi > 0) {
 		if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI,
-					       iomidi, 0,
+					       iomidi, integrated_midi,
 					       cm->irq, 0, &cm->rmidi)) < 0) {
 			printk(KERN_ERR "cmipci: no UART401 device at 0x%lx\n", iomidi);
 		}
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index dc87e01..aea2c47 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -523,8 +523,7 @@
 			delay = 1;
 		end_time = jiffies + delay;
 		do {
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
+			schedule_timeout_uninterruptible(1);
 		} while (time_after_eq(end_time, jiffies));
 	} else {
 		udelay(delay);
@@ -533,8 +532,7 @@
 
 static inline void snd_cs4281_delay_long(void)
 {
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(1);
+	schedule_timeout_uninterruptible(1);
 }
 
 static inline void snd_cs4281_pokeBA0(cs4281_t *chip, unsigned long offset, unsigned int val)
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 6e3855b..9b8af5b 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -163,7 +163,7 @@
 			goto ok1;
 	}
 
-	snd_printk("AC'97 read problem (ACCTL_DCV), reg = 0x%x\n", reg);
+	snd_printk(KERN_ERR "AC'97 read problem (ACCTL_DCV), reg = 0x%x\n", reg);
 	result = 0xffff;
 	goto end;
 	
@@ -182,7 +182,7 @@
 		udelay(10);
 	}
 	
-	snd_printk("AC'97 read problem (ACSTS_VSTS), codec_index %d, reg = 0x%x\n", codec_index, reg);
+	snd_printk(KERN_ERR "AC'97 read problem (ACSTS_VSTS), codec_index %d, reg = 0x%x\n", codec_index, reg);
 	result = 0xffff;
 	goto end;
 
@@ -281,7 +281,7 @@
 			goto end;
 		}
 	}
-	snd_printk("AC'97 write problem, codec_index = %d, reg = 0x%x, val = 0x%x\n", codec_index, reg, val);
+	snd_printk(KERN_ERR "AC'97 write problem, codec_index = %d, reg = 0x%x, val = 0x%x\n", codec_index, reg, val);
  end:
 	chip->active_ctrl(chip, -1);
 }
@@ -510,7 +510,7 @@
 	}
 
 	if (snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR)
-		snd_printk("SPCR_RUNFR never reset\n");
+		snd_printk(KERN_ERR "SPCR_RUNFR never reset\n");
 }
 
 static void snd_cs46xx_proc_stop(cs46xx_t *chip)
@@ -2403,7 +2403,7 @@
 		msleep(10);
 	} while (time_after_eq(end_time, jiffies));
 
-	snd_printk("CS46xx secondary codec dont respond!\n");  
+	snd_printk(KERN_ERR "CS46xx secondary codec doesn't respond!\n");  
 }
 #endif
 
@@ -2906,10 +2906,7 @@
 		snd_cs46xx_region_t *region = &chip->region.idx[idx];
 		if (region->remap_addr)
 			iounmap(region->remap_addr);
-		if (region->resource) {
-			release_resource(region->resource);
-			kfree_nocheck(region->resource);
-		}
+		release_and_free_resource(region->resource);
 	}
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *)chip);
@@ -3075,8 +3072,8 @@
 	}
 
 
-	snd_printk("create - never read codec ready from AC'97\n");
-	snd_printk("it is not probably bug, try to use CS4236 driver\n");
+	snd_printk(KERN_ERR "create - never read codec ready from AC'97\n");
+	snd_printk(KERN_ERR "it is not probably bug, try to use CS4236 driver\n");
 	return -EIO;
  ok1:
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
@@ -3124,17 +3121,17 @@
 	}
 
 #ifndef CONFIG_SND_CS46XX_NEW_DSP
-	snd_printk("create - never read ISV3 & ISV4 from AC'97\n");
+	snd_printk(KERN_ERR "create - never read ISV3 & ISV4 from AC'97\n");
 	return -EIO;
 #else
 	/* This may happen on a cold boot with a Terratec SiXPack 5.1.
 	   Reloading the driver may help, if there's other soundcards 
 	   with the same problem I would like to know. (Benny) */
 
-	snd_printk("ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n");
-	snd_printk("       Try reloading the ALSA driver, if you find something\n");
-        snd_printk("       broken or not working on your soundcard upon\n");
-	snd_printk("       this message please report to alsa-devel@lists.sourceforge.net\n");
+	snd_printk(KERN_ERR "ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n");
+	snd_printk(KERN_ERR "       Try reloading the ALSA driver, if you find something\n");
+        snd_printk(KERN_ERR "       broken or not working on your soundcard upon\n");
+	snd_printk(KERN_ERR "       this message please report to alsa-devel@lists.sourceforge.net\n");
 
 	return -EIO;
 #endif
@@ -3215,7 +3212,7 @@
 #else
 	/* old image */
 	if (snd_cs46xx_download_image(chip) < 0) {
-		snd_printk("image download error\n");
+		snd_printk(KERN_ERR "image download error\n");
 		return -EIO;
 	}
 
@@ -3790,7 +3787,7 @@
 	chip->ba1_addr = pci_resource_start(pci, 1);
 	if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 ||
 	    chip->ba1_addr == 0 || chip->ba1_addr == (unsigned long)~0) {
-	    	snd_printk("wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n", chip->ba0_addr, chip->ba1_addr);
+	    	snd_printk(KERN_ERR "wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n", chip->ba0_addr, chip->ba1_addr);
 	    	snd_cs46xx_free(chip);
 	    	return -ENOMEM;
 	}
@@ -3839,12 +3836,12 @@
 	}
 
 	if (external_amp) {
-		snd_printk("Crystal EAPD support forced on.\n");
+		snd_printk(KERN_INFO "Crystal EAPD support forced on.\n");
 		chip->amplifier_ctrl = amp_voyetra;
 	}
 
 	if (thinkpad) {
-		snd_printk("Activating CLKRUN hack for Thinkpad.\n");
+		snd_printk(KERN_INFO "Activating CLKRUN hack for Thinkpad.\n");
 		chip->active_ctrl = clkrun_hack;
 		clkrun_init(chip);
 	}
@@ -3861,20 +3858,20 @@
 	for (idx = 0; idx < 5; idx++) {
 		region = &chip->region.idx[idx];
 		if ((region->resource = request_mem_region(region->base, region->size, region->name)) == NULL) {
-			snd_printk("unable to request memory region 0x%lx-0x%lx\n", region->base, region->base + region->size - 1);
+			snd_printk(KERN_ERR "unable to request memory region 0x%lx-0x%lx\n", region->base, region->base + region->size - 1);
 			snd_cs46xx_free(chip);
 			return -EBUSY;
 		}
 		region->remap_addr = ioremap_nocache(region->base, region->size);
 		if (region->remap_addr == NULL) {
-			snd_printk("%s ioremap problem\n", region->name);
+			snd_printk(KERN_ERR "%s ioremap problem\n", region->name);
 			snd_cs46xx_free(chip);
 			return -ENOMEM;
 		}
 	}
 
 	if (request_irq(pci->irq, snd_cs46xx_interrupt, SA_INTERRUPT|SA_SHIRQ, "CS46XX", (void *) chip)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_cs46xx_free(chip);
 		return -EBUSY;
 	}
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index b0e00f0..dd1ea9d 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -188,7 +188,7 @@
 	if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH,
 			       sizeof(snd_emu10k1_synth_arg_t), &wave) < 0 ||
 	    wave == NULL) {
-		snd_printk("can't initialize Emu10k1 wavetable synth\n");
+		snd_printk(KERN_WARNING "can't initialize Emu10k1 wavetable synth\n");
 	} else {
 		snd_emu10k1_synth_arg_t *arg;
 		arg = SNDRV_SEQ_DEVICE_ARGPTR(wave);
diff --git a/sound/pci/emu10k1/emu10k1_callback.c b/sound/pci/emu10k1/emu10k1_callback.c
index 7cf2f90..6589bf2 100644
--- a/sound/pci/emu10k1/emu10k1_callback.c
+++ b/sound/pci/emu10k1/emu10k1_callback.c
@@ -241,7 +241,7 @@
 		else if (state == SNDRV_EMUX_ST_RELEASED ||
 			 state == SNDRV_EMUX_ST_PENDING) {
 			bp = best + V_RELEASED;
-#if 0
+#if 1
 			val = snd_emu10k1_ptr_read(hw, CVCF_CURRENTVOL, vp->ch);
 			if (! val)
 				bp = best + V_OFF;
@@ -349,7 +349,7 @@
 	}
 
 	/* channel to be silent and idle */
-	snd_emu10k1_ptr_write(hw, DCYSUSV, ch, 0x0080);
+	snd_emu10k1_ptr_write(hw, DCYSUSV, ch, 0x0000);
 	snd_emu10k1_ptr_write(hw, VTFT, ch, 0x0000FFFF);
 	snd_emu10k1_ptr_write(hw, CVCF, ch, 0x0000FFFF);
 	snd_emu10k1_ptr_write(hw, PTRX, ch, 0);
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index ad15755..cbb6894 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -759,10 +759,8 @@
 	outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG);
 
 	// release the i/o port
-	if (chip->res_port) {
-		release_resource(chip->res_port);
-		kfree_nocheck(chip->res_port);
-	}
+	release_and_free_resource(chip->res_port);
+
 	// release the irq
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *)chip);
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index 646b5d9..03e8c16 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -364,12 +364,18 @@
 			snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, db_table[val]);
 			break;
 		case EMU10K1_GPR_TRANSLATION_BASS:
-			snd_runtime_check((ctl->count % 5) == 0 && (ctl->count / 5) == ctl->vcount, change = -EIO; goto __error);
+			if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
+				change = -EIO;
+				goto __error;
+			}
 			for (j = 0; j < 5; j++)
 				snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, bass_table[val][j]);
 			break;
 		case EMU10K1_GPR_TRANSLATION_TREBLE:
-			snd_runtime_check((ctl->count % 5) == 0 && (ctl->count / 5) == ctl->vcount, change = -EIO; goto __error);
+			if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
+				change = -EIO;
+				goto __error;
+			}
 			for (j = 0; j < 5; j++)
 				snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, treble_table[val][j]);
 			break;
@@ -412,8 +418,6 @@
 	snd_emu10k1_fx8010_irq_t *irq;
 	unsigned long flags;
 	
-	snd_runtime_check(emu, return -EINVAL);
-	snd_runtime_check(handler, return -EINVAL);
 	irq = kmalloc(sizeof(*irq), GFP_ATOMIC);
 	if (irq == NULL)
 		return -ENOMEM;
@@ -442,7 +446,6 @@
 	snd_emu10k1_fx8010_irq_t *tmp;
 	unsigned long flags;
 	
-	snd_runtime_check(irq, return -EINVAL);
 	spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
 	if ((tmp = emu->fx8010.irq_handlers) == irq) {
 		emu->fx8010.irq_handlers = tmp->next;
@@ -717,9 +720,15 @@
 			err = -EFAULT;
 			goto __error;
 		}
-		snd_runtime_check(gctl->id.iface == SNDRV_CTL_ELEM_IFACE_MIXER ||
-		                  gctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM, err = -EINVAL; goto __error);
-		snd_runtime_check(gctl->id.name[0] != '\0', err = -EINVAL; goto __error);
+		if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
+		    gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
+			err = -EINVAL;
+			goto __error;
+		}
+		if (! gctl->id.name[0]) {
+			err = -EINVAL;
+			goto __error;
+		}
 		ctl = snd_emu10k1_look_for_ctl(emu, &gctl->id);
 		memset(&knew, 0, sizeof(knew));
 		knew.iface = gctl->id.iface;
@@ -783,7 +792,8 @@
 	
 	for (i = 0, _id = icode->gpr_del_controls;
 	     i < icode->gpr_del_control_count; i++, _id++) {
-	     	snd_runtime_check(copy_from_user(&id, _id, sizeof(id)) == 0, return -EFAULT);
+	     	if (copy_from_user(&id, _id, sizeof(id)))
+			return -EFAULT;
 		down_write(&card->controls_rwsem);
 		ctl = snd_emu10k1_look_for_ctl(emu, &id);
 		if (ctl)
@@ -964,8 +974,8 @@
 	return err;
 }
 
-#define SND_EMU10K1_GPR_CONTROLS	41
-#define SND_EMU10K1_INPUTS		10
+#define SND_EMU10K1_GPR_CONTROLS	44
+#define SND_EMU10K1_INPUTS		12
 #define SND_EMU10K1_PLAYBACK_CHANNELS	8
 #define SND_EMU10K1_CAPTURE_CHANNELS	4
 
@@ -1382,7 +1392,7 @@
 		A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
 		if ((z==1) && (emu->card_capabilities->spdif_bug)) {
 			/* Due to a SPDIF output bug on some Audigy cards, this code delays the Right channel by 1 sample */
-			snd_printk("Installing spdif_bug patch: %s\n", emu->card_capabilities->name);
+			snd_printk(KERN_INFO "Installing spdif_bug patch: %s\n", emu->card_capabilities->name);
 			A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(gpr - 3), A_C_00000000, A_C_00000000);
 			A_OP(icode, &ptr, iACC3, A_GPR(gpr - 3), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
 		} else {
@@ -1527,7 +1537,7 @@
 
 	strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
 	ptr = 0; i = 0;
-	/* we have 10 inputs */
+	/* we have 12 inputs */
 	playback = SND_EMU10K1_INPUTS;
 	/* we have 6 playback channels and tone control doubles */
 	capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
@@ -1551,6 +1561,8 @@
 	OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
 	OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000);	/* S/PDIF left */
 	OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000);	/* S/PDIF right */
+	OP(icode, &ptr, iMACINT0, GPR(10), C_00000000, FXBUS(FXBUS_PCM_LEFT_FRONT), C_00000004);
+	OP(icode, &ptr, iMACINT0, GPR(11), C_00000000, FXBUS(FXBUS_PCM_RIGHT_FRONT), C_00000004);
 
 	/* Raw S/PDIF PCM */
 	ipcm->substream = 0;
@@ -1697,6 +1709,21 @@
 	VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
 	snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
 
+	/* Front Playback Volume */
+	for (z = 0; z < 2; z++)
+		VOLUME_ADD(icode, &ptr, playback + z, 10 + z, gpr + z);
+	snd_emu10k1_init_stereo_control(controls + i++, "Front Playback Volume", gpr, 100);
+	gpr += 2;
+
+	/* Front Capture Volume + Switch */
+	for (z = 0; z < 2; z++) {
+		SWITCH(icode, &ptr, tmp + 0, 10 + z, gpr + 2);
+		VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
+	}
+	snd_emu10k1_init_stereo_control(controls + i++, "Front Capture Volume", gpr, 0);
+	snd_emu10k1_init_mono_onoff_control(controls + i++, "Front Capture Switch", gpr + 2, 0);
+	gpr += 3;
+
 	/*
 	 *  Process inputs
 	 */
@@ -2058,14 +2085,16 @@
 #if 0 // FIXME: who use them?
 int snd_emu10k1_fx8010_tone_control_activate(emu10k1_t *emu, int output)
 {
-	snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
+	if (output < 0 || output >= 6)
+		return -EINVAL;
 	snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
 	return 0;
 }
 
 int snd_emu10k1_fx8010_tone_control_deactivate(emu10k1_t *emu, int output)
 {
-	snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
+	if (output < 0 || output >= 6)
+		return -EINVAL;
 	snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
 	return 0;
 }
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 66ba27a..bf7490d 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -965,7 +965,8 @@
 {
 	snd_ctl_elem_id_t id;
 
-	snd_runtime_check(kctl != NULL, return);
+	if (! kctl)
+		return;
 	if (activate)
 		kctl->vd[idx].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
 	else
diff --git a/sound/pci/emu10k1/irq.c b/sound/pci/emu10k1/irq.c
index cd8460d..594ea06 100644
--- a/sound/pci/emu10k1/irq.c
+++ b/sound/pci/emu10k1/irq.c
@@ -41,7 +41,7 @@
 		orig_status = status;
 		handled = 1;
 		if (status & IPR_PCIERROR) {
-			snd_printk("interrupt: PCI error\n");
+			snd_printk(KERN_ERR "interrupt: PCI error\n");
 			snd_emu10k1_intr_disable(emu, INTE_PCIERRORENABLE);
 			status &= ~IPR_PCIERROR;
 		}
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index 6afeaea..d42e4ae 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -232,11 +232,11 @@
 static int is_valid_page(emu10k1_t *emu, dma_addr_t addr)
 {
 	if (addr & ~emu->dma_mask) {
-		snd_printk("max memory size is 0x%lx (addr = 0x%lx)!!\n", emu->dma_mask, (unsigned long)addr);
+		snd_printk(KERN_ERR "max memory size is 0x%lx (addr = 0x%lx)!!\n", emu->dma_mask, (unsigned long)addr);
 		return 0;
 	}
 	if (addr & (EMUPAGESIZE-1)) {
-		snd_printk("page is not aligned\n");
+		snd_printk(KERN_ERR "page is not aligned\n");
 		return 0;
 	}
 	return 1;
@@ -501,7 +501,7 @@
 	snd_assert(page >= 0 && page < emu->max_cache_pages, return NULL);
 	ptr = emu->page_ptr_table[page];
 	if (! ptr) {
-		printk("emu10k1: access to NULL ptr: page = %d\n", page);
+		printk(KERN_ERR "emu10k1: access to NULL ptr: page = %d\n", page);
 		return NULL;
 	}
 	ptr += offset & (PAGE_SIZE - 1);
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
index d59c7f3..e27ebb9 100644
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -546,7 +546,7 @@
 	ptr=ptr2;
 	if (ptr >= runtime->buffer_size) {
 		ptr -= runtime->buffer_size;
-		printk("buffer capture limited!\n");
+		printk(KERN_WARNING "buffer capture limited!\n");
 	}
 	//printk("ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n", ptr1, ptr2, ptr, (int)runtime->buffer_size, (int)runtime->period_size, (int)runtime->frame_bits, (int)runtime->rate);
 
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index bef9a59..92ff7c5 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -508,7 +508,7 @@
 			return r;
 		cond_resched();
 	}
-	snd_printk("wait source ready timeout 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_SMPRATE), r);
+	snd_printk(KERN_ERR "wait source ready timeout 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_SMPRATE), r);
 	return 0;
 }
 
@@ -576,10 +576,9 @@
 			outw(ES_1370_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1370_CODEC));
 			return;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	} while (time_after(end_time, jiffies));
-	snd_printk("codec write timeout, status = 0x%x\n", inl(ES_REG(ensoniq, STATUS)));
+	snd_printk(KERN_ERR "codec write timeout, status = 0x%x\n", inl(ES_REG(ensoniq, STATUS)));
 }
 
 #endif /* CHIP1370 */
@@ -620,7 +619,7 @@
 		}
 	}
 	up(&ensoniq->src_mutex);
-	snd_printk("codec write timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
+	snd_printk(KERN_ERR "codec write timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
 }
 
 static unsigned short snd_es1371_codec_read(ac97_t *ac97,
@@ -667,14 +666,14 @@
 			}
 			up(&ensoniq->src_mutex);
 			if (++fail > 10) {
-				snd_printk("codec read timeout (final) at 0x%lx, reg = 0x%x [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), reg, inl(ES_REG(ensoniq, 1371_CODEC)));
+				snd_printk(KERN_ERR "codec read timeout (final) at 0x%lx, reg = 0x%x [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), reg, inl(ES_REG(ensoniq, 1371_CODEC)));
 				return 0;
 			}
 			goto __again;
 		}
 	}
 	up(&ensoniq->src_mutex);
-	snd_printk("es1371: codec read timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
+	snd_printk(KERN_ERR "es1371: codec read timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
 	return 0;
 }
 
@@ -1960,7 +1959,7 @@
 	}
 	ensoniq->port = pci_resource_start(pci, 0);
 	if (request_irq(pci->irq, snd_audiopci_interrupt, SA_INTERRUPT|SA_SHIRQ, "Ensoniq AudioPCI", (void *)ensoniq)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_ensoniq_free(ensoniq);
 		return -EBUSY;
 	}
@@ -1968,7 +1967,7 @@
 #ifdef CHIP1370
 	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
 				16, &ensoniq->dma_bug) < 0) {
-		snd_printk("unable to allocate space for phantom area - dma_bug\n");
+		snd_printk(KERN_ERR "unable to allocate space for phantom area - dma_bug\n");
 		snd_ensoniq_free(ensoniq);
 		return -EBUSY;
 	}
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 17fa80c..78f90de 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -267,7 +267,7 @@
 	outb(val, SLSB_REG(chip, MIXERDATA));
 	spin_unlock_irqrestore(&chip->mixer_lock, flags);
 #ifdef REG_DEBUG
-	snd_printk("Mixer reg %02x set to %02x\n", reg, val);
+	snd_printk(KERN_DEBUG "Mixer reg %02x set to %02x\n", reg, val);
 #endif
 }
 
@@ -283,7 +283,7 @@
 	data = inb(SLSB_REG(chip, MIXERDATA));
 	spin_unlock_irqrestore(&chip->mixer_lock, flags);
 #ifdef REG_DEBUG
-	snd_printk("Mixer reg %02x now is %02x\n", reg, data);
+	snd_printk(KERN_DEBUG "Mixer reg %02x now is %02x\n", reg, data);
 #endif
 	return data;
 }
@@ -303,7 +303,8 @@
 		new = (old & ~mask) | (val & mask);
 		outb(new, SLSB_REG(chip, MIXERDATA));
 #ifdef REG_DEBUG
-		snd_printk("Mixer reg %02x was %02x, set to %02x\n", reg, old, new);
+		snd_printk(KERN_DEBUG "Mixer reg %02x was %02x, set to %02x\n",
+			   reg, old, new);
 #endif
 	}
 	spin_unlock_irqrestore(&chip->mixer_lock, flags);
@@ -323,7 +324,7 @@
 			return;
 		}
 	}
-	printk("snd_es1938_write_cmd timeout (0x02%x/0x02%x)\n", cmd, v);
+	printk(KERN_ERR "snd_es1938_write_cmd timeout (0x02%x/0x02%x)\n", cmd, v);
 }
 
 /* -----------------------------------------------------------------
@@ -336,7 +337,7 @@
 	for (i = GET_LOOP_TIMEOUT; i; i--)
 		if ((v = inb(SLSB_REG(chip, STATUS))) & 0x80)
 			return inb(SLSB_REG(chip, READDATA));
-	snd_printk("get_byte timeout: status 0x02%x\n", v);
+	snd_printk(KERN_ERR "get_byte timeout: status 0x02%x\n", v);
 	return -ENODEV;
 }
 
@@ -351,7 +352,7 @@
 	snd_es1938_write_cmd(chip, val);
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 #ifdef REG_DEBUG
-	snd_printk("Reg %02x set to %02x\n", reg, val);
+	snd_printk(KERN_DEBUG "Reg %02x set to %02x\n", reg, val);
 #endif
 }
 
@@ -368,7 +369,7 @@
 	val = snd_es1938_get_byte(chip);
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 #ifdef REG_DEBUG
-	snd_printk("Reg %02x now is %02x\n", reg, val);
+	snd_printk(KERN_DEBUG "Reg %02x now is %02x\n", reg, val);
 #endif
 	return val;
 }
@@ -390,7 +391,8 @@
 		new = (old & ~mask) | (val & mask);
 		snd_es1938_write_cmd(chip, new);
 #ifdef REG_DEBUG
-		snd_printk("Reg %02x was %02x, set to %02x\n", reg, old, new);
+		snd_printk(KERN_DEBUG "Reg %02x was %02x, set to %02x\n",
+			   reg, old, new);
 #endif
 	}
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
@@ -413,7 +415,7 @@
 				goto __next;
 		}
 	}
-	snd_printk("ESS Solo-1 reset failed\n");
+	snd_printk(KERN_ERR "ESS Solo-1 reset failed\n");
 
      __next:
 	snd_es1938_write_cmd(chip, ESS_CMD_ENABLEEXT);
@@ -543,10 +545,12 @@
 	int val;
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
 		val = 0x0f;
 		chip->active |= ADC1;
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
 		val = 0x00;
 		chip->active &= ~ADC1;
 		break;
@@ -563,6 +567,7 @@
 	es1938_t *chip = snd_pcm_substream_chip(substream);
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
 		/* According to the documentation this should be:
 		   0x13 but that value may randomly swap stereo channels */
                 snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0x92);
@@ -575,6 +580,7 @@
 		chip->active |= DAC2;
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
 		outb(0, SLIO_REG(chip, AUDIO2MODE));
 		snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0);
 		chip->active &= ~DAC2;
@@ -592,10 +598,12 @@
 	int val;
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
 		val = 5;
 		chip->active |= DAC1;
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
 		val = 0;
 		chip->active &= ~DAC1;
 		break;
@@ -1390,7 +1398,8 @@
 		*d = snd_es1938_reg_read(chip, *s);
 
 	outb(0x00, SLIO_REG(chip, IRQCONTROL)); /* disable irqs */
-
+	if (chip->irq >= 0)
+		free_irq(chip->irq, (void *)chip);  
 	pci_disable_device(chip->pci);
 	return 0;
 }
@@ -1401,6 +1410,9 @@
 	unsigned char *s, *d;
 
 	pci_enable_device(chip->pci);
+	request_irq(chip->pci->irq, snd_es1938_interrupt,
+		    SA_INTERRUPT|SA_SHIRQ, "ES1938", (void *)chip);
+	chip->irq = chip->pci->irq;
 	snd_es1938_chip_init(chip);
 
 	/* restore mixer-related registers */
@@ -1489,7 +1501,7 @@
         /* check, if we can restrict PCI DMA transfers to 24 bits */
 	if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
 	    pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
-                snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
+		snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
 		pci_disable_device(pci);
                 return -ENXIO;
         }
@@ -1514,13 +1526,13 @@
 	chip->mpu_port = pci_resource_start(pci, 3);
 	chip->game_port = pci_resource_start(pci, 4);
 	if (request_irq(pci->irq, snd_es1938_interrupt, SA_INTERRUPT|SA_SHIRQ, "ES1938", (void *)chip)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_es1938_free(chip);
 		return -EBUSY;
 	}
 	chip->irq = pci->irq;
 #ifdef ES1938_DDEBUG
-	snd_printk("create: io: 0x%lx, sb: 0x%lx, vc: 0x%lx, mpu: 0x%lx, game: 0x%lx\n",
+	snd_printk(KERN_DEBUG "create: io: 0x%lx, sb: 0x%lx, vc: 0x%lx, mpu: 0x%lx, game: 0x%lx\n",
 		   chip->io_port, chip->sb_port, chip->vc_port, chip->mpu_port, chip->game_port);
 #endif
 
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index ecdcada..ac8294e 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -1462,13 +1462,13 @@
 						   snd_dma_pci_data(chip->pci),
 						   chip->total_bufsize, &chip->dma);
 		if (err < 0 || ! chip->dma.area) {
-			snd_printk("es1968: can't allocate dma pages for size %d\n",
+			snd_printk(KERN_ERR "es1968: can't allocate dma pages for size %d\n",
 				   chip->total_bufsize);
 			return -ENOMEM;
 		}
 		if ((chip->dma.addr + chip->dma.bytes - 1) & ~((1 << 28) - 1)) {
 			snd_dma_free_pages(&chip->dma);
-			snd_printk("es1968: DMA buffer beyond 256MB.\n");
+			snd_printk(KERN_ERR "es1968: DMA buffer beyond 256MB.\n");
 			return -ENOMEM;
 		}
 	}
@@ -1741,11 +1741,11 @@
 
 	/* search 2 APUs (although one apu is enough) */
 	if ((apu = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_PLAY)) < 0) {
-		snd_printk("Hmm, cannot find empty APU pair!?\n");
+		snd_printk(KERN_ERR "Hmm, cannot find empty APU pair!?\n");
 		return;
 	}
 	if ((memory = snd_es1968_new_memory(chip, CLOCK_MEASURE_BUFSIZE)) == NULL) {
-		snd_printk("cannot allocate dma buffer - using default clock %d\n", chip->clock);
+		snd_printk(KERN_ERR "cannot allocate dma buffer - using default clock %d\n", chip->clock);
 		snd_es1968_free_apu_pair(chip, apu);
 		return;
 	}
@@ -1806,7 +1806,7 @@
 	else
 		t += stop_time.tv_usec - start_time.tv_usec;
 	if (t == 0) {
-		snd_printk("?? calculation error..\n");
+		snd_printk(KERN_ERR "?? calculation error..\n");
 	} else {
 		offset *= 1000;
 		offset = (offset / t) * 1000 + ((offset % t) * 1000) / t;
@@ -2090,7 +2090,7 @@
 	outw(inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c);
 
 #if 0				/* the loop here needs to be much better if we want it.. */
-	snd_printk("trying software reset\n");
+	snd_printk(KERN_INFO "trying software reset\n");
 	/* try and do a software reset */
 	outb(0x80 | 0x7c, ioaddr + 0x30);
 	for (w = 0;; w++) {
@@ -2461,8 +2461,7 @@
 	chip->gameport = gp = gameport_allocate_port();
 	if (!gp) {
 		printk(KERN_ERR "es1968: cannot allocate memory for gameport\n");
-		release_resource(r);
-		kfree_nocheck(r);
+		release_and_free_resource(r);
 		return -ENOMEM;
 	}
 
@@ -2488,8 +2487,7 @@
 		gameport_unregister_port(chip->gameport);
 		chip->gameport = NULL;
 
-		release_resource(r);
-		kfree_nocheck(r);
+		release_and_free_resource(r);
 	}
 }
 #else
@@ -2564,7 +2562,7 @@
 	/* check, if we can restrict PCI DMA transfers to 28 bits */
 	if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
 	    pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
-		snd_printk("architecture does not support 28bit PCI busmaster DMA\n");
+		snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n");
 		pci_disable_device(pci);
 		return -ENXIO;
 	}
@@ -2599,7 +2597,7 @@
 	chip->io_port = pci_resource_start(pci, 0);
 	if (request_irq(pci->irq, snd_es1968_interrupt, SA_INTERRUPT|SA_SHIRQ,
 			"ESS Maestro", (void*)chip)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_es1968_free(chip);
 		return -EBUSY;
 	}
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index e5cfa2a..4c7c8d2 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -237,7 +237,7 @@
 			goto ok1;
 		udelay(10);
 	}
-	snd_printk("AC'97 interface is busy (1)\n");
+	snd_printk(KERN_ERR "AC'97 interface is busy (1)\n");
 	return;
 
  ok1:
@@ -252,7 +252,7 @@
 			return;
 		udelay(10);
 	}
-	snd_printk("AC'97 interface #%d is busy (2)\n", ac97->num);
+	snd_printk(KERN_ERR "AC'97 interface #%d is busy (2)\n", ac97->num);
 }
 
 static unsigned short snd_fm801_codec_read(ac97_t *ac97, unsigned short reg)
@@ -268,7 +268,7 @@
 			goto ok1;
 		udelay(10);
 	}
-	snd_printk("AC'97 interface is busy (1)\n");
+	snd_printk(KERN_ERR "AC'97 interface is busy (1)\n");
 	return 0;
 
  ok1:
@@ -279,7 +279,7 @@
 			goto ok2;
 		udelay(10);
 	}
-	snd_printk("AC'97 interface #%d is busy (2)\n", ac97->num);
+	snd_printk(KERN_ERR "AC'97 interface #%d is busy (2)\n", ac97->num);
 	return 0;
 
  ok2:
@@ -288,7 +288,7 @@
 			goto ok3;
 		udelay(10);
 	}
-	snd_printk("AC'97 interface #%d is not valid (2)\n", ac97->num);
+	snd_printk(KERN_ERR "AC'97 interface #%d is not valid (2)\n", ac97->num);
 	return 0;
 
  ok3:
@@ -1279,7 +1279,7 @@
 	}
 	chip->port = pci_resource_start(pci, 0);
 	if (request_irq(pci->irq, snd_fm801_interrupt, SA_INTERRUPT|SA_SHIRQ, "FM801", (void *)chip)) {
-		snd_printk("unable to grab IRQ %d\n", chip->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->irq);
 		snd_fm801_free(chip);
 		return -EBUSY;
 	}
@@ -1303,10 +1303,9 @@
 	do {
 		if ((inw(FM801_REG(chip, AC97_CMD)) & (3<<8)) == (1<<8))
 			goto __ac97_secondary;
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	} while (time_after(timeout, jiffies));
-	snd_printk("Primary AC'97 codec not found\n");
+	snd_printk(KERN_ERR "Primary AC'97 codec not found\n");
 	snd_fm801_free(chip);
 	return -EIO;
 
@@ -1329,8 +1328,7 @@
 					goto __ac97_ok;
 				}
 			}
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
+			schedule_timeout_uninterruptible(1);
 		} while (time_after(timeout, jiffies));
 	}
 
@@ -1343,10 +1341,9 @@
 	do {
 		if ((inw(FM801_REG(chip, AC97_CMD)) & (3<<8)) == (1<<8))
 			goto __ac97_ok;
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	} while (time_after(timeout, jiffies));
-	snd_printk("Primary AC'97 codec not responding\n");
+	snd_printk(KERN_ERR "Primary AC'97 codec not responding\n");
 	snd_fm801_free(chip);
 	return -EIO;
 
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 3815403..0dbeeaf 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -518,6 +518,13 @@
 		return -ENODEV;
 	}
 
+	if (! codec->subsystem_id) {
+		hda_nid_t nid = codec->afg ? codec->afg : codec->mfg;
+		codec->subsystem_id = snd_hda_codec_read(codec, nid, 0,
+							 AC_VERB_GET_SUBSYSTEM_ID,
+							 0);
+	}
+
 	codec->preset = find_codec_preset(codec);
 	if (! *bus->card->mixername)
 		snd_hda_get_codec_name(codec, bus->card->mixername,
@@ -814,6 +821,51 @@
 }
 
 /*
+ * bound volume controls
+ *
+ * bind multiple volumes (# indices, from 0)
+ */
+
+#define AMP_VAL_IDX_SHIFT	19
+#define AMP_VAL_IDX_MASK	(0x0f<<19)
+
+int snd_hda_mixer_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	unsigned long pval;
+	int err;
+
+	down(&codec->spdif_mutex); /* reuse spdif_mutex */
+	pval = kcontrol->private_value;
+	kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
+	err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
+	kcontrol->private_value = pval;
+	up(&codec->spdif_mutex);
+	return err;
+}
+
+int snd_hda_mixer_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	unsigned long pval;
+	int i, indices, err = 0, change = 0;
+
+	down(&codec->spdif_mutex); /* reuse spdif_mutex */
+	pval = kcontrol->private_value;
+	indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
+	for (i = 0; i < indices; i++) {
+		kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT);
+		err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
+		if (err < 0)
+			break;
+		change |= err;
+	}
+	kcontrol->private_value = pval;
+	up(&codec->spdif_mutex);
+	return err < 0 ? err : change;
+}
+
+/*
  * SPDIF out controls
  */
 
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index bb53bcf..1179d6c 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -79,6 +79,8 @@
 #define AC_VERB_GET_GPIO_MASK			0x0f16
 #define AC_VERB_GET_GPIO_DIRECTION		0x0f17
 #define AC_VERB_GET_CONFIG_DEFAULT		0x0f1c
+/* f20: AFG/MFG */
+#define AC_VERB_GET_SUBSYSTEM_ID		0x0f20
 
 /*
  * SET verbs
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 6fe696e..9d1412a 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -47,23 +47,24 @@
 #include "hda_codec.h"
 
 
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static char *model[SNDRV_CARDS];
-static int position_fix[SNDRV_CARDS];
+static int index = SNDRV_DEFAULT_IDX1;
+static char *id = SNDRV_DEFAULT_STR1;
+static char *model;
+static int position_fix;
 
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
 MODULE_PARM_DESC(id, "ID string for Intel HD audio interface.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Intel HD audio interface.");
-module_param_array(model, charp, NULL, 0444);
+module_param(model, charp, 0444);
 MODULE_PARM_DESC(model, "Use the given board model.");
-module_param_array(position_fix, int, NULL, 0444);
+module_param(position_fix, int, 0444);
 MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size).");
 
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
 			 "{Intel, ICH6M},"
@@ -223,6 +224,9 @@
 #define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR   0x42
 #define ATI_SB450_HDAUDIO_ENABLE_SNOOP      0x02
 
+/* Defines for Nvidia HDA support */
+#define NVIDIA_HDA_TRANSREG_ADDR      0x4e
+#define NVIDIA_HDA_ENABLE_COHBITS     0x0f
 
 /*
  * Use CORB/RIRB for communication from/to codecs.
@@ -328,6 +332,7 @@
 	AZX_DRIVER_VIA,
 	AZX_DRIVER_SIS,
 	AZX_DRIVER_ULI,
+	AZX_DRIVER_NVIDIA,
 };
 
 static char *driver_short_names[] __devinitdata = {
@@ -335,7 +340,8 @@
 	[AZX_DRIVER_ATI] = "HDA ATI SB",
 	[AZX_DRIVER_VIA] = "HDA VIA VT82xx",
 	[AZX_DRIVER_SIS] = "HDA SIS966",
-	[AZX_DRIVER_ULI] = "HDA ULI M5461"
+	[AZX_DRIVER_ULI] = "HDA ULI M5461",
+	[AZX_DRIVER_NVIDIA] = "HDA NVidia",
 };
 
 /*
@@ -710,14 +716,14 @@
  */
 static void azx_init_chip(azx_t *chip)
 {
-	unsigned char tcsel_reg, ati_misc_cntl2;
+	unsigned char reg;
 
 	/* Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
 	 * TCSEL == Traffic Class Select Register, which sets PCI express QOS
 	 * Ensuring these bits are 0 clears playback static on some HD Audio codecs
 	 */
-	pci_read_config_byte (chip->pci, ICH6_PCIREG_TCSEL, &tcsel_reg);
-	pci_write_config_byte(chip->pci, ICH6_PCIREG_TCSEL, tcsel_reg & 0xf8);
+	pci_read_config_byte (chip->pci, ICH6_PCIREG_TCSEL, &reg);
+	pci_write_config_byte(chip->pci, ICH6_PCIREG_TCSEL, reg & 0xf8);
 
 	/* reset controller */
 	azx_reset(chip);
@@ -733,13 +739,21 @@
 	azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
 	azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr));
 
-	/* For ATI SB450 azalia HD audio, we need to enable snoop */
-	if (chip->driver_type == AZX_DRIVER_ATI) {
+	switch (chip->driver_type) {
+	case AZX_DRIVER_ATI:
+		/* For ATI SB450 azalia HD audio, we need to enable snoop */
 		pci_read_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 
-				     &ati_misc_cntl2);
+				     &reg);
 		pci_write_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 
-				      (ati_misc_cntl2 & 0xf8) | ATI_SB450_HDAUDIO_ENABLE_SNOOP);
-	}
+				      (reg & 0xf8) | ATI_SB450_HDAUDIO_ENABLE_SNOOP);
+		break;
+	case AZX_DRIVER_NVIDIA:
+		/* For NVIDIA HDA, enable snoop */
+		pci_read_config_byte(chip->pci,NVIDIA_HDA_TRANSREG_ADDR, &reg);
+		pci_write_config_byte(chip->pci,NVIDIA_HDA_TRANSREG_ADDR,
+				      (reg & 0xf0) | NVIDIA_HDA_ENABLE_COHBITS);
+		break;
+        }
 }
 
 
@@ -1264,6 +1278,7 @@
 			err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev);
 			if (err < 0)
 				return err;
+			chip->pcm[pcm_dev]->dev_class = SNDRV_PCM_CLASS_MODEM;
 			pcm_dev++;
 		}
 	}
@@ -1530,32 +1545,24 @@
 
 static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 {
-	static int dev;
 	snd_card_t *card;
 	azx_t *chip;
 	int err = 0;
 
-	if (dev >= SNDRV_CARDS)
-		return -ENODEV;
-	if (! enable[dev]) {
-		dev++;
-		return -ENOENT;
-	}
-
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	card = snd_card_new(index, id, THIS_MODULE, 0);
 	if (NULL == card) {
 		snd_printk(KERN_ERR SFX "Error creating card!\n");
 		return -ENOMEM;
 	}
 
-	if ((err = azx_create(card, pci, position_fix[dev], pci_id->driver_data,
+	if ((err = azx_create(card, pci, position_fix, pci_id->driver_data,
 			      &chip)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
 
 	/* create codec instances */
-	if ((err = azx_codec_create(chip, model[dev])) < 0) {
+	if ((err = azx_codec_create(chip, model)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
@@ -1581,7 +1588,6 @@
 	}
 
 	pci_set_drvdata(pci, card);
-	dev++;
 
 	return err;
 }
@@ -1601,6 +1607,8 @@
 	{ 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 */
 	{ 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */
+	{ 0x10de, 0x026c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 026c */
+	{ 0x10de, 0x0371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 0371 */
 	{ 0, }
 };
 MODULE_DEVICE_TABLE(pci, azx_ids);
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 810cfd2..f51a56f 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -27,28 +27,36 @@
  * for mixer controls
  */
 #define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19))
+/* mono volume with index (index=0,1,...) (channel=1,2) */
 #define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx,  \
 	  .info = snd_hda_mixer_amp_volume_info, \
 	  .get = snd_hda_mixer_amp_volume_get, \
 	  .put = snd_hda_mixer_amp_volume_put, \
 	  .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
+/* stereo volume with index */
 #define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \
 	HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction)
+/* mono volume */
 #define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \
 	HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, channel, xindex, direction)
+/* stereo volume */
 #define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \
 	HDA_CODEC_VOLUME_MONO(xname, nid, 3, xindex, direction)
+/* mono mute switch with index (index=0,1,...) (channel=1,2) */
 #define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
 	  .info = snd_hda_mixer_amp_switch_info, \
 	  .get = snd_hda_mixer_amp_switch_get, \
 	  .put = snd_hda_mixer_amp_switch_put, \
 	  .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
+/* stereo mute switch with index */
 #define HDA_CODEC_MUTE_IDX(xname, xcidx, nid, xindex, direction) \
 	HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, 3, xindex, direction)
+/* mono mute switch */
 #define HDA_CODEC_MUTE_MONO(xname, nid, channel, xindex, direction) \
 	HDA_CODEC_MUTE_MONO_IDX(xname, 0, nid, channel, xindex, direction)
+/* stereo mute switch */
 #define HDA_CODEC_MUTE(xname, nid, xindex, direction) \
 	HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction)
 
@@ -59,6 +67,20 @@
 int snd_hda_mixer_amp_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
 int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
 
+/* mono switch binding multiple inputs */
+#define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \
+	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
+	  .info = snd_hda_mixer_amp_switch_info, \
+	  .get = snd_hda_mixer_bind_switch_get, \
+	  .put = snd_hda_mixer_bind_switch_put, \
+	  .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) }
+
+/* stereo switch binding multiple inputs */
+#define HDA_BIND_MUTE(xname,nid,indices,dir) HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir)
+
+int snd_hda_mixer_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
+int snd_hda_mixer_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
+
 int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid);
 int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid);
 
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 08f6a6e..39ddf1c 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -281,6 +281,11 @@
 			print_pcm_caps(buffer, codec, nid);
 		}
 
+		if (wid_caps & AC_WCAP_POWER)
+			snd_iprintf(buffer, "  Power: 0x%x\n",
+				    snd_hda_codec_read(codec, nid, 0,
+						       AC_VERB_GET_POWER_STATE, 0));
+
 		if (wid_caps & AC_WCAP_CONN_LIST) {
 			int c, curr = -1;
 			if (conn_len > 1 && wid_type != AC_WID_AUD_MIX)
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index da6874d..d7d636d 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -28,15 +28,38 @@
 #include "hda_local.h"
 
 struct ad198x_spec {
-	struct semaphore amp_mutex;	/* PCM volume/mute control mutex */
-	struct hda_multi_out multiout;	/* playback */
-	hda_nid_t adc_nid;
+	snd_kcontrol_new_t *mixers[5];
+	int num_mixers;
+
+	const struct hda_verb *init_verbs[3];	/* initialization verbs
+						 * don't forget NULL termination!
+						 */
+	unsigned int num_init_verbs;
+
+	/* playback */
+	struct hda_multi_out multiout;	/* playback set-up
+					 * max_channels, dacs must be set
+					 * dig_out_nid and hp_nid are optional
+					 */
+
+	/* capture */
+	unsigned int num_adc_nids;
+	hda_nid_t *adc_nids;
+	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
+
+	/* capture source */
 	const struct hda_input_mux *input_mux;
-	unsigned int cur_mux;		/* capture source */
+	unsigned int cur_mux[3];
+
+	/* channel model */
+	const struct alc_channel_mode *channel_mode;
+	int num_channel_mode;
+
+	/* PCM information */
+	struct hda_pcm pcm_rec[2];	/* used in alc_build_pcms() */
+
+	struct semaphore amp_mutex;	/* PCM volume/mute control mutex */
 	unsigned int spdif_route;
-	snd_kcontrol_new_t *mixers;
-	const struct hda_verb *init_verbs;
-	struct hda_pcm pcm_rec[2];	/* PCM information */
 };
 
 /*
@@ -54,8 +77,9 @@
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct ad198x_spec *spec = codec->spec;
+	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 
-	ucontrol->value.enumerated.item[0] = spec->cur_mux;
+	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
 	return 0;
 }
 
@@ -63,9 +87,10 @@
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct ad198x_spec *spec = codec->spec;
+	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 
 	return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
-				     spec->adc_nid, &spec->cur_mux);
+				     spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]);
 }
 
 /*
@@ -74,22 +99,34 @@
 static int ad198x_init(struct hda_codec *codec)
 {
 	struct ad198x_spec *spec = codec->spec;
-	snd_hda_sequence_write(codec, spec->init_verbs);
+	int i;
+
+	for (i = 0; i < spec->num_init_verbs; i++)
+		snd_hda_sequence_write(codec, spec->init_verbs[i]);
 	return 0;
 }
 
 static int ad198x_build_controls(struct hda_codec *codec)
 {
 	struct ad198x_spec *spec = codec->spec;
+	unsigned int i;
 	int err;
 
-	err = snd_hda_add_new_ctls(codec, spec->mixers);
-	if (err < 0)
-		return err;
-	if (spec->multiout.dig_out_nid)
+	for (i = 0; i < spec->num_mixers; i++) {
+		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
+		if (err < 0)
+			return err;
+	}
+	if (spec->multiout.dig_out_nid) {
 		err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
-	if (err < 0)
-		return err;
+		if (err < 0)
+			return err;
+	} 
+	if (spec->dig_in_nid) {
+		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
+		if (err < 0)
+			return err;
+	}
 	return 0;
 }
 
@@ -152,7 +189,8 @@
 				      snd_pcm_substream_t *substream)
 {
 	struct ad198x_spec *spec = codec->spec;
-	snd_hda_codec_setup_stream(codec, spec->adc_nid, stream_tag, 0, format);
+	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
+				   stream_tag, 0, format);
 	return 0;
 }
 
@@ -161,7 +199,8 @@
 				      snd_pcm_substream_t *substream)
 {
 	struct ad198x_spec *spec = codec->spec;
-	snd_hda_codec_setup_stream(codec, spec->adc_nid, 0, 0, 0);
+	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
+				   0, 0, 0);
 	return 0;
 }
 
@@ -171,7 +210,7 @@
 static struct hda_pcm_stream ad198x_pcm_analog_playback = {
 	.substreams = 1,
 	.channels_min = 2,
-	.channels_max = 6,
+	.channels_max = 6, /* changed later */
 	.nid = 0, /* fill later */
 	.ops = {
 		.open = ad198x_playback_pcm_open,
@@ -181,7 +220,7 @@
 };
 
 static struct hda_pcm_stream ad198x_pcm_analog_capture = {
-	.substreams = 2,
+	.substreams = 1,
 	.channels_min = 2,
 	.channels_max = 2,
 	.nid = 0, /* fill later */
@@ -202,6 +241,13 @@
 	},
 };
 
+static struct hda_pcm_stream ad198x_pcm_digital_capture = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 2,
+	/* NID is set in alc_build_pcms */
+};
+
 static int ad198x_build_pcms(struct hda_codec *codec)
 {
 	struct ad198x_spec *spec = codec->spec;
@@ -215,7 +261,8 @@
 	info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels;
 	info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
 	info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture;
-	info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nid;
+	info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
+	info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
 
 	if (spec->multiout.dig_out_nid) {
 		info++;
@@ -223,6 +270,10 @@
 		info->name = "AD198x Digital";
 		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
 		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
+		if (spec->dig_in_nid) {
+			info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture;
+			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
+		}
 	}
 
 	return 0;
@@ -237,10 +288,15 @@
 static int ad198x_resume(struct hda_codec *codec)
 {
 	struct ad198x_spec *spec = codec->spec;
+	int i;
 
 	ad198x_init(codec);
-	snd_hda_resume_ctls(codec, spec->mixers);
-	snd_hda_resume_spdif_out(codec);
+	for (i = 0; i < spec->num_mixers; i++)
+		snd_hda_resume_ctls(codec, spec->mixers[i]);
+	if (spec->multiout.dig_out_nid)
+		snd_hda_resume_spdif_out(codec);
+	if (spec->dig_in_nid)
+		snd_hda_resume_spdif_in(codec);
 	return 0;
 }
 #endif
@@ -269,6 +325,7 @@
 static hda_nid_t ad1986a_dac_nids[3] = {
 	AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
 };
+static hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC };
 
 static struct hda_input_mux ad1986a_capture_source = {
 	.num_items = 7,
@@ -476,10 +533,13 @@
 	spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
 	spec->multiout.dac_nids = ad1986a_dac_nids;
 	spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
-	spec->adc_nid = AD1986A_ADC;
+	spec->num_adc_nids = 1;
+	spec->adc_nids = ad1986a_adc_nids;
 	spec->input_mux = &ad1986a_capture_source;
-	spec->mixers = ad1986a_mixers;
-	spec->init_verbs = ad1986a_init_verbs;
+	spec->num_mixers = 1;
+	spec->mixers[0] = ad1986a_mixers;
+	spec->num_init_verbs = 1;
+	spec->init_verbs[0] = ad1986a_init_verbs;
 
 	codec->patch_ops = ad198x_patch_ops;
 
@@ -495,6 +555,7 @@
 #define AD1983_ADC		0x04
 
 static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
+static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC };
 
 static struct hda_input_mux ad1983_capture_source = {
 	.num_items = 4,
@@ -619,6 +680,7 @@
 	{ } /* end */
 };
 
+
 static int patch_ad1983(struct hda_codec *codec)
 {
 	struct ad198x_spec *spec;
@@ -634,10 +696,13 @@
 	spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids);
 	spec->multiout.dac_nids = ad1983_dac_nids;
 	spec->multiout.dig_out_nid = AD1983_SPDIF_OUT;
-	spec->adc_nid = AD1983_ADC;
+	spec->num_adc_nids = 1;
+	spec->adc_nids = ad1983_adc_nids;
 	spec->input_mux = &ad1983_capture_source;
-	spec->mixers = ad1983_mixers;
-	spec->init_verbs = ad1983_init_verbs;
+	spec->num_mixers = 1;
+	spec->mixers[0] = ad1983_mixers;
+	spec->num_init_verbs = 1;
+	spec->init_verbs[0] = ad1983_init_verbs;
 	spec->spdif_route = 0;
 
 	codec->patch_ops = ad198x_patch_ops;
@@ -655,6 +720,7 @@
 #define AD1981_ADC		0x04
 
 static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
+static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC };
 
 /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
 static struct hda_input_mux ad1981_capture_source = {
@@ -775,10 +841,13 @@
 	spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
 	spec->multiout.dac_nids = ad1981_dac_nids;
 	spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
-	spec->adc_nid = AD1981_ADC;
+	spec->num_adc_nids = 1;
+	spec->adc_nids = ad1981_adc_nids;
 	spec->input_mux = &ad1981_capture_source;
-	spec->mixers = ad1981_mixers;
-	spec->init_verbs = ad1981_init_verbs;
+	spec->num_mixers = 1;
+	spec->mixers[0] = ad1981_mixers;
+	spec->num_init_verbs = 1;
+	spec->init_verbs[0] = ad1981_init_verbs;
 	spec->spdif_route = 0;
 
 	codec->patch_ops = ad198x_patch_ops;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 7327deb..cffb83f 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -57,6 +57,7 @@
 enum {
 	ALC260_BASIC,
 	ALC260_HP,
+	ALC260_FUJITSU_S702x,
 	ALC260_MODEL_LAST /* last tag */
 };
 
@@ -72,6 +73,7 @@
 #define PIN_VREF50	0x21
 #define PIN_OUT		0x40
 #define PIN_HP		0xc0
+#define PIN_HP_AMP	0x80
 
 struct alc_spec {
 	/* codec parameterization */
@@ -113,8 +115,6 @@
 	/* PCM information */
 	struct hda_pcm pcm_rec[2];	/* used in alc_build_pcms() */
 
-	struct semaphore bind_mutex;	/* for bound controls */
-
 	/* dynamic controls, init_verbs and input_mux */
 	struct auto_pin_cfg autocfg;
 	unsigned int num_kctl_alloc, num_kctl_used;
@@ -218,72 +218,53 @@
 
 
 /*
- * bound volume controls
- *
- * bind multiple volumes (# indices, from 0)
+ * Control of pin widget settings via the mixer.  Only boolean settings are
+ * supported, so VrefEn can't be controlled using these functions as they
+ * stand.
  */
-
-#define AMP_VAL_IDX_SHIFT	19
-#define AMP_VAL_IDX_MASK	(0x0f<<19)
-
-static int alc_bind_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int alc_pinctl_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
 {
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct alc_spec *spec = codec->spec;
-	unsigned long pval;
-
-	down(&spec->bind_mutex);
-	pval = kcontrol->private_value;
-	kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
-	snd_hda_mixer_amp_switch_info(kcontrol, uinfo);
-	kcontrol->private_value = pval;
-	up(&spec->bind_mutex);
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
 	return 0;
 }
 
-static int alc_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int alc_pinctl_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct alc_spec *spec = codec->spec;
-	unsigned long pval;
+	hda_nid_t nid = kcontrol->private_value & 0xffff;
+	long mask = (kcontrol->private_value >> 16) & 0xff;
+	long *valp = ucontrol->value.integer.value;
 
-	down(&spec->bind_mutex);
-	pval = kcontrol->private_value;
-	kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
-	snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
-	kcontrol->private_value = pval;
-	up(&spec->bind_mutex);
+	*valp = 0;
+	if (snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00) & mask)
+		*valp = 1;
 	return 0;
 }
 
-static int alc_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int alc_pinctl_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct alc_spec *spec = codec->spec;
-	unsigned long pval;
-	int i, indices, change = 0;
+	hda_nid_t nid = kcontrol->private_value & 0xffff;
+	long mask = (kcontrol->private_value >> 16) & 0xff;
+	long *valp = ucontrol->value.integer.value;
+	unsigned int pinctl = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00);
+	int change = ((pinctl & mask)!=0) != *valp;
 
-	down(&spec->bind_mutex);
-	pval = kcontrol->private_value;
-	indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
-	for (i = 0; i < indices; i++) {
-		kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT);
-		change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
-	}
-	kcontrol->private_value = pval;
-	up(&spec->bind_mutex);
+	if (change)
+		snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL,
+			*valp?(pinctl|mask):(pinctl&~mask));
 	return change;
 }
 
-#define ALC_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \
+#define ALC_PINCTL_SWITCH(xname, nid, mask) \
 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
-	  .info = alc_bind_switch_info, \
-	  .get = alc_bind_switch_get, \
-	  .put = alc_bind_switch_put, \
-	  .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) }
-
-#define ALC_BIND_MUTE(xname,nid,indices,dir) ALC_BIND_MUTE_MONO(xname,nid,3,indices,dir)
-
+	  .info = alc_pinctl_switch_info, \
+	  .get = alc_pinctl_switch_get, \
+	  .put = alc_pinctl_switch_put, \
+	  .private_value = (nid) | (mask<<16) }
 
 /*
  * ALC880 3-stack model
@@ -354,13 +335,13 @@
 
 static snd_kcontrol_new_t alc880_three_stack_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
-	ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
@@ -441,7 +422,7 @@
 /* additional mixers to alc880_three_stack_mixer */
 static snd_kcontrol_new_t alc880_five_stack_mixer[] = {
 	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
 	{ } /* end */
 };
 
@@ -498,15 +479,15 @@
 
 static snd_kcontrol_new_t alc880_six_stack_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
-	ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
@@ -566,13 +547,13 @@
 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
 static snd_kcontrol_new_t alc880_w810_base_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
-	ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 	{ } /* end */
 };
@@ -597,9 +578,9 @@
 
 static snd_kcontrol_new_t alc880_z71v_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -623,9 +604,9 @@
 
 static snd_kcontrol_new_t alc880_f1734_mixer[] = {
 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -648,13 +629,13 @@
 
 static snd_kcontrol_new_t alc880_asus_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
-	ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
@@ -1383,10 +1364,10 @@
 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
-	ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
-	ALC_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
-	ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
 	PIN_CTL_TEST("Front Pin Mode", 0x14),
 	PIN_CTL_TEST("Surround Pin Mode", 0x15),
 	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
@@ -1769,7 +1750,7 @@
 static snd_kcontrol_new_t alc880_control_templates[] = {
 	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
 	HDA_CODEC_MUTE(NULL, 0, 0, 0),
-	ALC_BIND_MUTE(NULL, 0, 0, 0),
+	HDA_BIND_MUTE(NULL, 0, 0, 0),
 };
 
 /* add dynamic controls */
@@ -2087,7 +2068,6 @@
 	if (spec == NULL)
 		return -ENOMEM;
 
-	init_MUTEX(&spec->bind_mutex);
 	codec->spec = spec;
 
 	board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl);
@@ -2205,6 +2185,17 @@
 	},
 };
 
+/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack
+ * and the internal CD lines.
+ */
+static struct hda_input_mux alc260_fujitsu_capture_source = {
+	.num_items = 2,
+	.items = {
+		{ "Mic/Line", 0x0 },
+		{ "CD", 0x4 },
+	},
+};
+
 /*
  * This is just place-holder, so there's something for alc_build_pcms to look
  * at when it calculates the maximum number of channels. ALC260 has no mixer
@@ -2217,7 +2208,7 @@
 
 static snd_kcontrol_new_t alc260_base_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
 	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
 	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
@@ -2229,9 +2220,9 @@
 	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
 	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
 	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
 	{
@@ -2246,7 +2237,7 @@
 
 static snd_kcontrol_new_t alc260_hp_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
 	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
 	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
@@ -2256,9 +2247,9 @@
 	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
 	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
 	HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
 	{
@@ -2271,6 +2262,30 @@
 	{ } /* end */
 };
 
+static snd_kcontrol_new_t alc260_fujitsu_mixer[] = {
+	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
+	ALC_PINCTL_SWITCH("Headphone Amp Switch", 0x14, PIN_HP_AMP),
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
+	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
+	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Capture Source",
+		.info = alc_mux_enum_info,
+		.get = alc_mux_enum_get,
+		.put = alc_mux_enum_put,
+	},
+	{ } /* end */
+};
+
 static struct hda_verb alc260_init_verbs[] = {
 	/* Line In pin widget for input */
 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
@@ -2332,6 +2347,60 @@
 	{ }
 };
 
+/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
+ * laptops.
+ */
+static struct hda_verb alc260_fujitsu_init_verbs[] = {
+	/* Disable all GPIOs */
+	{0x01, AC_VERB_SET_GPIO_MASK, 0},
+	/* Internal speaker is connected to headphone pin */
+	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+        /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
+        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+        /* Ensure all other unused pins are disabled and muted.
+	 * Note: trying to set widget 0x15 to anything blocks all audio
+	 * output for some reason, so just leave that at the default.
+	 */
+        {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
+        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
+        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
+        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+        /* Disable digital (SPDIF) pins */
+        {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
+        {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
+
+        /* Start with mixer outputs muted */
+        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+
+        /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
+        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+        /* Unmute Line1 pin widget amp left and right (no equiv mixer ctrl) */
+        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	/* Unmute pin widget used for Line-in (no equiv mixer ctrl) */
+        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+
+        /* Mute capture amp left and right */
+        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+        /* Set ADC connection select to line in (on mic1 pin) */
+        {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
+
+        /* Mute all inputs to mixer widget (even unconnected ones) */
+        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
+        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
+        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
+        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
+        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
+        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
+        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
+        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
+};
+
 static struct hda_pcm_stream alc260_pcm_analog_playback = {
 	.substreams = 1,
 	.channels_min = 2,
@@ -2347,6 +2416,8 @@
 static struct hda_board_config alc260_cfg_tbl[] = {
 	{ .modelname = "hp", .config = ALC260_HP },
 	{ .pci_subvendor = 0x103c, .config = ALC260_HP },
+	{ .modelname = "fujitsu", .config = ALC260_FUJITSU_S702x },
+	{ .pci_subvendor = 0x10cf, .pci_subdevice = 0x1326, .config = ALC260_FUJITSU_S702x },
 	{}
 };
 
@@ -2359,7 +2430,6 @@
 	if (spec == NULL)
 		return -ENOMEM;
 
-	init_MUTEX(&spec->bind_mutex);
 	codec->spec = spec;
 
 	board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl);
@@ -2373,14 +2443,23 @@
 		spec->mixers[spec->num_mixers] = alc260_hp_mixer;
 		spec->num_mixers++;
 		break;
+	case ALC260_FUJITSU_S702x:
+		spec->mixers[spec->num_mixers] = alc260_fujitsu_mixer;
+		spec->num_mixers++;
+		break;
 	default:
 		spec->mixers[spec->num_mixers] = alc260_base_mixer;
 		spec->num_mixers++;
 		break;
 	}
 
-	spec->init_verbs[0] = alc260_init_verbs;
-	spec->num_init_verbs = 1;
+	if (board_config != ALC260_FUJITSU_S702x) {
+		spec->init_verbs[0] = alc260_init_verbs;
+		spec->num_init_verbs = 1;
+	} else {
+		spec->init_verbs[0] = alc260_fujitsu_init_verbs;
+		spec->num_init_verbs = 1;
+	}
 
 	spec->channel_mode = alc260_modes;
 	spec->num_channel_mode = ARRAY_SIZE(alc260_modes);
@@ -2393,7 +2472,11 @@
 	spec->multiout.num_dacs = ARRAY_SIZE(alc260_dac_nids);
 	spec->multiout.dac_nids = alc260_dac_nids;
 
-	spec->input_mux = &alc260_capture_source;
+	if (board_config != ALC260_FUJITSU_S702x) {
+		spec->input_mux = &alc260_capture_source;
+	} else {
+		spec->input_mux = &alc260_fujitsu_capture_source;
+	}
 	switch (board_config) {
 	case ALC260_HP:
 		spec->num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids);
@@ -2483,15 +2566,15 @@
  */
 static snd_kcontrol_new_t alc882_base_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
-	ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
@@ -2609,7 +2692,6 @@
 	if (spec == NULL)
 		return -ENOMEM;
 
-	init_MUTEX(&spec->bind_mutex);
 	codec->spec = spec;
 
 	spec->mixers[spec->num_mixers] = alc882_base_mixer;
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index d014b7b..9c7fe0b 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -3,7 +3,7 @@
  *
  * HD audio interface patch for Silicon Labs 3054/5 modem codec
  *
- * Copyright (c) 2005 Sasha Khapyorsky <sashak@smlink.com>
+ * Copyright (c) 2005 Sasha Khapyorsky <sashak@alsa-project.org>
  *                    Takashi Iwai <tiwai@suse.de>
  *
  *
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 2e0a316..db12b03 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -960,7 +960,7 @@
 	if (change)
 		wm_put(ice, WM_ADC_MUX, nval);
 	snd_ice1712_restore_gpio_status(ice);
-	return 0;
+	return change;
 }
 
 /*
@@ -1672,9 +1672,9 @@
 		snd_ice1712_save_gpio_status(ice);
 		id = aureon_cs8415_get(ice, CS8415_ID);
 		if (id != 0x41)
-			snd_printk("No CS8415 chip. Skipping CS8415 controls.\n");
+			snd_printk(KERN_INFO "No CS8415 chip. Skipping CS8415 controls.\n");
 		else if ((id & 0x0F) != 0x01)
-			snd_printk("Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
+			snd_printk(KERN_INFO "Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
 		else {
 			for (i = 0; i< ARRAY_SIZE(cs8415_controls); i++) {
 				snd_kcontrol_t *kctl;
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index 39fbe66..576f69d 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -546,7 +546,7 @@
 	case ICE1712_SUBDEVICE_DELTA1010LT:
 	case ICE1712_SUBDEVICE_VX442:
 		if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
-			snd_printk("unable to create I2C bus\n");
+			snd_printk(KERN_ERR "unable to create I2C bus\n");
 			return err;
 		}
 		ice->i2c->private_data = ice;
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
index e36efa1..c8ec5ca 100644
--- a/sound/pci/ice1712/ews.c
+++ b/sound/pci/ice1712/ews.c
@@ -438,7 +438,7 @@
 
 	/* create i2c */
 	if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
-		snd_printk("unable to create I2C bus\n");
+		snd_printk(KERN_ERR "unable to create I2C bus\n");
 		return err;
 	}
 	ice->i2c->private_data = ice;
@@ -448,7 +448,7 @@
 	switch (ice->eeprom.subvendor) {
 	case ICE1712_SUBDEVICE_DMX6FIRE:
 		if ((err = snd_i2c_device_create(ice->i2c, "PCF9554", ICE1712_6FIRE_PCF9554_ADDR, &ice->spec.i2cdevs[EWS_I2C_6FIRE])) < 0) {
-			snd_printk("PCF9554 initialization failed\n");
+			snd_printk(KERN_ERR "PCF9554 initialization failed\n");
 			return err;
 		}
 		snd_ice1712_6fire_write_pca(ice, PCF9554_REG_CONFIG, 0x80);
@@ -791,7 +791,7 @@
 	byte = 0;
 	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], &byte, 1) != 1) {
 		snd_i2c_unlock(ice->i2c);
-		printk("cannot read pca\n");
+		printk(KERN_ERR "cannot read pca\n");
 		return -EIO;
 	}
 	snd_i2c_unlock(ice->i2c);
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index a6d9801..5aca377 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -387,7 +387,7 @@
 	if ((err = snd_cs8427_create(ice->i2c, addr,
 				     (ice->cs8427_timeout * HZ) / 1000,
 				     &ice->cs8427)) < 0) {
-		snd_printk("CS8427 initialization failed\n");
+		snd_printk(KERN_ERR "CS8427 initialization failed\n");
 		return err;
 	}
 	ice->spdif.ops.open = open_cs8427;
@@ -2348,12 +2348,12 @@
 	if (ice->eeprom.size < 6)
 		ice->eeprom.size = 32; /* FIXME: any cards without the correct size? */
 	else if (ice->eeprom.size > 32) {
-		snd_printk("invalid EEPROM (size = %i)\n", ice->eeprom.size);
+		snd_printk(KERN_ERR "invalid EEPROM (size = %i)\n", ice->eeprom.size);
 		return -EIO;
 	}
 	ice->eeprom.version = snd_ice1712_read_i2c(ice, dev, 0x05);
 	if (ice->eeprom.version != 1) {
-		snd_printk("invalid EEPROM version %i\n", ice->eeprom.version);
+		snd_printk(KERN_ERR "invalid EEPROM version %i\n", ice->eeprom.version);
 		/* return -EIO; */
 	}
 	size = ice->eeprom.size - 6;
@@ -2524,7 +2524,7 @@
 	/* check, if we can restrict PCI DMA transfers to 28 bits */
 	if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
 	    pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
-		snd_printk("architecture does not support 28bit PCI busmaster DMA\n");
+		snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n");
 		pci_disable_device(pci);
 		return -ENXIO;
 	}
@@ -2573,7 +2573,7 @@
 	ice->profi_port = pci_resource_start(pci, 3);
 
 	if (request_irq(pci->irq, snd_ice1712_interrupt, SA_INTERRUPT|SA_SHIRQ, "ICE1712", (void *) ice)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_ice1712_free(ice);
 		return -EIO;
 	}
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index c3ce8f9..5b4293f 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -675,9 +675,12 @@
 				 SNDRV_PCM_INFO_MMAP_VALID |
 				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
 	.formats =		SNDRV_PCM_FMTBIT_S32_LE,
-	.rates =	        SNDRV_PCM_RATE_32000|SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000,
+	.rates =	        (SNDRV_PCM_RATE_32000|SNDRV_PCM_RATE_44100|
+				 SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_88200|
+				 SNDRV_PCM_RATE_96000|SNDRV_PCM_RATE_176400|
+				 SNDRV_PCM_RATE_192000),
 	.rate_min =		32000,
-	.rate_max =		48000,
+	.rate_max =		192000,
 	.channels_min =		2,
 	.channels_max =		2,
 	.buffer_bytes_max =	(1UL << 18),	/* 16bits dword */
@@ -905,6 +908,10 @@
 	case 44100: break;
 	case 48000: nval |= 2 << 12; break;
 	case 32000: nval |= 3 << 12; break;
+	case 88200: nval |= 4 << 12; break;
+	case 96000: nval |= 5 << 12; break;
+	case 192000: nval |= 6 << 12; break;
+	case 176400: nval |= 7 << 12; break;
 	}
 	if (val != nval)
 		update_spdif_bits(ice, nval);
@@ -1292,22 +1299,32 @@
 
 static unsigned int encode_spdif_bits(snd_aes_iec958_t *diga)
 {
-	unsigned int val;
+	unsigned int val, rbits;
 
 	val = diga->status[0] & 0x03; /* professional, non-audio */
 	if (val & 0x01) {
 		/* professional */
 		if ((diga->status[0] & IEC958_AES0_PRO_EMPHASIS) == IEC958_AES0_PRO_EMPHASIS_5015)
 			val |= 1U << 3;
-		switch (diga->status[0] & IEC958_AES0_PRO_FS) {
-		case IEC958_AES0_PRO_FS_44100:
-			break;
-		case IEC958_AES0_PRO_FS_32000:
-			val |= 3U << 12;
-			break;
-		default:
-			val |= 2U << 12;
-			break;
+		rbits = (diga->status[4] >> 3) & 0x0f;
+		if (rbits) {
+			switch (rbits) {
+			case 2: val |= 5 << 12; break; /* 96k */
+			case 3: val |= 6 << 12; break; /* 192k */
+			case 10: val |= 4 << 12; break; /* 88.2k */
+			case 11: val |= 7 << 12; break; /* 176.4k */
+			}
+		} else {
+			switch (diga->status[0] & IEC958_AES0_PRO_FS) {
+			case IEC958_AES0_PRO_FS_44100:
+				break;
+			case IEC958_AES0_PRO_FS_32000:
+				val |= 3U << 12;
+				break;
+			default:
+				val |= 2U << 12;
+				break;
+			}
 		}
 	} else {
 		/* consumer */
@@ -2154,7 +2171,7 @@
 	ice->profi_port = pci_resource_start(pci, 1);
 
 	if (request_irq(pci->irq, snd_vt1724_interrupt, SA_INTERRUPT|SA_SHIRQ, "ICE1724", (void *) ice)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_vt1724_free(ice);
 		return -EIO;
 	}
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c
index a5f852b..773a1ec 100644
--- a/sound/pci/ice1712/pontis.c
+++ b/sound/pci/ice1712/pontis.c
@@ -794,8 +794,7 @@
 	/* initialize WM8776 codec */
 	for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
 		wm_put(ice, wm_inits[i], wm_inits[i+1]);
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(1);
+	schedule_timeout_uninterruptible(1);
 	for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2)
 		wm_put(ice, wm_inits2[i], wm_inits2[i+1]);
 
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c
index d48d425..1fe2100 100644
--- a/sound/pci/ice1712/revo.c
+++ b/sound/pci/ice1712/revo.c
@@ -128,17 +128,6 @@
 	.mask_flags = 0,
 };
 
-static unsigned int rates[] = {
-	32000, 44100, 48000, 64000, 88200, 96000,
-	176400, 192000,
-};
-
-static snd_pcm_hw_constraint_list_t revo_rates = {
-	.count = ARRAY_SIZE(rates),
-	.list = rates,
-	.mask = 0,
-};
-
 static int __devinit revo_init(ice1712_t *ice)
 {
 	akm4xxx_t *ak;
@@ -173,8 +162,6 @@
 		break;
 	}
 
-	ice->hw_rates = &revo_rates; /* AK codecs don't support lower than 32k */
-
 	return 0;
 }
 
diff --git a/sound/pci/ice1712/vt1720_mobo.c b/sound/pci/ice1712/vt1720_mobo.c
index ab61e38..90c85cd 100644
--- a/sound/pci/ice1712/vt1720_mobo.c
+++ b/sound/pci/ice1712/vt1720_mobo.c
@@ -71,6 +71,22 @@
 	0x00,	/* - */
 };
 
+static unsigned char sn25p_eeprom[] __devinitdata = {
+	0x01,	/* SYSCONF: clock 256, 1ADC, 2DACs */
+	0x02,	/* ACLINK: ACLINK, packed */
+	0x00,	/* I2S: - */
+	0x41,	/* SPDIF: - */
+	0xff,	/* GPIO_DIR */
+	0xff,	/* GPIO_DIR1 */
+	0x00,	/* - */
+	0xff,	/* GPIO_MASK */
+	0xff,	/* GPIO_MASK1 */
+	0x00,	/* - */
+	0x00,	/* GPIO_STATE */
+	0x00,	/* GPIO_STATE1 */
+	0x00,	/* - */
+};
+
 
 /* entry point */
 struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = {
@@ -113,11 +129,11 @@
 	{
 		.subvendor = VT1720_SUBDEVICE_SN25P,
 		.name = "Shuttle SN25P",
-		/* identical with k8x800 */
+		.model = "sn25p",
 		.chip_init = k8x800_init,
 		.build_controls = k8x800_add_controls,
 		.eeprom_size = sizeof(k8x800_eeprom),
-		.eeprom_data = k8x800_eeprom,
+		.eeprom_data = sn25p_eeprom,
 	},
 	{ } /* terminator */
 };
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 1a96198..0801083 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -64,36 +64,35 @@
 		"{AMD,AMD8111},"
 	        "{ALI,M5455}}");
 
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
-static char *ac97_quirk[SNDRV_CARDS];
-static int buggy_semaphore[SNDRV_CARDS];
-static int buggy_irq[SNDRV_CARDS];
-static int xbox[SNDRV_CARDS];
+static int index = SNDRV_DEFAULT_IDX1;	/* Index 0-MAX */
+static char *id = SNDRV_DEFAULT_STR1;	/* ID for this card */
+static int ac97_clock = 0;
+static char *ac97_quirk;
+static int buggy_semaphore;
+static int buggy_irq = -1; /* auto-check */
+static int xbox;
 
-#ifdef SUPPORT_MIDI
-static int mpu_port[SNDRV_CARDS]; /* disabled */
-#endif
-
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
 MODULE_PARM_DESC(id, "ID string for Intel i8x0 soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Intel i8x0 soundcard.");
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
-module_param_array(ac97_quirk, charp, NULL, 0444);
+module_param(ac97_quirk, charp, 0444);
 MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
-module_param_array(buggy_semaphore, bool, NULL, 0444);
+module_param(buggy_semaphore, bool, 0444);
 MODULE_PARM_DESC(buggy_semaphore, "Enable workaround for hardwares with problematic codec semaphores.");
-module_param_array(buggy_irq, bool, NULL, 0444);
+module_param(buggy_irq, bool, 0444);
 MODULE_PARM_DESC(buggy_irq, "Enable workaround for buggy interrupts on some motherboards.");
-module_param_array(xbox, bool, NULL, 0444);
+module_param(xbox, bool, 0444);
 MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection.");
 
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+static int joystick;
+module_param(joystick, int, 0444);
+
 /*
  *  Direct registers
  */
@@ -539,7 +538,7 @@
 	/* access to some forbidden (non existant) ac97 registers will not
 	 * reset the semaphore. So even if you don't get the semaphore, still
 	 * continue the access. We don't need the semaphore anyway. */
-	snd_printk("codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
+	snd_printk(KERN_ERR "codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
 			igetbyte(chip, ICHREG(ACC_SEMA)), igetdword(chip, ICHREG(GLOB_STA)));
 	iagetword(chip, 0);	/* clear semaphore flag */
 	/* I don't care about the semaphore */
@@ -554,7 +553,7 @@
 	
 	if (snd_intel8x0_codec_semaphore(chip, ac97->num) < 0) {
 		if (! chip->in_ac97_init)
-			snd_printk("codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
+			snd_printk(KERN_ERR "codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
 	}
 	iaputword(chip, reg + ac97->num * 0x80, val);
 }
@@ -568,7 +567,7 @@
 
 	if (snd_intel8x0_codec_semaphore(chip, ac97->num) < 0) {
 		if (! chip->in_ac97_init)
-			snd_printk("codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
+			snd_printk(KERN_ERR "codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
 		res = 0xffff;
 	} else {
 		res = iagetword(chip, reg + ac97->num * 0x80);
@@ -576,7 +575,7 @@
 			/* reset RCS and preserve other R/WC bits */
 			iputdword(chip, ICHREG(GLOB_STA), tmp & ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
 			if (! chip->in_ac97_init)
-				snd_printk("codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
+				snd_printk(KERN_ERR "codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
 			res = 0xffff;
 		}
 	}
@@ -607,16 +606,19 @@
 		if (val & mask)
 			return 0;
 	}
-	snd_printd(KERN_WARNING "intel8x0: AC97 codec ready timeout.\n");
+	if (! chip->in_ac97_init)
+		snd_printd(KERN_WARNING "intel8x0: AC97 codec ready timeout.\n");
 	return -EBUSY;
 }
 
 static int snd_intel8x0_ali_codec_semaphore(intel8x0_t *chip)
 {
 	int time = 100;
+	if (chip->buggy_semaphore)
+		return 0; /* just ignore ... */
 	while (time-- && (igetdword(chip, ICHREG(ALI_CAS)) & ALI_CAS_SEM_BUSY))
 		udelay(1);
-	if (! time)
+	if (! time && ! chip->in_ac97_init)
 		snd_printk(KERN_WARNING "ali_codec_semaphore timeout\n");
 	return snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_CODEC_READY);
 }
@@ -1716,6 +1718,12 @@
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
+		.subvendor = 0x1025,
+		.subdevice = 0x0083,
+		.name = "Acer Aspire 3003LCi",
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
 		.subvendor = 0x1028,
 		.subdevice = 0x00d8,
 		.name = "Dell Precision 530",	/* AD1885 */
@@ -1758,6 +1766,12 @@
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
+		.subvendor = 0x1028,
+		.subdevice = 0x0191,
+		.name = "Dell Inspiron 8600",
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
 		.subvendor = 0x103c,
 		.subdevice = 0x006d,
 		.name = "HP zv5000",
@@ -2022,7 +2036,6 @@
 	if ((err = snd_ac97_bus(chip->card, 0, ops, chip, &pbus)) < 0)
 		goto __err;
 	pbus->private_free = snd_intel8x0_mixer_free_ac97_bus;
-	pbus->shared_type = AC97_SHARED_TYPE_ICH;	/* shared with modem driver */
 	if (ac97_clock >= 8000 && ac97_clock <= 48000)
 		pbus->clock = ac97_clock;
 	/* FIXME: my test board doesn't work well with VRA... */
@@ -2131,14 +2144,13 @@
 	iputdword(chip, ICHREG(ALI_FIFOCR2), 0x83838383);
 	iputdword(chip, ICHREG(ALI_FIFOCR3), 0x83838383);
 	iputdword(chip, ICHREG(ALI_INTERFACECR),
-		  ICH_ALI_IF_MC|ICH_ALI_IF_PI|ICH_ALI_IF_PO);
+		  ICH_ALI_IF_PI|ICH_ALI_IF_PO);
 	iputdword(chip, ICHREG(ALI_INTERRUPTCR), 0x00000000);
 	iputdword(chip, ICHREG(ALI_INTERRUPTSR), 0x00000000);
 }
 
 #define do_delay(chip) do {\
-	set_current_state(TASK_UNINTERRUPTIBLE);\
-	schedule_timeout(1);\
+	schedule_timeout_uninterruptible(1);\
 } while (0)
 
 static int snd_intel8x0_ich_chip_init(intel8x0_t *chip, int probing)
@@ -2166,7 +2178,7 @@
 			goto __ok;
 		do_delay(chip);
 	} while (time_after_eq(end_time, jiffies));
-	snd_printk("AC'97 warm reset still in progress? [0x%x]\n", igetdword(chip, ICHREG(GLOB_CNT)));
+	snd_printk(KERN_ERR "AC'97 warm reset still in progress? [0x%x]\n", igetdword(chip, ICHREG(GLOB_CNT)));
 	return -EIO;
 
       __ok:
@@ -2441,7 +2453,7 @@
 
 	subs = chip->pcm[0]->streams[0].substream;
 	if (! subs || subs->dma_buffer.bytes < INTEL8X0_TESTBUF_SIZE) {
-		snd_printk("no playback buffer allocated - aborting measure ac97 clock\n");
+		snd_printk(KERN_WARNING "no playback buffer allocated - aborting measure ac97 clock\n");
 		return;
 	}
 	ichdev = &chip->ichd[ICHD_PCMOUT];
@@ -2477,7 +2489,7 @@
 	do_gettimeofday(&stop_time);
 	/* stop */
 	if (chip->device_type == DEVICE_ALI) {
-		iputdword(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 8));
+		iputdword(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 16));
 		iputbyte(chip, port + ICH_REG_OFF_CR, 0);
 		while (igetbyte(chip, port + ICH_REG_OFF_CR))
 			;
@@ -2556,7 +2568,6 @@
 static int __devinit snd_intel8x0_create(snd_card_t * card,
 					 struct pci_dev *pci,
 					 unsigned long device_type,
-					 int buggy_sem,
 					 intel8x0_t ** r_intel8x0)
 {
 	intel8x0_t *chip;
@@ -2614,18 +2625,17 @@
 	chip->card = card;
 	chip->pci = pci;
 	chip->irq = -1;
-	chip->buggy_semaphore = buggy_sem;
+
+	/* module parameters */
+	chip->buggy_irq = buggy_irq;
+	chip->buggy_semaphore = buggy_semaphore;
+	if (xbox)
+		chip->xbox = 1;
 
 	if (pci->vendor == PCI_VENDOR_ID_INTEL &&
 	    pci->device == PCI_DEVICE_ID_INTEL_440MX)
 		chip->fix_nocache = 1; /* enable workaround */
 
-	/* some Nforce[2] and ICH boards have problems with IRQ handling.
-	 * Needs to return IRQ_HANDLED for unknown irqs.
-	 */
-	if (device_type == DEVICE_NFORCE)
-		chip->buggy_irq = 1;
-
 	if ((err = pci_request_regions(pci, card->shortname)) < 0) {
 		kfree(chip);
 		pci_disable_device(pci);
@@ -2644,7 +2654,7 @@
 		chip->remap_addr = ioremap_nocache(chip->addr,
 						   pci_resource_len(pci, 2));
 		if (chip->remap_addr == NULL) {
-			snd_printk("AC'97 space ioremap problem\n");
+			snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
 			snd_intel8x0_free(chip);
 			return -EIO;
 		}
@@ -2657,7 +2667,7 @@
 		chip->remap_bmaddr = ioremap_nocache(chip->bmaddr,
 						     pci_resource_len(pci, 3));
 		if (chip->remap_bmaddr == NULL) {
-			snd_printk("Controller space ioremap problem\n");
+			snd_printk(KERN_ERR "Controller space ioremap problem\n");
 			snd_intel8x0_free(chip);
 			return -EIO;
 		}
@@ -2666,15 +2676,6 @@
 	}
 
  port_inited:
-	if (request_irq(pci->irq, snd_intel8x0_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
-		snd_intel8x0_free(chip);
-		return -EBUSY;
-	}
-	chip->irq = pci->irq;
-	pci_set_master(pci);
-	synchronize_irq(chip->irq);
-
 	chip->bdbars_count = bdbars[device_type];
 
 	/* initialize offsets */
@@ -2725,13 +2726,27 @@
 	int_sta_masks = 0;
 	for (i = 0; i < chip->bdbars_count; i++) {
 		ichdev = &chip->ichd[i];
-		ichdev->bdbar = ((u32 *)chip->bdbars.area) + (i * ICH_MAX_FRAGS * 2);
-		ichdev->bdbar_addr = chip->bdbars.addr + (i * sizeof(u32) * ICH_MAX_FRAGS * 2);
+		ichdev->bdbar = ((u32 *)chip->bdbars.area) +
+			(i * ICH_MAX_FRAGS * 2);
+		ichdev->bdbar_addr = chip->bdbars.addr +
+			(i * sizeof(u32) * ICH_MAX_FRAGS * 2);
 		int_sta_masks |= ichdev->int_sta_mask;
 	}
-	chip->int_sta_reg = device_type == DEVICE_ALI ? ICH_REG_ALI_INTERRUPTSR : ICH_REG_GLOB_STA;
+	chip->int_sta_reg = device_type == DEVICE_ALI ?
+		ICH_REG_ALI_INTERRUPTSR : ICH_REG_GLOB_STA;
 	chip->int_sta_mask = int_sta_masks;
 
+	/* request irq after initializaing int_sta_mask, etc */
+	if (request_irq(pci->irq, snd_intel8x0_interrupt,
+			SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
+		snd_intel8x0_free(chip);
+		return -EBUSY;
+	}
+	chip->irq = pci->irq;
+	pci_set_master(pci);
+	synchronize_irq(chip->irq);
+
 	if ((err = snd_intel8x0_chip_init(chip, 1)) < 0) {
 		snd_intel8x0_free(chip);
 		return err;
@@ -2782,20 +2797,12 @@
 static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
 					const struct pci_device_id *pci_id)
 {
-	static int dev;
 	snd_card_t *card;
 	intel8x0_t *chip;
 	int err;
 	struct shortname_table *name;
 
-	if (dev >= SNDRV_CARDS)
-		return -ENODEV;
-	if (!enable[dev]) {
-		dev++;
-		return -ENOENT;
-	}
-
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	card = snd_card_new(index, id, THIS_MODULE, 0);
 	if (card == NULL)
 		return -ENOMEM;
 
@@ -2819,17 +2826,23 @@
 		}
 	}
 
+	if (buggy_irq < 0) {
+		/* some Nforce[2] and ICH boards have problems with IRQ handling.
+		 * Needs to return IRQ_HANDLED for unknown irqs.
+		 */
+		if (pci_id->driver_data == DEVICE_NFORCE)
+			buggy_irq = 1;
+		else
+			buggy_irq = 0;
+	}
+
 	if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data,
-				       buggy_semaphore[dev], &chip)) < 0) {
+				       &chip)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
-	if (buggy_irq[dev])
-		chip->buggy_irq = 1;
-	if (xbox[dev])
-		chip->xbox = 1;
 
-	if ((err = snd_intel8x0_mixer(chip, ac97_clock[dev], ac97_quirk[dev])) < 0) {
+	if ((err = snd_intel8x0_mixer(chip, ac97_clock, ac97_quirk)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
@@ -2844,7 +2857,7 @@
 		 "%s with %s at %#lx, irq %i", card->shortname,
 		 snd_ac97_get_short_name(chip->ac97[0]), chip->addr, chip->irq);
 
-	if (! ac97_clock[dev])
+	if (! ac97_clock)
 		intel8x0_measure_ac97_clock(chip);
 
 	if ((err = snd_card_register(card)) < 0) {
@@ -2852,7 +2865,6 @@
 		return err;
 	}
 	pci_set_drvdata(pci, card);
-	dev++;
 	return 0;
 }
 
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 9e2060d..acfb197 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -3,7 +3,7 @@
  *
  *	Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
  *
- *   This is modified (by Sasha Khapyorsky <sashak@smlink.com>) version
+ *   This is modified (by Sasha Khapyorsky <sashak@alsa-project.org>) version
  *   of ALSA ICH sound driver intel8x0.c .
  *
  *
@@ -56,20 +56,21 @@
 		"{NVidia,NForce3 Modem},"
 		"{AMD,AMD768}}");
 
-static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
+static int index = -2; /* Exclude the first card */
+static char *id = SNDRV_DEFAULT_STR1;	/* ID for this card */
+static int ac97_clock = 0;
 
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for Intel i8x0 modemcard.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
 MODULE_PARM_DESC(id, "ID string for Intel i8x0 modemcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Intel i8x0 modemcard.");
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
 
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
 /*
  *  Direct registers
  */
@@ -362,7 +363,7 @@
 	/* access to some forbidden (non existant) ac97 registers will not
 	 * reset the semaphore. So even if you don't get the semaphore, still
 	 * continue the access. We don't need the semaphore anyway. */
-	snd_printk("codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
+	snd_printk(KERN_ERR "codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
 			igetbyte(chip, ICHREG(ACC_SEMA)), igetdword(chip, ICHREG(GLOB_STA)));
 	iagetword(chip, 0);	/* clear semaphore flag */
 	/* I don't care about the semaphore */
@@ -377,7 +378,7 @@
 	
 	if (snd_intel8x0m_codec_semaphore(chip, ac97->num) < 0) {
 		if (! chip->in_ac97_init)
-			snd_printk("codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
+			snd_printk(KERN_ERR "codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
 	}
 	iaputword(chip, reg + ac97->num * 0x80, val);
 }
@@ -391,7 +392,7 @@
 
 	if (snd_intel8x0m_codec_semaphore(chip, ac97->num) < 0) {
 		if (! chip->in_ac97_init)
-			snd_printk("codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
+			snd_printk(KERN_ERR "codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
 		res = 0xffff;
 	} else {
 		res = iagetword(chip, reg + ac97->num * 0x80);
@@ -399,7 +400,7 @@
 			/* reset RCS and preserve other R/WC bits */
 			iputdword(chip, ICHREG(GLOB_STA), tmp & ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
 			if (! chip->in_ac97_init)
-				snd_printk("codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
+				snd_printk(KERN_ERR "codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
 			res = 0xffff;
 		}
 	}
@@ -746,6 +747,7 @@
 
 	pcm->private_data = chip;
 	pcm->info_flags = 0;
+	pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
 	if (rec->suffix)
 		sprintf(pcm->name, "%s - %s", chip->card->shortname, rec->suffix);
 	else
@@ -854,7 +856,6 @@
 	if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
 		goto __err;
 	pbus->private_free = snd_intel8x0_mixer_free_ac97_bus;
-	pbus->shared_type = AC97_SHARED_TYPE_ICH;	/* shared with audio driver */
 	if (ac97_clock >= 8000 && ac97_clock <= 48000)
 		pbus->clock = ac97_clock;
 	chip->ac97_bus = pbus;
@@ -889,8 +890,7 @@
  */
 
 #define do_delay(chip) do {\
-	set_current_state(TASK_UNINTERRUPTIBLE);\
-	schedule_timeout(1);\
+	schedule_timeout_uninterruptible(1);\
 } while (0)
 
 static int snd_intel8x0m_ich_chip_init(intel8x0_t *chip, int probing)
@@ -916,7 +916,7 @@
 			goto __ok;
 		do_delay(chip);
 	} while (time_after_eq(end_time, jiffies));
-	snd_printk("AC'97 warm reset still in progress? [0x%x]\n", igetdword(chip, ICHREG(GLOB_CNT)));
+	snd_printk(KERN_ERR "AC'97 warm reset still in progress? [0x%x]\n", igetdword(chip, ICHREG(GLOB_CNT)));
 	return -EIO;
 
       __ok:
@@ -1142,7 +1142,7 @@
 		chip->remap_addr = ioremap_nocache(chip->addr,
 						   pci_resource_len(pci, 2));
 		if (chip->remap_addr == NULL) {
-			snd_printk("AC'97 space ioremap problem\n");
+			snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
 			snd_intel8x0_free(chip);
 			return -EIO;
 		}
@@ -1155,7 +1155,7 @@
 		chip->remap_bmaddr = ioremap_nocache(chip->bmaddr,
 						     pci_resource_len(pci, 3));
 		if (chip->remap_bmaddr == NULL) {
-			snd_printk("Controller space ioremap problem\n");
+			snd_printk(KERN_ERR "Controller space ioremap problem\n");
 			snd_intel8x0_free(chip);
 			return -EIO;
 		}
@@ -1165,7 +1165,7 @@
 
  port_inited:
 	if (request_irq(pci->irq, snd_intel8x0_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_intel8x0_free(chip);
 		return -EBUSY;
 	}
@@ -1263,20 +1263,12 @@
 static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
 					const struct pci_device_id *pci_id)
 {
-	static int dev;
 	snd_card_t *card;
 	intel8x0_t *chip;
 	int err;
 	struct shortname_table *name;
 
-	if (dev >= SNDRV_CARDS)
-		return -ENODEV;
-	if (!enable[dev]) {
-		dev++;
-		return -ENOENT;
-	}
-
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	card = snd_card_new(index, id, THIS_MODULE, 0);
 	if (card == NULL)
 		return -ENOMEM;
 
@@ -1295,7 +1287,7 @@
 		return err;
 	}
 
-	if ((err = snd_intel8x0_mixer(chip, ac97_clock[dev])) < 0) {
+	if ((err = snd_intel8x0_mixer(chip, ac97_clock)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
@@ -1314,7 +1306,6 @@
 		return err;
 	}
 	pci_set_drvdata(pci, card);
-	dev++;
 	return 0;
 }
 
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 2693b6f..99eb76c5 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -1492,7 +1492,7 @@
 	/* set buffer address */
 	s->buffer_addr = substream->runtime->dma_addr;
 	if (s->buffer_addr & 0x3) {
-		snd_printk("oh my, not aligned\n");
+		snd_printk(KERN_ERR "oh my, not aligned\n");
 		s->buffer_addr = s->buffer_addr & ~0x3;
 	}
 	return 0;
@@ -1942,7 +1942,7 @@
 			return 0;
 	} while (i-- > 0);
 
-	snd_printk("ac97 serial bus busy\n");
+	snd_printk(KERN_ERR "ac97 serial bus busy\n");
 	return 1;
 }
 
@@ -2046,8 +2046,7 @@
 		outw(0, io + GPIO_DATA);
 		outw(dir | GPO_PRIMARY_AC97, io + GPIO_DIRECTION);
 
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout((delay1 * HZ) / 1000);
+		schedule_timeout_uninterruptible(msecs_to_jiffies(delay1));
 
 		outw(GPO_PRIMARY_AC97, io + GPIO_DATA);
 		udelay(5);
@@ -2055,8 +2054,7 @@
 		outw(IO_SRAM_ENABLE | SERIAL_AC_LINK_ENABLE, io + RING_BUS_CTRL_A);
 		outw(~0, io + GPIO_MASK);
 
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout((delay2 * HZ) / 1000);
+		schedule_timeout_uninterruptible(msecs_to_jiffies(delay2));
 
 		if (! snd_m3_try_read_vendor(chip))
 			break;
@@ -2101,8 +2099,7 @@
 
 	/* seems ac97 PCM needs initialization.. hack hack.. */
 	snd_ac97_write(chip->ac97, AC97_PCM, 0x8000 | (15 << 8) | 15);
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ / 10);
+	schedule_timeout_uninterruptible(msecs_to_jiffies(100));
 	snd_ac97_write(chip->ac97, AC97_PCM, 0);
 
 	memset(&id, 0, sizeof(id));
@@ -2367,7 +2364,7 @@
 	address = 0x1100 + ((data_bytes/2) * index);
 
 	if ((address + (data_bytes/2)) >= 0x1c00) {
-		snd_printk("no memory for %d bytes at ind %d (addr 0x%x)\n",
+		snd_printk(KERN_ERR "no memory for %d bytes at ind %d (addr 0x%x)\n",
 			   data_bytes, index, address);
 		return -ENOMEM;
 	}
@@ -2476,6 +2473,7 @@
 	t |= ASSP_0_WS_ENABLE; 
 	outb(t, chip->iobase + ASSP_CONTROL_A);
 
+	snd_m3_assp_init(chip); /* download DSP code before starting ASSP below */
 	outb(RUN_ASSP, chip->iobase + ASSP_CONTROL_B); 
 
 	outb(0x00, io + HARDWARE_VOL_CTRL);
@@ -2655,7 +2653,7 @@
 	/* check, if we can restrict PCI DMA transfers to 28 bits */
 	if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
 	    pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
-		snd_printk("architecture does not support 28bit PCI busmaster DMA\n");
+		snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n");
 		pci_disable_device(pci);
 		return -ENXIO;
 	}
@@ -2734,14 +2732,13 @@
 
 	snd_m3_ac97_reset(chip);
 
-	snd_m3_assp_init(chip);
 	snd_m3_amp_enable(chip, 1);
 
 	tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip);
 
 	if (request_irq(pci->irq, snd_m3_interrupt, SA_INTERRUPT|SA_SHIRQ,
 			card->driver, (void *)chip)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_m3_free(chip);
 		return -ENOMEM;
 	}
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 1a62c7f..c341c99 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -451,8 +451,7 @@
 			snd_printk(KERN_ERR "mixart: cannot process nonblock events!\n");
 			return -EBUSY;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	}
 	return 0;
 }
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 5c55a3b..e7aa151 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -52,37 +52,43 @@
  * some compile conditions.
  */
 
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static int playback_bufsize[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 16};
-static int capture_bufsize[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 16};
-static int force_ac97[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled as default */
-static int buffer_top[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* not specified */
-static int use_cache[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled */
-static int vaio_hack[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled */
-static int reset_workaround[SNDRV_CARDS];
+static int index = SNDRV_DEFAULT_IDX1;	/* Index */
+static char *id = SNDRV_DEFAULT_STR1;	/* ID for this card */
+static int playback_bufsize = 16;
+static int capture_bufsize = 16;
+static int force_ac97;			/* disabled as default */
+static int buffer_top;			/* not specified */
+static int use_cache;			/* disabled */
+static int vaio_hack;			/* disabled */
+static int reset_workaround;
+static int reset_workaround_2;
 
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
 MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable this soundcard.");
-module_param_array(playback_bufsize, int, NULL, 0444);
+module_param(playback_bufsize, int, 0444);
 MODULE_PARM_DESC(playback_bufsize, "DAC frame size in kB for " CARD_NAME " soundcard.");
-module_param_array(capture_bufsize, int, NULL, 0444);
+module_param(capture_bufsize, int, 0444);
 MODULE_PARM_DESC(capture_bufsize, "ADC frame size in kB for " CARD_NAME " soundcard.");
-module_param_array(force_ac97, bool, NULL, 0444);
+module_param(force_ac97, bool, 0444);
 MODULE_PARM_DESC(force_ac97, "Force to use AC97 codec for " CARD_NAME " soundcard.");
-module_param_array(buffer_top, int, NULL, 0444);
+module_param(buffer_top, int, 0444);
 MODULE_PARM_DESC(buffer_top, "Set the top address of audio buffer for " CARD_NAME " soundcard.");
-module_param_array(use_cache, bool, NULL, 0444);
+module_param(use_cache, bool, 0444);
 MODULE_PARM_DESC(use_cache, "Enable the cache for coefficient table access.");
-module_param_array(vaio_hack, bool, NULL, 0444);
+module_param(vaio_hack, bool, 0444);
 MODULE_PARM_DESC(vaio_hack, "Enable workaround for Sony VAIO notebooks.");
-module_param_array(reset_workaround, bool, NULL, 0444);
+module_param(reset_workaround, bool, 0444);
 MODULE_PARM_DESC(reset_workaround, "Enable AC97 RESET workaround for some laptops.");
+module_param(reset_workaround_2, bool, 0444);
+MODULE_PARM_DESC(reset_workaround_2, "Enable extended AC97 RESET workaround for some other laptops.");
+
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
+
 
 /*
  * hw definitions
@@ -226,6 +232,7 @@
 	unsigned int coeffs_current: 1;	/* coeff. table is loaded? */
 	unsigned int use_cache: 1;	/* use one big coef. table */
 	unsigned int reset_workaround: 1; /* Workaround for some laptops to avoid freeze */
+	unsigned int reset_workaround_2: 1; /* Extended workaround for some other laptops to avoid freeze */
 
 	int mixer_base;			/* register offset of ac97 mixer */
 	int mixer_status_offset;	/* offset of mixer status reg. */
@@ -313,9 +320,9 @@
 snd_nm256_write_buffer(nm256_t *chip, void *src, int offset, int size)
 {
 	offset -= chip->buffer_start;
-#ifdef SNDRV_CONFIG_DEBUG
+#ifdef CONFIG_SND_DEBUG
 	if (offset < 0 || offset >= chip->buffer_size) {
-		snd_printk("write_buffer invalid offset = %d size = %d\n", offset, size);
+		snd_printk(KERN_ERR "write_buffer invalid offset = %d size = %d\n", offset, size);
 		return;
 	}
 #endif
@@ -459,7 +466,7 @@
 	if (chip->irq < 0) {
 		if (request_irq(chip->pci->irq, chip->interrupt, SA_INTERRUPT|SA_SHIRQ,
 				chip->card->driver, (void*)chip)) {
-			snd_printk("unable to grab IRQ %d\n", chip->pci->irq);
+			snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->pci->irq);
 			up(&chip->irq_mutex);
 			return -EBUSY;
 		}
@@ -1199,8 +1206,11 @@
 		/* Dell latitude LS will lock up by this */
 		snd_nm256_writeb(chip, 0x6cc, 0x87);
 	}
-	snd_nm256_writeb(chip, 0x6cc, 0x80);
-	snd_nm256_writeb(chip, 0x6cc, 0x0);
+	if (! chip->reset_workaround_2) {
+		/* Dell latitude CSx will lock up by this */
+		snd_nm256_writeb(chip, 0x6cc, 0x80);
+		snd_nm256_writeb(chip, 0x6cc, 0x0);
+	}
 }
 
 /* create an ac97 mixer interface */
@@ -1263,7 +1273,7 @@
 
 	temp = ioremap_nocache(chip->buffer_addr + chip->buffer_end - 0x400, 16);
 	if (temp == NULL) {
-		snd_printk("Unable to scan for card signature in video RAM\n");
+		snd_printk(KERN_ERR "Unable to scan for card signature in video RAM\n");
 		return -EBUSY;
 	}
 
@@ -1277,7 +1287,7 @@
 		if (pointer == 0xffffffff ||
 		    pointer < chip->buffer_size ||
 		    pointer > chip->buffer_end) {
-			snd_printk("invalid signature found: 0x%x\n", pointer);
+			snd_printk(KERN_ERR "invalid signature found: 0x%x\n", pointer);
 			iounmap(temp);
 			return -ENODEV;
 		} else {
@@ -1347,14 +1357,8 @@
 		iounmap(chip->cport);
 	if (chip->buffer)
 		iounmap(chip->buffer);
-	if (chip->res_cport) {
-		release_resource(chip->res_cport);
-		kfree_nocheck(chip->res_cport);
-	}
-	if (chip->res_buffer) {
-		release_resource(chip->res_buffer);
-		kfree_nocheck(chip->res_buffer);
-	}
+	release_and_free_resource(chip->res_cport);
+	release_and_free_resource(chip->res_buffer);
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void*)chip);
 
@@ -1420,14 +1424,14 @@
 	chip->res_cport = request_mem_region(chip->cport_addr, NM_PORT2_SIZE,
 					     card->driver);
 	if (chip->res_cport == NULL) {
-		snd_printk("memory region 0x%lx (size 0x%x) busy\n",
+		snd_printk(KERN_ERR "memory region 0x%lx (size 0x%x) busy\n",
 			   chip->cport_addr, NM_PORT2_SIZE);
 		err = -EBUSY;
 		goto __error;
 	}
 	chip->cport = ioremap_nocache(chip->cport_addr, NM_PORT2_SIZE);
 	if (chip->cport == NULL) {
-		snd_printk("unable to map control port %lx\n", chip->cport_addr);
+		snd_printk(KERN_ERR "unable to map control port %lx\n", chip->cport_addr);
 		err = -ENOMEM;
 		goto __error;
 	}
@@ -1485,7 +1489,7 @@
 					      chip->buffer_size,
 					      card->driver);
 	if (chip->res_buffer == NULL) {
-		snd_printk("nm256: buffer 0x%lx (size 0x%x) busy\n",
+		snd_printk(KERN_ERR "nm256: buffer 0x%lx (size 0x%x) busy\n",
 			   chip->buffer_addr, chip->buffer_size);
 		err = -EBUSY;
 		goto __error;
@@ -1493,7 +1497,7 @@
 	chip->buffer = ioremap_nocache(chip->buffer_addr, chip->buffer_size);
 	if (chip->buffer == NULL) {
 		err = -ENOMEM;
-		snd_printk("unable to map ring buffer at %lx\n", chip->buffer_addr);
+		snd_printk(KERN_ERR "unable to map ring buffer at %lx\n", chip->buffer_addr);
 		goto __error;
 	}
 
@@ -1542,7 +1546,7 @@
 	int type;
 };
 
-enum { NM_BLACKLISTED, NM_RESET_WORKAROUND };
+enum { NM_BLACKLISTED, NM_RESET_WORKAROUND, NM_RESET_WORKAROUND_2 };
 
 static struct nm256_quirk nm256_quirks[] __devinitdata = {
 	/* HP omnibook 4150 has cs4232 codec internally */
@@ -1551,6 +1555,8 @@
 	{ .vendor = 0x104d, .device = 0x8041, .type = NM_RESET_WORKAROUND },
 	/* Dell Latitude LS */
 	{ .vendor = 0x1028, .device = 0x0080, .type = NM_RESET_WORKAROUND },
+	/* Dell Latitude CSx */
+	{ .vendor = 0x1028, .device = 0x0091, .type = NM_RESET_WORKAROUND_2 },
 	{ } /* terminator */
 };
 
@@ -1558,7 +1564,6 @@
 static int __devinit snd_nm256_probe(struct pci_dev *pci,
 				     const struct pci_device_id *pci_id)
 {
-	static int dev;
 	snd_card_t *card;
 	nm256_t *chip;
 	int err;
@@ -1566,13 +1571,6 @@
 	struct nm256_quirk *q;
 	u16 subsystem_vendor, subsystem_device;
 
-	if (dev >= SNDRV_CARDS)
-		return -ENODEV;
-	if (!enable[dev]) {
-		dev++;
-		return -ENOENT;
-	}
-
 	pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
 	pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device);
 
@@ -1582,14 +1580,17 @@
 			case NM_BLACKLISTED:
 				printk(KERN_INFO "nm256: The device is blacklisted.  Loading stopped\n");
 				return -ENODEV;
+			case NM_RESET_WORKAROUND_2:
+				reset_workaround_2 = 1;
+				/* Fall-through */
 			case NM_RESET_WORKAROUND:
-				reset_workaround[dev] = 1;
+				reset_workaround = 1;
 				break;
 			}
 		}
 	}
 
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	card = snd_card_new(index, id, THIS_MODULE, 0);
 	if (card == NULL)
 		return -ENOMEM;
 
@@ -1604,40 +1605,45 @@
 		strcpy(card->driver, "NM256XL+");
 		break;
 	default:
-		snd_printk("invalid device id 0x%x\n", pci->device);
+		snd_printk(KERN_ERR "invalid device id 0x%x\n", pci->device);
 		snd_card_free(card);
 		return -EINVAL;
 	}
 
-	if (vaio_hack[dev])
+	if (vaio_hack)
 		xbuffer_top = 0x25a800;	/* this avoids conflicts with XFree86 server */
 	else
-		xbuffer_top = buffer_top[dev];
+		xbuffer_top = buffer_top;
 
-	if (playback_bufsize[dev] < 4)
-		playback_bufsize[dev] = 4;
-	if (playback_bufsize[dev] > 128)
-		playback_bufsize[dev] = 128;
-	if (capture_bufsize[dev] < 4)
-		capture_bufsize[dev] = 4;
-	if (capture_bufsize[dev] > 128)
-		capture_bufsize[dev] = 128;
+	if (playback_bufsize < 4)
+		playback_bufsize = 4;
+	if (playback_bufsize > 128)
+		playback_bufsize = 128;
+	if (capture_bufsize < 4)
+		capture_bufsize = 4;
+	if (capture_bufsize > 128)
+		capture_bufsize = 128;
 	if ((err = snd_nm256_create(card, pci,
-				    playback_bufsize[dev] * 1024, /* in bytes */
-				    capture_bufsize[dev] * 1024,  /* in bytes */
-				    force_ac97[dev],
+				    playback_bufsize * 1024, /* in bytes */
+				    capture_bufsize * 1024,  /* in bytes */
+				    force_ac97,
 				    xbuffer_top,
-				    use_cache[dev],
+				    use_cache,
 				    &chip)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
 
-	if (reset_workaround[dev]) {
+	if (reset_workaround) {
 		snd_printdd(KERN_INFO "nm256: reset_workaround activated\n");
 		chip->reset_workaround = 1;
 	}
 
+	if (reset_workaround_2) {
+		snd_printdd(KERN_INFO "nm256: reset_workaround_2 activated\n");
+		chip->reset_workaround_2 = 1;
+	}
+
 	if ((err = snd_nm256_pcm(chip, 0)) < 0 ||
 	    (err = snd_nm256_mixer(chip)) < 0) {
 		snd_card_free(card);
@@ -1655,7 +1661,6 @@
 	}
 
 	pci_set_drvdata(pci, card);
-	dev++;
 	return 0;
 }
 
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index cd313af..e6627b0 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -1369,13 +1369,13 @@
 	rme32->port = pci_resource_start(rme32->pci, 0);
 
 	if (request_irq(pci->irq, snd_rme32_interrupt, SA_INTERRUPT | SA_SHIRQ, "RME32", (void *) rme32)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		return -EBUSY;
 	}
 	rme32->irq = pci->irq;
 
 	if ((rme32->iobase = ioremap_nocache(rme32->port, RME32_IO_SIZE)) == 0) {
-		snd_printk("unable to remap memory region 0x%lx-0x%lx\n",
+		snd_printk(KERN_ERR "unable to remap memory region 0x%lx-0x%lx\n",
 			   rme32->port, rme32->port + RME32_IO_SIZE - 1);
 		return -ENOMEM;
 	}
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index c495cae..0eddeb1 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -1570,13 +1570,13 @@
 	rme96->port = pci_resource_start(rme96->pci, 0);
 
 	if (request_irq(pci->irq, snd_rme96_interrupt, SA_INTERRUPT|SA_SHIRQ, "RME96", (void *)rme96)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		return -EBUSY;
 	}
 	rme96->irq = pci->irq;
 
 	if ((rme96->iobase = ioremap_nocache(rme96->port, RME96_IO_SIZE)) == 0) {
-		snd_printk("unable to remap memory region 0x%lx-0x%lx\n", rme96->port, rme96->port + RME96_IO_SIZE - 1);
+		snd_printk(KERN_ERR "unable to remap memory region 0x%lx-0x%lx\n", rme96->port, rme96->port + RME96_IO_SIZE - 1);
 		return -ENOMEM;
 	}
 
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 52525eb..845158b 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -671,11 +671,7 @@
 			}
 		}
 
-		if ((1000 / HZ) < 3000) {
-			ssleep(3);
-		} else {
-			mdelay(3000);
-		}
+		ssleep(3);
 		
 		if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
 			snd_printk ("Hammerfall-DSP: timeout at end of firmware loading\n");
@@ -692,7 +688,7 @@
 		
 	}
 	if (hdsp->state & HDSP_InitializationComplete) {
-		snd_printk("Hammerfall-DSP: firmware loaded from cache, restoring defaults\n");
+		snd_printk(KERN_INFO "Hammerfall-DSP: firmware loaded from cache, restoring defaults\n");
 		spin_lock_irqsave(&hdsp->lock, flags);
 		snd_hdsp_set_defaults(hdsp);
 		spin_unlock_irqrestore(&hdsp->lock, flags); 
@@ -709,9 +705,8 @@
 	
 		hdsp_write (hdsp, HDSP_control2Reg, HDSP_PROGRAM);
 		hdsp_write (hdsp, HDSP_fifoData, 0);
-		if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0) {
+		if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0)
 			return -EIO;
-		}
 
 		hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
 		hdsp_write (hdsp, HDSP_fifoData, 0);
@@ -726,22 +721,30 @@
 		} 
 	} else {
 		/* firmware was already loaded, get iobox type */
-		if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) {
+		if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
 			hdsp->io_type = Multiface;
-		} else {
+		else
 			hdsp->io_type = Digiface;
-		}
 	}
 	return 0;
 }
 
 
-static int hdsp_check_for_firmware (hdsp_t *hdsp)
+static int hdsp_check_for_firmware (hdsp_t *hdsp, int show_err)
 {
 	if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
 	if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
-		snd_printk("Hammerfall-DSP: firmware not present.\n");
+		snd_printk(KERN_ERR "Hammerfall-DSP: firmware not present.\n");
 		hdsp->state &= ~HDSP_FirmwareLoaded;
+		if (! show_err)
+			return -EIO;
+		/* try to load firmware */
+		if (hdsp->state & HDSP_FirmwareCached) {
+			if (snd_hdsp_load_firmware_from_cache(hdsp) != 0)
+				snd_printk(KERN_ERR "Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
+		} else {
+			snd_printk(KERN_ERR "Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
+		}
 		return -EIO;
 	}
 	return 0;
@@ -775,9 +778,9 @@
 
 static int hdsp_read_gain (hdsp_t *hdsp, unsigned int addr)
 {
-	if (addr >= HDSP_MATRIX_MIXER_SIZE) {
+	if (addr >= HDSP_MATRIX_MIXER_SIZE)
 		return 0;
-	}
+
 	return hdsp->mixer_matrix[addr];
 }
 
@@ -802,13 +805,11 @@
 		   memory."
 		*/
 
-		if (hdsp->io_type == H9632 && addr >= 512) {
+		if (hdsp->io_type == H9632 && addr >= 512)
 			return 0;
-		}
 
-		if (hdsp->io_type == H9652 && addr >= 1352) {
+		if (hdsp->io_type == H9652 && addr >= 1352)
 			return 0;
-		}
 
 		hdsp->mixer_matrix[addr] = data;
 
@@ -832,9 +833,8 @@
 
 		ad = (addr << 16) + data;
 		
-		if (hdsp_fifo_wait(hdsp, 127, HDSP_LONG_WAIT)) {
+		if (hdsp_fifo_wait(hdsp, 127, HDSP_LONG_WAIT))
 			return -1;
-		}
 
 		hdsp_write (hdsp, HDSP_fifoData, ad);
 		hdsp->mixer_matrix[addr] = data;
@@ -851,9 +851,8 @@
 
 	spin_lock_irqsave(&hdsp->lock, flags);
 	if ((hdsp->playback_pid != hdsp->capture_pid) &&
-	    (hdsp->playback_pid >= 0) && (hdsp->capture_pid >= 0)) {
+	    (hdsp->playback_pid >= 0) && (hdsp->capture_pid >= 0))
 		ret = 0;
-	}
 	spin_unlock_irqrestore(&hdsp->lock, flags);
 	return ret;
 }
@@ -880,9 +879,8 @@
 	unsigned int status = hdsp_read(hdsp, HDSP_statusRegister);
 	unsigned int rate_bits = (status & HDSP_spdifFrequencyMask);
 
-	if (status & HDSP_SPDIFErrorFlag) {
+	if (status & HDSP_SPDIFErrorFlag)
 		return 0;
-	}
 	
 	switch (rate_bits) {
 	case HDSP_spdifFrequency32KHz: return 32000;
@@ -918,9 +916,8 @@
 
 	position = hdsp_read(hdsp, HDSP_statusRegister);
 
-	if (!hdsp->precise_ptr) {
+	if (!hdsp->precise_ptr)
 		return (position & HDSP_BufferID) ? (hdsp->period_bytes / 4) : 0;
-	}
 
 	position &= HDSP_BufferPositionMask;
 	position /= 4;
@@ -989,19 +986,19 @@
 	if (!(hdsp->control_register & HDSP_ClockModeMaster)) {	
 		if (called_internally) {
 			/* request from ctl or card initialization */
-			snd_printk("Hammerfall-DSP: device is not running as a clock master: cannot set sample rate.\n");
+			snd_printk(KERN_ERR "Hammerfall-DSP: device is not running as a clock master: cannot set sample rate.\n");
 			return -1;
 		} else {		
 			/* hw_param request while in AutoSync mode */
 			int external_freq = hdsp_external_sample_rate(hdsp);
 			int spdif_freq = hdsp_spdif_sample_rate(hdsp);
 		
-			if ((spdif_freq == external_freq*2) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1)) {
-				snd_printk("Hammerfall-DSP: Detected ADAT in double speed mode\n");
-			} else if (hdsp->io_type == H9632 && (spdif_freq == external_freq*4) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1)) {
-				snd_printk("Hammerfall-DSP: Detected ADAT in quad speed mode\n");			
-			} else if (rate != external_freq) {
-				snd_printk("Hammerfall-DSP: No AutoSync source for requested rate\n");
+			if ((spdif_freq == external_freq*2) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1))
+				snd_printk(KERN_INFO "Hammerfall-DSP: Detected ADAT in double speed mode\n");
+			else if (hdsp->io_type == H9632 && (spdif_freq == external_freq*4) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1))
+				snd_printk(KERN_INFO "Hammerfall-DSP: Detected ADAT in quad speed mode\n");			
+			else if (rate != external_freq) {
+				snd_printk(KERN_INFO "Hammerfall-DSP: No AutoSync source for requested rate\n");
 				return -1;
 			}		
 		}	
@@ -1019,63 +1016,53 @@
 	   exists for externally-driven rate changes. All we can do
 	   is to flag rate changes in the read/write routines.  */
 
-	if (rate > 96000 && hdsp->io_type != H9632) {
+	if (rate > 96000 && hdsp->io_type != H9632)
 		return -EINVAL;
-	}
 	
 	switch (rate) {
 	case 32000:
-		if (current_rate > 48000) {
+		if (current_rate > 48000)
 			reject_if_open = 1;
-		}
 		rate_bits = HDSP_Frequency32KHz;
 		break;
 	case 44100:
-		if (current_rate > 48000) {
+		if (current_rate > 48000)
 			reject_if_open = 1;
-		}
 		rate_bits = HDSP_Frequency44_1KHz;
 		break;
 	case 48000:
-		if (current_rate > 48000) {
+		if (current_rate > 48000)
 			reject_if_open = 1;
-		}
 		rate_bits = HDSP_Frequency48KHz;
 		break;
 	case 64000:
-		if (current_rate <= 48000 || current_rate > 96000) {
+		if (current_rate <= 48000 || current_rate > 96000)
 			reject_if_open = 1;
-		}
 		rate_bits = HDSP_Frequency64KHz;
 		break;
 	case 88200:
-		if (current_rate <= 48000 || current_rate > 96000) {
+		if (current_rate <= 48000 || current_rate > 96000)
 			reject_if_open = 1;
-		}
 		rate_bits = HDSP_Frequency88_2KHz;
 		break;
 	case 96000:
-		if (current_rate <= 48000 || current_rate > 96000) {
+		if (current_rate <= 48000 || current_rate > 96000)
 			reject_if_open = 1;
-		}
 		rate_bits = HDSP_Frequency96KHz;
 		break;
 	case 128000:
-		if (current_rate < 128000) {
+		if (current_rate < 128000)
 			reject_if_open = 1;
-		}
 		rate_bits = HDSP_Frequency128KHz;
 		break;
 	case 176400:
-		if (current_rate < 128000) {
+		if (current_rate < 128000)
 			reject_if_open = 1;
-		}
 		rate_bits = HDSP_Frequency176_4KHz;
 		break;
 	case 192000:
-		if (current_rate < 128000) {
+		if (current_rate < 128000)
 			reject_if_open = 1;
-		}
 		rate_bits = HDSP_Frequency192KHz;
 		break;
 	default:
@@ -1096,11 +1083,10 @@
 	if (rate >= 128000) {
 		hdsp->channel_map = channel_map_H9632_qs;
 	} else if (rate > 48000) {
-		if (hdsp->io_type == H9632) {
+		if (hdsp->io_type == H9632)
 			hdsp->channel_map = channel_map_H9632_ds;
-		} else {
+		else
 			hdsp->channel_map = channel_map_ds;
-		}
 	} else {
 		switch (hdsp->io_type) {
 		case Multiface:
@@ -1131,54 +1117,48 @@
 static unsigned char snd_hdsp_midi_read_byte (hdsp_t *hdsp, int id)
 {
 	/* the hardware already does the relevant bit-mask with 0xff */
-	if (id) {
+	if (id)
 		return hdsp_read(hdsp, HDSP_midiDataIn1);
-	} else {
+	else
 		return hdsp_read(hdsp, HDSP_midiDataIn0);
-	}
 }
 
 static void snd_hdsp_midi_write_byte (hdsp_t *hdsp, int id, int val)
 {
 	/* the hardware already does the relevant bit-mask with 0xff */
-	if (id) {
+	if (id)
 		hdsp_write(hdsp, HDSP_midiDataOut1, val);
-	} else {
+	else
 		hdsp_write(hdsp, HDSP_midiDataOut0, val);
-	}
 }
 
 static int snd_hdsp_midi_input_available (hdsp_t *hdsp, int id)
 {
-	if (id) {
+	if (id)
 		return (hdsp_read(hdsp, HDSP_midiStatusIn1) & 0xff);
-	} else {
+	else
 		return (hdsp_read(hdsp, HDSP_midiStatusIn0) & 0xff);
-	}
 }
 
 static int snd_hdsp_midi_output_possible (hdsp_t *hdsp, int id)
 {
 	int fifo_bytes_used;
 
-	if (id) {
+	if (id)
 		fifo_bytes_used = hdsp_read(hdsp, HDSP_midiStatusOut1) & 0xff;
-	} else {
+	else
 		fifo_bytes_used = hdsp_read(hdsp, HDSP_midiStatusOut0) & 0xff;
-	}
 
-	if (fifo_bytes_used < 128) {
+	if (fifo_bytes_used < 128)
 		return  128 - fifo_bytes_used;
-	} else {
+	else
 		return 0;
-	}
 }
 
 static void snd_hdsp_flush_midi_input (hdsp_t *hdsp, int id)
 {
-	while (snd_hdsp_midi_input_available (hdsp, id)) {
+	while (snd_hdsp_midi_input_available (hdsp, id))
 		snd_hdsp_midi_read_byte (hdsp, id);
-	}
 }
 
 static int snd_hdsp_midi_output_write (hdsp_midi_t *hmidi)
@@ -1219,28 +1199,23 @@
 	spin_lock_irqsave (&hmidi->lock, flags);
 	if ((n_pending = snd_hdsp_midi_input_available (hmidi->hdsp, hmidi->id)) > 0) {
 		if (hmidi->input) {
-			if (n_pending > (int)sizeof (buf)) {
+			if (n_pending > (int)sizeof (buf))
 				n_pending = sizeof (buf);
-			}
-			for (i = 0; i < n_pending; ++i) {
+			for (i = 0; i < n_pending; ++i)
 				buf[i] = snd_hdsp_midi_read_byte (hmidi->hdsp, hmidi->id);
-			}
-			if (n_pending) {
+			if (n_pending)
 				snd_rawmidi_receive (hmidi->input, buf, n_pending);
-			}
 		} else {
 			/* flush the MIDI input FIFO */
-			while (--n_pending) {
+			while (--n_pending)
 				snd_hdsp_midi_read_byte (hmidi->hdsp, hmidi->id);
-			}
 		}
 	}
 	hmidi->pending = 0;
-	if (hmidi->id) {
+	if (hmidi->id)
 		hmidi->hdsp->control_register |= HDSP_Midi1InterruptEnable;
-	} else {
+	else
 		hmidi->hdsp->control_register |= HDSP_Midi0InterruptEnable;
-	}
 	hdsp_write(hmidi->hdsp, HDSP_controlRegister, hmidi->hdsp->control_register);
 	spin_unlock_irqrestore (&hmidi->lock, flags);
 	return snd_hdsp_midi_output_write (hmidi);
@@ -1310,9 +1285,8 @@
 			hmidi->istimer++;
 		}
 	} else {
-		if (hmidi->istimer && --hmidi->istimer <= 0) {
+		if (hmidi->istimer && --hmidi->istimer <= 0)
 			del_timer (&hmidi->timer);
-		}
 	}
 	spin_unlock_irqrestore (&hmidi->lock, flags);
 	if (up)
@@ -1400,9 +1374,8 @@
 	spin_lock_init (&hdsp->midi[id].lock);
 
 	sprintf (buf, "%s MIDI %d", card->shortname, id+1);
-	if (snd_rawmidi_new (card, buf, id, 1, 1, &hdsp->midi[id].rmidi) < 0) {
+	if (snd_rawmidi_new (card, buf, id, 1, 1, &hdsp->midi[id].rmidi) < 0)
 		return -1;
-	}
 
 	sprintf (hdsp->midi[id].rmidi->name, "%s MIDI %d", card->id, id+1);
 	hdsp->midi[id].rmidi->private_data = &hdsp->midi[id];
@@ -1588,11 +1561,10 @@
 
 static int hdsp_set_spdif_output(hdsp_t *hdsp, int out)
 {
-	if (out) {
+	if (out)
 		hdsp->control_register |= HDSP_SPDIFOpticalOut;
-	} else {
+	else
 		hdsp->control_register &= ~HDSP_SPDIFOpticalOut;
-	}
 	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
 	return 0;
 }
@@ -1642,11 +1614,10 @@
 
 static int hdsp_set_spdif_professional(hdsp_t *hdsp, int val)
 {
-	if (val) {
+	if (val)
 		hdsp->control_register |= HDSP_SPDIFProfessional;
-	} else {
+	else
 		hdsp->control_register &= ~HDSP_SPDIFProfessional;
-	}
 	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
 	return 0;
 }
@@ -1687,11 +1658,10 @@
 
 static int hdsp_set_spdif_emphasis(hdsp_t *hdsp, int val)
 {
-	if (val) {
+	if (val)
 		hdsp->control_register |= HDSP_SPDIFEmphasis;
-	} else {
+	else
 		hdsp->control_register &= ~HDSP_SPDIFEmphasis;
-	}
 	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
 	return 0;
 }
@@ -1732,11 +1702,10 @@
 
 static int hdsp_set_spdif_nonaudio(hdsp_t *hdsp, int val)
 {
-	if (val) {
+	if (val)
 		hdsp->control_register |= HDSP_SPDIFNonAudio;
-	} else {
+	else
 		hdsp->control_register &= ~HDSP_SPDIFNonAudio;
-	}
 	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
 	return 0;
 }
@@ -1921,11 +1890,10 @@
 
 static int hdsp_system_clock_mode(hdsp_t *hdsp)
 {
-	if (hdsp->control_register & HDSP_ClockModeMaster) {
+	if (hdsp->control_register & HDSP_ClockModeMaster)
 		return 0;
-	} else if (hdsp_external_sample_rate(hdsp) != hdsp->system_sample_rate) {
+	else if (hdsp_external_sample_rate(hdsp) != hdsp->system_sample_rate)
 			return 0;
-	}
 	return 1;
 }
 
@@ -2074,16 +2042,17 @@
 	val = ucontrol->value.enumerated.item[0];
 	if (val < 0) val = 0;
 	if (hdsp->io_type == H9632) {
-	    if (val > 9) val = 9;
+		if (val > 9)
+			val = 9;
 	} else {
-	    if (val > 6) val = 6;
+		if (val > 6)
+			val = 6;
 	}
 	spin_lock_irq(&hdsp->lock);
-	if (val != hdsp_clock_source(hdsp)) {
+	if (val != hdsp_clock_source(hdsp))
 		change = (hdsp_set_clock_source(hdsp, val) == 0) ? 1 : 0;
-	} else {
+	else
 		change = 0;
-	}
 	spin_unlock_irq(&hdsp->lock);
 	return change;
 }
@@ -2193,11 +2162,10 @@
 	if (val < 0) val = 0;
 	if (val > 2) val = 2;
 	spin_lock_irq(&hdsp->lock);
-	if (val != hdsp_da_gain(hdsp)) {
+	if (val != hdsp_da_gain(hdsp))
 		change = (hdsp_set_da_gain(hdsp, val) == 0) ? 1 : 0;
-	} else {
+	else
 		change = 0;
-	}
 	spin_unlock_irq(&hdsp->lock);
 	return change;
 }
@@ -2279,11 +2247,10 @@
 	if (val < 0) val = 0;
 	if (val > 2) val = 2;
 	spin_lock_irq(&hdsp->lock);
-	if (val != hdsp_ad_gain(hdsp)) {
+	if (val != hdsp_ad_gain(hdsp))
 		change = (hdsp_set_ad_gain(hdsp, val) == 0) ? 1 : 0;
-	} else {
+	else
 		change = 0;
-	}
 	spin_unlock_irq(&hdsp->lock);
 	return change;
 }
@@ -2365,11 +2332,10 @@
 	if (val < 0) val = 0;
 	if (val > 2) val = 2;
 	spin_lock_irq(&hdsp->lock);
-	if (val != hdsp_phone_gain(hdsp)) {
+	if (val != hdsp_phone_gain(hdsp))
 		change = (hdsp_set_phone_gain(hdsp, val) == 0) ? 1 : 0;
-	} else {
+	else
 		change = 0;
-	}
 	spin_unlock_irq(&hdsp->lock);
 	return change;
 }
@@ -2385,19 +2351,17 @@
 
 static int hdsp_xlr_breakout_cable(hdsp_t *hdsp)
 {
-	if (hdsp->control_register & HDSP_XLRBreakoutCable) {
+	if (hdsp->control_register & HDSP_XLRBreakoutCable)
 		return 1;
-	}
 	return 0;
 }
 
 static int hdsp_set_xlr_breakout_cable(hdsp_t *hdsp, int mode)
 {
-	if (mode) {
+	if (mode)
 		hdsp->control_register |= HDSP_XLRBreakoutCable;
-	} else {
+	else
 		hdsp->control_register &= ~HDSP_XLRBreakoutCable;
-	}
 	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
 	return 0;
 }
@@ -2450,19 +2414,17 @@
 
 static int hdsp_aeb(hdsp_t *hdsp)
 {
-	if (hdsp->control_register & HDSP_AnalogExtensionBoard) {
+	if (hdsp->control_register & HDSP_AnalogExtensionBoard)
 		return 1;
-	}
 	return 0;
 }
 
 static int hdsp_set_aeb(hdsp_t *hdsp, int mode)
 {
-	if (mode) {
+	if (mode)
 		hdsp->control_register |= HDSP_AnalogExtensionBoard;
-	} else {
+	else
 		hdsp->control_register &= ~HDSP_AnalogExtensionBoard;
-	}
 	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
 	return 0;
 }
@@ -2705,11 +2667,10 @@
 
 static int hdsp_set_line_output(hdsp_t *hdsp, int out)
 {
-	if (out) {
+	if (out)
 		hdsp->control_register |= HDSP_LineOut;
-	} else {
+	else
 		hdsp->control_register &= ~HDSP_LineOut;
-	}
 	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
 	return 0;
 }
@@ -2760,11 +2721,10 @@
 
 static int hdsp_set_precise_pointer(hdsp_t *hdsp, int precise)
 {
-	if (precise) {
+	if (precise)
 		hdsp->precise_ptr = 1;
-	} else {
+	else
 		hdsp->precise_ptr = 0;
-	}
 	return 0;
 }
 
@@ -2814,11 +2774,10 @@
 
 static int hdsp_set_use_midi_tasklet(hdsp_t *hdsp, int use_tasklet)
 {
-	if (use_tasklet) {
+	if (use_tasklet)
 		hdsp->use_midi_tasklet = 1;
-	} else {
+	else
 		hdsp->use_midi_tasklet = 0;
-	}
 	return 0;
 }
 
@@ -2889,11 +2848,10 @@
 	source = ucontrol->value.integer.value[0];
 	destination = ucontrol->value.integer.value[1];
 	
-	if (source >= hdsp->max_channels) {
+	if (source >= hdsp->max_channels)
 		addr = hdsp_playback_to_output_key(hdsp,source-hdsp->max_channels,destination);
-	} else {
+	else
 		addr = hdsp_input_to_output_key(hdsp,source, destination);
-	}
 	
 	spin_lock_irq(&hdsp->lock);
 	ucontrol->value.integer.value[2] = hdsp_read_gain (hdsp, addr);
@@ -2916,11 +2874,10 @@
 	source = ucontrol->value.integer.value[0];
 	destination = ucontrol->value.integer.value[1];
 
-	if (source >= hdsp->max_channels) {
+	if (source >= hdsp->max_channels)
 		addr = hdsp_playback_to_output_key(hdsp,source-hdsp->max_channels, destination);
-	} else {
+	else
 		addr = hdsp_input_to_output_key(hdsp,source, destination);
-	}
 
 	gain = ucontrol->value.integer.value[2];
 
@@ -2957,14 +2914,12 @@
 {
 	int status2 = hdsp_read(hdsp, HDSP_status2Register);
 	if (status2 & HDSP_wc_lock) {
-		if (status2 & HDSP_wc_sync) {
+		if (status2 & HDSP_wc_sync)
 			return 2;
-		} else {
+		else
 			 return 1;
-		}
-	} else {		
+	} else
 		return 0;
-	}
 	return 0;
 }
 
@@ -2988,14 +2943,13 @@
 static int hdsp_spdif_sync_check(hdsp_t *hdsp)
 {
 	int status = hdsp_read(hdsp, HDSP_statusRegister);
-	if (status & HDSP_SPDIFErrorFlag) {
+	if (status & HDSP_SPDIFErrorFlag)
 		return 0;
-	} else {	
-		if (status & HDSP_SPDIFSync) {
+	else {	
+		if (status & HDSP_SPDIFSync)
 			return 2;
-		} else {
+		else
 			return 1;
-		}
 	}
 	return 0;
 }
@@ -3021,14 +2975,12 @@
 {
 	int status = hdsp_read(hdsp, HDSP_statusRegister);
 	if (status & HDSP_TimecodeLock) {
-		if (status & HDSP_TimecodeSync) {
+		if (status & HDSP_TimecodeSync)
 			return 2;
-		} else {
+		else
 			return 1;
-		}
-	} else {
+	} else
 		return 0;
-	}
 }	
 
 static int snd_hdsp_get_adatsync_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
@@ -3051,14 +3003,12 @@
 	int status = hdsp_read(hdsp, HDSP_statusRegister);
 	
 	if (status & (HDSP_Lock0>>idx)) {
-		if (status & (HDSP_Sync0>>idx)) {
+		if (status & (HDSP_Sync0>>idx))
 			return 2;
-		} else {
+		else
 			return 1;		
-		}
-	} else {
+	} else
 		return 0;
-	}		
 } 
 
 static int snd_hdsp_get_adat_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
@@ -3171,9 +3121,8 @@
 	snd_kcontrol_t *kctl;
 
 	for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_controls); idx++) {
-		if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0) {
+		if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0)
 			return err;
-		}
 		if (idx == 1)	/* IEC958 (S/PDIF) Stream */
 			hdsp->spdif_ctl = kctl;
 	}
@@ -3181,32 +3130,28 @@
 	/* ADAT SyncCheck status */
 	snd_hdsp_adat_sync_check.name = "ADAT Lock Status";
 	snd_hdsp_adat_sync_check.index = 1;
-	if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp)))) {
+	if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp))))
 		return err;
-	}	
 	if (hdsp->io_type == Digiface || hdsp->io_type == H9652) {
 		for (idx = 1; idx < 3; ++idx) {
 			snd_hdsp_adat_sync_check.index = idx+1;
-			if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp)))) {
+			if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp))))
 				return err;
-			}
 		}
 	}
 	
 	/* DA, AD and Phone gain and XLR breakout cable controls for H9632 cards */
 	if (hdsp->io_type == H9632) {
 		for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_9632_controls); idx++) {
-			if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_9632_controls[idx], hdsp))) < 0) {
+			if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_9632_controls[idx], hdsp))) < 0)
 				return err;
-			}
 		}
 	}
 
 	/* AEB control for H96xx card */
 	if (hdsp->io_type == H9632 || hdsp->io_type == H9652) {
-		if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_96xx_aeb, hdsp))) < 0) {
+		if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_96xx_aeb, hdsp))) < 0)
 				return err;
-		}	
 	}
 
 	return 0;
@@ -3228,12 +3173,11 @@
 	char *clock_source;
 	int x;
 
-	if (hdsp_check_for_iobox (hdsp)) {
+	if (hdsp_check_for_iobox (hdsp))
 		snd_iprintf(buffer, "No I/O box connected.\nPlease connect one and upload firmware.\n");
 		return;
-	}
 
-	if (hdsp_check_for_firmware(hdsp)) {
+	if (hdsp_check_for_firmware(hdsp, 0)) {
 		if (hdsp->state & HDSP_FirmwareCached) {
 			if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
 				snd_iprintf(buffer, "Firmware loading from cache failed, please upload manually.\n");
@@ -3314,11 +3258,10 @@
 	}
 	snd_iprintf (buffer, "Sample Clock Source: %s\n", clock_source);
 			
-	if (hdsp_system_clock_mode(hdsp)) {
+	if (hdsp_system_clock_mode(hdsp))
 		system_clock_mode = "Slave";
-	} else {
+	else
 		system_clock_mode = "Master";
-	}
 	
 	switch (hdsp_pref_sync_ref (hdsp)) {
 	case HDSP_SYNC_FROM_WORD:
@@ -3400,85 +3343,75 @@
 		break;
 	}
 	
-	if (hdsp->control_register & HDSP_SPDIFOpticalOut) {
+	if (hdsp->control_register & HDSP_SPDIFOpticalOut)
 		snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n");
-	} else {
+	else
 		snd_iprintf(buffer, "IEC958 output: Coaxial only\n");
-	}
 
-	if (hdsp->control_register & HDSP_SPDIFProfessional) {
+	if (hdsp->control_register & HDSP_SPDIFProfessional)
 		snd_iprintf(buffer, "IEC958 quality: Professional\n");
-	} else {
+	else
 		snd_iprintf(buffer, "IEC958 quality: Consumer\n");
-	}
 
-	if (hdsp->control_register & HDSP_SPDIFEmphasis) {
+	if (hdsp->control_register & HDSP_SPDIFEmphasis)
 		snd_iprintf(buffer, "IEC958 emphasis: on\n");
-	} else {
+	else
 		snd_iprintf(buffer, "IEC958 emphasis: off\n");
-	}
 
-	if (hdsp->control_register & HDSP_SPDIFNonAudio) {
+	if (hdsp->control_register & HDSP_SPDIFNonAudio)
 		snd_iprintf(buffer, "IEC958 NonAudio: on\n");
-	} else {
+	else
 		snd_iprintf(buffer, "IEC958 NonAudio: off\n");
-	}
-	if ((x = hdsp_spdif_sample_rate (hdsp)) != 0) {
+	if ((x = hdsp_spdif_sample_rate (hdsp)) != 0)
 		snd_iprintf (buffer, "IEC958 sample rate: %d\n", x);
-	} else {
+	else
 		snd_iprintf (buffer, "IEC958 sample rate: Error flag set\n");
-	}
 
 	snd_iprintf(buffer, "\n");
 
 	/* Sync Check */
 	x = status & HDSP_Sync0;
-	if (status & HDSP_Lock0) {
+	if (status & HDSP_Lock0)
 		snd_iprintf(buffer, "ADAT1: %s\n", x ? "Sync" : "Lock");
-	} else {
+	else
 		snd_iprintf(buffer, "ADAT1: No Lock\n");
-	}
 
 	switch (hdsp->io_type) {
 	case Digiface:
 	case H9652:
 		x = status & HDSP_Sync1;
-		if (status & HDSP_Lock1) {
+		if (status & HDSP_Lock1)
 			snd_iprintf(buffer, "ADAT2: %s\n", x ? "Sync" : "Lock");
-		} else {
+		else
 			snd_iprintf(buffer, "ADAT2: No Lock\n");
-		}
 		x = status & HDSP_Sync2;
-		if (status & HDSP_Lock2) {
+		if (status & HDSP_Lock2)
 			snd_iprintf(buffer, "ADAT3: %s\n", x ? "Sync" : "Lock");
-		} else {
+		else
 			snd_iprintf(buffer, "ADAT3: No Lock\n");
-		}
+		break;
 	default:
 		/* relax */
 		break;
 	}
 
 	x = status & HDSP_SPDIFSync;
-	if (status & HDSP_SPDIFErrorFlag) {
+	if (status & HDSP_SPDIFErrorFlag)
 		snd_iprintf (buffer, "SPDIF: No Lock\n");
-	} else {
+	else
 		snd_iprintf (buffer, "SPDIF: %s\n", x ? "Sync" : "Lock");
-	}
 	
 	x = status2 & HDSP_wc_sync;
-	if (status2 & HDSP_wc_lock) {
+	if (status2 & HDSP_wc_lock)
 		snd_iprintf (buffer, "Word Clock: %s\n", x ? "Sync" : "Lock");
-	} else {
+	else
 		snd_iprintf (buffer, "Word Clock: No Lock\n");
-	}
 	
 	x = status & HDSP_TimecodeSync;
-	if (status & HDSP_TimecodeLock) {
+	if (status & HDSP_TimecodeLock)
 		snd_iprintf(buffer, "ADAT Sync: %s\n", x ? "Sync" : "Lock");
-	} else {
+	else
 		snd_iprintf(buffer, "ADAT Sync: No Lock\n");
-	}
 
 	snd_iprintf(buffer, "\n");
 	
@@ -3527,11 +3460,10 @@
 
 		snd_iprintf(buffer, "XLR Breakout Cable : %s\n", hdsp_xlr_breakout_cable(hdsp) ? "yes" : "no");	
 		
-		if (hdsp->control_register & HDSP_AnalogExtensionBoard) {
+		if (hdsp->control_register & HDSP_AnalogExtensionBoard)
 			snd_iprintf(buffer, "AEB : on (ADAT1 internal)\n");
-		} else {
+		else
 			snd_iprintf(buffer, "AEB : off (ADAT1 external)\n");
-		}
 		snd_iprintf(buffer, "\n");
 	}
 
@@ -3610,25 +3542,22 @@
 #else
 	hdsp->control2_register = 0;
 #endif
-	if (hdsp->io_type == H9652) {
+	if (hdsp->io_type == H9652)
 	        snd_hdsp_9652_enable_mixer (hdsp);
-	} else {
-	    hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register);
-	} 
+	else
+		hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register);
 
 	hdsp_reset_hw_pointer(hdsp);
 	hdsp_compute_period_size(hdsp);
 
 	/* silence everything */
 	
-	for (i = 0; i < HDSP_MATRIX_MIXER_SIZE; ++i) {
+	for (i = 0; i < HDSP_MATRIX_MIXER_SIZE; ++i)
 		hdsp->mixer_matrix[i] = MINUS_INFINITY_GAIN;
-	}
 
 	for (i = 0; i < ((hdsp->io_type == H9652 || hdsp->io_type == H9632) ? 1352 : HDSP_MATRIX_MIXER_SIZE); ++i) {
-		if (hdsp_write_gain (hdsp, i, MINUS_INFINITY_GAIN)) {
+		if (hdsp_write_gain (hdsp, i, MINUS_INFINITY_GAIN))
 			return -EIO;
-		}
 	}
 	
 	/* H9632 specific defaults */
@@ -3649,12 +3578,10 @@
 {
 	hdsp_t *hdsp = (hdsp_t *)arg;
 	
-	if (hdsp->midi[0].pending) {
+	if (hdsp->midi[0].pending)
 		snd_hdsp_midi_input_read (&hdsp->midi[0]);
-	}
-	if (hdsp->midi[1].pending) {
+	if (hdsp->midi[1].pending)
 		snd_hdsp_midi_input_read (&hdsp->midi[1]);
-	}
 } 
 
 static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -3674,9 +3601,8 @@
 	midi0 = status & HDSP_midi0IRQPending;
 	midi1 = status & HDSP_midi1IRQPending;
 
-	if (!audio && !midi0 && !midi1) {
+	if (!audio && !midi0 && !midi1)
 		return IRQ_NONE;
-	}
 
 	hdsp_write(hdsp, HDSP_interruptConfirmation, 0);
 
@@ -3684,13 +3610,11 @@
 	midi1status = hdsp_read (hdsp, HDSP_midiStatusIn1) & 0xff;
 	
 	if (audio) {
-		if (hdsp->capture_substream) {
+		if (hdsp->capture_substream)
 			snd_pcm_period_elapsed(hdsp->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
-		}
 		
-		if (hdsp->playback_substream) {
+		if (hdsp->playback_substream)
 			snd_pcm_period_elapsed(hdsp->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream);
-		}
 	}
 	
 	if (midi0 && midi0status) {
@@ -3735,15 +3659,13 @@
 
         snd_assert(channel >= 0 && channel < hdsp->max_channels, return NULL);
         
-	if ((mapped_channel = hdsp->channel_map[channel]) < 0) {
+	if ((mapped_channel = hdsp->channel_map[channel]) < 0)
 		return NULL;
-	}
 	
-	if (stream == SNDRV_PCM_STREAM_CAPTURE) {
+	if (stream == SNDRV_PCM_STREAM_CAPTURE)
 		return hdsp->capture_buffer + (mapped_channel * HDSP_CHANNEL_BUFFER_BYTES);
-	} else {
+	else
 		return hdsp->playback_buffer + (mapped_channel * HDSP_CHANNEL_BUFFER_BYTES);
-	}
 }
 
 static int snd_hdsp_playback_copy(snd_pcm_substream_t *substream, int channel,
@@ -3824,20 +3746,11 @@
 	pid_t this_pid;
 	pid_t other_pid;
 
-	if (hdsp_check_for_iobox (hdsp)) {
+	if (hdsp_check_for_iobox (hdsp))
 		return -EIO;
-	}
 
-	if (hdsp_check_for_firmware(hdsp)) {
-		if (hdsp->state & HDSP_FirmwareCached) {
-			if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
-				snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
-			}
-		} else {
-			snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
-		}
+	if (hdsp_check_for_firmware(hdsp, 1))
 		return -EIO;
-	}
 
 	spin_lock_irq(&hdsp->lock);
 
@@ -3908,9 +3821,8 @@
 
 	snd_assert(info->channel < hdsp->max_channels, return -EINVAL);
 
-	if ((mapped_channel = hdsp->channel_map[info->channel]) < 0) {
+	if ((mapped_channel = hdsp->channel_map[info->channel]) < 0)
 		return -EINVAL;
-	}
 
 	info->offset = mapped_channel * HDSP_CHANNEL_BUFFER_BYTES;
 	info->first = 0;
@@ -3923,14 +3835,9 @@
 {
 	switch (cmd) {
 	case SNDRV_PCM_IOCTL1_RESET:
-	{
 		return snd_hdsp_reset(substream);
-	}
 	case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
-	{
-		snd_pcm_channel_info_t *info = arg;
-		return snd_hdsp_channel_info(substream, info);
-	}
+		return snd_hdsp_channel_info(substream, arg);
 	default:
 		break;
 	}
@@ -3944,20 +3851,11 @@
 	snd_pcm_substream_t *other;
 	int running;
 	
-	if (hdsp_check_for_iobox (hdsp)) {
+	if (hdsp_check_for_iobox (hdsp))
 		return -EIO;
-	}
 
-	if (hdsp_check_for_firmware(hdsp)) {
-		if (hdsp->state & HDSP_FirmwareCached) {
-			if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
-				snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
-			}
-		} else {
-			snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
-		}
+	if (hdsp_check_for_firmware(hdsp, 1))
 		return -EIO;
-	}
 
 	spin_lock(&hdsp->lock);
 	running = hdsp->running;
@@ -4022,20 +3920,11 @@
 	hdsp_t *hdsp = snd_pcm_substream_chip(substream);
 	int result = 0;
 
-	if (hdsp_check_for_iobox (hdsp)) {
+	if (hdsp_check_for_iobox (hdsp))
 		return -EIO;
-	}
 
-	if (hdsp_check_for_firmware(hdsp)) {
-		if (hdsp->state & HDSP_FirmwareCached) {
-			if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
-				snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
-			}
-		} else {
-			snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
-		}
+	if (hdsp_check_for_firmware(hdsp, 1))
 		return -EIO;
-	}
 
 	spin_lock_irq(&hdsp->lock);
 	if (!hdsp->running)
@@ -4285,20 +4174,11 @@
 	hdsp_t *hdsp = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 
-	if (hdsp_check_for_iobox (hdsp)) {
+	if (hdsp_check_for_iobox (hdsp))
 		return -EIO;
-	}
 
-	if (hdsp_check_for_firmware(hdsp)) {
-		if (hdsp->state & HDSP_FirmwareCached) {
-			if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
-				snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
-			}
-		} else {
-			snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
-		}
+	if (hdsp_check_for_firmware(hdsp, 1))
 		return -EIO;
-	}
 
 	spin_lock_irq(&hdsp->lock);
 
@@ -4367,20 +4247,11 @@
 	hdsp_t *hdsp = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 
-	if (hdsp_check_for_iobox (hdsp)) {
+	if (hdsp_check_for_iobox (hdsp))
 		return -EIO;
-	}
 
-	if (hdsp_check_for_firmware(hdsp)) {
-		if (hdsp->state & HDSP_FirmwareCached) {
-			if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
-				snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
-			}
-		} else {
-			snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
-		}
+	if (hdsp_check_for_firmware(hdsp, 1))
 		return -EIO;
-	}
 
 	spin_lock_irq(&hdsp->lock);
 
@@ -4589,19 +4460,17 @@
 		int i;
 		
 		if (!(hdsp->state & HDSP_FirmwareLoaded)) {
-			snd_printk("Hammerfall-DSP: Firmware needs to be uploaded to the card.\n");	
+			snd_printk(KERN_ERR "Hammerfall-DSP: Firmware needs to be uploaded to the card.\n");	
 			return -EINVAL;
 		}
 		spin_lock_irqsave(&hdsp->lock, flags);
 		info.pref_sync_ref = (unsigned char)hdsp_pref_sync_ref(hdsp);
 		info.wordclock_sync_check = (unsigned char)hdsp_wc_sync_check(hdsp);
-		if (hdsp->io_type != H9632) {
+		if (hdsp->io_type != H9632)
 		    info.adatsync_sync_check = (unsigned char)hdsp_adatsync_sync_check(hdsp);
-		}
 		info.spdif_sync_check = (unsigned char)hdsp_spdif_sync_check(hdsp);
-		for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != H9632) ? 3 : 1); ++i) {
+		for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != H9632) ? 3 : 1); ++i)
 			info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i);
-		}
 		info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp);
 		info.spdif_out = (unsigned char)hdsp_spdif_out(hdsp);
 		info.spdif_professional = (unsigned char)hdsp_spdif_professional(hdsp);
@@ -4621,9 +4490,8 @@
 			info.xlr_breakout_cable = (unsigned char)hdsp_xlr_breakout_cable(hdsp);
 		
 		}
-		if (hdsp->io_type == H9632 || hdsp->io_type == H9652) {
+		if (hdsp->io_type == H9632 || hdsp->io_type == H9652)
 			info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp);
-		}
 		spin_unlock_irqrestore(&hdsp->lock, flags);
 		if (copy_to_user(argp, &info, sizeof(info)))
 			return -EFAULT;
@@ -4645,15 +4513,13 @@
 		
 		if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return -EINVAL;
 		if (hdsp->io_type == Undefined) {
-			if ((err = hdsp_get_iobox_version(hdsp)) < 0) {
+			if ((err = hdsp_get_iobox_version(hdsp)) < 0)
 				return err;
-			}
 		}
 		hdsp_version.io_type = hdsp->io_type;
 		hdsp_version.firmware_rev = hdsp->firmware_rev;
-		if ((err = copy_to_user(argp, &hdsp_version, sizeof(hdsp_version)))) {
+		if ((err = copy_to_user(argp, &hdsp_version, sizeof(hdsp_version))))
 		    	return -EFAULT;
-		}
 		break;
 	}
 	case SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE: {
@@ -4668,38 +4534,33 @@
 		if (hdsp->state & (HDSP_FirmwareCached | HDSP_FirmwareLoaded))
 			return -EBUSY;
 
-		snd_printk("Hammerfall-DSP: initializing firmware upload\n");
+		snd_printk(KERN_INFO "Hammerfall-DSP: initializing firmware upload\n");
 		firmware = (hdsp_firmware_t __user *)argp;
 
-		if (get_user(firmware_data, &firmware->firmware_data)) {
+		if (get_user(firmware_data, &firmware->firmware_data))
 			return -EFAULT;
-		}
 		
-		if (hdsp_check_for_iobox (hdsp)) {
+		if (hdsp_check_for_iobox (hdsp))
 			return -EIO;
-		}
 
-		if (copy_from_user(hdsp->firmware_cache, firmware_data, sizeof(hdsp->firmware_cache)) != 0) {
+		if (copy_from_user(hdsp->firmware_cache, firmware_data, sizeof(hdsp->firmware_cache)) != 0)
 			return -EFAULT;
-		}
 		
 		hdsp->state |= HDSP_FirmwareCached;
 
-		if ((err = snd_hdsp_load_firmware_from_cache(hdsp)) < 0) {
+		if ((err = snd_hdsp_load_firmware_from_cache(hdsp)) < 0)
 			return err;
-		}
 		
 		if (!(hdsp->state & HDSP_InitializationComplete)) {
-			if ((err = snd_hdsp_enable_io(hdsp)) < 0) {
+			if ((err = snd_hdsp_enable_io(hdsp)) < 0)
 				return err;
-			}
 			
 			snd_hdsp_initialize_channels(hdsp);		
 			snd_hdsp_initialize_midi_flush(hdsp);
 	    
 			if ((err = snd_hdsp_create_alsa_devices(hdsp->card, hdsp)) < 0) {
-				snd_printk("Hammerfall-DSP: error creating alsa devices\n");
-			    return err;
+				snd_printk(KERN_ERR "Hammerfall-DSP: error creating alsa devices\n");
+				return err;
 			}
 		}
 		break;
@@ -4790,7 +4651,7 @@
 	int i;
 	
 	if (hdsp_fifo_wait (hdsp, 0, 100)) {
-		snd_printk("Hammerfall-DSP: enable_io fifo_wait failed\n");
+		snd_printk(KERN_ERR "Hammerfall-DSP: enable_io fifo_wait failed\n");
 		return -EIO;
 	}
 	
@@ -4856,25 +4717,25 @@
 	int err;
 	
 	if ((err = snd_hdsp_create_pcm(card, hdsp)) < 0) {
-		snd_printk("Hammerfall-DSP: Error creating pcm interface\n");
+		snd_printk(KERN_ERR "Hammerfall-DSP: Error creating pcm interface\n");
 		return err;
 	}
 	
 
 	if ((err = snd_hdsp_create_midi(card, hdsp, 0)) < 0) {
-		snd_printk("Hammerfall-DSP: Error creating first midi interface\n");
+		snd_printk(KERN_ERR "Hammerfall-DSP: Error creating first midi interface\n");
 		return err;
 	}
 
 	if (hdsp->io_type == Digiface || hdsp->io_type == H9652) {
 		if ((err = snd_hdsp_create_midi(card, hdsp, 1)) < 0) {
-			snd_printk("Hammerfall-DSP: Error creating second midi interface\n");
+			snd_printk(KERN_ERR "Hammerfall-DSP: Error creating second midi interface\n");
 			return err;
 		}
 	}
 
 	if ((err = snd_hdsp_create_controls(card, hdsp)) < 0) {
-		snd_printk("Hammerfall-DSP: Error creating ctl interface\n");
+		snd_printk(KERN_ERR "Hammerfall-DSP: Error creating ctl interface\n");
 		return err;
 	}
 
@@ -4887,7 +4748,7 @@
 	hdsp->playback_substream = NULL;
 
 	if ((err = snd_hdsp_set_defaults(hdsp)) < 0) {
-		snd_printk("Hammerfall-DSP: Error setting default values\n");
+		snd_printk(KERN_ERR "Hammerfall-DSP: Error setting default values\n");
 		return err;
 	}
 	
@@ -4897,7 +4758,7 @@
 			hdsp->port, hdsp->irq);
 	    
 		if ((err = snd_card_register(card)) < 0) {
-			snd_printk("Hammerfall-DSP: error registering card\n");
+			snd_printk(KERN_ERR "Hammerfall-DSP: error registering card\n");
 			return err;
 		}
 		hdsp->state |= HDSP_InitializationComplete;
@@ -4963,18 +4824,17 @@
 		return err;
 		
 	if (!(hdsp->state & HDSP_InitializationComplete)) {
-		if ((err = snd_hdsp_enable_io(hdsp)) < 0) {
+		if ((err = snd_hdsp_enable_io(hdsp)) < 0)
 			return err;
-		}
 
 		if ((err = snd_hdsp_create_hwdep(hdsp->card, hdsp)) < 0) {
-			snd_printk("Hammerfall-DSP: error creating hwdep device\n");
+			snd_printk(KERN_ERR "Hammerfall-DSP: error creating hwdep device\n");
 			return err;
 		}
 		snd_hdsp_initialize_channels(hdsp);
 		snd_hdsp_initialize_midi_flush(hdsp);
 		if ((err = snd_hdsp_create_alsa_devices(hdsp->card, hdsp)) < 0) {
-			snd_printk("Hammerfall-DSP: error creating alsa devices\n");
+			snd_printk(KERN_ERR "Hammerfall-DSP: error creating alsa devices\n");
 			return err;
 		}
 	}
@@ -5029,11 +4889,11 @@
 	strcpy(card->driver, "H-DSP");
 	strcpy(card->mixername, "Xilinx FPGA");
 
-	if (hdsp->firmware_rev < 0xa) {
+	if (hdsp->firmware_rev < 0xa)
 		return -ENODEV;
-	} else if (hdsp->firmware_rev < 0x64) {
+	else if (hdsp->firmware_rev < 0x64)
 		hdsp->card_name = "RME Hammerfall DSP";
-	} else if (hdsp->firmware_rev < 0x96) {
+	else if (hdsp->firmware_rev < 0x96) {
 		hdsp->card_name = "RME HDSP 9652";
 		is_9652 = 1;
 	} else {
@@ -5042,9 +4902,8 @@
 		is_9632 = 1;	
 	}
 
-	if ((err = pci_enable_device(pci)) < 0) {
+	if ((err = pci_enable_device(pci)) < 0)
 		return err;
-	}
 
 	pci_set_master(hdsp->pci);
 
@@ -5052,12 +4911,12 @@
 		return err;
 	hdsp->port = pci_resource_start(pci, 0);
 	if ((hdsp->iobase = ioremap_nocache(hdsp->port, HDSP_IO_EXTENT)) == NULL) {
-		snd_printk("Hammerfall-DSP: unable to remap region 0x%lx-0x%lx\n", hdsp->port, hdsp->port + HDSP_IO_EXTENT - 1);
+		snd_printk(KERN_ERR "Hammerfall-DSP: unable to remap region 0x%lx-0x%lx\n", hdsp->port, hdsp->port + HDSP_IO_EXTENT - 1);
 		return -EBUSY;
 	}
 
 	if (request_irq(pci->irq, snd_hdsp_interrupt, SA_INTERRUPT|SA_SHIRQ, "hdsp", (void *)hdsp)) {
-		snd_printk("Hammerfall-DSP: unable to use IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "Hammerfall-DSP: unable to use IRQ %d\n", pci->irq);
 		return -EBUSY;
 	}
 
@@ -5065,71 +4924,58 @@
 	hdsp->precise_ptr = 1;
 	hdsp->use_midi_tasklet = 1;
 
-	if ((err = snd_hdsp_initialize_memory(hdsp)) < 0) {
+	if ((err = snd_hdsp_initialize_memory(hdsp)) < 0)
 		return err;
-	}
 	
 	if (!is_9652 && !is_9632) {
 		/* we wait 2 seconds to let freshly inserted cardbus cards do their hardware init */
- 		if ((1000 / HZ) < 2000) {
-			ssleep(2);
-		} else {
-			mdelay(2000);
-		}
+		ssleep(2);
 
 		if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
 #ifdef HDSP_FW_LOADER
-			if ((err = hdsp_request_fw_loader(hdsp)) < 0) {
+			if ((err = hdsp_request_fw_loader(hdsp)) < 0)
 				/* we don't fail as this can happen
 				   if userspace is not ready for
 				   firmware upload
 				*/
-				snd_printk("Hammerfall-DSP: couldn't get firmware from userspace. try using hdsploader\n");
-			} else {
+				snd_printk(KERN_ERR "Hammerfall-DSP: couldn't get firmware from userspace. try using hdsploader\n");
+			else
 				/* init is complete, we return */
 				return 0;
-			}
 #endif
 			/* no iobox connected, we defer initialization */
-			snd_printk("Hammerfall-DSP: card initialization pending : waiting for firmware\n");
-			if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0) {
+			snd_printk(KERN_INFO "Hammerfall-DSP: card initialization pending : waiting for firmware\n");
+			if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0)
 				return err;
-			}
 			return 0;
 		} else {
-			snd_printk("Hammerfall-DSP: Firmware already present, initializing card.\n");	    
-			if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) {
+			snd_printk(KERN_INFO "Hammerfall-DSP: Firmware already present, initializing card.\n");	    
+			if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
 				hdsp->io_type = Multiface;
-			} else {
+			else 
 				hdsp->io_type = Digiface;
-			}
 		}
 	}
 	
-	if ((err = snd_hdsp_enable_io(hdsp)) != 0) {
+	if ((err = snd_hdsp_enable_io(hdsp)) != 0)
 		return err;
-	}
 	
-	if (is_9652) {
+	if (is_9652)
 	        hdsp->io_type = H9652;
-	}
 	
-	if (is_9632) {
+	if (is_9632)
 		hdsp->io_type = H9632;
-	}
 
-	if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0) {
+	if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0)
 		return err;
-	}
 	
 	snd_hdsp_initialize_channels(hdsp);
 	snd_hdsp_initialize_midi_flush(hdsp);
 
 	hdsp->state |= HDSP_FirmwareLoaded;	
 
-	if ((err = snd_hdsp_create_alsa_devices(card, hdsp)) < 0) {
+	if ((err = snd_hdsp_create_alsa_devices(card, hdsp)) < 0)
 		return err;
-	}
 
 	return 0;	
 }
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index fc3f328..60a1141 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -3563,8 +3563,7 @@
 		free_irq(hdspm->irq, (void *) hdspm);
 
 
-	if (hdspm->mixer)
-		kfree(hdspm->mixer);
+	kfree(hdspm->mixer);
 
 	if (hdspm->iobase)
 		iounmap(hdspm->iobase);
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index b600f45..59fcef9 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -779,7 +779,7 @@
 		break;
 
 	default:
-		snd_printk("%s: unknown S/PDIF input rate (bits = 0x%x)\n",
+		snd_printk(KERN_ERR "%s: unknown S/PDIF input rate (bits = 0x%x)\n",
 			   s->card_name, rate_bits);
 		return 0;
 		break;
@@ -2496,12 +2496,12 @@
 	rme9652->port = pci_resource_start(pci, 0);
 	rme9652->iobase = ioremap_nocache(rme9652->port, RME9652_IO_EXTENT);
 	if (rme9652->iobase == NULL) {
-		snd_printk("unable to remap region 0x%lx-0x%lx\n", rme9652->port, rme9652->port + RME9652_IO_EXTENT - 1);
+		snd_printk(KERN_ERR "unable to remap region 0x%lx-0x%lx\n", rme9652->port, rme9652->port + RME9652_IO_EXTENT - 1);
 		return -EBUSY;
 	}
 	
 	if (request_irq(pci->irq, snd_rme9652_interrupt, SA_INTERRUPT|SA_SHIRQ, "rme9652", (void *)rme9652)) {
-		snd_printk("unable to request IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to request IRQ %d\n", pci->irq);
 		return -EBUSY;
 	}
 	rme9652->irq = pci->irq;
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 1f6c2bf..9a35474 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -591,7 +591,7 @@
 		return IRQ_NONE;
 	if (status == 0xff) {	/* failure */
 		outb(sonic->irqmask = ~0, SV_REG(sonic, IRQMASK));
-		snd_printk("IRQ failure - interrupts disabled!!\n");
+		snd_printk(KERN_ERR "IRQ failure - interrupts disabled!!\n");
 		return IRQ_HANDLED;
 	}
 	if (sonic->pcm) {
@@ -1205,14 +1205,8 @@
 	pci_write_config_dword(sonic->pci, 0x48, sonic->dmac_port);
 	if (sonic->irq >= 0)
 		free_irq(sonic->irq, (void *)sonic);
-	if (sonic->res_dmaa) {
-		release_resource(sonic->res_dmaa);
-		kfree_nocheck(sonic->res_dmaa);
-	}
-	if (sonic->res_dmac) {
-		release_resource(sonic->res_dmac);
-		kfree_nocheck(sonic->res_dmac);
-	}
+	release_and_free_resource(sonic->res_dmaa);
+	release_and_free_resource(sonic->res_dmac);
 	pci_release_regions(sonic->pci);
 	pci_disable_device(sonic->pci);
 	kfree(sonic);
@@ -1245,7 +1239,7 @@
 	/* check, if we can restrict PCI DMA transfers to 24 bits */
         if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
 	    pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
-                snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
+		snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
 		pci_disable_device(pci);
                 return -ENXIO;
         }
@@ -1273,7 +1267,7 @@
 	sonic->game_port = pci_resource_start(pci, 4);
 
 	if (request_irq(pci->irq, snd_sonicvibes_interrupt, SA_INTERRUPT|SA_SHIRQ, "S3 SonicVibes", (void *)sonic)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_sonicvibes_free(sonic);
 		return -EBUSY;
 	}
@@ -1287,24 +1281,24 @@
 	if (!dmaa) {
 		dmaa = dmaio;
 		dmaio += 0x10;
-		snd_printk("BIOS did not allocate DDMA channel A i/o, allocated at 0x%x\n", dmaa);
+		snd_printk(KERN_INFO "BIOS did not allocate DDMA channel A i/o, allocated at 0x%x\n", dmaa);
 	}
 	if (!dmac) {
 		dmac = dmaio;
 		dmaio += 0x10;
-		snd_printk("BIOS did not allocate DDMA channel C i/o, allocated at 0x%x\n", dmac);
+		snd_printk(KERN_INFO "BIOS did not allocate DDMA channel C i/o, allocated at 0x%x\n", dmac);
 	}
 	pci_write_config_dword(pci, 0x40, dmaa);
 	pci_write_config_dword(pci, 0x48, dmac);
 
 	if ((sonic->res_dmaa = request_region(dmaa, 0x10, "S3 SonicVibes DDMA-A")) == NULL) {
 		snd_sonicvibes_free(sonic);
-		snd_printk("unable to grab DDMA-A port at 0x%x-0x%x\n", dmaa, dmaa + 0x10 - 1);
+		snd_printk(KERN_ERR "unable to grab DDMA-A port at 0x%x-0x%x\n", dmaa, dmaa + 0x10 - 1);
 		return -EBUSY;
 	}
 	if ((sonic->res_dmac = request_region(dmac, 0x10, "S3 SonicVibes DDMA-C")) == NULL) {
 		snd_sonicvibes_free(sonic);
-		snd_printk("unable to grab DDMA-C port at 0x%x-0x%x\n", dmac, dmac + 0x10 - 1);
+		snd_printk(KERN_ERR "unable to grab DDMA-C port at 0x%x-0x%x\n", dmac, dmac + 0x10 - 1);
 		return -EBUSY;
 	}
 
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 777da9a..b9b93c7 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -153,7 +153,7 @@
 	}
 
 	if (count == 0 && !trident->ac97_detect) {
-		snd_printk("ac97 codec read TIMEOUT [0x%x/0x%x]!!!\n", reg, data);
+		snd_printk(KERN_ERR "ac97 codec read TIMEOUT [0x%x/0x%x]!!!\n", reg, data);
 		data = 0;
 	}
 
@@ -2893,7 +2893,8 @@
 {
 	snd_ctl_elem_id_t id;
 
-	snd_runtime_check(kctl != NULL, return);
+	if (! kctl)
+		return;
 	if (activate)
 		kctl->vd[num].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
 	else
@@ -2989,13 +2990,13 @@
 		_ac97.num = 1;
 		err = snd_ac97_mixer(trident->ac97_bus, &_ac97, &trident->ac97_sec);
 		if (err < 0)
-			snd_printk("SI7018: the secondary codec - invalid access\n");
+			snd_printk(KERN_ERR "SI7018: the secondary codec - invalid access\n");
 #if 0	// only for my testing purpose --jk
 		{
 			ac97_t *mc97;
 			err = snd_ac97_modem(trident->card, &_ac97, &mc97);
 			if (err < 0)
-				snd_printk("snd_ac97_modem returned error %i\n", err);
+				snd_printk(KERN_ERR "snd_ac97_modem returned error %i\n", err);
 		}
 #endif
 	}
@@ -3206,8 +3207,7 @@
  */
 static inline void do_delay(trident_t *chip)
 {
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(1);
+	schedule_timeout_uninterruptible(1);
 }
 
 /*
@@ -3243,7 +3243,7 @@
 			goto __si7018_ok;
 		do_delay(trident);
 	} while (time_after_eq(end_time, jiffies));
-	snd_printk("AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)));
+	snd_printk(KERN_ERR "AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)));
 	if (r-- > 0) {
 		end_time = jiffies + HZ;
 		do {
@@ -3541,7 +3541,7 @@
 	/* check, if we can restrict PCI DMA transfers to 30 bits */
 	if (pci_set_dma_mask(pci, 0x3fffffff) < 0 ||
 	    pci_set_consistent_dma_mask(pci, 0x3fffffff) < 0) {
-		snd_printk("architecture does not support 30bit PCI busmaster DMA\n");
+		snd_printk(KERN_ERR "architecture does not support 30bit PCI busmaster DMA\n");
 		pci_disable_device(pci);
 		return -ENXIO;
 	}
@@ -3578,7 +3578,7 @@
 	trident->port = pci_resource_start(pci, 0);
 
 	if (request_irq(pci->irq, snd_trident_interrupt, SA_INTERRUPT|SA_SHIRQ, "Trident Audio", (void *) trident)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_trident_free(trident);
 		return -EBUSY;
 	}
diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c
index 333d379..f3e6c54 100644
--- a/sound/pci/trident/trident_memory.c
+++ b/sound/pci/trident/trident_memory.c
@@ -170,11 +170,11 @@
 static int is_valid_page(unsigned long ptr)
 {
 	if (ptr & ~0x3fffffffUL) {
-		snd_printk("max memory size is 1GB!!\n");
+		snd_printk(KERN_ERR "max memory size is 1GB!!\n");
 		return 0;
 	}
 	if (ptr & (SNDRV_TRIDENT_PAGE_SIZE-1)) {
-		snd_printk("page is not aligned\n");
+		snd_printk(KERN_ERR "page is not aligned\n");
 		return 0;
 	}
 	return 1;
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 3c0205b..523eace 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -41,6 +41,9 @@
  *	  device for applications.
  *	- clean up the code, separate low-level initialization
  *	  routines for each chipset.
+ *
+ * Sep. 26, 2005	Karsten Wiese <annabellesgarden@yahoo.de>
+ *	- Optimize position calculation for the 823x chips. 
  */
 
 #include <sound/driver.h>
@@ -73,36 +76,37 @@
 #define SUPPORT_JOYSTICK 1
 #endif
 
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
-static long mpu_port[SNDRV_CARDS];
+static int index = SNDRV_DEFAULT_IDX1;	/* Index 0-MAX */
+static char *id = SNDRV_DEFAULT_STR1;	/* ID for this card */
+static long mpu_port;
 #ifdef SUPPORT_JOYSTICK
-static int joystick[SNDRV_CARDS];
+static int joystick;
 #endif
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
-static char *ac97_quirk[SNDRV_CARDS];
-static int dxs_support[SNDRV_CARDS];
+static int ac97_clock = 48000;
+static char *ac97_quirk;
+static int dxs_support;
 
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for VIA 82xx bridge.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
 MODULE_PARM_DESC(id, "ID string for VIA 82xx bridge.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable audio part of VIA 82xx bridge.");
-module_param_array(mpu_port, long, NULL, 0444);
+module_param(mpu_port, long, 0444);
 MODULE_PARM_DESC(mpu_port, "MPU-401 port. (VT82C686x only)");
 #ifdef SUPPORT_JOYSTICK
-module_param_array(joystick, bool, NULL, 0444);
+module_param(joystick, bool, 0444);
 MODULE_PARM_DESC(joystick, "Enable joystick. (VT82C686x only)");
 #endif
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
-module_param_array(ac97_quirk, charp, NULL, 0444);
+module_param(ac97_quirk, charp, 0444);
 MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
-module_param_array(dxs_support, int, NULL, 0444);
+module_param(dxs_support, int, 0444);
 MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA, 5 = enable any sample rate)");
 
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
 
 /* revision numbers for via686 */
 #define VIA_REV_686_A		0x10
@@ -130,6 +134,7 @@
 /* common offsets */
 #define VIA_REG_OFFSET_STATUS		0x00	/* byte - channel status */
 #define   VIA_REG_STAT_ACTIVE		0x80	/* RO */
+#define   VIA8233_SHADOW_STAT_ACTIVE	0x08	/* RO */
 #define   VIA_REG_STAT_PAUSED		0x40	/* RO */
 #define   VIA_REG_STAT_TRIGGER_QUEUED	0x08	/* RO */
 #define   VIA_REG_STAT_STOPPED		0x04	/* RWC */
@@ -328,6 +333,9 @@
 	unsigned int fragsize;
 	unsigned int bufsize;
 	unsigned int bufsize2;
+	int hwptr_done;		/* processed frame position in the buffer */
+	int in_interrupt;
+	int shadow_shift;
 };
 
 
@@ -360,7 +368,8 @@
 	unsigned int mpu_port_saved;
 #endif
 
-	unsigned char playback_volume[2]; /* for VIA8233/C/8235; default = 0 */
+	unsigned char playback_volume[4][2]; /* for VIA8233/C/8235; default = 0 */
+	unsigned char playback_volume_c[2]; /* for VIA8233/C/8235; default = 0 */
 
 	unsigned int intr_mask; /* SGD_SHADOW mask to check interrupts */
 
@@ -393,8 +402,10 @@
 };
 
 static struct pci_device_id snd_via82xx_ids[] = {
-	{ 0x1106, 0x3058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA686, },	/* 686A */
-	{ 0x1106, 0x3059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA8233, },	/* VT8233 */
+	/* 0x1106, 0x3058 */
+	{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA686, },	/* 686A */
+	/* 0x1106, 0x3059 */
+	{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA8233, },	/* VT8233 */
 	{ 0, }
 };
 
@@ -548,7 +559,7 @@
 {
 	via82xx_t *chip = ac97->private_data;
 	unsigned int xval;
-	
+
 	xval = !ac97->num ? VIA_REG_AC97_CODEC_ID_PRIMARY : VIA_REG_AC97_CODEC_ID_SECONDARY;
 	xval <<= VIA_REG_AC97_CODEC_ID_SHIFT;
 	xval |= reg << VIA_REG_AC97_CMD_SHIFT;
@@ -596,14 +607,15 @@
 	outb(0x00, VIADEV_REG(viadev, OFFSET_TYPE)); /* for via686 */
 	// outl(0, VIADEV_REG(viadev, OFFSET_CURR_PTR));
 	viadev->lastpos = 0;
+	viadev->hwptr_done = 0;
 }
 
 
 /*
  *  Interrupt handler
+ *  Used for 686 and 8233A
  */
-
-static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_via686_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	via82xx_t *chip = dev_id;
 	unsigned int status;
@@ -622,13 +634,23 @@
 	for (i = 0; i < chip->num_devs; i++) {
 		viadev_t *viadev = &chip->devs[i];
 		unsigned char c_status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
-		c_status &= (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG|VIA_REG_STAT_STOPPED);
-		if (! c_status)
+		if (! (c_status & (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG|VIA_REG_STAT_STOPPED)))
 			continue;
 		if (viadev->substream && viadev->running) {
+			/*
+			 * Update hwptr_done based on 'period elapsed'
+			 * interrupts. We'll use it, when the chip returns 0 
+			 * for OFFSET_CURR_COUNT.
+			 */
+			if (c_status & VIA_REG_STAT_EOL)
+				viadev->hwptr_done = 0;
+			else
+				viadev->hwptr_done += viadev->fragsize;
+			viadev->in_interrupt = c_status;
 			spin_unlock(&chip->reg_lock);
 			snd_pcm_period_elapsed(viadev->substream);
 			spin_lock(&chip->reg_lock);
+			viadev->in_interrupt = 0;
 		}
 		outb(c_status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
 	}
@@ -637,6 +659,60 @@
 }
 
 /*
+ *  Interrupt handler
+ */
+static irqreturn_t snd_via8233_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	via82xx_t *chip = dev_id;
+	unsigned int status;
+	unsigned int i;
+	int irqreturn = 0;
+
+	/* check status for each stream */
+	spin_lock(&chip->reg_lock);
+	status = inl(VIAREG(chip, SGD_SHADOW));
+
+	for (i = 0; i < chip->num_devs; i++) {
+		viadev_t *viadev = &chip->devs[i];
+		snd_pcm_substream_t *substream;
+		unsigned char c_status, shadow_status;
+
+		shadow_status = (status >> viadev->shadow_shift) &
+			(VIA8233_SHADOW_STAT_ACTIVE|VIA_REG_STAT_EOL|
+			 VIA_REG_STAT_FLAG);
+		c_status = shadow_status & (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG);
+		if (!c_status)
+			continue;
+
+		substream = viadev->substream;
+		if (substream && viadev->running) {
+			/*
+			 * Update hwptr_done based on 'period elapsed'
+			 * interrupts. We'll use it, when the chip returns 0 
+			 * for OFFSET_CURR_COUNT.
+			 */
+			if (c_status & VIA_REG_STAT_EOL)
+				viadev->hwptr_done = 0;
+			else
+				viadev->hwptr_done += viadev->fragsize;
+			viadev->in_interrupt = c_status;
+			if (shadow_status & VIA8233_SHADOW_STAT_ACTIVE)
+				viadev->in_interrupt |= VIA_REG_STAT_ACTIVE;
+			spin_unlock(&chip->reg_lock);
+
+			snd_pcm_period_elapsed(substream);
+
+			spin_lock(&chip->reg_lock);
+			viadev->in_interrupt = 0;
+		}
+		outb(c_status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
+		irqreturn = 1;
+	}
+	spin_unlock(&chip->reg_lock);
+	return IRQ_RETVAL(irqreturn);
+}
+
+/*
  *  PCM callbacks
  */
 
@@ -699,6 +775,8 @@
 	size = viadev->idx_table[idx].size;
 	base = viadev->idx_table[idx].offset;
 	res = base + size - count;
+	if (res >= viadev->bufsize)
+		res -= viadev->bufsize;
 
 	/* check the validity of the calculated position */
 	if (size < count) {
@@ -728,9 +806,6 @@
 			}
 		}
 	}
-	viadev->lastpos = res; /* remember the last position */
-	if (res >= viadev->bufsize)
-		res -= viadev->bufsize;
 	return res;
 }
 
@@ -758,6 +833,7 @@
 	else /* CURR_PTR holds the address + 8 */
 		idx = ((ptr - (unsigned int)viadev->table.addr) / 8 - 1) % viadev->tbl_entries;
 	res = calc_linear_pos(viadev, idx, count);
+	viadev->lastpos = res; /* remember the last position */
 	spin_unlock(&chip->reg_lock);
 
 	return bytes_to_frames(substream->runtime, res);
@@ -771,30 +847,44 @@
 	via82xx_t *chip = snd_pcm_substream_chip(substream);
 	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
 	unsigned int idx, count, res;
-	int timeout = 5000;
+	int status;
 	
 	snd_assert(viadev->tbl_entries, return 0);
-	if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE))
-		return 0;
+
 	spin_lock(&chip->reg_lock);
-	do {
-		count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT));
-		/* some mobos read 0 count */
-		if ((count & 0xffffff) || ! viadev->running)
-			break;
-	} while (--timeout);
-	if (! timeout)
-		snd_printd(KERN_ERR "zero position is read\n");
-	idx = count >> 24;
-	if (idx >= viadev->tbl_entries) {
-#ifdef POINTER_DEBUG
-		printk("fail: invalid idx = %i/%i\n", idx, viadev->tbl_entries);
-#endif
-		res = viadev->lastpos;
-	} else {
-		count &= 0xffffff;
-		res = calc_linear_pos(viadev, idx, count);
+	count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT));
+	status = viadev->in_interrupt;
+	if (!status)
+		status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
+
+	if (!(status & VIA_REG_STAT_ACTIVE)) {
+		res = 0;
+		goto unlock;
 	}
+	if (count & 0xffffff) {
+		idx = count >> 24;
+		if (idx >= viadev->tbl_entries) {
+#ifdef POINTER_DEBUG
+			printk(KERN_DEBUG "fail: invalid idx = %i/%i\n", idx, viadev->tbl_entries);
+#endif
+			res = viadev->lastpos;
+		} else {
+			count &= 0xffffff;
+			res = calc_linear_pos(viadev, idx, count);
+		}
+	} else {
+		res = viadev->hwptr_done;
+		if (!viadev->in_interrupt) {
+			if (status & VIA_REG_STAT_EOL) {
+				res = 0;
+			} else
+				if (status & VIA_REG_STAT_FLAG) {
+					res += viadev->fragsize;
+				}
+		}
+	}			    
+unlock:
+	viadev->lastpos = res;
 	spin_unlock(&chip->reg_lock);
 
 	return bytes_to_frames(substream->runtime, res);
@@ -936,8 +1026,8 @@
 	snd_assert((rbits & ~0xfffff) == 0, return -EINVAL);
 	snd_via82xx_channel_reset(chip, viadev);
 	snd_via82xx_set_table_ptr(chip, viadev);
-	outb(chip->playback_volume[0], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_L));
-	outb(chip->playback_volume[1], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_R));
+	outb(chip->playback_volume[viadev->reg_offset / 0x10][0], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_L));
+	outb(chip->playback_volume[viadev->reg_offset / 0x10][1], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_R));
 	outl((runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA8233_REG_TYPE_16BIT : 0) | /* format */
 	     (runtime->channels > 1 ? VIA8233_REG_TYPE_STEREO : 0) | /* stereo */
 	     rbits | /* rate */
@@ -1239,9 +1329,10 @@
 };
 
 
-static void init_viadev(via82xx_t *chip, int idx, unsigned int reg_offset, int direction)
+static void init_viadev(via82xx_t *chip, int idx, unsigned int reg_offset, int shadow_pos, int direction)
 {
 	chip->devs[idx].reg_offset = reg_offset;
+	chip->devs[idx].shadow_shift = shadow_pos * 4;
 	chip->devs[idx].direction = direction;
 	chip->devs[idx].port = chip->port + reg_offset;
 }
@@ -1271,9 +1362,9 @@
 	chip->pcms[0] = pcm;
 	/* set up playbacks */
 	for (i = 0; i < 4; i++)
-		init_viadev(chip, i, 0x10 * i, 0);
+		init_viadev(chip, i, 0x10 * i, i, 0);
 	/* capture */
-	init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 1);
+	init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 6, 1);
 
 	if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
 							 snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
@@ -1289,9 +1380,9 @@
 	strcpy(pcm->name, chip->card->shortname);
 	chip->pcms[1] = pcm;
 	/* set up playback */
-	init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 0);
+	init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 4, 0);
 	/* set up capture */
-	init_viadev(chip, chip->capture_devno + 1, VIA_REG_CAPTURE_8233_STATUS + 0x10, 1);
+	init_viadev(chip, chip->capture_devno + 1, VIA_REG_CAPTURE_8233_STATUS + 0x10, 7, 1);
 
 	if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
 						         snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
@@ -1324,9 +1415,9 @@
 	strcpy(pcm->name, chip->card->shortname);
 	chip->pcms[0] = pcm;
 	/* set up playback */
-	init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 0);
+	init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 4, 0);
 	/* capture */
-	init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 1);
+	init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 6, 1);
 
 	if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
 							 snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
@@ -1345,7 +1436,7 @@
 	strcpy(pcm->name, chip->card->shortname);
 	chip->pcms[1] = pcm;
 	/* set up playback */
-	init_viadev(chip, chip->playback_devno, 0x30, 0);
+	init_viadev(chip, chip->playback_devno, 0x30, 3, 0);
 
 	if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
 							 snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
@@ -1375,8 +1466,8 @@
 	pcm->private_data = chip;
 	strcpy(pcm->name, chip->card->shortname);
 	chip->pcms[0] = pcm;
-	init_viadev(chip, 0, VIA_REG_PLAYBACK_STATUS, 0);
-	init_viadev(chip, 1, VIA_REG_CAPTURE_STATUS, 1);
+	init_viadev(chip, 0, VIA_REG_PLAYBACK_STATUS, 0, 0);
+	init_viadev(chip, 1, VIA_REG_CAPTURE_STATUS, 0, 1);
 
 	if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
 							 snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
@@ -1497,14 +1588,46 @@
 static int snd_via8233_dxs_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
-	ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume[0];
-	ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume[1];
+	unsigned int idx = snd_ctl_get_ioff(kcontrol, &ucontrol->id);
+
+	ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][0];
+	ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][1];
+	return 0;
+}
+
+static int snd_via8233_pcmdxs_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
+	ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume_c[0];
+	ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume_c[1];
 	return 0;
 }
 
 static int snd_via8233_dxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
+	unsigned int idx = snd_ctl_get_ioff(kcontrol, &ucontrol->id);
+	unsigned long port = chip->port + 0x10 * idx;
+	unsigned char val;
+	int i, change = 0;
+
+	for (i = 0; i < 2; i++) {
+		val = ucontrol->value.integer.value[i];
+		if (val > VIA_DXS_MAX_VOLUME)
+			val = VIA_DXS_MAX_VOLUME;
+		val = VIA_DXS_MAX_VOLUME - val;
+		change |= val != chip->playback_volume[idx][i];
+		if (change) {
+			chip->playback_volume[idx][i] = val;
+			outb(val, port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
+		}
+	}
+	return change;
+}
+
+static int snd_via8233_pcmdxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
 	unsigned int idx;
 	unsigned char val;
 	int i, change = 0;
@@ -1514,11 +1637,12 @@
 		if (val > VIA_DXS_MAX_VOLUME)
 			val = VIA_DXS_MAX_VOLUME;
 		val = VIA_DXS_MAX_VOLUME - val;
-		if (val != chip->playback_volume[i]) {
+		if (val != chip->playback_volume_c[i]) {
 			change = 1;
-			chip->playback_volume[i] = val;
+			chip->playback_volume_c[i] = val;
 			for (idx = 0; idx < 4; idx++) {
 				unsigned long port = chip->port + 0x10 * idx;
+				chip->playback_volume[idx][i] = val;
 				outb(val, port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
 			}
 		}
@@ -1526,10 +1650,19 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_via8233_dxs_volume_control __devinitdata = {
+static snd_kcontrol_new_t snd_via8233_pcmdxs_volume_control __devinitdata = {
 	.name = "PCM Playback Volume",
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.info = snd_via8233_dxs_volume_info,
+	.get = snd_via8233_pcmdxs_volume_get,
+	.put = snd_via8233_pcmdxs_volume_put,
+};
+
+static snd_kcontrol_new_t snd_via8233_dxs_volume_control __devinitdata = {
+	.name = "VIA DXS Playback Volume",
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.count = 4,
+	.info = snd_via8233_dxs_volume_info,
 	.get = snd_via8233_dxs_volume_get,
 	.put = snd_via8233_dxs_volume_put,
 };
@@ -1616,12 +1749,12 @@
 		return err;
 	chip->ac97_bus->private_free = snd_via82xx_mixer_free_ac97_bus;
 	chip->ac97_bus->clock = chip->ac97_clock;
-	chip->ac97_bus->shared_type = AC97_SHARED_TYPE_VIA;
 
 	memset(&ac97, 0, sizeof(ac97));
 	ac97.private_data = chip;
 	ac97.private_free = snd_via82xx_mixer_free_ac97;
 	ac97.pci = chip->pci;
+	ac97.scaps = AC97_SCAP_SKIP_MODEM;
 	if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
 		return err;
 
@@ -1637,12 +1770,12 @@
 
 #ifdef SUPPORT_JOYSTICK
 #define JOYSTICK_ADDR	0x200
-static int __devinit snd_via686_create_gameport(via82xx_t *chip, int dev, unsigned char *legacy)
+static int __devinit snd_via686_create_gameport(via82xx_t *chip, unsigned char *legacy)
 {
 	struct gameport *gp;
 	struct resource *r;
 
-	if (!joystick[dev])
+	if (!joystick)
 		return -ENODEV;
 
 	r = request_region(JOYSTICK_ADDR, 8, "VIA686 gameport");
@@ -1654,8 +1787,7 @@
 	chip->gameport = gp = gameport_allocate_port();
 	if (!gp) {
 		printk(KERN_ERR "via82xx: cannot allocate memory for gameport\n");
-		release_resource(r);
-		kfree_nocheck(r);
+		release_and_free_resource(r);
 		return -ENOMEM;
 	}
 
@@ -1681,12 +1813,11 @@
 
 		gameport_unregister_port(chip->gameport);
 		chip->gameport = NULL;
-		release_resource(r);
-		kfree_nocheck(r);
+		release_and_free_resource(r);
 	}
 }
 #else
-static inline int snd_via686_create_gameport(via82xx_t *chip, int dev, unsigned char *legacy)
+static inline int snd_via686_create_gameport(via82xx_t *chip, unsigned char *legacy)
 {
 	return -ENOSYS;
 }
@@ -1698,7 +1829,7 @@
  *
  */
 
-static int __devinit snd_via8233_init_misc(via82xx_t *chip, int dev)
+static int __devinit snd_via8233_init_misc(via82xx_t *chip)
 {
 	int i, err, caps;
 	unsigned char val;
@@ -1724,12 +1855,19 @@
 		strcpy(sid.name, "PCM Playback Volume");
 		sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 		if (! snd_ctl_find_id(chip->card, &sid)) {
+			snd_printd(KERN_INFO "Using DXS as PCM Playback\n");
+			err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_pcmdxs_volume_control, chip));
+			if (err < 0)
+				return err;
+		}
+		else /* Using DXS when PCM emulation is enabled is really weird */
+		{
+			/* Standalone DXS controls */
 			err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_dxs_volume_control, chip));
 			if (err < 0)
 				return err;
 		}
 	}
-
 	/* select spdif data slot 10/11 */
 	pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &val);
 	val = (val & ~VIA8233_SPDIF_SLOT_MASK) | VIA8233_SPDIF_SLOT_1011;
@@ -1739,7 +1877,7 @@
 	return 0;
 }
 
-static int __devinit snd_via686_init_misc(via82xx_t *chip, int dev)
+static int __devinit snd_via686_init_misc(via82xx_t *chip)
 {
 	unsigned char legacy, legacy_cfg;
 	int rev_h = 0;
@@ -1750,32 +1888,33 @@
 	legacy &= ~VIA_FUNC_ENABLE_GAME;	/* disable joystick */
 	if (chip->revision >= VIA_REV_686_H) {
 		rev_h = 1;
-		if (mpu_port[dev] >= 0x200) {	/* force MIDI */
-			mpu_port[dev] &= 0xfffc;
-			pci_write_config_dword(chip->pci, 0x18, mpu_port[dev] | 0x01);
+		if (mpu_port >= 0x200) {	/* force MIDI */
+			mpu_port &= 0xfffc;
+			pci_write_config_dword(chip->pci, 0x18, mpu_port | 0x01);
 #ifdef CONFIG_PM
-			chip->mpu_port_saved = mpu_port[dev];
+			chip->mpu_port_saved = mpu_port;
 #endif
 		} else {
-			mpu_port[dev] = pci_resource_start(chip->pci, 2);
+			mpu_port = pci_resource_start(chip->pci, 2);
 		}
 	} else {
-		switch (mpu_port[dev]) {	/* force MIDI */
+		switch (mpu_port) {	/* force MIDI */
 		case 0x300:
 		case 0x310:
 		case 0x320:
 		case 0x330:
 			legacy_cfg &= ~(3 << 2);
-			legacy_cfg |= (mpu_port[dev] & 0x0030) >> 2;
+			legacy_cfg |= (mpu_port & 0x0030) >> 2;
 			break;
 		default:			/* no, use BIOS settings */
 			if (legacy & VIA_FUNC_ENABLE_MIDI)
-				mpu_port[dev] = 0x300 + ((legacy_cfg & 0x000c) << 2);
+				mpu_port = 0x300 + ((legacy_cfg & 0x000c) << 2);
 			break;
 		}
 	}
-	if (mpu_port[dev] >= 0x200 &&
-	    (chip->mpu_res = request_region(mpu_port[dev], 2, "VIA82xx MPU401")) != NULL) {
+	if (mpu_port >= 0x200 &&
+	    (chip->mpu_res = request_region(mpu_port, 2, "VIA82xx MPU401"))
+	    != NULL) {
 		if (rev_h)
 			legacy |= VIA_FUNC_MIDI_PNP;	/* enable PCI I/O 2 */
 		legacy |= VIA_FUNC_ENABLE_MIDI;
@@ -1783,16 +1922,17 @@
 		if (rev_h)
 			legacy &= ~VIA_FUNC_MIDI_PNP;	/* disable PCI I/O 2 */
 		legacy &= ~VIA_FUNC_ENABLE_MIDI;
-		mpu_port[dev] = 0;
+		mpu_port = 0;
 	}
 
 	pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy);
 	pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg);
 	if (chip->mpu_res) {
 		if (snd_mpu401_uart_new(chip->card, 0, MPU401_HW_VIA686A,
-					mpu_port[dev], 1,
+					mpu_port, 1,
 					chip->irq, 0, &chip->rmidi) < 0) {
-			printk(KERN_WARNING "unable to initialize MPU-401 at 0x%lx, skipping\n", mpu_port[dev]);
+			printk(KERN_WARNING "unable to initialize MPU-401"
+			       " at 0x%lx, skipping\n", mpu_port);
 			legacy &= ~VIA_FUNC_ENABLE_MIDI;
 		} else {
 			legacy &= ~VIA_FUNC_MIDI_IRQMASK;	/* enable MIDI interrupt */
@@ -1800,7 +1940,7 @@
 		pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy);
 	}
 
-	snd_via686_create_gameport(chip, dev, &legacy);
+	snd_via686_create_gameport(chip, &legacy);
 
 #ifdef CONFIG_PM
 	chip->legacy_saved = legacy;
@@ -1887,12 +2027,11 @@
 		pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
 		if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */
 			break;
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	} while (time_before(jiffies, end_time));
 
 	if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
-		snd_printk("AC'97 codec is not ready [0x%x]\n", val);
+		snd_printk(KERN_ERR "AC'97 codec is not ready [0x%x]\n", val);
 
 #if 0 /* FIXME: we don't support the second codec yet so skip the detection now.. */
 	snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
@@ -1907,8 +2046,7 @@
 			chip->ac97_secondary = 1;
 			goto __ac97_ok2;
 		}
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_interruptible(1);
 	} while (time_before(jiffies, end_time));
 	/* This is ok, the most of motherboards have only one codec */
 
@@ -1940,8 +2078,10 @@
 		int i, idx;
 		for (idx = 0; idx < 4; idx++) {
 			unsigned long port = chip->port + 0x10 * idx;
-			for (i = 0; i < 2; i++)
-				outb(chip->playback_volume[i], port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
+			for (i = 0; i < 2; i++) {
+				chip->playback_volume[idx][i]=chip->playback_volume_c[i];
+				outb(chip->playback_volume_c[i], port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
+			}
 		}
 	}
 
@@ -2020,10 +2160,7 @@
       __end_hw:
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *)chip);
-	if (chip->mpu_res) {
-		release_resource(chip->mpu_res);
-		kfree_nocheck(chip->mpu_res);
-	}
+	release_and_free_resource(chip->mpu_res);
 	pci_release_regions(chip->pci);
 
 	if (chip->chip_type == TYPE_VIA686) {
@@ -2084,9 +2221,12 @@
 		return err;
 	}
 	chip->port = pci_resource_start(pci, 0);
-	if (request_irq(pci->irq, snd_via82xx_interrupt, SA_INTERRUPT|SA_SHIRQ,
+	if (request_irq(pci->irq,
+			chip_type == TYPE_VIA8233 ?
+			snd_via8233_interrupt :	snd_via686_interrupt,
+			SA_INTERRUPT|SA_SHIRQ,
 			card->driver, (void *)chip)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_via82xx_free(chip);
 		return -EBUSY;
 	}
@@ -2178,6 +2318,7 @@
 		{ .subvendor = 0x147b, .subdevice = 0x1415, .action = VIA_DXS_NO_VRA }, /* Abit AV8 */
 		{ .subvendor = 0x14ff, .subdevice = 0x0403, .action = VIA_DXS_ENABLE }, /* Twinhead mobo */
 		{ .subvendor = 0x14ff, .subdevice = 0x0408, .action = VIA_DXS_SRC }, /* Twinhead laptop */
+		{ .subvendor = 0x1558, .subdevice = 0x4701, .action = VIA_DXS_SRC }, /* Clevo D470 */
 		{ .subvendor = 0x1584, .subdevice = 0x8120, .action = VIA_DXS_ENABLE }, /* Gericom/Targa/Vobis/Uniwill laptop */
 		{ .subvendor = 0x1584, .subdevice = 0x8123, .action = VIA_DXS_NO_VRA }, /* Uniwill (Targa Visionary XP-210) */
 		{ .subvendor = 0x161f, .subdevice = 0x202b, .action = VIA_DXS_NO_VRA }, /* Amira Note book */
@@ -2221,7 +2362,6 @@
 static int __devinit snd_via82xx_probe(struct pci_dev *pci,
 				       const struct pci_device_id *pci_id)
 {
-	static int dev;
 	snd_card_t *card;
 	via82xx_t *chip;
 	unsigned char revision;
@@ -2229,14 +2369,7 @@
 	unsigned int i;
 	int err;
 
-	if (dev >= SNDRV_CARDS)
-		return -ENODEV;
-	if (!enable[dev]) {
-		dev++;
-		return -ENOENT;
-	}
-
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	card = snd_card_new(index, id, THIS_MODULE, 0);
 	if (card == NULL)
 		return -ENOMEM;
 
@@ -2259,12 +2392,12 @@
 			}
 		}
 		if (chip_type != TYPE_VIA8233A) {
-			if (dxs_support[dev] == VIA_DXS_AUTO)
-				dxs_support[dev] = check_dxs_list(pci);
+			if (dxs_support == VIA_DXS_AUTO)
+				dxs_support = check_dxs_list(pci);
 			/* force to use VIA8233 or 8233A model according to
 			 * dxs_support module option
 			 */
-			if (dxs_support[dev] == VIA_DXS_DISABLE)
+			if (dxs_support == VIA_DXS_DISABLE)
 				chip_type = TYPE_VIA8233A;
 			else
 				chip_type = TYPE_VIA8233;
@@ -2282,14 +2415,15 @@
 		goto __error;
 	}
 		
-	if ((err = snd_via82xx_create(card, pci, chip_type, revision, ac97_clock[dev], &chip)) < 0)
+	if ((err = snd_via82xx_create(card, pci, chip_type, revision,
+				      ac97_clock, &chip)) < 0)
 		goto __error;
-	if ((err = snd_via82xx_mixer_new(chip, ac97_quirk[dev])) < 0)
+	if ((err = snd_via82xx_mixer_new(chip, ac97_quirk)) < 0)
 		goto __error;
 
 	if (chip_type == TYPE_VIA686) {
 		if ((err = snd_via686_pcm_new(chip)) < 0 ||
-		    (err = snd_via686_init_misc(chip, dev)) < 0)
+		    (err = snd_via686_init_misc(chip)) < 0)
 			goto __error;
 	} else {
 		if (chip_type == TYPE_VIA8233A) {
@@ -2299,16 +2433,16 @@
 		} else {
 			if ((err = snd_via8233_pcm_new(chip)) < 0)
 				goto __error;
-			if (dxs_support[dev] == VIA_DXS_48K)
+			if (dxs_support == VIA_DXS_48K)
 				chip->dxs_fixed = 1;
-			else if (dxs_support[dev] == VIA_DXS_NO_VRA)
+			else if (dxs_support == VIA_DXS_NO_VRA)
 				chip->no_vra = 1;
-			else if (dxs_support[dev] == VIA_DXS_SRC) {
+			else if (dxs_support == VIA_DXS_SRC) {
 				chip->no_vra = 1;
 				chip->dxs_src = 1;
 			}
 		}
-		if ((err = snd_via8233_init_misc(chip, dev)) < 0)
+		if ((err = snd_via8233_init_misc(chip)) < 0)
 			goto __error;
 	}
 
@@ -2329,7 +2463,6 @@
 		return err;
 	}
 	pci_set_drvdata(pci, card);
-	dev++;
 	return 0;
 
  __error:
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 7eac6f6..011f0fb 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -26,7 +26,7 @@
 /*
  * Changes:
  *
- * Sep. 2,  2004  Sasha Khapyorsky <sashak@smlink.com>
+ * Sep. 2,  2004  Sasha Khapyorsky <sashak@alsa-project.org>
  *      Modified from original audio driver 'via82xx.c' to support AC97
  *      modems.
  */
@@ -55,20 +55,21 @@
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{VIA,VT82C686A/B/C modem,pci}}");
 
-static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
+static int index = -2; /* Exclude the first card */
+static char *id = SNDRV_DEFAULT_STR1;	/* ID for this card */
+static int ac97_clock = 48000;
 
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for VIA 82xx bridge.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
 MODULE_PARM_DESC(id, "ID string for VIA 82xx bridge.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable modem part of VIA 82xx bridge.");
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
 
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
 
 /*
  *  Direct registers
@@ -569,7 +570,7 @@
 		res = viadev->lastpos;
 	} else if (check_invalid_pos(viadev, res)) {
 #ifdef POINTER_DEBUG
-		printk("fail: idx = %i/%i, lastpos = 0x%x, bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos, viadev->bufsize2, viadev->idx_table[idx].offset, viadev->idx_table[idx].size, count);
+		printk(KERN_DEBUG "fail: idx = %i/%i, lastpos = 0x%x, bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos, viadev->bufsize2, viadev->idx_table[idx].offset, viadev->idx_table[idx].size, count);
 #endif
 		if (count && size < count) {
 			snd_printd(KERN_ERR "invalid via82xx_cur_ptr, using last valid pointer\n");
@@ -832,6 +833,7 @@
 		return err;
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via686_playback_ops);
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via686_capture_ops);
+	pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
 	pcm->private_data = chip;
 	strcpy(pcm->name, chip->card->shortname);
 	chip->pcms[0] = pcm;
@@ -878,7 +880,6 @@
 		return err;
 	chip->ac97_bus->private_free = snd_via82xx_mixer_free_ac97_bus;
 	chip->ac97_bus->clock = chip->ac97_clock;
-	chip->ac97_bus->shared_type = AC97_SHARED_TYPE_VIA;
 
 	memset(&ac97, 0, sizeof(ac97));
 	ac97.private_data = chip;
@@ -967,12 +968,11 @@
 		pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
 		if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */
 			break;
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	} while (time_before(jiffies, end_time));
 
 	if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
-		snd_printk("AC'97 codec is not ready [0x%x]\n", val);
+		snd_printk(KERN_ERR "AC'97 codec is not ready [0x%x]\n", val);
 
 	snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
 				 VIA_REG_AC97_SECONDARY_VALID |
@@ -986,8 +986,7 @@
 			chip->ac97_secondary = 1;
 			goto __ac97_ok2;
 		}
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_interruptible(1);
 	} while (time_before(jiffies, end_time));
 	/* This is ok, the most of motherboards have only one codec */
 
@@ -1101,7 +1100,7 @@
 	chip->port = pci_resource_start(pci, 0);
 	if (request_irq(pci->irq, snd_via82xx_interrupt, SA_INTERRUPT|SA_SHIRQ,
 			card->driver, (void *)chip)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_via82xx_free(chip);
 		return -EBUSY;
 	}
@@ -1135,7 +1134,6 @@
 static int __devinit snd_via82xx_probe(struct pci_dev *pci,
 				       const struct pci_device_id *pci_id)
 {
-	static int dev;
 	snd_card_t *card;
 	via82xx_t *chip;
 	unsigned char revision;
@@ -1143,14 +1141,7 @@
 	unsigned int i;
 	int err;
 
-	if (dev >= SNDRV_CARDS)
-		return -ENODEV;
-	if (!enable[dev]) {
-		dev++;
-		return -ENOENT;
-	}
-
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	card = snd_card_new(index, id, THIS_MODULE, 0);
 	if (card == NULL)
 		return -ENOMEM;
 
@@ -1167,7 +1158,8 @@
 		goto __error;
 	}
 		
-	if ((err = snd_via82xx_create(card, pci, chip_type, revision, ac97_clock[dev], &chip)) < 0)
+	if ((err = snd_via82xx_create(card, pci, chip_type, revision,
+				      ac97_clock, &chip)) < 0)
 		goto __error;
 	if ((err = snd_via82xx_mixer_new(chip)) < 0)
 		goto __error;
@@ -1191,7 +1183,6 @@
 		return err;
 	}
 	pci_set_drvdata(pci, card);
-	dev++;
 	return 0;
 
  __error:
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index 2e69abe..1bbba32 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -130,8 +130,7 @@
 	chip->gameport = gp = gameport_allocate_port();
 	if (!gp) {
 		printk(KERN_ERR "ymfpci: cannot allocate memory for gameport\n");
-		release_resource(r);
-		kfree_nocheck(r);
+		release_and_free_resource(r);
 		return -ENOMEM;
 	}
 
@@ -161,8 +160,7 @@
 		gameport_unregister_port(chip->gameport);
 		chip->gameport = NULL;
 
-		release_resource(r);
-		kfree_nocheck(r);
+		release_and_free_resource(r);
 	}
 }
 #else
@@ -267,14 +265,8 @@
 				     old_legacy_ctrl,
 			 	     &chip)) < 0) {
 		snd_card_free(card);
-		if (mpu_res) {
-			release_resource(mpu_res);
-			kfree_nocheck(mpu_res);
-		}
-		if (fm_res) {
-			release_resource(fm_res);
-			kfree_nocheck(fm_res);
-		}
+		release_and_free_resource(mpu_res);
+		release_and_free_resource(fm_res);
 		return err;
 	}
 	chip->fm_res = fm_res;
@@ -328,7 +320,7 @@
 			pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);
 		} else if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
 			snd_card_free(card);
-			snd_printk("cannot create opl3 hwdep\n");
+			snd_printk(KERN_ERR "cannot create opl3 hwdep\n");
 			return err;
 		}
 	}
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 27fa523..88a43e0 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -92,9 +92,9 @@
 		if ((snd_ymfpci_readw(chip, reg) & 0x8000) == 0)
 			return 0;
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	} while (time_before(jiffies, end_time));
-	snd_printk("codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg));
+	snd_printk(KERN_ERR "codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg));
 	return -EBUSY;
 }
 
@@ -728,8 +728,7 @@
 		init_waitqueue_entry(&wait, current);
 		add_wait_queue(&chip->interrupt_sleep, &wait);
 		atomic_inc(&chip->interrupt_sleep_count);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HZ/20);
+		schedule_timeout_uninterruptible(msecs_to_jiffies(50));
 		remove_wait_queue(&chip->interrupt_sleep, &wait);
 	}
 }
@@ -1421,15 +1420,18 @@
  *  Mixer controls
  */
 
-#define YMFPCI_SINGLE(xname, xindex, reg) \
+#define YMFPCI_SINGLE(xname, xindex, reg, shift) \
 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
   .info = snd_ymfpci_info_single, \
   .get = snd_ymfpci_get_single, .put = snd_ymfpci_put_single, \
-  .private_value = reg }
+  .private_value = ((reg) | ((shift) << 16)) }
 
-static int snd_ymfpci_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ymfpci_info_single(snd_kcontrol_t *kcontrol,
+				  snd_ctl_elem_info_t *uinfo)
 {
-	switch (kcontrol->private_value) {
+	int reg = kcontrol->private_value & 0xffff;
+
+	switch (reg) {
 	case YDSXGR_SPDIFOUTCTRL: break;
 	case YDSXGR_SPDIFINCTRL: break;
 	default: return -EINVAL;
@@ -1441,30 +1443,35 @@
 	return 0;
 }
 
-static int snd_ymfpci_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ymfpci_get_single(snd_kcontrol_t *kcontrol,
+				 snd_ctl_elem_value_t *ucontrol)
 {
 	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
-	int reg = kcontrol->private_value;
-	unsigned int shift = 0, mask = 1;
+	int reg = kcontrol->private_value & 0xffff;
+	unsigned int shift = (kcontrol->private_value >> 16) & 0xff;
+	unsigned int mask = 1;
 	
-	switch (kcontrol->private_value) {
+	switch (reg) {
 	case YDSXGR_SPDIFOUTCTRL: break;
 	case YDSXGR_SPDIFINCTRL: break;
 	default: return -EINVAL;
 	}
-	ucontrol->value.integer.value[0] = (snd_ymfpci_readl(chip, reg) >> shift) & mask;
+	ucontrol->value.integer.value[0] =
+		(snd_ymfpci_readl(chip, reg) >> shift) & mask;
 	return 0;
 }
 
-static int snd_ymfpci_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ymfpci_put_single(snd_kcontrol_t *kcontrol,
+				 snd_ctl_elem_value_t *ucontrol)
 {
 	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
-	int reg = kcontrol->private_value;
-	unsigned int shift = 0, mask = 1;
+	int reg = kcontrol->private_value & 0xffff;
+	unsigned int shift = (kcontrol->private_value >> 16) & 0xff;
+ 	unsigned int mask = 1;
 	int change;
 	unsigned int val, oval;
 	
-	switch (kcontrol->private_value) {
+	switch (reg) {
 	case YDSXGR_SPDIFOUTCTRL: break;
 	case YDSXGR_SPDIFINCTRL: break;
 	default: return -EINVAL;
@@ -1583,8 +1590,9 @@
 YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("", CAPTURE,VOLUME), 0, YDSXGR_ZVLOOPVOL),
 YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ",PLAYBACK,VOLUME), 1, YDSXGR_SPDIFOUTVOL),
 YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,VOLUME), 1, YDSXGR_SPDIFLOOPVOL),
-YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 0, YDSXGR_SPDIFOUTCTRL),
-YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, YDSXGR_SPDIFINCTRL),
+YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 0, YDSXGR_SPDIFOUTCTRL, 0),
+YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, YDSXGR_SPDIFINCTRL, 0),
+YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("Loop",NONE,NONE), 0, YDSXGR_SPDIFINCTRL, 4),
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "4ch Duplication",
@@ -1842,9 +1850,7 @@
 	unsigned int count;
 
 	chip = snd_timer_chip(timer);
-	count = timer->sticks - 1;
-	if (count == 0) /* minimum time is 20.8 us */
-		count = 1;
+	count = (timer->sticks << 1) - 1;
 	spin_lock_irqsave(&chip->reg_lock, flags);
 	snd_ymfpci_writew(chip, YDSXGR_TIMERCOUNT, count);
 	snd_ymfpci_writeb(chip, YDSXGR_TIMERCTRL, 0x03);
@@ -1868,14 +1874,14 @@
 					       unsigned long *num, unsigned long *den)
 {
 	*num = 1;
-	*den = 96000;
+	*den = 48000;
 	return 0;
 }
 
 static struct _snd_timer_hardware snd_ymfpci_timer_hw = {
 	.flags = SNDRV_TIMER_HW_AUTO,
-	.resolution = 10417, /* 1/2fs = 10.41666...us */
-	.ticks = 65536,
+	.resolution = 20833, /* 1/fs = 20.8333...us */
+	.ticks = 0x8000,
 	.start = snd_ymfpci_timer_start,
 	.stop = snd_ymfpci_timer_stop,
 	.precise_resolution = snd_ymfpci_timer_precise_resolution,
@@ -2142,14 +2148,8 @@
 #ifdef CONFIG_PM
 	vfree(chip->saved_regs);
 #endif
-	if (chip->mpu_res) {
-		release_resource(chip->mpu_res);
-		kfree_nocheck(chip->mpu_res);
-	}
-	if (chip->fm_res) {
-		release_resource(chip->fm_res);
-		kfree_nocheck(chip->fm_res);
-	}
+	release_and_free_resource(chip->mpu_res);
+	release_and_free_resource(chip->fm_res);
 	snd_ymfpci_free_gameport(chip);
 	if (chip->reg_area_virt)
 		iounmap(chip->reg_area_virt);
@@ -2158,10 +2158,7 @@
 	
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *)chip);
-	if (chip->res_reg_area) {
-		release_resource(chip->res_reg_area);
-		kfree_nocheck(chip->res_reg_area);
-	}
+	release_and_free_resource(chip->res_reg_area);
 
 	pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl);
 	
@@ -2290,12 +2287,12 @@
 	pci_set_master(pci);
 
 	if ((chip->res_reg_area = request_mem_region(chip->reg_area_phys, 0x8000, "YMFPCI")) == NULL) {
-		snd_printk("unable to grab memory region 0x%lx-0x%lx\n", chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1);
+		snd_printk(KERN_ERR "unable to grab memory region 0x%lx-0x%lx\n", chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1);
 		snd_ymfpci_free(chip);
 		return -EBUSY;
 	}
 	if (request_irq(pci->irq, snd_ymfpci_interrupt, SA_INTERRUPT|SA_SHIRQ, "YMFPCI", (void *) chip)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_ymfpci_free(chip);
 		return -EBUSY;
 	}
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
index 0a954dc..20b86d8 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
@@ -50,9 +50,9 @@
 	if (runtime->dma_area) {
 		if (runtime->dma_bytes >= size)
 			return 0; /* already enough large */
-		vfree_nocheck(runtime->dma_area);
+		vfree(runtime->dma_area);
 	}
-	runtime->dma_area = vmalloc_nocheck(size);
+	runtime->dma_area = vmalloc_32(size);
 	if (! runtime->dma_area)
 		return -ENOMEM;
 	runtime->dma_bytes = size;
@@ -67,7 +67,7 @@
 {
 	snd_pcm_runtime_t *runtime = subs->runtime;
 	if (runtime->dma_area) {
-		vfree_nocheck(runtime->dma_area);
+		vfree(runtime->dma_area);
 		runtime->dma_area = NULL;
 	}
 	return 0;
diff --git a/sound/ppc/beep.c b/sound/ppc/beep.c
index 1681ee1..d4ec6cc 100644
--- a/sound/ppc/beep.c
+++ b/sound/ppc/beep.c
@@ -171,8 +171,6 @@
  * beep volume mixer
  */
 
-#define chip_t pmac_t
-
 static int snd_pmac_info_beep(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index 392b2ab..db2f1815 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -220,7 +220,8 @@
 
 	/* set up constraints */
 	astr = snd_pmac_get_stream(chip, another_stream(rec->stream));
-	snd_runtime_check(astr, return -EINVAL);
+	if (! astr)
+		return -EINVAL;
 	astr->cur_freqs = 1 << rate_index;
 	astr->cur_formats = 1 << runtime->format;
 	chip->rate_index = rate_index;
@@ -467,7 +468,8 @@
 	pmac_stream_t *rec = snd_pmac_get_stream(chip, rule->deps[0]);
 	int i, freq_table[8], num_freqs;
 
-	snd_runtime_check(rec, return -EINVAL);
+	if (! rec)
+		return -EINVAL;
 	num_freqs = 0;
 	for (i = chip->num_freqs - 1; i >= 0; i--) {
 		if (rec->cur_freqs & (1 << i))
@@ -484,7 +486,8 @@
 	pmac_t *chip = rule->private;
 	pmac_stream_t *rec = snd_pmac_get_stream(chip, rule->deps[0]);
 
-	snd_runtime_check(rec, return -EINVAL);
+	if (! rec)
+		return -EINVAL;
 	return snd_mask_refine_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
 				   rec->cur_formats);
 }
@@ -569,7 +572,8 @@
 	snd_pmac_dma_stop(rec);
 
 	astr = snd_pmac_get_stream(chip, another_stream(rec->stream));
-	snd_runtime_check(astr, return -EINVAL);
+	if (! astr)
+		return -EINVAL;
 
 	/* reset constraints */
 	astr->cur_freqs = chip->freqs_ok;
@@ -1158,7 +1162,6 @@
 		.dev_free =	snd_pmac_dev_free,
 	};
 
-	snd_runtime_check(chip_return, return -EINVAL);
 	*chip_return = NULL;
 
 	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
@@ -1382,7 +1385,8 @@
 	pmac_t *chip;
 
 	chip = sleeping_pmac;
-	snd_runtime_check(chip, return 0);
+	if (! chip)
+		return 0;
 
 	switch (when) {
 	case PBOOK_SLEEP_NOW:
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index b5c4c15..59a77129 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -343,9 +343,6 @@
 	struct snd_dbri *next;
 } snd_dbri_t;
 
-/* Needed for the ALSA macros to work */
-#define chip_t snd_dbri_t
-
 #define DBRI_MAX_VOLUME		63	/* Output volume */
 #define DBRI_MAX_GAIN		15	/* Input gain */
 #define DBRI_RIGHT_BALANCE	255
@@ -1767,7 +1764,7 @@
 	spin_unlock_irqrestore(&dbri->lock, flags);
 }
 
-DECLARE_TASKLET(xmit_descs_task, xmit_descs, 0);
+static DECLARE_TASKLET(xmit_descs_task, xmit_descs, 0);
 
 /* transmission_complete_intr()
  *
diff --git a/sound/synth/emux/emux_synth.c b/sound/synth/emux/emux_synth.c
index 751bf12..bd71b73 100644
--- a/sound/synth/emux/emux_synth.c
+++ b/sound/synth/emux/emux_synth.c
@@ -171,7 +171,6 @@
 		vp = &emu->voices[ch];
 		if (STATE_IS_PLAYING(vp->state) &&
 		    vp->chan == chan && vp->key == note) {
-			vp->time = emu->use_time++;
 			vp->state = SNDRV_EMUX_ST_RELEASED;
 			if (vp->ontime == jiffies) {
 				/* if note-off is sent too shortly after
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 2ead878..99dae02 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -41,7 +41,6 @@
 #include <sound/driver.h>
 #include <linux/bitops.h>
 #include <linux/init.h>
-#include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/string.h>
@@ -185,7 +184,6 @@
 	unsigned int num_formats;		/* number of supported audio formats (list) */
 	struct list_head fmt_list;	/* format list */
 	spinlock_t lock;
-	struct tasklet_struct start_period_elapsed;	/* for start trigger */
 
 	struct snd_urb_ops ops;		/* callbacks (must be filled at init) */
 };
@@ -480,6 +478,28 @@
 }
 
 /*
+ * Prepare urb for streaming before playback starts.
+ *
+ * We don't care about (or have) any data, so we just send a transfer delimiter.
+ */
+static int prepare_startup_playback_urb(snd_usb_substream_t *subs,
+					snd_pcm_runtime_t *runtime,
+					struct urb *urb)
+{
+	unsigned int i;
+	snd_urb_ctx_t *ctx = urb->context;
+
+	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;
+	}
+	urb->transfer_buffer_length = 0;
+	return 0;
+}
+
+/*
  * prepare urb for playback data pipe
  *
  * Since a URB can handle only a single linear buffer, we must use double
@@ -568,12 +588,8 @@
 		subs->hwptr_done -= runtime->buffer_size;
 	spin_unlock_irqrestore(&subs->lock, flags);
 	urb->transfer_buffer_length = offs * stride;
-	if (period_elapsed) {
-		if (likely(subs->running))
-			snd_pcm_period_elapsed(subs->pcm_substream);
-		else
-			tasklet_hi_schedule(&subs->start_period_elapsed);
-	}
+	if (period_elapsed)
+		snd_pcm_period_elapsed(subs->pcm_substream);
 	return 0;
 }
 
@@ -588,22 +604,12 @@
 	return 0;
 }
 
-/*
- * Delay the snd_pcm_period_elapsed() call until after the start trigger
- * callback so that we're not longer in the substream's lock.
- */
-static void start_period_elapsed(unsigned long data)
-{
-	snd_usb_substream_t *subs = (snd_usb_substream_t *)data;
-	snd_pcm_period_elapsed(subs->pcm_substream);
-}
-
 
 /*
  */
 static struct snd_urb_ops audio_urb_ops[2] = {
 	{
-		.prepare =	prepare_playback_urb,
+		.prepare =	prepare_startup_playback_urb,
 		.retire =	retire_playback_urb,
 		.prepare_sync =	prepare_playback_sync_urb,
 		.retire_sync =	retire_playback_sync_urb,
@@ -618,7 +624,7 @@
 
 static struct snd_urb_ops audio_urb_ops_high_speed[2] = {
 	{
-		.prepare =	prepare_playback_urb,
+		.prepare =	prepare_startup_playback_urb,
 		.retire =	retire_playback_urb,
 		.prepare_sync =	prepare_playback_sync_urb_hs,
 		.retire_sync =	retire_playback_sync_urb_hs,
@@ -692,9 +698,9 @@
 	if (runtime->dma_area) {
 		if (runtime->dma_bytes >= size)
 			return 0; /* already large enough */
-		vfree_nocheck(runtime->dma_area);
+		vfree(runtime->dma_area);
 	}
-	runtime->dma_area = vmalloc_nocheck(size);
+	runtime->dma_area = vmalloc(size);
 	if (! runtime->dma_area)
 		return -ENOMEM;
 	runtime->dma_bytes = size;
@@ -706,7 +712,7 @@
 {
 	snd_pcm_runtime_t *runtime = subs->runtime;
 	if (runtime->dma_area) {
-		vfree_nocheck(runtime->dma_area);
+		vfree(runtime->dma_area);
 		runtime->dma_area = NULL;
 	}
 	return 0;
@@ -838,8 +844,7 @@
 		}
 		if (! alive)
 			break;
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	} while (time_before(jiffies, end_time));
 	if (alive)
 		snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
@@ -864,25 +869,40 @@
 
 
 /*
- * start/stop substream
+ * start/stop playback substream
  */
-static int snd_usb_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
+static int snd_usb_pcm_playback_trigger(snd_pcm_substream_t *substream,
+					int cmd)
 {
-	snd_usb_substream_t *subs = (snd_usb_substream_t *)substream->runtime->private_data;
-	int err;
+	snd_usb_substream_t *subs = substream->runtime->private_data;
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
-		err = start_urbs(subs, substream->runtime);
-		break;
+		subs->ops.prepare = prepare_playback_urb;
+		return 0;
 	case SNDRV_PCM_TRIGGER_STOP:
-		err = deactivate_urbs(subs, 0, 0);
-		break;
+		return deactivate_urbs(subs, 0, 0);
 	default:
-		err = -EINVAL;
-		break;
+		return -EINVAL;
 	}
-	return err < 0 ? err : 0;
+}
+
+/*
+ * start/stop capture substream
+ */
+static int snd_usb_pcm_capture_trigger(snd_pcm_substream_t *substream,
+				       int cmd)
+{
+	snd_usb_substream_t *subs = substream->runtime->private_data;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		return start_urbs(subs, substream->runtime);
+	case SNDRV_PCM_TRIGGER_STOP:
+		return deactivate_urbs(subs, 0, 0);
+	default:
+		return -EINVAL;
+	}
 }
 
 
@@ -1044,7 +1064,7 @@
 		u->urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
 		u->urb->interval = 1 << subs->datainterval;
 		u->urb->context = u;
-		u->urb->complete = snd_usb_complete_callback(snd_complete_urb);
+		u->urb->complete = snd_complete_urb;
 	}
 
 	if (subs->syncpipe) {
@@ -1070,7 +1090,7 @@
 			u->urb->number_of_packets = 1;
 			u->urb->interval = 1 << subs->syncinterval;
 			u->urb->context = u;
-			u->urb->complete = snd_usb_complete_callback(snd_complete_sync_urb);
+			u->urb->complete = snd_complete_sync_urb;
 		}
 	}
 	return 0;
@@ -1414,7 +1434,7 @@
 static int snd_usb_pcm_prepare(snd_pcm_substream_t *substream)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_usb_substream_t *subs = (snd_usb_substream_t *)runtime->private_data;
+	snd_usb_substream_t *subs = runtime->private_data;
 
 	if (! subs->cur_audiofmt) {
 		snd_printk(KERN_ERR "usbaudio: no format is specified!\n");
@@ -1434,7 +1454,13 @@
 	deactivate_urbs(subs, 0, 1);
 	wait_clear_urbs(subs);
 
-	return 0;
+	/* for playback, submit the URBs now; otherwise, the first hwptr_done
+	 * updates for all URBs would happen at the same time when starting */
+	if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
+		subs->ops.prepare = prepare_startup_playback_urb;
+		return start_urbs(subs, runtime);
+	} else
+		return 0;
 }
 
 static snd_pcm_hardware_t snd_usb_playback =
@@ -1848,7 +1874,7 @@
 	.hw_params =	snd_usb_hw_params,
 	.hw_free =	snd_usb_hw_free,
 	.prepare =	snd_usb_pcm_prepare,
-	.trigger =	snd_usb_pcm_trigger,
+	.trigger =	snd_usb_pcm_playback_trigger,
 	.pointer =	snd_usb_pcm_pointer,
 	.page =		snd_pcm_get_vmalloc_page,
 };
@@ -1860,7 +1886,7 @@
 	.hw_params =	snd_usb_hw_params,
 	.hw_free =	snd_usb_hw_free,
 	.prepare =	snd_usb_pcm_prepare,
-	.trigger =	snd_usb_pcm_trigger,
+	.trigger =	snd_usb_pcm_capture_trigger,
 	.pointer =	snd_usb_pcm_pointer,
 	.page =		snd_pcm_get_vmalloc_page,
 };
@@ -2079,9 +2105,6 @@
 
 	INIT_LIST_HEAD(&subs->fmt_list);
 	spin_lock_init(&subs->lock);
-	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
-		tasklet_init(&subs->start_period_elapsed, start_period_elapsed,
-			     (unsigned long)subs);
 
 	subs->stream = as;
 	subs->direction = stream;
@@ -2755,9 +2778,9 @@
 /*
  * create a stream for an interface with proper descriptors
  */
-static int create_standard_interface_quirk(snd_usb_audio_t *chip,
-					   struct usb_interface *iface,
-					   const snd_usb_audio_quirk_t *quirk)
+static int create_standard_audio_quirk(snd_usb_audio_t *chip,
+				       struct usb_interface *iface,
+				       const snd_usb_audio_quirk_t *quirk)
 {
 	struct usb_host_interface *alts;
 	struct usb_interface_descriptor *altsd;
@@ -2765,24 +2788,14 @@
 
 	alts = &iface->altsetting[0];
 	altsd = get_iface_desc(alts);
-	switch (quirk->type) {
-	case QUIRK_AUDIO_STANDARD_INTERFACE:
-		err = parse_audio_endpoints(chip, altsd->bInterfaceNumber);
-		if (!err)
-			usb_set_interface(chip->dev, altsd->bInterfaceNumber, 0); /* reset the current interface */
-		break;
-	case QUIRK_MIDI_STANDARD_INTERFACE:
-		err = snd_usb_create_midi_interface(chip, iface, NULL);
-		break;
-	default:
-		snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
-		return -ENXIO;
-	}
+	err = parse_audio_endpoints(chip, altsd->bInterfaceNumber);
 	if (err < 0) {
 		snd_printk(KERN_ERR "cannot setup if %d: error %d\n",
 			   altsd->bInterfaceNumber, err);
 		return err;
 	}
+	/* reset the current interface */
+	usb_set_interface(chip->dev, altsd->bInterfaceNumber, 0);
 	return 0;
 }
 
@@ -3044,7 +3057,7 @@
 		[QUIRK_MIDI_RAW] = snd_usb_create_midi_interface,
 		[QUIRK_MIDI_EMAGIC] = snd_usb_create_midi_interface,
 		[QUIRK_MIDI_MIDITECH] = snd_usb_create_midi_interface,
-		[QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_interface_quirk,
+		[QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
 		[QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
 		[QUIRK_AUDIO_EDIROL_UA700_UA25] = create_ua700_ua25_quirk,
 		[QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk,
@@ -3222,7 +3235,6 @@
 				 struct usb_interface *intf,
 				 const struct usb_device_id *usb_id)
 {
-	struct usb_host_config *config = dev->actconfig;
 	const snd_usb_audio_quirk_t *quirk = (const snd_usb_audio_quirk_t *)usb_id->driver_info;
 	int i, err;
 	snd_usb_audio_t *chip;
@@ -3243,7 +3255,6 @@
 	if (id == USB_ID(0x041e, 0x3000)) {
 		if (snd_usb_extigy_boot_quirk(dev, intf) < 0)
 			goto __err_val;
-		config = dev->actconfig;
 	}
 	/* SB Audigy 2 NX needs its own boot-up magic, too */
 	if (id == USB_ID(0x041e, 0x3020)) {
@@ -3272,11 +3283,6 @@
 		/* it's a fresh one.
 		 * now look for an empty slot and create a new card instance
 		 */
-		/* first, set the current configuration for this device */
-		if (usb_reset_configuration(dev) < 0) {
-			snd_printk(KERN_ERR "cannot reset configuration (value 0x%x)\n", get_cfg_desc(config)->bConfigurationValue);
-			goto __error;
-		}
 		for (i = 0; i < SNDRV_CARDS; i++)
 			if (enable[i] && ! usb_chip[i] &&
 			    (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index ad9eab2..b580202 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -249,14 +249,6 @@
 #define get_cfg_desc(cfg)	(&(cfg)->desc)
 #endif
 
-#ifndef usb_pipe_needs_resubmit
-#define usb_pipe_needs_resubmit(pipe) 1
-#endif
-
-#ifndef snd_usb_complete_callback
-#define snd_usb_complete_callback(x) (x)
-#endif
-
 #ifndef snd_usb_get_speed
 #define snd_usb_get_speed(dev) ((dev)->speed)
 #endif
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index f1a2e2c..f8aa662 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -47,7 +47,6 @@
 #include <linux/timer.h>
 #include <linux/usb.h>
 #include <sound/core.h>
-#include <sound/minors.h>
 #include <sound/rawmidi.h>
 #include "usbaudio.h"
 
@@ -246,10 +245,8 @@
 		}
 	}
 
-	if (usb_pipe_needs_resubmit(urb->pipe)) {
-		urb->dev = ep->umidi->chip->dev;
-		snd_usbmidi_submit_urb(urb, GFP_ATOMIC);
-	}
+	urb->dev = ep->umidi->chip->dev;
+	snd_usbmidi_submit_urb(urb, GFP_ATOMIC);
 }
 
 static void snd_usbmidi_out_urb_complete(struct urb* urb, struct pt_regs *regs)
@@ -863,13 +860,12 @@
 		return -ENOMEM;
 	}
 	if (ep_info->in_interval)
-		usb_fill_int_urb(ep->urb, umidi->chip->dev, pipe, buffer, length,
-				 snd_usb_complete_callback(snd_usbmidi_in_urb_complete),
-				 ep, ep_info->in_interval);
+		usb_fill_int_urb(ep->urb, umidi->chip->dev, pipe, buffer,
+				 length, snd_usbmidi_in_urb_complete, ep,
+				 ep_info->in_interval);
 	else
-		usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, length,
-				  snd_usb_complete_callback(snd_usbmidi_in_urb_complete),
-				  ep);
+		usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer,
+				  length, snd_usbmidi_in_urb_complete, ep);
 	ep->urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
 
 	rep->in = ep;
@@ -933,8 +929,7 @@
 		return -ENOMEM;
 	}
 	usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer,
-			  ep->max_transfer,
-			  snd_usb_complete_callback(snd_usbmidi_out_urb_complete), ep);
+			  ep->max_transfer, snd_usbmidi_out_urb_complete, ep);
 	ep->urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
 
 	spin_lock_init(&ep->buffer_lock);
@@ -1550,46 +1545,45 @@
 
 	/* detect the endpoint(s) to use */
 	memset(endpoints, 0, sizeof(endpoints));
-	if (!quirk) {
+	switch (quirk ? quirk->type : QUIRK_MIDI_STANDARD_INTERFACE) {
+	case QUIRK_MIDI_STANDARD_INTERFACE:
 		err = snd_usbmidi_get_ms_info(umidi, endpoints);
-	} else {
-		switch (quirk->type) {
-		case QUIRK_MIDI_FIXED_ENDPOINT:
-			memcpy(&endpoints[0], quirk->data,
-			       sizeof(snd_usb_midi_endpoint_info_t));
-			err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
-			break;
-		case QUIRK_MIDI_YAMAHA:
-			err = snd_usbmidi_detect_yamaha(umidi, &endpoints[0]);
-			break;
-		case QUIRK_MIDI_MIDIMAN:
-			umidi->usb_protocol_ops = &snd_usbmidi_midiman_ops;
-			memcpy(&endpoints[0], quirk->data,
-			       sizeof(snd_usb_midi_endpoint_info_t));
-			err = 0;
-			break;
-		case QUIRK_MIDI_NOVATION:
-			umidi->usb_protocol_ops = &snd_usbmidi_novation_ops;
-			err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
-			break;
-		case QUIRK_MIDI_RAW:
-			umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
-			err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
-			break;
-		case QUIRK_MIDI_EMAGIC:
-			umidi->usb_protocol_ops = &snd_usbmidi_emagic_ops;
-			memcpy(&endpoints[0], quirk->data,
-			       sizeof(snd_usb_midi_endpoint_info_t));
-			err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
-			break;
-		case QUIRK_MIDI_MIDITECH:
-			err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
-			break;
-		default:
-			snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
-			err = -ENXIO;
-			break;
-		}
+		break;
+	case QUIRK_MIDI_FIXED_ENDPOINT:
+		memcpy(&endpoints[0], quirk->data,
+		       sizeof(snd_usb_midi_endpoint_info_t));
+		err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
+		break;
+	case QUIRK_MIDI_YAMAHA:
+		err = snd_usbmidi_detect_yamaha(umidi, &endpoints[0]);
+		break;
+	case QUIRK_MIDI_MIDIMAN:
+		umidi->usb_protocol_ops = &snd_usbmidi_midiman_ops;
+		memcpy(&endpoints[0], quirk->data,
+		       sizeof(snd_usb_midi_endpoint_info_t));
+		err = 0;
+		break;
+	case QUIRK_MIDI_NOVATION:
+		umidi->usb_protocol_ops = &snd_usbmidi_novation_ops;
+		err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
+		break;
+	case QUIRK_MIDI_RAW:
+		umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
+		err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
+		break;
+	case QUIRK_MIDI_EMAGIC:
+		umidi->usb_protocol_ops = &snd_usbmidi_emagic_ops;
+		memcpy(&endpoints[0], quirk->data,
+		       sizeof(snd_usb_midi_endpoint_info_t));
+		err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
+		break;
+	case QUIRK_MIDI_MIDITECH:
+		err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
+		break;
+	default:
+		snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
+		err = -ENXIO;
+		break;
 	}
 	if (err < 0) {
 		kfree(umidi);
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index c3c08c9..e570d14 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -911,7 +911,7 @@
 	case USB_ID(0x0672, 0x1041):
 		if (!strcmp(kctl->id.name, "PCM Playback Volume") &&
 		    cval->min == -15616) {
-			snd_printk("using volume control quirk for the UDA1321/N101 chip\n");
+			snd_printk(KERN_INFO "using volume control quirk for the UDA1321/N101 chip\n");
 			cval->max = -256;
 		}
 	}
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index 948759d..ba506c3 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -294,6 +294,7 @@
 	}
 },
 {
+	/* a later revision uses ID 0x0099 */
 	USB_DEVICE(0x0582, 0x0005),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -384,6 +385,7 @@
 	}
 },
 {
+	/* a later revision uses ID 0x009d */
 	USB_DEVICE(0x0582, 0x0009),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -532,6 +534,7 @@
 	}
 },
 {
+	/* has ID 0x0013 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0012),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
@@ -545,6 +548,7 @@
 	}
 },
 {
+	/* has ID 0x0015 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0014),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -558,6 +562,7 @@
 	}
 },
 {
+	/* has ID 0x0017 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0016),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -588,6 +593,7 @@
 	}
 },
 {
+	/* has ID 0x001c when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x001b),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
@@ -618,6 +624,7 @@
 	}
 },
 {
+	/* has ID 0x001e when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x001d),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
@@ -631,6 +638,7 @@
 	}
 },
 {
+	/* has ID 0x0024 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0023),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -675,6 +683,7 @@
 	}
 },
 {
+	/* has ID 0x0028 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0027),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -688,6 +697,7 @@
 	}
 },
 {
+	/* has ID 0x002a when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0029),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -732,6 +742,7 @@
 	}
 },
 {
+	/* has ID 0x002e when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x002d),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
@@ -745,6 +756,7 @@
 	}
 },
 {
+	/* has ID 0x0030 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x002f),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
@@ -758,6 +770,7 @@
 	}
 },
 {
+	/* has ID 0x0034 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0033),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -770,7 +783,12 @@
 		}
 	}
 },
+	/* TODO: add Roland M-1000 support */
 {
+	/*
+	 * Has ID 0x0038 when not in "Advanced Driver" mode;
+	 * later revisions use IDs 0x0054 and 0x00a2.
+	 */
 	USB_DEVICE(0x0582, 0x0037),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
@@ -815,6 +833,7 @@
 	}
 },
 {
+	/* has ID 0x0041 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0040),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
@@ -828,6 +847,7 @@
 	}
 },
 {
+	/* has ID 0x0043 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0042),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
@@ -871,6 +891,7 @@
 	}
 },
 {
+	/* has ID 0x004a when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0048),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -883,7 +904,9 @@
 		}
 	}
 },
+	/* TODO: add Edirol M-100FX support */
 {
+	/* has ID 0x004f when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x004d),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -931,7 +954,9 @@
 		.type = QUIRK_MIDI_STANDARD_INTERFACE
 	}
 },
+	/* TODO: add Roland EXR support */
 {
+	/* has ID 0x0067 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0065),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -945,6 +970,7 @@
 	}
 },
 {
+	/* has ID 0x006b when not in "Advanced Driver" mode */
 	USB_DEVICE_VENDOR_SPEC(0x0582, 0x006a),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
@@ -958,6 +984,7 @@
 	}
 },
 {
+	/* has ID 0x006e when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x006d),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
@@ -1002,6 +1029,7 @@
 	}
 },
 {
+	/* has ID 0x0076 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0075),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "BOSS",
@@ -1015,10 +1043,11 @@
 	}
 },
 {
+	/* has ID 0x007b when not in "Advanced Driver" mode */
 	USB_DEVICE_VENDOR_SPEC(0x0582, 0x007a),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
-		/* RD-700SX, RD-300SX */
+		/* "RD" or "RD-700SX"? */
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
 		.data = & (const snd_usb_midi_endpoint_info_t) {
@@ -1048,6 +1077,15 @@
 		}
 	}
 },
+	/* TODO: add Edirol UA-101 support */
+	/* TODO: add Roland G-70 support */
+	/* TODO: add Roland V-SYNTH XT support */
+	/* TODO: add BOSS GT-PRO support */
+	/* TODO: add Edirol PC-50 support */
+	/* TODO: add Edirol PC-80 support */
+	/* TODO: add Edirol UA-1EX support */
+	/* TODO: add Edirol UM-3 support */
+	/* TODO: add Edirol MD-P1 support */
 
 /* Midiman/M-Audio devices */
 {
diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
index 0281a36..8abe086 100644
--- a/sound/usb/usx2y/usX2Yhwdep.c
+++ b/sound/usb/usx2y/usX2Yhwdep.c
@@ -193,7 +193,7 @@
 
 	do {
 		if ((err = usX2Y_create_usbmidi(card)) < 0) {
-			snd_printk("usX2Y_create_alsa_devices: usX2Y_create_usbmidi error %i \n", err);
+			snd_printk(KERN_ERR "usX2Y_create_alsa_devices: usX2Y_create_usbmidi error %i \n", err);
 			break;
 		}
 		if ((err = usX2Y_audio_create(card)) < 0) 
@@ -224,7 +224,7 @@
 		}
 		err = usb_set_interface(dev, 0, 1);
 		if (err)
-			snd_printk("usb_set_interface error \n");
+			snd_printk(KERN_ERR "usb_set_interface error \n");
 		else
 			err = usb_bulk_msg(dev, usb_sndbulkpipe(dev, 2), buf, dsp->length, &lret, 6000);
 		kfree(buf);
@@ -235,17 +235,17 @@
 		msleep(250);				// give the device some time
 		err = usX2Y_AsyncSeq04_init(priv);
 		if (err) {
-			snd_printk("usX2Y_AsyncSeq04_init error \n");
+			snd_printk(KERN_ERR "usX2Y_AsyncSeq04_init error \n");
 			return err;
 		}
 		err = usX2Y_In04_init(priv);
 		if (err) {
-			snd_printk("usX2Y_In04_init error \n");
+			snd_printk(KERN_ERR "usX2Y_In04_init error \n");
 			return err;
 		}
 		err = usX2Y_create_alsa_devices(hw->card);
 		if (err) {
-			snd_printk("usX2Y_create_alsa_devices error %i \n", err);
+			snd_printk(KERN_ERR "usX2Y_create_alsa_devices error %i \n", err);
 			snd_card_free(hw->card);
 			return err;
 		}
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index e6e6da1..cf77313 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -251,9 +251,8 @@
 			}
 		}
 
-	if (err) {
-		snd_printk("In04Int() usb_submit_urb err=%i\n", err);
-	}
+	if (err)
+		snd_printk(KERN_ERR "In04Int() usb_submit_urb err=%i\n", err);
 
 	urb->dev = usX2Y->chip.dev;
 	usb_submit_urb(urb, GFP_ATOMIC);
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index 0f09e0d..affda97 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -78,7 +78,7 @@
 	for (i = 0; i < nr_of_packs(); i++) {
 		cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
 		if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
-			snd_printk("activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status);
+			snd_printk(KERN_ERR "activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status);
 			return urb->iso_frame_desc[i].status;
 		}
 		len = urb->iso_frame_desc[i].actual_length / usX2Y->stride;
@@ -134,7 +134,7 @@
 		counts = cap_urb->iso_frame_desc[pack].actual_length / usX2Y->stride;
 		count += counts;
 		if (counts < 43 || counts > 50) {
-			snd_printk("should not be here with counts=%i\n", counts);
+			snd_printk(KERN_ERR "should not be here with counts=%i\n", counts);
 			return -EPIPE;
 		}
 		/* set up descriptor */
@@ -196,7 +196,7 @@
 	urb->hcpriv = NULL;
 	urb->dev = subs->usX2Y->chip.dev; /* we need to set this at each time */
 	if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
-		snd_printk("usb_submit_urb() returned %i\n", err);
+		snd_printk(KERN_ERR "usb_submit_urb() returned %i\n", err);
 		return err;
 	}
 	return 0;
@@ -283,16 +283,16 @@
 
 static void usX2Y_error_urb_status(usX2Ydev_t *usX2Y, snd_usX2Y_substream_t *subs, struct urb *urb)
 {
-	snd_printk("ep=%i stalled with status=%i\n", subs->endpoint, urb->status);
+	snd_printk(KERN_ERR "ep=%i stalled with status=%i\n", subs->endpoint, urb->status);
 	urb->status = 0;
 	usX2Y_clients_stop(usX2Y);
 }
 
 static void usX2Y_error_sequence(usX2Ydev_t *usX2Y, snd_usX2Y_substream_t *subs, struct urb *urb)
 {
-	snd_printk("Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
-		   "Most propably some urb of usb-frame %i is still missing.\n"
-		   "Cause could be too long delays in usb-hcd interrupt handling.\n",
+	snd_printk(KERN_ERR "Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
+		   KERN_ERR "Most propably some urb of usb-frame %i is still missing.\n"
+		   KERN_ERR "Cause could be too long delays in usb-hcd interrupt handling.\n",
 		   usb_get_current_frame_number(usX2Y->chip.dev),
 		   subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame);
 	usX2Y_clients_stop(usX2Y);
@@ -653,9 +653,8 @@
 {
 	usX2Ydev_t*	usX2Y = urb->context;
 	
-	if (urb->status) {
-		snd_printk("snd_usX2Y_04Int() urb->status=%i\n", urb->status);
-	}
+	if (urb->status)
+		snd_printk(KERN_ERR "snd_usX2Y_04Int() urb->status=%i\n", urb->status);
 	if (0 == --usX2Y->US04->len)
 		wake_up(&usX2Y->In04WaitQueue);
 }
@@ -740,7 +739,7 @@
 	}
 	usb_kill_urb(usX2Y->In04urb);
 	if ((err = usb_set_interface(usX2Y->chip.dev, 0, alternate))) {
-		snd_printk("usb_set_interface error \n");
+		snd_printk(KERN_ERR "usb_set_interface error \n");
 		return err;
 	}
 	usX2Y->In04urb->dev = usX2Y->chip.dev;
@@ -787,7 +786,7 @@
 		}
 	}
 	if (0 > (err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)))) {
-		snd_printk("snd_pcm_lib_malloc_pages(%p, %i) returned %i\n", substream, params_buffer_bytes(hw_params), err);
+		snd_printk(KERN_ERR "snd_pcm_lib_malloc_pages(%p, %i) returned %i\n", substream, params_buffer_bytes(hw_params), err);
 		return err;
 	}
 	return 0;
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index d0199c4..0dc828f 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -73,7 +73,7 @@
 	}
 	for (i = 0; i < nr_of_packs(); i++) {
 		if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
-			snd_printk("activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status);
+			snd_printk(KERN_ERR "activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status);
 			return urb->iso_frame_desc[i].status;
 		}
 		lens += urb->iso_frame_desc[i].actual_length / usX2Y->stride;
@@ -126,7 +126,7 @@
 		/* calculate the size of a packet */
 		counts = shm->captured_iso[shm->playback_iso_head].length / usX2Y->stride;
 		if (counts < 43 || counts > 50) {
-			snd_printk("should not be here with counts=%i\n", counts);
+			snd_printk(KERN_ERR "should not be here with counts=%i\n", counts);
 			return -EPIPE;
 		}
 		/* set up descriptor */